{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
module Network.AWS.Easy.Service
( AWSConfig
, Endpoint(..)
, HostName
, Logging(..)
, Port
, awscCredentials
, awscEndpoint
, awscLogging
, awsConfig
, connect
, withAWS
) where
import Control.Lens ((<&>), makeLenses, set)
import Control.Monad.Trans.AWS
( AWST'
, reconfigure
, runAWST
, within
)
import Data.ByteString (ByteString)
import Network.AWS
( Credentials(..)
, Env
, LogLevel(..)
, Region(..)
, Service
, envLogger
, newEnv
, newLogger
, runResourceT
, setEndpoint
)
import Network.AWS.Easy.Classes
import Network.AWS.Easy.Types
import System.IO (stdout)
#if __GLASGOW_HASKELL__ >= 802
import Control.Monad.Trans.Control (MonadBaseControl)
import Control.Monad.Trans.Resource
( MonadUnliftIO
, ResourceT
)
#else
import Control.Monad.Trans.Resource
( MonadBaseControl
, ResourceT
)
#endif
type HostName = ByteString
type Port = Int
data Logging = LoggingEnabled | LoggingDisabled
data Endpoint = AWSRegion Region | Local HostName Port
data AWSConfig = AWSConfig
{ _awscEndpoint :: Endpoint
, _awscLogging :: Logging
, _awscCredentials :: Credentials
}
makeLenses ''AWSConfig
awsConfig :: Endpoint -> AWSConfig
awsConfig endpoint = AWSConfig endpoint LoggingDisabled Discover
connect :: forall a . ServiceClass a => AWSConfig -> a -> IO (TypedSession a)
connect (AWSConfig endpoint logging credentials) service = do
let serviceRaw = rawService service
e <- mkEnv logging credentials
let (r, s) = regionService endpoint serviceRaw
session' <- return $ Session e r s
let session = wrappedSession @a session'
return session
mkEnv :: Logging -> Credentials -> IO Env
mkEnv LoggingEnabled c = do
logger <- newLogger Debug stdout
newEnv c <&> set envLogger logger
mkEnv LoggingDisabled c = newEnv c
regionService :: Endpoint -> Service -> (Region, Service)
regionService (AWSRegion region) s = (region, s)
regionService (Local hostName port) s = (NorthVirginia, setEndpoint False hostName port s)
#if __GLASGOW_HASKELL__ >= 802
withAWS :: (MonadBaseControl IO m, MonadUnliftIO m, SessionClass b) =>
#else
withAWS :: (MonadBaseControl IO m, SessionClass b) =>
#endif
AWST' Env (ResourceT m) a
-> b
-> m a
withAWS action session =
let Session{..} = rawSession session
in
runResourceT . runAWST _sEnv . within _sRegion $ do
reconfigure _sService action