Skip to content
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

feat(idempotency): add internal powertools JMESPath support #578

Merged
merged 29 commits into from
May 9, 2024

Conversation

hjgraca
Copy link
Contributor

@hjgraca hjgraca commented Apr 18, 2024

Description of your changes

This PR introduces support for Powertools internal JMESPath functions to the Idempotency utility.
This PR will remove the 3rd party dependency of JMESPath.NET thus strengthening our project to supply chain attacks and 3rd party maintainers.

With this new feature customers can use the powertools_json(), powertools_base64(), and powertools_base64_gzip() custom functions to deserialize encoded payloads and use the values within them as idempotency key.

This is especially useful when working with API Gateway or SQS messages among others, since oftentimes the customer defined part of the payload is encoded as JSON stringified object or base64 encoded value:

 {
  "body": "eyJjdXN0b21lcklkIjoiZGQ0NjQ5ZTYtMjQ4NC00OTkzLWFjYjgtMGY5MTIzMTAzMzk0In0=",
  "deeply_nested": [
    {
      "some_data": [
        1,
        2,
        3
      ]
    }
  ]
}
var transformer = JsonTransformer.Parse("powertools_base64(body).customerId");
using var result = transformer.Transform(doc.RootElement);
Logger.LogInformation(result.RootElement.GetRawText()); // "dd4649e6-2484-4993-acb8-0f9123103394"

The feature is added by having the Idempotency utility take a dependency on the new AWS.Lambda.Powertools.JMESPath project and replacing the existing, JMESPath.NET external dependency.

To be discussed if we should release AWS.Lambda.Powertools.JMESPath as a new NuGet package, so people can use it outside Idempotency utility.

Related issues, RFCs

Issue number: #568

Checklist


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.

@auto-assign auto-assign bot requested review from amirkaws and sliedig April 18, 2024 14:11
@boring-cyborg boring-cyborg bot added area/idempotency documentation Improvements or additions to documentation labels Apr 18, 2024
@pull-request-size pull-request-size bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Apr 18, 2024
@github-actions github-actions bot added the feature New features or minor changes label Apr 18, 2024
@hjgraca hjgraca linked an issue Apr 18, 2024 that may be closed by this pull request
2 tasks
@boring-cyborg boring-cyborg bot added github-actions Changes in GitHub workflows internal Maintenance changes labels Apr 19, 2024
@boring-cyborg boring-cyborg bot added the tests label Apr 19, 2024
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://jmespath.org/specification.html#sort-by

Sort an array using an expression _expr as the sort key. For each element in the array of _resources, the _expr expression is applied and the resulting value is used as the key used when sorting the _resources.

If the result of evaluating the _expr against the current array _resources results in type other than a number or a string, an invalid-type error will occur.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://jmespath.org/specification.html#sort

This function accepts an array arg[0] argument and returns the sorted elements of the arg[0] as an array.
The array must be a list of strings or numbers. Sorting strings is based on code points. Locale is not taken into account.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://jmespath.org/specification.html#sum

Returns the sum of the provided array argument.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checks if it is number and first tries decimal and later double sum operation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://jmespath.org/specification.html#to-array

If:

  • array - Returns the passed in value.
  • number/string/object/boolean - Returns a one element array containing the passed in argument.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://jmespath.org/specification.html#to-number

  • string - Returns the parsed number. Any string that conforms to the json-number production is supported. Note that the floating number support will be implementation specific, but implementations should support at least IEEE 754-2008 binary64 (double precision) numbers, as this is generally available and widely used.
  • number - Returns the passed in value.
  • array - null
  • object - null
  • boolean - null
  • null - null

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://jmespath.org/specification.html#to-string

  • string - Returns the passed in value.
  • number/array/object/boolean - The JSON encoded value of the object. The JSON encoder should emit the encoded JSON value without adding any additional new lines.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://jmespath.org/specification.html#type

Returns the JavaScript type of the given arg[0] argument as a string value.

The return value MUST be one of the following:

  • number
  • string
  • boolean
  • array
  • object
  • null

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://jmespath.org/specification.html#values

Returns the values of the provided object. Note that because JSON hashes are inheritently unordered, the values associated with the provided object obj are inheritently unordered. Implementations are not required to return values in any specific order.

