Fork me on GitHub
#aws
<
2022-01-15
>
Ben Hammond00:01:01

Hi. I am trying to use apigatewaymanagementapi to post data to a websocket When I run this from the repl

(-> (aws/client {:api :apigatewaymanagementapi
                 :region :eu-west-2
                 :endpoint-override {:hostname "ws.foo.bar"
                                     :stage "dev"
                                     :protocol :https}
                 })
    (aws/invoke {:op :PostToConnection
                 :request {:ConnectionId "L9YKjdwtrPEAbMA="
                           :Data "helloworld"}}))
=>
{:message "Invalid connectionId: L9YKjdwtrPEAbMA=L9YKjdwtrPEAbMA=",
 :cognitect.anomalies/category :cognitect.anomalies/incorrect}
and I see from the meta that somehow the ConnectionId `L9YKjdwtrPEAbMA=` gets turned in to `L9YKjdwtrPEAbMA=L9YKjdwtrPEAbMA=`
(meta *1)
=>
{:http-request {:request-method :post,
                :scheme :https,
                :server-port 443,
                :uri "/@connections/L9YKjdwtrPEAbMA%3DL9YKjdwtrPEAbMA=",
                :headers {"x-amz-date" "20220114T233422Z",
                          "x-amz-target" ".PostToConnection",
                          "content-type" "application/x-amz-json-1.1",
                          "host" "ws.foo.bar",
                          "authorization" "***"
                          :body #object[java.nio.HeapByteBuffer
                              0x2e98a804
                              "java.nio.HeapByteBuffer[pos=0 lim=10 cap=10]"],
                :server-name ""},
 :http-response {:status 400,
                 :headers {"x-amz-apigw-id" "***=",
                           "connection" "keep-alive",
                           "x-amzn-requestid" "4af13b6f-5010-4f5e-b8cf-59eff9f856ba",
                           "x-amzn-errortype" "BadRequestException",
                           "content-length" "68",
                           "date" "Fri, 14 Jan 2022 23:34:22 GMT",
                           "content-type" "application/json"},
                 :body #object[java.io.BufferedInputStream
                               0x12c52eb4
                               "java.io.BufferedInputStream@12c52eb4"]}}
I am running
com.cognitect.aws/apigatewaymanagementapi {:mvn/version "770.2.568.0"}
am I somehow misusing the api? is this a bug? How can I work around it?

Jarrod Taylor (Clojure team)00:01:53

I am successfully sending messages with the following:

👍 1
hadils04:01:15

Thanks @U0508JRJC I reported this problem over a month ago. I appreciate this solution.

Jarrod Taylor (Clojure team)14:01:34

You are both welcome. It took longer that I would have liked to workout all the parts of a functioning websocket implementation through API Gateway. I have a blog post in the works that walks through the full process of implementing an authenticated websocket. My hope is it will save others significant time when endeavoring to do the same.

Ben Hammond17:01:24

do you know of a way to pass an x-api-key HttpHeader in the initial js/WebSocket() call? Do you authenticate AFTER the WebSocket is hooked up?

hadils04:01:42

I am trying to adapt sente to an api gw solution.

kenny18:01:57

Does DefaultAwsRegionProviderChain also work for AWS Fargate tasks? The https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/regions/providers/DefaultAwsRegionProviderChain.html seems to imply no. > AWS Region provider that looks for the region in this order: > 1. Check the 'aws.region' system property for the region. > 2. Check the 'AWS_REGION' environment variable for the region. > 3. Check the {user.home}/.aws/credentials and {user.home}/.aws/config files for the region. > 4. If running in EC2, check the EC2 metadata service for the region.

viesti11:01:08

I remember having to specify AWS_REGION for Fargate tasks

viesti11:01:48

so maybe DefaultAwsRegionProviderChain doesn't use the AWS_CONTAINER_CREDENTIALS_RELATIVE_URI that is available when running in ECS

viesti11:01:12

not sure, but would explain why I remember having to manually specify AWS_REGION

viesti11:01:37

I remember having to do that for python libs too, wondering is there some reason for this...

viesti11:01:29

heh, looked too quick, that metadata service in ECS that I was remembering might be only for the credentials, like it kinda says in that environment variable name.. so maybe (str "" (System/getenv "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI")) gives only the api keys, not the region, would have to check

viesti11:01:41

so I guess the answer is that no

viesti12:01:12

but interestingly, you can read stuff from the ECS metadata server and deduce the current region from say ARNs 😄

sh-4.2# curl -s  | jq -r '.ContainerARN' | cut -d: -f4
eu-west-1

viesti12:01:24

but if you know the region where you deploy to, depending on the deploy system, I guess specifying the region at deploy time as environment variable in the task definition isn't that bad (I've been using Terraform so you could read the current region from the aws provider)

viesti12:01:37

or then hack and use say ContainerARN 🙂

viesti12:01:58

also, if you manually specify region, then you don't need DefaultAwsRegionProviderChain

viesti12:01:29

the above curl thing I quickly explored with https://github.com/viesti/ecs-exec, running a shell in the container and looking at the env

lukasz16:01:27

Here's the ECS creds provider that we have in use in prod for over a year: https://gist.github.com/lukaszkorecki/120008f7832e23702e94f4205b8e3df5#file-ecs-simple-clj no issues whatsoever

lukasz16:01:51

the region only comes in play when making calls against AWS APIs so we set that as application level configuration

👍 1