-
Notifications
You must be signed in to change notification settings - Fork 175
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
Add hasTags() function to dataprepper expressions #2680
Conversation
Signed-off-by: Krishna Kondaka <krishkdk@amazon.com>
tags = new ArrayList<>(); | ||
Random random = new Random(); | ||
numTags = random.nextInt(9) + 1; | ||
for (int i = 0; i < numTags; i++) { |
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.
I think we should control the number of arguments in the testing.
That is, we should test with some specific number of arguments. I'd definitely recommend testing with 1
argument and "more than 1" argument - could be 2
, could be 10
.
This could be done through @Nested
. But, I think this could also be done using @ParameterizedTest
where you parameterize the number of tags.
e.g.
@ParameterizedTest
@ValueSource(ints = { 1, 2, 10 }
void testHasTagsBasic(int numTags /* Also, remove the field used */) {
hasTagsExpressionFunction = createObjectUnderTest();
tags = generateTags(numTags); // refactor this code to generate the tags on the fly
for (int i = 1; i <= numTags; i++) {
assertThat(hasTagsExpressionFunction.evaluate(tags.subList(0, i), testEvent, testFunction), equalTo(true));
}
}
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.
This might be improved upon by my more recent suggestion to add EventMetadata::hasTags
.
if (args.size() == 0) { | ||
throw new RuntimeException("hasTags() takes at least one argument"); | ||
} | ||
Set<String> tags = event.getMetadata().getTags(); |
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.
I think we may benefit from adding the hasTags()
method to the EventMetadata
.
This has a couple benefits in my opinion:
- It separates the concerns - determining whether an Event has a tag versus interpreting the function arguments.
- It creates a function that could end up being useful elsewhere.
- You can make the tests for this focus more on the arguments.
In EventMetadata
:
boolean hasTags(List<String> tags) {
for(String tag : tags) {
if(!tags.contains(tag)) {
return false;
}
}
return true;
}
This code can then be something like:
if(!args.stream()
.allMatch(a -> a instanceof String)) {
throw new RuntimeException("...");
}
final List<String> tags = args.stream()
.map(a -> (String) a)
.collect(Collectors.toList());
return event.getMetadata().hasTags(tags);
docs/expression_syntax.md
Outdated
- takes at least one argument | ||
- all arguments must be of String type | ||
- returns true if all arguments are present in the event's tags, returns false otherwise | ||
For example, if event has tags "tag1", "tag2", and "tag3", `hasTags("tag1")` or `hasTags("tag1", "tag2")` would return true and `hasTags("tag4")` would return false. |
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.
What about hasTags("tag1", "tag4")
? False? Please add this as an example as well
Signed-off-by: Krishna Kondaka <krishkdk@amazon.com>
Signed-off-by: Krishna Kondaka <krishkdk@amazon.com>
assertTrue(result.hasTag("tag1")); | ||
assertTrue(result.hasTag("tag2")); | ||
assertTrue(result.hasTag("tag3")); | ||
assertTrue(result.hasTags(List.of("tag1"))); |
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.
We should have some negative tests cases.
assertFalse(result.hasTag("notPresent");
assertFalse(result.hasTag("notPresent1", "notPresent2");
assertFalse(result.hasTag("tag1", "notPresent");
Signed-off-by: Krishna Kondaka <krishkdk@amazon.com>
Signed-off-by: Krishna Kondaka <krishkdk@amazon.com>
Codecov Report
@@ Coverage Diff @@
## main #2680 +/- ##
============================================
- Coverage 93.56% 93.54% -0.02%
- Complexity 2238 2250 +12
============================================
Files 261 262 +1
Lines 6275 6291 +16
Branches 519 520 +1
============================================
+ Hits 5871 5885 +14
- Misses 266 268 +2
Partials 138 138
|
…literals Signed-off-by: Krishna Kondaka <krishkdk@amazon.com>
@@ -21,11 +21,14 @@ public Object evaluate(final List<Object> args, Event event, Function<Object, Ob | |||
if (args.size() == 0) { | |||
throw new RuntimeException("hasTags() takes at least one argument"); | |||
} | |||
if(!args.stream().allMatch(a -> a instanceof String)) { | |||
throw new RuntimeException("hasTags() takes only String type arguments"); | |||
if(!args.stream().allMatch(a -> ((a instanceof String) && (((String)a).length() > 0) && (((String)a).charAt(0) == '"')))) { |
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.
I'd probably consider splitting this so that if this error pops up, we can better know which situation it is. But, I don't think this is critical for now.
} | ||
final List<String> tags = args.stream() | ||
.map(a -> (String) a) | ||
.map(a -> { |
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.
You can split map functions so that you can use the compact lambda form. This is not critical though.
.map(a -> (String)a)
.map(str -> str.substring(1, str.length() - 1))
…#2680) * Add hasTags() function to dataprepper expressions Signed-off-by: Krishna Kondaka <krishkdk@amazon.com> * Addressed review comments Signed-off-by: Krishna Kondaka <krishkdk@amazon.com> * Updated documentation Signed-off-by: Krishna Kondaka <krishkdk@amazon.com> * Addressed review comments Signed-off-by: Krishna Kondaka <krishkdk@amazon.com> * Fixed code coverage build failure Signed-off-by: Krishna Kondaka <krishkdk@amazon.com> * Modified to make sure that the arguments passed to hasTags is string literals Signed-off-by: Krishna Kondaka <krishkdk@amazon.com> --------- Signed-off-by: Krishna Kondaka <krishkdk@amazon.com> Signed-off-by: rajeshLovesToCode <rajesh.dharamdasani3021@gmail.com>
…-project#2680)" This reverts commit 76c1753.
…-project#2680)" This reverts commit 76c1753.
Description
Add hasTags() function to dataprepper expressions.
Data Prepper expressions can now check about presence of tags in the event.
For example an expression may look like
hasTag("tag1") and /status_code == 200
which returns true if the event has a tag with name "tag1" and status_code value is 200.
Resolves #629
Issues Resolved
#629
Check List
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.