1# Protocol Buffers - Google's data interchange format 2# Copyright 2008 Google Inc. All rights reserved. 3# https://developers.google.com/protocol-buffers/ 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions are 7# met: 8# 9# * Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# * Redistributions in binary form must reproduce the above 12# copyright notice, this list of conditions and the following disclaimer 13# in the documentation and/or other materials provided with the 14# distribution. 15# * Neither the name of Google Inc. nor the names of its 16# contributors may be used to endorse or promote products derived from 17# this software without specific prior written permission. 18# 19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31"""DEPRECATED: Declares the RPC service interfaces. 32 33This module declares the abstract interfaces underlying proto2 RPC 34services. These are intended to be independent of any particular RPC 35implementation, so that proto2 services can be used on top of a variety 36of implementations. Starting with version 2.3.0, RPC implementations should 37not try to build on these, but should instead provide code generator plugins 38which generate code specific to the particular RPC implementation. This way 39the generated code can be more appropriate for the implementation in use 40and can avoid unnecessary layers of indirection. 41""" 42 43__author__ = 'petar@google.com (Petar Petrov)' 44 45 46class RpcException(Exception): 47 """Exception raised on failed blocking RPC method call.""" 48 pass 49 50 51class Service(object): 52 53 """Abstract base interface for protocol-buffer-based RPC services. 54 55 Services themselves are abstract classes (implemented either by servers or as 56 stubs), but they subclass this base interface. The methods of this 57 interface can be used to call the methods of the service without knowing 58 its exact type at compile time (analogous to the Message interface). 59 """ 60 61 def GetDescriptor(): 62 """Retrieves this service's descriptor.""" 63 raise NotImplementedError 64 65 def CallMethod(self, method_descriptor, rpc_controller, 66 request, done): 67 """Calls a method of the service specified by method_descriptor. 68 69 If "done" is None then the call is blocking and the response 70 message will be returned directly. Otherwise the call is asynchronous 71 and "done" will later be called with the response value. 72 73 In the blocking case, RpcException will be raised on error. 74 75 Preconditions: 76 77 * method_descriptor.service == GetDescriptor 78 * request is of the exact same classes as returned by 79 GetRequestClass(method). 80 * After the call has started, the request must not be modified. 81 * "rpc_controller" is of the correct type for the RPC implementation being 82 used by this Service. For stubs, the "correct type" depends on the 83 RpcChannel which the stub is using. 84 85 Postconditions: 86 87 * "done" will be called when the method is complete. This may be 88 before CallMethod() returns or it may be at some point in the future. 89 * If the RPC failed, the response value passed to "done" will be None. 90 Further details about the failure can be found by querying the 91 RpcController. 92 """ 93 raise NotImplementedError 94 95 def GetRequestClass(self, method_descriptor): 96 """Returns the class of the request message for the specified method. 97 98 CallMethod() requires that the request is of a particular subclass of 99 Message. GetRequestClass() gets the default instance of this required 100 type. 101 102 Example: 103 method = service.GetDescriptor().FindMethodByName("Foo") 104 request = stub.GetRequestClass(method)() 105 request.ParseFromString(input) 106 service.CallMethod(method, request, callback) 107 """ 108 raise NotImplementedError 109 110 def GetResponseClass(self, method_descriptor): 111 """Returns the class of the response message for the specified method. 112 113 This method isn't really needed, as the RpcChannel's CallMethod constructs 114 the response protocol message. It's provided anyway in case it is useful 115 for the caller to know the response type in advance. 116 """ 117 raise NotImplementedError 118 119 120class RpcController(object): 121 122 """An RpcController mediates a single method call. 123 124 The primary purpose of the controller is to provide a way to manipulate 125 settings specific to the RPC implementation and to find out about RPC-level 126 errors. The methods provided by the RpcController interface are intended 127 to be a "least common denominator" set of features which we expect all 128 implementations to support. Specific implementations may provide more 129 advanced features (e.g. deadline propagation). 130 """ 131 132 # Client-side methods below 133 134 def Reset(self): 135 """Resets the RpcController to its initial state. 136 137 After the RpcController has been reset, it may be reused in 138 a new call. Must not be called while an RPC is in progress. 139 """ 140 raise NotImplementedError 141 142 def Failed(self): 143 """Returns true if the call failed. 144 145 After a call has finished, returns true if the call failed. The possible 146 reasons for failure depend on the RPC implementation. Failed() must not 147 be called before a call has finished. If Failed() returns true, the 148 contents of the response message are undefined. 149 """ 150 raise NotImplementedError 151 152 def ErrorText(self): 153 """If Failed is true, returns a human-readable description of the error.""" 154 raise NotImplementedError 155 156 def StartCancel(self): 157 """Initiate cancellation. 158 159 Advises the RPC system that the caller desires that the RPC call be 160 canceled. The RPC system may cancel it immediately, may wait awhile and 161 then cancel it, or may not even cancel the call at all. If the call is 162 canceled, the "done" callback will still be called and the RpcController 163 will indicate that the call failed at that time. 164 """ 165 raise NotImplementedError 166 167 # Server-side methods below 168 169 def SetFailed(self, reason): 170 """Sets a failure reason. 171 172 Causes Failed() to return true on the client side. "reason" will be 173 incorporated into the message returned by ErrorText(). If you find 174 you need to return machine-readable information about failures, you 175 should incorporate it into your response protocol buffer and should 176 NOT call SetFailed(). 177 """ 178 raise NotImplementedError 179 180 def IsCanceled(self): 181 """Checks if the client cancelled the RPC. 182 183 If true, indicates that the client canceled the RPC, so the server may 184 as well give up on replying to it. The server should still call the 185 final "done" callback. 186 """ 187 raise NotImplementedError 188 189 def NotifyOnCancel(self, callback): 190 """Sets a callback to invoke on cancel. 191 192 Asks that the given callback be called when the RPC is canceled. The 193 callback will always be called exactly once. If the RPC completes without 194 being canceled, the callback will be called after completion. If the RPC 195 has already been canceled when NotifyOnCancel() is called, the callback 196 will be called immediately. 197 198 NotifyOnCancel() must be called no more than once per request. 199 """ 200 raise NotImplementedError 201 202 203class RpcChannel(object): 204 205 """Abstract interface for an RPC channel. 206 207 An RpcChannel represents a communication line to a service which can be used 208 to call that service's methods. The service may be running on another 209 machine. Normally, you should not use an RpcChannel directly, but instead 210 construct a stub {@link Service} wrapping it. Example: 211 212 Example: 213 RpcChannel channel = rpcImpl.Channel("remotehost.example.com:1234") 214 RpcController controller = rpcImpl.Controller() 215 MyService service = MyService_Stub(channel) 216 service.MyMethod(controller, request, callback) 217 """ 218 219 def CallMethod(self, method_descriptor, rpc_controller, 220 request, response_class, done): 221 """Calls the method identified by the descriptor. 222 223 Call the given method of the remote service. The signature of this 224 procedure looks the same as Service.CallMethod(), but the requirements 225 are less strict in one important way: the request object doesn't have to 226 be of any specific class as long as its descriptor is method.input_type. 227 """ 228 raise NotImplementedError 229