-
Notifications
You must be signed in to change notification settings - Fork 32
fix(nullfilter): filters out attributes with null values #214
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
Conversation
Pull Request Test Coverage Report for Build 635
💛 - Coveralls |
@@ -168,6 +168,11 @@ public LogEvent createConversionEvent(@Nonnull ProjectConfig projectConfig, | |||
List<Attribute> attributesList = new ArrayList<Attribute>(); | |||
|
|||
for (Map.Entry<String, ?> entry : attributes.entrySet()) { | |||
//Ignore null value attribute | |||
if (entry.getValue() == null) { |
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.
Can we whitelist strings, numbers (probably just int
s and double
s for now, but the team might need to discuss more), and booleans rather than blacklisting some of the values we don't want to send? I should mention that OASIS-3537 has been updated and might not have mentioned that initially. 😬
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.
@nchilada this is related to OASIS-3535 not for OASIS-3537
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.
Oh, interesting. @mikeng13 can you clarify the difference between 3535 and 3537?
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.
As per my understanding, this is only related to NULL values, while OASIS-3537 is more related to filtering out all unsupported values but we have hold-off for OASIS-3537.
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've deprecated 3537 in favor of 3535. So the requirement from @nchilada for this particular PR is right. We should filter out values that aren't strings, numbers, or booleans. This includes filtering out NULLs as well.
…r null than ignore it
@@ -168,6 +168,15 @@ public LogEvent createConversionEvent(@Nonnull ProjectConfig projectConfig, | |||
List<Attribute> attributesList = new ArrayList<Attribute>(); | |||
|
|||
for (Map.Entry<String, ?> entry : attributes.entrySet()) { | |||
//Ignore null value attribute |
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.
Slightly out of date. Maybe change to
// Filter down to the types of values we're allowed to track.
// Don't allow Longs, BigIntegers, or BigDecimals - they /can/ theoretically be serialized as JSON numbers
// but may take on values that can't be faithfully parsed by the backend.
// https://github.com/optimizely/avro-schemas/blob/baeba19a7bd227aae67026474aec239110c5801d/event_batch/src/main/avro/EventBatch.avsc#L22
?
@mikecdavis @thomaszurkan-optimizely @mikeng13 @ceimaj can you review what I'm proposing as the supported data types?
@@ -168,6 +168,15 @@ public LogEvent createConversionEvent(@Nonnull ProjectConfig projectConfig, | |||
List<Attribute> attributesList = new ArrayList<Attribute>(); | |||
|
|||
for (Map.Entry<String, ?> entry : attributes.entrySet()) { | |||
//Ignore null value attribute | |||
if (entry.getValue() == null || |
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.
Technically this check isn't necessary since null instanceof ...
evaluates to false
, but it's nice to be explicit in the reference SDK since we may be porting to languages that behave differently. Good thinking!
assertNotSame(feature.getValue(), null); | ||
} | ||
} | ||
|
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.
Can we include explicit unit tests to make sure
- Integers and Decimals are both tracked. I'm not sure if we can test them distinctly via the compatibility suite, since attribute values have to be serialized via JSON.
- Longs, BigIntegers, and BigDecimals aren't tracked? We definitely can't test these via the compatibility suite.
Maybe test that Booleans are also trackable (in addition to Strings, which I assume are already tested) but I'm less concerned since those can theoretically be covered by the compatibility suite.
(!(entry.getValue() instanceof String) && | ||
!(entry.getValue() instanceof Integer) && | ||
!(entry.getValue() instanceof Double) && | ||
!(entry.getValue() instanceof Boolean))) { |
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.
Just a suggestion, Usually don't like too many Not conditions. so why we can't convert it into one not.
!(e.getValue() instanceof String || e.getValue() instanceOf Int .... ) should be equal to the above condition.
@nchilada what do u suggest?
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.
Seems reasonable to me!
…ting passed in event factory building list * Added Unit test to verify bigdecimal and bigInteger are not getting passed in event factory building list
assertNotSame(feature.getValue(), null); | ||
} | ||
} | ||
|
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.
Should we test attribute selection for conversion events too?
BTW I think we could combine createImpressionEventIgnoresInvalidAttributes
, createImpressionEventWithIntegerDecimalBoolAndStringAttributes
, createImpressionEventIgnoresNullAttributes
- that'd reduce complexity while also confirming that we merely ignore invalid attributes rather than dropping all attributes when one or two are invalid.
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.
Lets leave these Unit Tests. I added one more unit test which is making ConversionEvent and in that unit test we are passing valid and invalid attributes in same attributes map, we are verifying that only valid attributes are getting passed and others are getting ignored. I think that will cover the condition you are asking to verify. So is that ok?
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.
Okay, that works too. Thanks!
@@ -168,6 +168,16 @@ public LogEvent createConversionEvent(@Nonnull ProjectConfig projectConfig, | |||
List<Attribute> attributesList = new ArrayList<Attribute>(); | |||
|
|||
for (Map.Entry<String, ?> entry : attributes.entrySet()) { | |||
// Filters down to the types of values that are allowed. |
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.
Can we link to https://github.com/optimizely/avro-schemas/blob/baeba19a7bd227aae67026474aec239110c5801d/event_batch/src/main/avro/EventBatch.avsc#L22 since that's the source of truth? Or actually https://developers.optimizely.com/x/events/api/#Attribute_ might be preferable since not everyone can view the avro-schemas repo
* Added Unit Test To test with ConversionEvent and verified that valid attributes are getting passed and invalid are getting ignored
// Filter down to the types of values we're allowed to track. | ||
// Don't allow Longs, BigIntegers, or BigDecimals - they /can/ theoretically be serialized as JSON numbers | ||
// but may take on values that can't be faithfully parsed by the backend. | ||
// https://github.com/optimizely/avro-schemas/blob/baeba19a7bd227aae67026474aec239110c5801d/event_batch/src/main/avro/EventBatch.avsc#L22 |
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 is a private repo. Please don't mention it here.
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.
Okay, fair enough. Can we link to https://developers.optimizely.com/x/events/api/#Attribute_ instead?
FYI, I ran integration tests for these changes and they passed =) |
This will ignore attributes with null values on creation of impression or conversion event.