aws

http://status.aws.amazon.com/ https://www.expeditedssl.com/aws-in-plain-english
FlavaDave 2020-09-08T15:39:55.017600Z

Having trouble writing to a dynamo db with aws api. I have also tried passing JSON as the request map but get the same error. Anyone know what im doing wrong?

FlavaDave 2020-09-08T15:39:55.017700Z

(def dynamo-client (aws/client {:api :dynamodb}))

(-> dynamo-client
    (aws/invoke {:op      :DescribeTable
                 :request {:TableName "PracticeTable"}}))

=>{:Table
 {:TableStatus "ACTIVE",
  :ItemCount 0,
  :TableId "xxxxxxxxxxxxxxxxxxxx",
  :GlobalSecondaryIndexes
  [{:IndexSizeBytes 0,
    :IndexArn
    "arn:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    :ItemCount 0,
    :KeySchema
    [{:AttributeName "GameTitle", :KeyType "HASH"}
     {:AttributeName "TopScore", :KeyType "RANGE"}],
    :ProvisionedThroughput
    {:NumberOfDecreasesToday 0, :ReadCapacityUnits 10, :WriteCapacityUnits 10},
    :IndexStatus "ACTIVE",
    :Projection {:ProjectionType "INCLUDE", :NonKeyAttributes ["UserId"]},
    :IndexName "GameTitleIndex"}],
  :KeySchema
  [{:AttributeName "UserId", :KeyType "HASH"}
   {:AttributeName "GameTitle", :KeyType "RANGE"}],
  :ProvisionedThroughput
  {:NumberOfDecreasesToday 0, :ReadCapacityUnits 20, :WriteCapacityUnits 20},
  :CreationDateTime #inst "2020-09-05T18:52:50.000-00:00",
  :TableName "PracticeTable",
  :AttributeDefinitions
  [{:AttributeName "GameTitle", :AttributeType "S"}
   {:AttributeName "TopScore", :AttributeType "N"}
   {:AttributeName "UserId", :AttributeType "S"}],
  :TableArn "arn:aws:dynamodb:xxxxxxxxxxxxxxxxxxxxx",
  :TableSizeBytes 0}}

(aws/invoke dynamo-client {:op      :PutItem
                           :request {:TableName "PracticeTable"
                                     :Item      {:GameTitle "mortal Kombat"
                                                 :TopScore  100
                                                 :UserId    "Bill"}}})

