-
Notifications
You must be signed in to change notification settings - Fork 90
Add Support for Differentiating Cached and Regular Responses in Idempotency Handling for Accurate Metrics #1780
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hey @fernando-mendonca1, thank you for your detailed feature request and for describing your use-case in so much detail. This is awesome! 🚀 We have recently published our roadmap for 2025 and feature parity between the Java library and Powertools libraries in other languages is something we are planning to work on. I believe that your feature request fits well in this context. There was already some work done regarding a new major version release and I can image that the feature you described could become part of this (see Regarding your proposed options (1 and 2), I believe both the response hook solution as well as your Idempotency.config()
.withPersistenceStore(
DynamoDBPersistenceStore.builder()
.withTableName(System.getenv("TABLE_NAME"))
.build())
// Make it part of IdempotencyConfig rather than persistence store
.withConfig(
IdempotencyConfig.builder()
.withEventKeyJMESPath("messageId")
// Logic to manipulate original response can be added here
.withResponseHook((response, idempotentData) -> {
return new SubscriptionResult(response.getPaymentId(), "noop", 200);
})
.build())
.configure(); I will triage your request further with the Powertools team. In the meantime, some questions:
|
Hey @fernando-mendonca1, we will pick this up for version 2.0.0 of Powertools. I prefer the response hook option since it is similar to the Python and TypeScript implementation. @hjgraca I assume you will go for the response hook option in .NET as well? @fernando-mendonca1, let me know what you think. |
Hi, @phipag, Coming back to this. Apologies for the great delay, I was on sick leave for a good while, and swamped once I came back. To start by answering your questions, I believe the example you wrote out on this comment will work very well, after having a few meetings with my team to check in with them. Regarding contribution, I'm happy to do it, I'm just not sure how much time I can allocate towards it and I don't want to slow down or impede anything. Perhaps something that might work and be helpful is if I help review and test the work? I'd be able to quickly plug the new version in and deploy it to out staging environment after reviewing. From now on I'll be more readily available, so please fell free to reach out if there's anything I can do. |
Hey @fernando-mendonca1, thanks for getting back to me. I hope you feel better now! 🚀 No problem, I understand that you have a busy schedule. We can work on this together where I do the implementation work with your help in reviewing it. In this branch, I created a first implementation draft and updated our idempotency example to reflect the use-case you described. Currently, the interface looks like this where the response hook will be called with a Java public App(DynamoDbClient client) {
Idempotency.config().withConfig(
IdempotencyConfig.builder()
.withEventKeyJMESPath("powertools_json(body).address")
// This is the new response hook option
.withResponseHook((responseData, dataRecord) -> {
if (responseData instanceof APIGatewayProxyResponseEvent) {
APIGatewayProxyResponseEvent proxyResponse = (APIGatewayProxyResponseEvent) responseData;
final Map<String, String> headers = new HashMap<>();
headers.putAll(proxyResponse.getHeaders());
headers.put("x-idempotency-response", "true");
headers.put("x-idempotency-expiration",
String.valueOf(dataRecord.getExpiryTimestamp()));
proxyResponse.setHeaders(headers);
return proxyResponse;
}
return responseData;
})
.build())
.withPersistenceStore(
DynamoDBPersistenceStore.builder()
.withDynamoDbClient(client)
.withTableName(System.getenv("IDEMPOTENCY_TABLE"))
.build())
.configure();
} Based on the use-case you described, I updated the example to append two Non-idempotent response:
Idempotent response:
What do you think about this? Does this address your use-case of generating client-side metrics regarding idempotent responses? Let me know if you have any suggestions for improvement. |
Hey @fernando-mendonca1, I just merged a PR with this feature and also updated our official example with an example of how to append HTTP Headers to idempotent responses: https://github.com/aws-powertools/powertools-lambda-java/blob/v2/examples/powertools-examples-idempotency/src/main/java/helloworld/App.java#L50-L65. The preview documentation website was also updated: https://docs.powertools.aws.dev/lambda/java/preview/utilities/idempotency/#manipulating-the-idempotent-response. I would love for you and your team to review and test this. Would you be able to pull the repository and test the I am happy to help – please let me know if you want to jump on a call for this and we can arrange this. |
Hi, @phipag, Amazing, thank you for working on this and for the update. I'd be very happy review and test it. I just finished my previous task last Friday, so this will be my priority this week. I will keep you updated through here. Regarding a call, let me give it a try first and see if I encounter any blockers, then we can set it up, it would be very appreciated. |
Awesome, let me know if you have any questions 🚀 |
Hey back, @phipag, Wanted to circle back and confirm that my tests with If there is anything else that I can do to help please feel free to ask. Also, what are the necessary steps until this version of the library is pushed to the official assets repository? |
Hey @fernando-mendonca1, welcome back! 👋 I am very happy to hear that your testing was successful. Let me know how you progress with your unit tests.
I am currently working on preparations for the This week, I will create public documentation about this process and will send you an update with more info once this is done. Additionally, I will let you know once the SNAPSHOT as well as potential pre-release assets are published to Maven Central. This will happen very soon as well. |
Great, thank you @phipag. Everything is clear. I'm done with the testing on my side. We've deployed a version of our code that uses I have some availability to help out, so please let me know if there's anything I can help with. |
Thanks @fernando-mendonca1, I am happy to hear that. I will keep you posted as we progress with the first Regarding this specific feature, there is nothing more to be done but you can have a look at our open issues especially those with the |
Hi, @phipag, I have a quick question from my time. When you publish pre-release versions, such as alpha and beta, do you do it on the main Maven repository, or somewhere else? Additionally, are these pre-release versions labeled SNAPSHOT, or release? |
we used to publish SNAPSHOT versions to https://aws.oss.sonatype.org: powertools-lambda-java/pom.xml Lines 100 to 105 in 8dcdddf
Caution: These are not up-to-date. Based on this migration guide it looks like we need to migrate to Maven Central soon (https://central.sonatype.org/faq/what-is-different-between-central-portal-and-legacy-ossrh/) which means that those SNAPSHOT releases will end up in the main Maven Repository once we completed this migration.
What do you mean by "labeled"? |
Hey @fernando-mendonca1, I have a quick update on the location where we will publish SNAPSHOT and And you can read the most up-to-date documentation for these releases here: https://docs.powertools.aws.dev/lambda/java/preview/ I will notify you here again once we made the first SNAPSHOT release to this location. |
Hey @phipag , Very nice, thank you for the clear information. We're currently running the Will keep an eye out for alpha releases. |
This is awesome to hear! Let's keep in touch on the progress you and us make. |
Is your feature request related to a problem? Please describe.
In the Account Security team at Booking, we rely on the Java Powertools library's idempotency support to manage both idempotent and non-idempotent downstream API calls. This functionality is crucial for ensuring that our security remediations are executed without unintended duplication or unnecessary load on our systems.
However, there is currently no mechanism to distinguish between a regular response and one that has been cached and returned by the Powertools library. While this behavior is technically correct and functions as intended, it presents a challenge when it comes to accurately tracking business metrics. Specifically, if we are unable to differentiate between regular and cached responses, our count of successful executions becomes inaccurate. This discrepancy impacts our projects on a business level, as we depend on these metrics to monitor key goals and milestones effectively.
Describe the solution you'd like
We propose two potential solutions, in decreasing order of preference:
Implementing either of these solutions would bring the Java implementation in line with the capabilities already available in the Python version of Powertools, which supports response manipulation as documented here: Powertools Python Documentation.
Describe alternatives you've considered
Moving the
@Idempotent
Annotation: Shifting the annotation to a secondary method rather than the handler method was deemed unviable, as idempotency execution is independent of the method itself.Custom Idempotency Annotation: Creating a custom annotation that inherits from Powertools was rejected due to the increased complexity in maintenance and the need to track upstream changes continuously.
Implementing Functionality In-House: Developing similar functionality within our project using DynamoDB would lead to duplication of existing features and an increased maintenance burden, which we aim to avoid.
The text was updated successfully, but these errors were encountered: