anyone ever handled an SQSEvent from a clojure-based lambda before? I’m trying to utilize the https://aws.amazon.com/about-aws/whats-new/2021/11/aws-lambda-partial-batch-response-sqs-event-source/ AWS came out with a couple of years ago for individual failing records in a batch of SQS messages, but I’m holding it wrong in some way.
originally, I was having my main lambda handler class :implements [com.amazonaws.services.lambda.runtime.RequestStreamHandler] , but even if I returned a JSON structure matching the syntax offered in https://docs.aws.amazon.com/lambda/latest/dg/services-sqs-errorhandling.html, the records whose message IDs were in that structure wouldn’t show up in the deadletter queue I’d set up.
• I know the DLQ is set up correctly, as before I tried throwing an exception from the lambda body, and the messages dutifully showed up in the DLQ as expected.
• I noticed in the second link that their example code :implements [com.amazonaws.services.lambda.runtime.RequestHandler] instead, so I’m trying to switch to that, but I haven’t quite figured out how to parse the LinkedHashMap that comes in from the SQS message yet
I know there’s no clear, concise question there … mostly looking to rubber-duck this with someone in a thread or something like that 🙂
ah! my first problem - after switching to the RequestHandler interface, I was treating java’s LinkedHashMap as a regular map, e.g. expecting (get "Records" event) to work. duh, this is java interop! that won’t work! more appropriate would be: (.get event "Records")
and once I got past that and returned a sort of dummy {"batchItemFailures": {"itemIdentifier": <messageId>"}} object, the object showed up in the DLQ!
“but why would this work and not the other interface that I was originally using (RequestStreamHandler)?” I wondered to myself
I wasn’t actually USING the outputstream the interface gives me! I was just returning the JSON string of batchItemFailures and expecting the lambda/AWS to pick up the rest. whoops!
yep - once I actually started WRITING to it, we’re good! final “dummy logging” code:
(ns app.main
(:require [clojure.data.json :as json]
[ :as io])
(:gen-class
:implements [com.amazonaws.services.lambda.runtime.RequestStreamHandler]))
(defn -handleRequest
[_main is os _context]
(let [records (-> (json/read (io/reader is) :key-fn keyword)
:Records)]
(with-open [writer (io/writer os)]
(json/write {:batchItemFailures {:itemIdentifier (:messageId (first records))}}
writer)
(.flush os)))) Hehe, I was getting ready to jump in here, but you duckie’d yourself to victory. 😂