LogCabin
|
00001 /* Copyright (c) 2012 Stanford University 00002 * Copyright (c) 2015 Diego Ongaro 00003 * 00004 * Permission to use, copy, modify, and distribute this software for any 00005 * purpose with or without fee is hereby granted, provided that the above 00006 * copyright notice and this permission notice appear in all copies. 00007 * 00008 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES 00009 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 00010 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR 00011 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 00012 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 00013 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 00014 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 00015 */ 00016 00017 #include <cinttypes> 00018 #include <google/protobuf/message.h> 00019 00020 #include "RPC/Protocol.h" 00021 #include "RPC/OpaqueServerRPC.h" 00022 00023 #ifndef LOGCABIN_RPC_SERVERRPC_H 00024 #define LOGCABIN_RPC_SERVERRPC_H 00025 00026 namespace LogCabin { 00027 namespace RPC { 00028 00029 /** 00030 * This class represents the server side of a remote procedure call. 00031 * A Server creates an instance when an RPC is initiated. This is used to send 00032 * the reply. 00033 * 00034 * This class may be used from any thread, but each object is meant to be 00035 * accessed by only one thread at a time. 00036 */ 00037 class ServerRPC { 00038 00039 /** 00040 * Constructor for ServerRPC. This is called by Server only. 00041 */ 00042 explicit ServerRPC(OpaqueServerRPC opaqueRPC); 00043 00044 public: 00045 /** 00046 * Default constructor for empty RPC that can't be replied to. 00047 * This is useful as a placeholder for a real ServerRPC. 00048 */ 00049 ServerRPC(); 00050 00051 /** 00052 * Move constructor. 00053 */ 00054 ServerRPC(ServerRPC&& other); 00055 00056 /** 00057 * Destructor. 00058 */ 00059 ~ServerRPC(); 00060 00061 /** 00062 * Move assignment. 00063 */ 00064 ServerRPC& operator=(ServerRPC&& other); 00065 00066 /** 00067 * Returns whether this RPC is waiting for a reply. 00068 * \return 00069 * True if the owner needs to take action based on this RPC; 00070 * false if the RPC is not valid or has already been replied to. If 00071 * this returns false, the caller should discard this ServerRPC 00072 * object. 00073 */ 00074 bool needsReply() const { 00075 return active; 00076 } 00077 00078 /** 00079 * This identifies which Service the RPC is destined for. 00080 * The Server class uses this to dispatch to the appropriate Service. 00081 */ 00082 uint16_t getService() const { 00083 return service; 00084 } 00085 00086 /** 00087 * This tells the Service what service-specific errors the client 00088 * understands. Services should take care not to send a client a 00089 * service-specific error that it doesn't understand. 00090 */ 00091 uint8_t getServiceSpecificErrorVersion() const { 00092 return serviceSpecificErrorVersion; 00093 } 00094 00095 /** 00096 * Return which RPC is being executed, scoped to the service. 00097 */ 00098 uint16_t getOpCode() const { 00099 return opCode; 00100 } 00101 00102 /** 00103 * Parse the request out of the RPC. 00104 * \param[out] request 00105 * An empty protocol buffer the request will be be unpacked into. 00106 * \return 00107 * True if 'request' contains a valid RPC request which needs to be 00108 * handled; false otherwise. If this returns false, the caller should 00109 * discard this ServerRPC object. 00110 */ 00111 bool getRequest(google::protobuf::Message& request); 00112 00113 /** 00114 * Copy the request out of the RPC. 00115 * \param[out] buffer 00116 * An empty buffer that the request will be copied into. 00117 * \return 00118 * True if 'request' contains a valid RPC request which needs to be 00119 * handled; false otherwise. If this returns false, the caller should 00120 * discard this ServerRPC object. 00121 */ 00122 bool getRequest(Core::Buffer& buffer) const; 00123 00124 /** 00125 * Send a normal response back to the client. 00126 * \param payload 00127 * A protocol buffer to serialize into the response. 00128 */ 00129 void reply(const google::protobuf::Message& payload); 00130 00131 /** 00132 * Send a service-specific error back to the client. 00133 * \param serviceSpecificError 00134 * Details explaining the error to send back to the client. 00135 */ 00136 void returnError(const google::protobuf::Message& serviceSpecificError); 00137 00138 /** 00139 * Reject the RPC on the grounds that it specifies an invalid service ID. 00140 */ 00141 void rejectInvalidService(); 00142 00143 /** 00144 * Reject the RPC on the grounds that it specifies an invalid request. 00145 */ 00146 void rejectInvalidRequest(); 00147 00148 /** 00149 * Close the session on which this request originated. This is an impolite 00150 * thing to do to a client but can be useful occasionally, for example for 00151 * testing. 00152 */ 00153 void closeSession(); 00154 00155 private: 00156 /** 00157 * Reject the RPC. 00158 * \param status 00159 * This should be INVALID_VERSION, INVALID_SERVICE, or 00160 * INVALID_REQUEST. 00161 */ 00162 void reject(RPC::Protocol::Status status); 00163 00164 /** 00165 * The underlying transport-level RPC object. It doesn't know how to 00166 * interpret the raw bytes of the RPC, but it gets them from here to there. 00167 */ 00168 OpaqueServerRPC opaqueRPC; 00169 00170 /** 00171 * Set to true if the RPC needs a reply, false otherwise. 00172 */ 00173 bool active; 00174 00175 /// See getService(). 00176 uint16_t service; 00177 /// See getServiceSpecificErrorVersion(). 00178 uint8_t serviceSpecificErrorVersion; 00179 /// See getOpCode(). 00180 uint16_t opCode; 00181 00182 friend class Server; 00183 00184 // ServerRPC is non-copyable. 00185 ServerRPC(const ServerRPC&) = delete; 00186 ServerRPC& operator=(const ServerRPC&) = delete; 00187 00188 }; // class ServerRPC 00189 00190 } // namespace LogCabin::RPC 00191 } // namespace LogCabin 00192 00193 #endif /* LOGCABIN_RPC_SERVERRPC_H */