-
Notifications
You must be signed in to change notification settings - Fork 139
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
fix(idempotency): deep sort payload during hashing #2570
fix(idempotency): deep sort payload during hashing #2570
Conversation
this function can sort a JSON with nested keys
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The integration tests for this branch are failing because the sorting changes the hashes/idempotency ID generated for some of the tests.
I have also left a couple comments in the code.
Thank you for the PR @arnabrahman, appreciate it! |
@am29d, @heitorlessa - This change deep sorts payloads before generating the hash in the Idempotency ID. This is a necessary change as it will lead to better idempotency detection. There is a risk however that if customers update Powertools and deploy functions with the new version that includes this change, they might see repeated requests due to the payload now being sorted and thus different. For example, this sequence could happen:
It's important to notice that this will happen only if:
Do you think this should be treated as a breaking change? I think there's an argument to be made that this new behavior should've been the default since the beginning and that we're covering a feature gap rather than adding a new feature, but I am not sure. What do you think? |
I agree that this is a necessary change and improves idempotency utility and this is a breaking change. As you said, this could disable idempotency for some cases which can lead to severe impact on the customer side. |
@dreamorosi for the e2e tests, i couldn't run it locally but maybe we need to |
@arnabrahman that's right, I believe that if we sort these payloads the tests should pass. Please bear with us while we agree on a way forward - I'm unsure whether this should be considered a bug fix or a new feature, in which case it might be a breaking change. Also what do you think? |
@dreamorosi , this is a peculiar situation. At a high level, this sounds like a bug fix. However, from my experience, I don't recall ever sorting a payload of objects before sending it. I might have done so unintentionally, but never intentionally. I believe that in the majority of cases, this change will cause issues. So, from a customer's perspective, this is a If so, in my opinion, we cannot say it's a bug fix. |
I see where you're coming from. Imo the fact that we were not ordering the payload, especially since Powertools for AWS Lambda (Python) does it, was not intended and even though the change could cause unintended side effects, these are only the results of us not sorting the payload in the first place. Like you said, sorting is not something customers would (nor should) think about it, but requests with the same payload content should be idempotent, so the fact that this wasn't the case maybe makes it a bug. |
Putting this on hold until @heitorlessa is back to advise on how to move forward. |
Take it as a bug fix, as this shouldn't have passed in our tests suite. There are internet proxies and the fact a client or a proxy could interfere with the guaranteed idempotency within a time window makes this a serious bug. e.g., HTTP headers ordering in API Gateway example: If we were changing the idempotency key format, I'd consider as a breaking change. Here, it'll cause bigger harm for new customers having mixed results without any way to debug it. In the worst case, we know > 90% of customers don't change the defaults, so idempotency records will expire within an hour.. reducing the impact window for the bugfix. |
Quality Gate passedIssues Measures |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this important PR and for the patience during the review!
Summary
According to the Issue, payloads containing the exact same keys should be considered idempotent regardless of their order.
For example, these two requests should be idempotent.
The same goes for JSON arrays, the following two requests should be idempotent.
To achieve this, we need to implement a function that deep sorts the payload & use it to sort the payload before generating the hash.
Changes
Implement a function that recursively sorts the keys of an object or elements of an array. The function is based on this blog post that was mentioned in the issue description. In addition, added support for sorting objects inside JSON array.
getType
from@aws-lambda-powertools/commons
to determine the input data type.Used this function before generating hash inside
BasePersistenceLayer
class.Also, written unit tests for the function for different scenarios that I can think of. I couldn't find a method in
jest
that checks if two objects are equal and ensures that the key positions are similar. Therefore, I usedJSON.stringify
to compare the two objects.I am not sure if I need to update any documentation for this. Please let me know if I need to make any tweaks.
Issue number: #2120
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.