module AWS.EC2.Query
( ec2Query
, ec2QuerySource
, ec2QuerySource'
#ifdef DEBUG
, ec2QueryDebug
#endif
, ec2Delete
, module AWS.Lib.Query
, apiVersion
) where
import Data.ByteString (ByteString)
import Data.ByteString.Lazy.Char8 ()
import Data.XML.Types (Event(..))
import Data.Conduit
import qualified Data.Conduit.List as CL
import qualified Text.XML.Stream.Parse as XmlP
import Control.Monad.Trans.Class (lift)
import Control.Monad.IO.Class (MonadIO)
import qualified Control.Monad.State as State
import qualified Control.Monad.Reader as Reader
import Control.Exception.Lifted as E
import Data.Text (Text)
import Control.Applicative
import Data.Conduit.Internal as CI
import AWS.Class
import AWS.EC2.Internal
import AWS.Lib.Parser hiding (sinkError)
import AWS.Lib.Query
#ifdef DEBUG
import Debug.Trace
import Control.Monad.IO.Class (liftIO)
import qualified Data.Conduit.Binary as CB
#endif
apiVersion :: ByteString
apiVersion = "2012-12-01"
sinkRequestId :: MonadThrow m
=> GLSink Event m Text
sinkRequestId = do
await
await
getT "requestId"
sinkError :: MonadThrow m => ByteString -> Int -> GLSink Event m a
sinkError a s = do
await
element "Response" $ do
(c,m) <- element "Errors" $ element "Error" $
(,) <$> getT "Code" <*> getT "Message"
r <- getT "RequestID"
lift $ monadThrow $ ClientError a s c m r
ec2Query
:: (MonadResource m, MonadBaseControl IO m)
=> ByteString
-> [QueryParam]
-> GLSink Event m o
-> EC2 m o
ec2Query action params sink = do
src <- ec2QuerySource action params $ sink >>= yield
lift (src $$+- CL.head) >>= maybe (fail "parse error") return
ec2QuerySource
:: (MonadResource m, MonadBaseControl IO m)
=> ByteString
-> [QueryParam]
-> Conduit Event m o
-> EC2 m (ResumableSource m o)
ec2QuerySource action params cond = do
ec2QuerySource' action params Nothing cond
($=+) :: MonadIO m
=> ResumableSource m a
-> Conduit a m b
-> m (ResumableSource m b)
a $=+ b = do
(sa, fa) <- unwrapResumable a
return $ CI.ResumableSource (sa $= b) fa
ec2QuerySource'
:: (MonadResource m, MonadBaseControl IO m)
=> ByteString
-> [QueryParam]
-> Maybe Text
-> Conduit Event m o
-> EC2 m (ResumableSource m o)
ec2QuerySource' action params token cond = do
cred <- Reader.ask
ctx <- State.get
(src1, rid) <- lift $ do
response <- requestQuery cred ctx action params' apiVersion sinkError
res <- response $=+ XmlP.parseBytes XmlP.def
res $$++ sinkRequestId
State.put ctx{lastRequestId = Just rid}
lift $ src1 $=+ (cond >> nextToken)
where
params' = ("NextToken" |=? token) : params
nextToken :: MonadThrow m => Conduit Event m o
nextToken = getT "nextToken" >>= maybe (return ()) (E.throw . NextToken)
#ifdef DEBUG
ec2QueryDebug
:: (MonadResource m, MonadBaseControl IO m)
=> ByteString
-> [QueryParam]
-> EC2 m a
ec2QueryDebug = debugQuery apiVersion
#endif
ec2Delete
:: (MonadResource m, MonadBaseControl IO m)
=> ByteString
-> Text
-> Text
-> EC2 m Bool
ec2Delete apiName idName targetId = do
ec2Query apiName [ idName |= targetId ] $ getT "return"