# LocalStack Testing in Clojure

If you are using the v2 AWS SDK clients, you can configure them like so:

```clojure
(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](https://github.com/mcohen01/amazonica#s3). 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.

```clojure
(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))
```
