Copyright | (c) 2013-2015 Brendan Hay |
---|---|
License | Mozilla Public License, v. 2.0. |
Maintainer | Brendan Hay <brendan.g.hay@gmail.com> |
Stability | provisional |
Portability | non-portable (GHC extensions) |
Safe Haskell | None |
Language | Haskell2010 |
The AWST
transformer provides the environment required to perform AWS
operations and constructs a Command
AST using FreeT
which can then be
interpreted using runAWST
. The transformer is intended to be used directly
or embedded as a layer within a transformer stack.
Network.AWS contains a IO
specialised version of AWST
with a typeclass
to assist in automatically lifting operations.
- data AWST m a
- runAWST :: (MonadCatch m, MonadResource m, HasEnv r) => r -> AWST m a -> m a
- execAWST :: (MonadCatch m, MonadResource m, HasEnv r) => (forall a. Either Error a -> m a) -> r -> AWST m b -> m b
- newEnv :: (Applicative m, MonadIO m, MonadCatch m) => Region -> Credentials -> m Env
- data Env
- class HasEnv a where
- environment :: Lens' a Env
- envRegion :: Lens' a Region
- envLogger :: Lens' a Logger
- envRetryCheck :: Lens' a (Int -> HttpException -> IO Bool)
- envRetryPolicy :: Lens' a (Maybe RetryPolicy)
- envTimeout :: Lens' a (Maybe Seconds)
- envManager :: Lens' a Manager
- envAuth :: Lens' a Auth
- envEC2 :: Getter a (IORef (Maybe Bool))
- data Credentials
- data Region :: *
- send :: (MonadFree Command m, AWSRequest a) => a -> m (Rs a)
- paginate :: (MonadFree Command m, AWSPager a) => a -> Source m (Rs a)
- await :: (MonadFree Command m, AWSRequest a) => Wait a -> a -> m (Rs a)
- within :: (MonadReader r m, HasEnv r) => Region -> m a -> m a
- once :: (MonadReader r m, HasEnv r) => m a -> m a
- timeout :: (MonadReader r m, HasEnv r) => Seconds -> m a -> m a
- sendWith :: (MonadFree Command m, AWSSigner (Sg s), AWSRequest a) => (Service (Sv a) -> Service s) -> a -> m (Rs a)
- paginateWith :: (MonadFree Command m, AWSSigner (Sg s), AWSPager a) => (Service (Sv a) -> Service s) -> a -> Source m (Rs a)
- awaitWith :: (MonadFree Command m, AWSSigner (Sg s), AWSRequest a) => (Service (Sv a) -> Service s) -> Wait a -> a -> m (Rs a)
- presignWith :: (MonadFree Command m, AWSPresigner (Sg s), AWSRequest a) => (Service (Sv a) -> Service s) -> UTCTime -> Seconds -> a -> m ClientRequest
- class ToBody a where
- sourceBody :: Digest SHA256 -> Int64 -> Source (ResourceT IO) ByteString -> RqBody
- sourceHandle :: Digest SHA256 -> Int64 -> Handle -> RqBody
- sourceFile :: Digest SHA256 -> Int64 -> FilePath -> RqBody
- sourceFileIO :: MonadIO m => FilePath -> m RqBody
- sinkBody :: MonadResource m => RsBody -> Sink ByteString m a -> m a
- getFileSize :: MonadIO m => FilePath -> m Int64
- sinkMD5 :: Monad m => Consumer ByteString m (Digest MD5)
- sinkSHA256 :: Monad m => Consumer ByteString m (Digest SHA256)
- presignURL :: (MonadFree Command m, AWSPresigner (Sg (Sv a)), AWSRequest a) => UTCTime -> Seconds -> a -> m ByteString
- presign :: (MonadFree Command m, AWSPresigner (Sg (Sv a)), AWSRequest a) => UTCTime -> Seconds -> a -> m ClientRequest
- isEC2 :: MonadFree Command m => m Bool
- dynamic :: MonadFree Command m => Dynamic -> m ByteString
- metadata :: MonadFree Command m => Metadata -> m ByteString
- userdata :: MonadFree Command m => m (Maybe ByteString)
- data Dynamic
- data Metadata
- = AMIId
- | AMILaunchIndex
- | AMIManifestPath
- | AncestorAMIIds
- | BlockDevice !Mapping
- | Hostname
- | IAM !Info
- | InstanceAction
- | InstanceId
- | InstanceType
- | KernelId
- | LocalHostname
- | LocalIPV4
- | MAC
- | Network !Text !Interface
- | AvailabilityZone
- | ProductCodes
- | PublicHostname
- | PublicIPV4
- | OpenSSHKey
- | RAMDiskId
- | ReservationId
- | SecurityGroups
- class AsError a where
- class AsAuthError a where
- trying :: MonadCatch m => Getting (First a) SomeException a -> m r -> m (Either a r)
- catching :: MonadCatch m => Getting (First a) SomeException a -> m r -> (a -> m r) -> m r
- type Logger = LogLevel -> Builder -> IO ()
- data LogLevel :: *
- newLogger :: MonadIO m => LogLevel -> Handle -> m Logger
- data RqBody :: *
- data RsBody :: *
- module Network.AWS.Types
- module Network.AWS.Waiter
- module Network.AWS.Pager
- runResourceT :: MonadBaseControl IO m => ResourceT m a -> m a
Running AWS Actions
The AWST
transformer.
MFunctor AWST | |
MonadTrans AWST | |
MonadAWS AWS | |
MonadState s m => MonadState s (AWST m) | |
Monad m => MonadReader Env (AWST m) | |
MonadBaseControl b m => MonadBaseControl b (AWST m) | |
Monad m => MonadFree Command (AWST m) | |
MonadError e m => MonadError e (AWST m) | |
MonadWriter w m => MonadWriter w (AWST m) | |
MonadBase b m => MonadBase b (AWST m) | |
MonadPlus m => Alternative (AWST m) | |
Monad m => Monad (AWST m) | |
Monad m => Functor (AWST m) | |
MonadPlus m => MonadPlus (AWST m) | |
Monad m => Applicative (AWST m) | |
MonadThrow m => MonadThrow (AWST m) | |
MonadCatch m => MonadCatch (AWST m) | |
MonadIO m => MonadIO (AWST m) | |
MonadResource m => MonadResource (AWST m) | |
type StM (AWST m) a = StM m (FreeF Command a (FreeT Command (ReaderT Env m) a)) |
runAWST :: (MonadCatch m, MonadResource m, HasEnv r) => r -> AWST m a -> m a Source
Run an AWST
action with the specified HasEnv
environment.
Any outstanding HTTP responses' ResumableSource
will
be closed when the ResourceT
computation is unwrapped with runResourceT
.
Throws Error
during interpretation of the underlying FreeT
Command
AST.
See: runResourceT
.
:: (MonadCatch m, MonadResource m, HasEnv r) | |
=> (forall a. Either Error a -> m a) | Lift an |
-> r | |
-> AWST m b | |
-> m b |
Authentication and Environment
:: (Applicative m, MonadIO m, MonadCatch m) | |
=> Region | Initial region to operate in. |
-> Credentials | Credential discovery mechanism. |
-> m Env |
Creates a new environment with a new Manager
without debug logging
and uses getAuth
to expand/discover the supplied Credentials
.
Lenses from HasEnv
can be used to further configure the resulting Env
.
Throws AuthError
when environment variables or IAM profiles cannot be read.
See: newEnvWith
.
The environment containing the parameters required to make AWS requests.
environment :: Lens' a Env Source
envRegion :: Lens' a Region Source
The current region.
envLogger :: Lens' a Logger Source
The function used to output log messages.
envRetryCheck :: Lens' a (Int -> HttpException -> IO Bool) Source
The function used to determine if an HttpException
should be retried.
envRetryPolicy :: Lens' a (Maybe RetryPolicy) Source
The RetryPolicy
used to determine backoff/on and retry delay/growth.
envTimeout :: Lens' a (Maybe Seconds) Source
A HTTP response timeout override to apply. This defaults to Nothing
,
and the timeout selection is outlined below.
Timeouts are chosen by considering:
- This
envTimeout
, if set. - The related
Service
timeout for the sent request if set. (Usually 70s) - The
envManager
timeout if set. - The default
ClientRequest
timeout. (Approximately 30s)
envManager :: Lens' a Manager Source
The Manager
used to create and manage open HTTP connections.
envAuth :: Lens' a Auth Source
The credentials used to sign requests for authentication with AWS.
envEC2 :: Getter a (IORef (Maybe Bool)) Source
A memoised predicate for whether the underlying host is an EC2 instance.
Credential Discovery
data Credentials Source
Determines how AuthN/AuthZ information is retrieved.
FromKeys AccessKey SecretKey | Explicit access and secret keys. See |
FromSession AccessKey SecretKey SessionToken | Explicit access key, secret key and a session token. See |
FromEnv Text Text (Maybe Text) | Lookup specific environment variables for access key, secret key, and an optional session token respectively. |
FromProfile Text | An IAM Profile name to lookup from the local EC2 instance-data. ^ Environment variables to lookup for the access key, secret key and optional session token. |
FromFile Text FilePath | A credentials profile name (the INI section) and the path to the AWS credentials file. |
Discover | Attempt to credentials discovery via the following steps:
An attempt is made to resolve http://instance-data rather than directly retrieving http://169.254.169.254 for IAM profile information. This assists in ensuring the DNS lookup terminates promptly if not running on EC2. |
AuthN/AuthZ information is handled similarly to other AWS SDKs. You can read some of the options available here.
When running on an EC2 instance and using FromProfile
or Discover
, a thread
is forked which transparently handles the expiry and subsequent refresh of IAM
profile information. See fromProfileName
for more information.
Supported Regions
data Region :: *
The sum of available AWS regions.
Ireland | Europe / eu-west-1 |
Frankfurt | Europe / eu-central-1 |
Tokyo | Asia Pacific / ap-northeast-1 |
Singapore | Asia Pacific / ap-southeast-1 |
Sydney | Asia Pacific / ap-southeast-2 |
Beijing | China / cn-north-1 |
NorthVirginia | US / us-east-1 |
NorthCalifornia | US / us-west-1 |
Oregon | US / us-west-2 |
GovCloud | AWS GovCloud / us-gov-west-1 |
GovCloudFIPS | AWS GovCloud (FIPS 140-2) S3 Only / fips-us-gov-west-1 |
SaoPaulo | South America / sa-east-1 |
Eq Region | |
Data Region | |
Ord Region | |
Read Region | |
Show Region | |
Generic Region | |
Hashable Region | |
ToLog Region | |
FromXML Region | |
ToXML Region | |
ToByteString Region | |
FromText Region | |
ToText Region | |
Typeable * Region | |
type Rep Region = D1 D1Region ((:+:) ((:+:) ((:+:) (C1 C1_0Region U1) ((:+:) (C1 C1_1Region U1) (C1 C1_2Region U1))) ((:+:) (C1 C1_3Region U1) ((:+:) (C1 C1_4Region U1) (C1 C1_5Region U1)))) ((:+:) ((:+:) (C1 C1_6Region U1) ((:+:) (C1 C1_7Region U1) (C1 C1_8Region U1))) ((:+:) (C1 C1_9Region U1) ((:+:) (C1 C1_10Region U1) (C1 C1_11Region U1))))) |
Sending Requests
To send a request you need to create a value of the desired operation type using
the relevant constructor, as well as any further modifications of default/optional
parameters using the appropriate lenses. This value can then be sent using send
or paginate
and the library will take care of serialisation/authentication and
so forth.
The default Service
configuration for a request (or the supplied Service
configuration
when using the *With
variants) contains retry configuration that is used to
determine if a request can safely be retried and what kind of back off/on strategy
should be used. (Usually exponential.)
Typically services define retry strategies that handle throttling, general server
errors and transport errors. Streaming requests are never retried.
send :: (MonadFree Command m, AWSRequest a) => a -> m (Rs a) Source
Send a request, returning the associated response if successful.
See: sendWith
Pagination
Some AWS operations return results that are incomplete and require subsequent
requests in order to obtain the entire result set. The process of sending
subsequent requests to continue where a previous request left off is called
pagination. For example, the ListObjects
operation of Amazon S3 returns up to
1000 objects at a time, and you must send subsequent requests with the
appropriate Marker in order to retrieve the next page of results.
Operations that have an AWSPager
instance can transparently perform subsequent
requests, correctly setting Markers and other request facets to iterate through
the entire result set of a truncated API operation. Operations which support
this have an additional note in the documentation.
Many operations have the ability to filter results on the server side. See the individual operation parameters for details.
paginate :: (MonadFree Command m, AWSPager a) => a -> Source m (Rs a) Source
Repeatedly send a request, automatically setting markers and paginating over multiple responses while available.
See: paginateWith
Waiters
Waiters poll by repeatedly sending a request until some remote success condition
configured by the Wait
specification is fulfilled. The Wait
specification
determines how many attempts should be made, in addition to delay and retry strategies.
Error conditions that are not handled by the Wait
configuration will be thrown,
or the first successful response that fulfills the success condition will be
returned.
Wait
specifications can be found under the Network.AWS.{ServiceName}.Waiters
namespace for services which support await
.
Overriding Service Configuration
When a request is sent, various configuration values such as the endpoint,
retry strategy, timeout and error handlers are taken from the associated Service
configuration.
You can override the default configuration for a series of one or more actions
by using within
, once
and timeout
, or by using the *With
suffixed
functions on an individual request basis below.
Scoped Actions
within :: (MonadReader r m, HasEnv r) => Region -> m a -> m a Source
Scope an action within the specific Region
.
once :: (MonadReader r m, HasEnv r) => m a -> m a Source
Scope an action such that any retry logic for the Service
is
ignored and any requests will at most be sent once.
timeout :: (MonadReader r m, HasEnv r) => Seconds -> m a -> m a Source
Scope an action such that any HTTP response will use this timeout value.
Per Request
:: (MonadFree Command m, AWSPresigner (Sg s), AWSRequest a) | |
=> (Service (Sv a) -> Service s) | Function to modify the service configuration. |
-> UTCTime | Signing time. |
-> Seconds | Expiry time. |
-> a | Request to presign. |
-> m ClientRequest |
Streaming
Streaming request bodies (such as PutObject
) require a precomputed
SHA256
for signing purposes.
The ToBody
typeclass has instances available to construct a RqBody
,
automatically calculating the hash as needed for types such as Text
and ByteString
.
For reading files and handles, functions such sourceFileIO
or sourceHandle
can be used.
For responses that contain streaming bodies (such as GetObject
), you can use
sinkBody
to connect the response body to a conduit
compatible sink.
Request Bodies
sourceBody :: Digest SHA256 -> Int64 -> Source (ResourceT IO) ByteString -> RqBody Source
Construct a RqBody
from a source, manually specifying the
SHA256 hash and file size.
sourceFileIO :: MonadIO m => FilePath -> m RqBody Source
Response Bodies
sinkBody :: MonadResource m => RsBody -> Sink ByteString m a -> m a Source
Connect a Sink
to a reponse body.
File Size and MD5/SHA256
getFileSize :: MonadIO m => FilePath -> m Int64 Source
Convenience function for obtaining the size of a file.
sinkSHA256 :: Monad m => Consumer ByteString m (Digest SHA256) Source
Presigning Requests
Presigning requires the Service
signer to be an instance of AWSPresigner
.
Not all signing algorithms support this.
:: (MonadFree Command m, AWSPresigner (Sg (Sv a)), AWSRequest a) | |
=> UTCTime | Signing time. |
-> Seconds | Expiry time. |
-> a | Request to presign. |
-> m ByteString |
Presign an URL that is valid from the specified time until the number of seconds expiry has elapsed.
See: presign
, presignWith
:: (MonadFree Command m, AWSPresigner (Sg (Sv a)), AWSRequest a) | |
=> UTCTime | Signing time. |
-> Seconds | Expiry time. |
-> a | Request to presign. |
-> m ClientRequest |
Presign an HTTP request that is valid from the specified time until the number of seconds expiry has elapsed.
See: presignWith
EC2 Instance Metadata
Metadata can be retrieved from the underlying host assuming that you're running
the code on an EC2 instance or have a compatible instance-data
endpoint available.
dynamic :: MonadFree Command m => Dynamic -> m ByteString Source
Retrieve the specified Dynamic
data.
userdata :: MonadFree Command m => m (Maybe ByteString) Source
Retrieve the user data. Returns Nothing
if no user data is assigned
to the instance.
FWS | Value showing whether the customer has enabled detailed one-minute monitoring in CloudWatch. Valid values: enabled | disabled. |
Document | JSON containing instance attributes, such as instance-id, private IP address, etc. |
PKCS7 | Used to verify the document's authenticity and content against the signature. |
Signature |
AMIId | The AMI ID used to launch the instance. |
AMILaunchIndex | If you started more than one instance at the same time, this value indicates the order in which the instance was launched. The value of the first instance launched is 0. |
AMIManifestPath | The path to the AMI's manifest file in Amazon S3. If you used an Amazon EBS-backed AMI to launch the instance, the returned result is unknown. |
AncestorAMIIds | The AMI IDs of any instances that were rebundled to create this AMI. This value will only exist if the AMI manifest file contained an ancestor-amis key. |
BlockDevice !Mapping | See: |
Hostname | The private hostname of the instance. In cases where multiple network interfaces are present, this refers to the eth0 device (the device for which the device number is 0). |
IAM !Info | See: |
InstanceAction | Notifies the instance that it should reboot in preparation for bundling. Valid values: none | shutdown | bundle-pending. |
InstanceId | The ID of this instance. |
InstanceType | The type of instance. See: |
KernelId | The ID of the kernel launched with this instance, if applicable. |
LocalHostname | The private DNS hostname of the instance. In cases where multiple network interfaces are present, this refers to the eth0 device (the device for which the device number is 0). |
LocalIPV4 | The private IP address of the instance. In cases where multiple network interfaces are present, this refers to the eth0 device (the device for which the device number is 0). |
MAC | The instance's media access control (MAC) address. In cases where multiple network interfaces are present, this refers to the eth0 device (the device for which the device number is 0). |
Network !Text !Interface | See: |
AvailabilityZone | The Availability Zone in which the instance launched. |
ProductCodes | Product codes associated with the instance, if any. |
PublicHostname | The instance's public DNS. If the instance is in a VPC, this category is only returned if the enableDnsHostnames attribute is set to true. For more information, see Using DNS with Your VPC. |
PublicIPV4 | The public IP address. If an Elastic IP address is associated with the instance, the value returned is the Elastic IP address. |
OpenSSHKey | Public key. Only available if supplied at instance launch time. |
RAMDiskId | The ID of the RAM disk specified at launch time, if applicable. |
ReservationId | ID of the reservation. |
SecurityGroups | The names of the security groups applied to the instance. |
Running Asynchronous Actions
Requests can be sent asynchronously, but due to guarantees about resource closure require the use of lifted-async.
The following example demonstrates retrieving two objects from S3 concurrently:
import Control.Concurrent.Async.Lifted import Control.Lens import Control.Monad.Trans.AWS import Network.AWS.S3 do x <- async . send $ getObject "bucket" "prefix/object-foo" y <- async . send $ getObject "bucket" "prefix/object-bar" foo <- wait x bar <- wait y ...
Handling Errors
Errors are thrown by the library using MonadThrow
(unless Control.Monad.Error.AWS is used).
Sub-errors of the canonical Error
type can be caught using trying
or
catching
and the appropriate AsError
Prism
:
trying_Error
(send $ ListObjects "bucket-name") :: EitherError
ListObjectsResponse trying_TransportError
(send $ ListObjects "bucket-name") :: EitherHttpException
ListObjectsResponse trying_SerializeError
(send $ ListObjects "bucket-name") :: EitherSerializeError
ListObjectsResponse trying_ServiceError
(send $ ListObjects "bucket-name") :: EitherServiceError
ListObjectsResponse
Many of the individual amazonka-*
libraries export compatible Getter
s for
matching service specific error codes and messages in the style above.
See the Error Matchers
heading in each respective library for details.
class AsError a where
A general Amazonka error.
_TransportError :: Prism' a HttpException
An error occured while communicating over HTTP with a remote service.
_SerializeError :: Prism' a SerializeError
A serialisation error occured when attempting to deserialise a response.
_ServiceError :: Prism' a ServiceError
A service specific error returned by the remote service.
class AsAuthError a where Source
_AuthError :: Prism' a AuthError Source
A general authentication error.
_RetrievalError :: Prism' a HttpException Source
An error occured while communicating over HTTP with the local metadata endpoint.
_MissingEnvError :: Prism' a Text Source
An error occured looking up a named environment variable.
_MissingFileError :: Prism' a FilePath Source
The specified credentials file could not be found.
_InvalidFileError :: Prism' a Text Source
An error occured parsing the credentials file.
_InvalidIAMError :: Prism' a Text Source
The specified IAM profile could not be found or deserialised.
trying :: MonadCatch m => Getting (First a) SomeException a -> m r -> m (Either a r)
A variant of try
that takes a Prism
(or any Fold
) to select which
exceptions are caught (c.f. tryJust
, catchJust
). If the
Exception
does not match the predicate, it is re-thrown.
trying
::MonadCatch
m =>Prism'
SomeException
a -> m r -> m (Either
a r)trying
::MonadCatch
m =>Lens'
SomeException
a -> m r -> m (Either
a r)trying
::MonadCatch
m =>Traversal'
SomeException
a -> m r -> m (Either
a r)trying
::MonadCatch
m =>Iso'
SomeException
a -> m r -> m (Either
a r)trying
::MonadCatch
m =>Getter
SomeException
a -> m r -> m (Either
a r)trying
::MonadCatch
m =>Fold
SomeException
a -> m r -> m (Either
a r)
catching :: MonadCatch m => Getting (First a) SomeException a -> m r -> (a -> m r) -> m r
Catch exceptions that match a given Prism
(or any Fold
, really).
>>>
catching _AssertionFailed (assert False (return "uncaught")) $ \ _ -> return "caught"
"caught"
catching
::MonadCatch
m =>Prism'
SomeException
a -> m r -> (a -> m r) -> m rcatching
::MonadCatch
m =>Lens'
SomeException
a -> m r -> (a -> m r) -> m rcatching
::MonadCatch
m =>Traversal'
SomeException
a -> m r -> (a -> m r) -> m rcatching
::MonadCatch
m =>Iso'
SomeException
a -> m r -> (a -> m r) -> m rcatching
::MonadCatch
m =>Getter
SomeException
a -> m r -> (a -> m r) -> m rcatching
::MonadCatch
m =>Fold
SomeException
a -> m r -> (a -> m r) -> m r
Logging
The exposed logging interface is a primitive Logger
function which gets
threaded through service calls and serialisation routines. This allows the
library to output useful information and diagnostics.
The newLogger
function can be used to construct a simple logger which writes
output to a Handle
, but in most production code you should probably consider
using a more robust logging library such as
tiny-log or
fast-logger.
type Logger = LogLevel -> Builder -> IO ()
A function threaded through various request and serialisation routines to log informational and debug messages.
data LogLevel :: *
Constructing a Logger
newLogger :: MonadIO m => LogLevel -> Handle -> m Logger Source
This is a primitive logger which can be used to log builds to a Handle
.
Note: A more sophisticated logging library such as tinylog or fast-logger should be used in production code.
Re-exported Types
module Network.AWS.Types
module Network.AWS.Waiter
module Network.AWS.Pager
runResourceT
runResourceT :: MonadBaseControl IO m => ResourceT m a -> m a
Unwrap a ResourceT
transformer, and call all registered release actions.
Note that there is some reference counting involved due to resourceForkIO
.
If multiple threads are sharing the same collection of resources, only the
last call to runResourceT
will deallocate the resources.
Since 0.3.0