hadoop-rpc-0.1.0.0: src/Data/Hadoop/Protobuf/Headers.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
module Data.Hadoop.Protobuf.Headers where
import Data.ByteString (ByteString)
import Data.ProtocolBuffers
import Data.ProtocolBuffers.Orphans ()
import Data.Text (Text)
import Data.Word (Word32, Word64)
import GHC.Generics (Generic)
------------------------------------------------------------------------
-- TODO From Hadoop source:
-- Spec for UserInformationProto is specified in ProtoUtil#makeIpcConnectionContext
-- | User information beyond what can be determined as part of the
-- security handshake at connection time (kerberos, tokens, etc)
data UserInformation = UserInformation
{ effectiveUser :: Optional 1 (Value Text)
, realUser :: Optional 2 (Value Text)
} deriving (Generic, Show)
instance Encode UserInformation
instance Decode UserInformation
-- | The connection context is sent as part of the connection
-- establishment. It establishes the context for ALL Rpc calls
-- within the connection.
data IpcConnectionContext = IpcConnectionContext
{ ctxUserInfo :: Optional 2 (Message UserInformation)
, ctxProtocol :: Optional 3 (Value Text) -- ^ Name of the next RPC layer.
} deriving (Generic, Show)
instance Encode IpcConnectionContext
instance Decode IpcConnectionContext
------------------------------------------------------------------------
-- | Determines the RPC Engine and the serialization of the RPC request.
data RpcKind = Builtin -- ^ Used for built-in calls by tests
| Writable -- ^ Use WritableRpcEngine
| ProtocolBuffer -- ^ Use ProtobufRpcEngine
deriving (Generic, Show, Enum)
data RpcOperation = FinalPacket -- ^ The final RPC packet
| ContinuationPacket -- ^ Not implemented yet
| CloseConnection -- ^ Close the RPC connection
deriving (Generic, Show, Enum)
data RpcRequestHeader = RpcRequestHeader
{ reqKind :: Optional 1 (Enumeration RpcKind)
, reqOp :: Optional 2 (Enumeration RpcOperation)
, reqCallId :: Required 3 (Value Word32) -- ^ A sequence number that is sent back in the response
-- Fields below don't apply until v9
--, reqClientId :: Required 4 (Value ByteString) -- ^ Globally unique client ID
--, reqRetryCount :: Optional 5 (Value Int32) -- ^ Retry count, 1 means this is the first retry
} deriving (Generic, Show)
instance Encode RpcRequestHeader
instance Decode RpcRequestHeader
-- | This message is used for Protobuf RPC Engine.
-- The message is used to marshal a RPC request from RPC client to the
-- RPC server. The response to the RPC call (including errors) are handled
-- as part of the standard RPC response.
data RpcRequest = RpcRequest
{ reqMethodName :: Required 1 (Value Text) -- ^ Name of the RPC method
, reqBytes :: Optional 2 (Value ByteString) -- ^ Bytes corresponding to the client protobuf request
, reqProtocolName :: Required 3 (Value Text) -- ^ Protocol name of class declaring the called method
, reqProtocolVersion :: Required 4 (Value Word64) -- ^ Protocol version of class declaring the called method
} deriving (Generic, Show)
instance Encode RpcRequest
instance Decode RpcRequest
------------------------------------------------------------------------
-- | Success or failure. The reponse header's error detail, exception
-- class name and error message contains further details on the error.
data RpcStatus = Success -- ^ Succeeded
| Error -- ^ Non-fatal error, connection left open
| Fatal -- ^ Fatal error, connection closed
deriving (Generic, Show, Eq, Enum)
-- | Note that RPC response header is also used when connection setup fails.
-- (i.e. the response looks like an RPC response with a fake callId)
--
-- For v7:
-- - If successfull then the Respose follows after this header
-- - length (4 byte int), followed by the response
-- - If error or fatal - the exception info follow
-- - length (4 byte int) Class name of exception - UTF-8 string
-- - length (4 byte int) Stacktrace - UTF-8 string
-- - if the strings are null then the length is -1
--
-- In case of Fatal error then the respose contains the Serverside's IPC version.
data RpcResponseHeader = RpcResponseHeader
{ rspCallId :: Required 1 (Value Word32) -- ^ Call ID used in request
, rspStatus :: Required 2 (Enumeration RpcStatus)
, rspServerIpcVersion :: Optional 3 (Value Word32) -- ^ v7: Sent if fatal v9: Sent if success or fail
-- Fields below don't apply until v9
--, rspExceptionClassName :: Optional 4 (Value Text) -- ^ If the request fails
--, rspErrorMsg :: Optional 5 (Value Text) -- ^ If the request fails, often contains stack trace
--, rspErrorDetail :: Optional 6 (Enumeration Error) -- ^ In case of error
--, rspClientId :: Optional 7 (Value ByteString) -- ^ Globally unique client ID
--, rspRetryCount :: Optional 8 (Value Int32)
} deriving (Generic, Show)
instance Encode RpcResponseHeader
instance Decode RpcResponseHeader
{-
-- Error doesn't apply until v9
-- | Describes why an RPC error occurred.
data Error = ErrorApplication -- ^ RPC failed - RPC app threw exception
| ErrorNoSuchMethod -- ^ RPC error - no such method
| ErrorNoSuchProtocol -- ^ RPC error - no such protocol
| ErrorRpcServer -- ^ RPC error on server side
| ErrorSerializingResponse -- ^ Error serializing response
| ErrorRpcVersionMismatch -- ^ RPC protocol version mismatch
| ErrorCode Int -- ^ RPC error that we don't know about
-- starts at 10
| FatalUnknown -- ^ Unknown fatal error
| FatalUnsupportedSerialization -- ^ IPC layer serilization type invalid
| FatalInvalidRpcHeader -- ^ Fields of RPC header are invalid
| FatalDeserializingRequest -- ^ Could not deserialize RPC request
| FatalVersionMismatch -- ^ IPC layer version mismatch
| FatalUnauthorized -- ^ Auth failed
| FatalCode Int -- ^ Fatal error that we don't know about
deriving (Generic, Show)
instance Enum Error where
toEnum n = case n of
1 -> ErrorApplication
2 -> ErrorNoSuchMethod
3 -> ErrorNoSuchProtocol
4 -> ErrorRpcServer
5 -> ErrorSerializingResponse
6 -> ErrorRpcVersionMismatch
10 -> FatalUnknown
11 -> FatalUnsupportedSerialization
12 -> FatalInvalidRpcHeader
13 -> FatalDeserializingRequest
14 -> FatalVersionMismatch
15 -> FatalUnauthorized
_ -> if n < 10 then ErrorCode n else FatalCode n
fromEnum e = case e of
ErrorApplication -> 1
ErrorNoSuchMethod -> 2
ErrorNoSuchProtocol -> 3
ErrorRpcServer -> 4
ErrorSerializingResponse -> 5
ErrorRpcVersionMismatch -> 6
ErrorCode n -> n
FatalUnknown -> 10
FatalUnsupportedSerialization -> 11
FatalInvalidRpcHeader -> 12
FatalDeserializingRequest -> 13
FatalVersionMismatch -> 14
FatalUnauthorized -> 15
FatalCode n -> n
-}