Statistics
| Branch: | Tag: | Revision:

root / htools / Ganeti / Rpc.hs @ d4709cce

History | View | Annotate | Download (2.6 kB)

1
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
2

    
3
{-| Implementation of the RPC client.
4

    
5
-}
6

    
7
{-
8

    
9
Copyright (C) 2012 Google Inc.
10

    
11
This program is free software; you can redistribute it and/or modify
12
it under the terms of the GNU General Public License as published by
13
the Free Software Foundation; either version 2 of the License, or
14
(at your option) any later version.
15

    
16
This program is distributed in the hope that it will be useful, but
17
WITHOUT ANY WARRANTY; without even the implied warranty of
18
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19
General Public License for more details.
20

    
21
You should have received a copy of the GNU General Public License
22
along with this program; if not, write to the Free Software
23
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24
02110-1301, USA.
25

    
26
-}
27

    
28
module Ganeti.Rpc
29
  ( RpcCall
30
  , RpcResult
31
  , Rpc
32
  , RpcError(..)
33

    
34
  , rpcCallName
35
  , rpcCallTimeout
36
  , rpcCallData
37
  , rpcCallAcceptOffline
38

    
39
  , rpcResultFill
40
  ) where
41

    
42
import qualified Text.JSON as J
43

    
44
import Ganeti.Objects
45

    
46
-- | Data type for RPC error reporting.
47
data RpcError
48
  = CurlDisabledError
49
  | CurlLayerError Node String
50
  | JsonDecodeError String
51
  | OfflineNodeError Node
52
  deriving Eq
53

    
54
instance Show RpcError where
55
  show CurlDisabledError =
56
    "RPC/curl backend disabled at compile time"
57
  show (CurlLayerError node code) =
58
    "Curl error for " ++ nodeName node ++ ", error " ++ code
59
  show (JsonDecodeError msg) =
60
    "Error while decoding JSON from HTTP response " ++ msg
61
  show (OfflineNodeError node) =
62
    "Node " ++ nodeName node ++ " is marked as offline"
63

    
64
rpcErrorJsonReport :: (Monad m) => J.Result a -> m (Either RpcError a)
65
rpcErrorJsonReport (J.Error x) = return $ Left $ JsonDecodeError x
66
rpcErrorJsonReport (J.Ok x) = return $ Right x
67

    
68
-- | A generic class for RPC calls.
69
class (J.JSON a) => RpcCall a where
70
  -- | Give the (Python) name of the procedure.
71
  rpcCallName :: a -> String
72
  -- | Calculate the timeout value for the call execution.
73
  rpcCallTimeout :: a -> Int
74
  -- | Prepare arguments of the call to be send as POST.
75
  rpcCallData :: Node -> a -> String
76
  -- | Whether we accept offline nodes when making a call.
77
  rpcCallAcceptOffline :: a -> Bool
78

    
79
  rpcCallData _ = J.encode
80

    
81
-- | A generic class for RPC results with default implementation.
82
class (J.JSON a) => RpcResult a where
83
  -- | Create a result based on the received HTTP response.
84
  rpcResultFill :: (Monad m) => String -> m (Either RpcError a)
85

    
86
  rpcResultFill res = rpcErrorJsonReport $  J.decode res
87

    
88
-- | Generic class that ensures matching RPC call with its respective
89
-- result.
90
class (RpcCall a, RpcResult b) => Rpc a b | a -> b