=>{:cognitect.anomalies/category :cognitect.anomalies/fault,
 :cognitect.aws.client/throwable #error {
 :cause "No implementation of method: :kv-reduce of protocol: #'clojure.core.protocols/IKVReduce found for class: java.lang.String"
 :via
 [{:type java.lang.IllegalArgumentException
   :message "No implementation of method: :kv-reduce of protocol: #'clojure.core.protocols/IKVReduce found for class: java.lang.String"
   :at [clojure.core$_cache_protocol_fn invokeStatic "core_deftype.clj" 583]}]
 :trace
 [[clojure.core$_cache_protocol_fn invokeStatic "core_deftype.clj" 583]
  [clojure.core.protocols$fn__8167$G__8162__8176 invoke "protocols.clj" 175]
  [clojure.core$reduce_kv invokeStatic "core.clj" 6856]
  [clojure.core$reduce_kv invoke "core.clj" 6847]
  [cognitect.aws.shape$fn__8987 invokeStatic "shape.clj" 184]
  [cognitect.aws.shape$fn__8987 invoke "shape.clj" 181]
  [clojure.lang.MultiFn invoke "MultiFn.java" 234]
  [cognitect.aws.shape$handle_map$fn__8947 invoke "shape.clj" 117]
  [clojure.core$fn__8429$fn__8431 invoke "core.clj" 6840]
  [clojure.core.protocols$iter_reduce invokeStatic "protocols.clj" 49]
  [clojure.core.protocols$fn__8140 invokeStatic "protocols.clj" 75]
  [clojure.core.protocols$fn__8140 invoke "protocols.clj" 75]
  [clojure.core.protocols$fn__8088$G__8083__8101 invoke "protocols.clj" 13]
  [clojure.core$reduce invokeStatic "core.clj" 6828]
  [clojure.core$fn__8429 invokeStatic "core.clj" 6830]
  [clojure.core$fn__8429 invoke "core.clj" 6830]
  [clojure.core.protocols$fn__8167$G__8162__8176 invoke "protocols.clj" 175]
  [clojure.core$reduce_kv invokeStatic "core.clj" 6856]
  [clojure.core$reduce_kv invoke "core.clj" 6847]
  [cognitect.aws.shape$handle_map invokeStatic "shape.clj" 117]
  [cognitect.aws.shape$handle_map invoke "shape.clj" 113]
  [cognitect.aws.shape$fn__8993 invokeStatic "shape.clj" 196]
  [cognitect.aws.shape$fn__8993 invoke "shape.clj" 194]
  [clojure.lang.MultiFn invoke "MultiFn.java" 234]
  [cognitect.aws.shape$fn__8987$fn__8988 invoke "shape.clj" 189]
  [clojure.core$fn__8429$fn__8431 invoke "core.clj" 6840]
  [clojure.core.protocols$iter_reduce invokeStatic "protocols.clj" 49]
  [clojure.core.protocols$fn__8140 invokeStatic "protocols.clj" 75]
  [clojure.core.protocols$fn__8140 invoke "protocols.clj" 75]
  [clojure.core.protocols$fn__8088$G__8083__8101 invoke "protocols.clj" 13]
  [clojure.core$reduce invokeStatic "core.clj" 6828]
  [clojure.core$fn__8429 invokeStatic "core.clj" 6830]
  [clojure.core$fn__8429 invoke "core.clj" 6830]
  [clojure.core.protocols$fn__8167$G__8162__8176 invoke "protocols.clj" 175]
  [clojure.core$reduce_kv invokeStatic "core.clj" 6856]
  [clojure.core$reduce_kv invoke "core.clj" 6847]
  [cognitect.aws.shape$fn__8987 invokeStatic "shape.clj" 184]
  [cognitect.aws.shape$fn__8987 invoke "shape.clj" 181]
  [clojure.lang.MultiFn invoke "MultiFn.java" 234]
  [cognitect.aws.shape$json_serialize invokeStatic "shape.clj" 212]
  [cognitect.aws.shape$json_serialize invoke "shape.clj" 209]
  [cognitect.aws.protocols.json$fn__451 invokeStatic "json.clj" 22]
  [cognitect.aws.protocols.json$fn__451 invoke "json.clj" 19]
  [clojure.lang.MultiFn invoke "MultiFn.java" 239]
  [cognitect.aws.protocols.json$fn__454 invokeStatic "json.clj" 34]
  [cognitect.aws.protocols.json$fn__454 invoke "json.clj" 24]
  [clojure.lang.MultiFn invoke "MultiFn.java" 234]
  [cognitect.aws.client$send_request$fn__9600$state_machine__5044__auto____9627$fn__9629$fn__9643 invoke "client.clj" 99]
  [cognitect.aws.client$send_request$fn__9600$state_machine__5044__auto____9627$fn__9629 invoke "client.clj" 96]
  [cognitect.aws.client$send_request$fn__9600$state_machine__5044__auto____9627 invoke "client.clj" 84]
  [clojure.core.async.impl.ioc_macros$run_state_machine invokeStatic "ioc_macros.clj" 978]
  [clojure.core.async.impl.ioc_macros$run_state_machine invoke "ioc_macros.clj" 977]
  [clojure.core.async.impl.ioc_macros$run_state_machine_wrapped invokeStatic "ioc_macros.clj" 982]
  [clojure.core.async.impl.ioc_macros$run_state_machine_wrapped invoke "ioc_macros.clj" 980]
  [cognitect.aws.client$send_request$fn__9600 invoke "client.clj" 84]
  [clojure.lang.AFn run "AFn.java" 22]
  [java.util.concurrent.ThreadPoolExecutor runWorker "ThreadPoolExecutor.java" 1149]
  [java.util.concurrent.ThreadPoolExecutor$Worker run "ThreadPoolExecutor.java" 624]
  [clojure.core.async.impl.concurrent$counted_thread_factory$reify__528$fn__529 invoke "concurrent.clj" 29]
  [clojure.lang.AFn run "AFn.java" 22]
  [java.lang.Thread run "Thread.java" 748]]}}

