LocalStack Testing in Clojure
If you are using the v2 AWS SDK clients, you can configure them like so:
(ns my.s3
(:import
(java.net URI)
(software.amazon.awssdk.regions Region)
(software.amazon.awssdk.services.s3 S3Client)
(software.amazon.awssdk.services.s3.model ListBucketsResponse)
(software.amazon.awssdk.auth.credentials StaticCredentialsProvider AwsBasicCredentials)))
;; The actual client should just read the values from the environment.
;; Never hard-code your credentials.
(defn create-standard-client []
(-> (S3Client/builder)
(.build))
;; The LocalStack client will need to override the URL and set
;; a region, access key, and secret key even though they are not used.
;; The actual values of the region and keys do not matter.
(defn create-localstack-client []
(-> (S3Client/builder)
(.credentialsProvider
(StaticCredentialsProvider/create
(AwsBasicCredentials/create "test" "test")))
(.endpointOverride (URI. "http://localhost:4566"))
(.region Region/US_EAST_1)
(.build)))
(defn list-buckets [^S3Client s3-client]
(.listBuckets s3-client))
If you are using Amazonica, you could implement the equivalent like so. Note that for S3 you might have to add :client-config
when running against LocalStack. More details are here. With Amazonica, if you omit the creds
argument to functions, it will just use the DefaultAWSCredentialsProviderChain
. If you prefer to structure your code in such a manner where you inject different clients, you can implement it by getting an instance of the provider chain.
(ns my.s3
(:require [amazonica.aws.s3 :as s3])
(:import (com.amazonaws.auth DefaultAWSCredentialsProviderChain)))
;; Not strictly necessary, but will simplify code that injects different clients depending on the context
(defn create-standard-credentials []
(DefaultAWSCredentialsProviderChain/getInstance))
(def localstack-credentials
{:access-key "test"
:secret-key "test"
:endpoint "http://localhost:4566"})
(defn list-buckets [creds]
(s3/list-buckets creds))