LogCabin
RPC/ServerRPC.h
Go to the documentation of this file.
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 */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines