Revision 9c0a27d0

b/src/Ganeti/Query/Common.hs
4 4

  
5 5
{-
6 6

  
7
Copyright (C) 2012 Google Inc.
7
Copyright (C) 2012, 2013 Google Inc.
8 8

  
9 9
This program is free software; you can redistribute it and/or modify
10 10
it under the terms of the GNU General Public License as published by
......
104 104

  
105 105
-- | Convert RpcError to ResultStatus
106 106
rpcErrorToStatus :: RpcError -> ResultStatus
107
rpcErrorToStatus (OfflineNodeError _) = RSOffline
107
rpcErrorToStatus OfflineNodeError = RSOffline
108 108
rpcErrorToStatus _ = RSNoData
109 109

  
110 110
-- * Common fields
b/src/Ganeti/Rpc.hs
98 98

  
99 99
-- | Data type for RPC error reporting.
100 100
data RpcError
101
  = CurlLayerError Node String
101
  = CurlLayerError String
102 102
  | JsonDecodeError String
103 103
  | RpcResultError String
104
  | OfflineNodeError Node
104
  | OfflineNodeError
105 105
  deriving (Show, Eq)
106 106

  
107 107
-- | Provide explanation to RPC errors.
108 108
explainRpcError :: RpcError -> String
109
explainRpcError (CurlLayerError node code) =
110
    "Curl error for " ++ nodeName node ++ ", " ++ code
109
explainRpcError (CurlLayerError code) =
110
    "Curl error:" ++ code
111 111
explainRpcError (JsonDecodeError msg) =
112 112
    "Error while decoding JSON from HTTP response: " ++ msg
113 113
explainRpcError (RpcResultError msg) =
114 114
    "Error reponse received from RPC server: " ++ msg
115
explainRpcError (OfflineNodeError node) =
116
    "Node " ++ nodeName node ++ " is marked as offline"
115
explainRpcError OfflineNodeError =
116
    "Node is marked offline"
117 117

  
118 118
type ERpcError = Either RpcError
119 119

  
......
153 153

  
154 154
-- | Execute the request and return the result as a plain String. When
155 155
-- curl reports an error, we propagate it.
156
executeHttpRequest :: Node -> ERpcError HttpClientRequest
157
                   -> IO (ERpcError String)
158
executeHttpRequest _ (Left rpc_err) = return $ Left rpc_err
159
executeHttpRequest node (Right request) = do
156
executeHttpRequest :: ERpcError HttpClientRequest -> IO (ERpcError String)
157
executeHttpRequest (Left rpc_err) = return $ Left rpc_err
158
executeHttpRequest (Right request) = do
160 159
  let reqOpts = CurlPostFields [requestData request]:requestOpts request
161 160
      url = requestUrl request
162 161
  -- FIXME: This is very similar to getUrl in Htools/Rapi.hs
163 162
  (code, !body) <- curlGetString url $ curlOpts ++ reqOpts
164 163
  return $ case code of
165 164
             CurlOK -> Right body
166
             _ -> Left $ CurlLayerError node (show code)
165
             _ -> Left $ CurlLayerError (show code)
167 166

  
168 167
-- | Prepare url for the HTTP request.
169 168
prepareUrl :: (RpcCall a) => Node -> a -> String
......
183 182
                              , requestData = rpcCallData node call
184 183
                              , requestOpts = opts ++ curlOpts
185 184
                              }
186
  | otherwise = Left $ OfflineNodeError node
185
  | otherwise = Left OfflineNodeError
187 186

  
188 187
-- | Parse a result based on the received HTTP response.
189 188
parseHttpResponse :: (Rpc a b) => a -> ERpcError String -> ERpcError b
......
201 200
                        [CurlOption] -> Node -> a -> IO (Node, ERpcError b)
202 201
executeSingleRpcCall opts node call = do
203 202
  let request = prepareHttpRequest opts node call
204
  response <- executeHttpRequest node request
203
  response <- executeHttpRequest request
205 204
  let result = parseHttpResponse call response
206 205
  return (node, result)
207 206

  
b/test/hs/Test/Ganeti/Rpc.hs
7 7

  
8 8
{-
9 9

  
10
Copyright (C) 2009, 2010, 2011, 2012 Google Inc.
10
Copyright (C) 2009, 2010, 2011, 2012, 2013 Google Inc.
11 11

  
12 12
This program is free software; you can redistribute it and/or modify
13 13
it under the terms of the GNU General Public License as published by
......
59 59
prop_noffl_request_allinstinfo call =
60 60
  forAll (arbitrary `suchThat` Objects.nodeOffline) $ \node -> monadicIO $ do
61 61
      res <- run $ Rpc.executeRpcCall [node] call
62
      stop $ res ==? [(node, Left (Rpc.OfflineNodeError node))]
62
      stop $ res ==? [(node, Left Rpc.OfflineNodeError)]
63 63

  
64 64
prop_noffl_request_instlist :: Rpc.RpcCallInstanceList -> Property
65 65
prop_noffl_request_instlist call =
66 66
  forAll (arbitrary `suchThat` Objects.nodeOffline) $ \node -> monadicIO $ do
67 67
      res <- run $ Rpc.executeRpcCall [node] call
68
      stop $ res ==? [(node, Left (Rpc.OfflineNodeError node))]
68
      stop $ res ==? [(node, Left Rpc.OfflineNodeError)]
69 69

  
70 70
prop_noffl_request_nodeinfo :: Rpc.RpcCallNodeInfo -> Property
71 71
prop_noffl_request_nodeinfo call =
72 72
  forAll (arbitrary `suchThat` Objects.nodeOffline) $ \node -> monadicIO $ do
73 73
      res <- run $ Rpc.executeRpcCall [node] call
74
      stop $ res ==? [(node, Left (Rpc.OfflineNodeError node))]
74
      stop $ res ==? [(node, Left Rpc.OfflineNodeError)]
75 75

  
76 76
testSuite "Rpc"
77 77
  [ 'prop_noffl_request_allinstinfo

Also available in: Unified diff