Copy link
Contributor Author

@hjgraca hjgraca May 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the main parser. The file was not modified from the original code. Also similar implementation from the c++ repository https://github.com/danielaparker/jsoncons/blob/master/include/jsoncons/json_parser.hpp

This class is responsible for parsing the string containing the JMESPath expression and creating a stack with the correct objects (Functions, Expressions, Comparers) when a token is found.

Copy link
Contributor Author

@hjgraca hjgraca May 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Provides functionality for applying a JMESPath expression to transform a JSON document

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://jmespath.org/specification.html#slices

A slice expression allows you to select a contiguous subset of an array. A slice has a start, stop, and step value. The general form of a slice is [start:stop:step], but each component is optional and can be omitted.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some tests/examples of using JMESPath

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Full JMesPath tests. There are multiple test files in the test_files folder.
These test files are in the format given and the cases to test

  • given is the Json payload
  • cases are the JMESTPath expressions and the expected result
    The tests will look into these files and compare the expected result with the result of the JMESPath operation result.

Copy link
Contributor Author

@hjgraca hjgraca left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ready to review, added comments.
Unfortunately GitHub does not do a good job when pushing new commits and removes (outdated) comments from the files changed, best option is to go through the comments here in the conversations tab or in the files changed tab click on the conversations to view old ones (previous commit)

Copy link
Contributor

@amirkaws amirkaws left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just some nitpick suggestions

Copy link

sonarcloud bot commented May 9, 2024

Quality Gate Passed Quality Gate passed

Issues
3 New issues
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
2.0% Duplication on New Code

See analysis details on SonarCloud

Copy link

codecov bot commented May 9, 2024

Codecov Report

Attention: Patch coverage is 72.32741% with 950 lines in your changes are missing coverage. Please review.

Project coverage is 72.58%. Comparing base (5bc87a0) to head (c744870).

Files Patch % Lines
...c/AWS.Lambda.Powertools.JMESPath/JmesPathParser.cs 88.67% 87 Missing and 45 partials ⚠️
...Lambda.Powertools.JMESPath/Values/ValueComparer.cs 13.33% 49 Missing and 3 partials ⚠️
....JMESPath/Utilities/JsonElementEqualityComparer.cs 32.39% 40 Missing and 8 partials ⚠️
...raries/src/AWS.Lambda.Powertools.JMESPath/Token.cs 64.81% 31 Missing and 7 partials ⚠️
...owertools.JMESPath/Values/ValueEqualityComparer.cs 44.77% 32 Missing and 5 partials ⚠️
...S.Lambda.Powertools.JMESPath/Values/DoubleValue.cs 0.00% 34 Missing ⚠️
...ambda.Powertools.JMESPath/Functions/SumFunction.cs 46.66% 20 Missing and 4 partials ⚠️
...Powertools.JMESPath/Expressions/SliceProjection.cs 65.15% 18 Missing and 5 partials ⚠️
...WS.Lambda.Powertools.JMESPath/Values/ArrayValue.cs 61.40% 22 Missing ⚠️
....Powertools.JMESPath/Functions/EvaluateMinMaxBy.cs 53.33% 15 Missing and 6 partials ⚠️
... and 66 more
Additional details and impacted files
@@             Coverage Diff             @@
##           develop     #578      +/-   ##
===========================================
- Coverage    72.91%   72.58%   -0.33%     
===========================================
  Files          109      190      +81     
  Lines         4489     7901    +3412     
  Branches       455      851     +396     
===========================================
+ Hits          3273     5735    +2462     
- Misses        1087     1873     +786     
- Partials       129      293     +164     
Flag Coverage Δ
unittests 72.58% <72.32%> (-0.33%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@hjgraca hjgraca merged commit 4e6681f into aws-powertools:develop May 9, 2024
6 of 8 checks passed
@hjgraca hjgraca mentioned this pull request May 9, 2024
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/idempotency documentation Improvements or additions to documentation feature New features or minor changes github-actions Changes in GitHub workflows internal Maintenance changes size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature request: Reduce use of lesser known packages in Idemopotency package
2 participants