Joe Lane 2020-09-08T15:46:43.019400Z

@dgonsalves22 You need something like

(aws/invoke
           dynamodb-client
           {:op      :PutItem
            :request {:TableName "PracticeTable"
                      :Item      {"GameTitle" {:S "mortal Kombat"}
                                  "TopScore"  {:N 100}
                                  "UserId"    {:S "Bill"}}}})

FlavaDave 2020-09-08T15:51:54.019900Z

That was the trick thank you very much

👍 1
souenzzo 2020-09-08T15:52:50.020200Z

Can I do (.getCredentials (DefaultAWSCredentialsProviderChain.)) using aws-api ?

kenny 2020-09-08T16:06:00.020400Z

Yes.

(cognitect.aws.credentials/fetch (cognitect.aws.client.shared/credentials-provider))

kenny 2020-09-08T16:06:49.020600Z

Can also use (cognitect.aws.credentials/default-credentials-provider) to create a new chain.

souenzzo 2020-09-08T16:10:26.020800Z

Did it 🙂

(aws.cred/fetch (aws.cred/default-credentials-provider aws.cred/fetch-async))
It's a public/stable api? cc @dchelimsky

kenny 2020-09-08T16:14:17.022400Z

I believe aws.creds is part of the public API. Not sure about aws.client.shared. The latter is the one implicitly passed when you don’t explicitly pass a creds provider.

2020-09-08T16:31:52.023Z

Public? Yes. Stable? “Alpha. Subject to change.” https://cognitect-labs.github.io/aws-api/cognitect.aws.credentials-api.html

👍 1
kenny 2020-09-08T17:09:00.024500Z

I'm pretty sure I've brought this up before, but I forget where we landed. Will returning an anomaly from a CredentialProvider's fetch method result in that anomaly getting returned after calling invoke?

2020-09-09T13:03:48.027200Z

Not in the current design. In the chained-credentials-provider, it’s only an anomaly if none of the chained providers produce credentials. I think it would be more consistent with the design of the rest of the lib if the individual providers returned anomalies and the chain provider could check for that, and possibly build up list of all the failed providers to include in the anomaly it returns if none provide credentials. Definitely worth looking at.

2020-09-09T13:04:52.027400Z

We’d still need to handle nil in case users provide their own creds providers (in which case the lib could add the appropriate anomaly).

kenny 2020-09-09T15:08:05.028500Z

Right, okay. I actually believe it happens to work right now. (tested it with a cached-credentials-with-auto-refresh )

kenny 2020-09-09T15:08:30.028700Z

i.e., if I return an anomaly from my passed in CredentialsProvider, that anomaly will be returned from invoke.

kenny 2020-09-08T17:12:16.026200Z

At the very least, it seems returning an anomaly map instead of nil is safe.

kenny 2020-09-08T17:23:24.026300Z

It appears like the below part of refresh!'s docstring is not correct. > If the credentials returned by the provider are not valid, resets > both atoms to nil, logs an error, and returns nil.

2020-09-09T13:07:46.027700Z

Yeah - that’s what you get for reading the documentation that is clearly left out of the public documentation 😉

2020-09-09T13:08:53.027900Z

It’s mostly correct. The only thing that’s incorrect about it is that the error is only logged if there is an error. The rest is accurate.

2020-09-09T13:11:02.028100Z

Fixed (in github).

kenny 2020-09-09T15:06:52.028300Z

@dchelimsky It says "If the credentials returned by the provider are not valid" but I don't see where it is checking to see if they are valid. Am I missing something obvious? 🙈

2020-09-09T15:22:30.028900Z

It’s a sketchy assumption that all the providers use the valid-credentials fn, which is designed to return valid credentials or nil.

kenny 2020-09-09T15:23:29.029100Z

Seems highly unlikely for anyone implementing their own creds provider given the docstring for valid-credentials says "For internal use. Don't call directly."

2020-09-09T15:25:57.029300Z

As I said, sketchy 🙂

✔️ 1