-
Notifications
You must be signed in to change notification settings - Fork 32
(feat): Feature Management getFeatureVariable Listener #270
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 903
💛 - Coveralls |
Pull Request Test Coverage Report for Build 976
💛 - Coveralls |
Isn't this already the case? |
No it was not the case already, we did that change in all sdks |
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.
Where are we asserting that the notification listener is being called with correct params?
|
||
public class DecisionInfoEnums { | ||
public enum GetFeatureVariableDecisionInfo { | ||
SOURCE_EXPERIMENT_KEY("source_experiment_key"), |
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.
nit. I think alphabetizing will be a good order for this.
…a-sdk into mnoman/getFeatVarListener
} else { | ||
logger.info("User \"{}\" was not bucketed into any variation for feature flag \"{}\". " + | ||
"The default value \"{}\" for \"{}\" is being returned.", | ||
userId, featureKey, variableValue, variableKey | ||
); | ||
} | ||
|
||
Object convertedValue = convertStringToType(variableValue, variableType); |
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 conversion is now happening twice per api call. Once here and once in the originating method.
} else { | ||
logger.info("User \"{}\" was not bucketed into any variation for feature flag \"{}\". " + | ||
"The default value \"{}\" for \"{}\" is being returned.", | ||
userId, featureKey, variableValue, variableKey | ||
); | ||
} | ||
|
||
Object convertedValue = convertStringToType(variableValue, variableType); | ||
Map<String, Object> decisionInfo = new HashMap<>(); | ||
decisionInfo.put(DecisionInfoEnums.FeatureVariableDecisionInfo.FEATURE_KEY.toString(), featureKey); |
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.
Not a valid use of Enums. What you're doing here just requires constants or can even be a builder.
Via constants this would reduce to:
decisionInfo.put(DECISION_FEATURE_KEY, featureKey);
decisionInfo.put(DECISION_FEATURE_ENABLED, featureEnabled);
...
Via a builder it would be:
Map<String, Object> decisionInfo = DecisionInfoMap.builder()
.withFeatureKey(featureKey)
.withFeatureEnabled(featureEnabled)
...
.build();
I personally like the builder approach since within the builder you'd abstract some of the conditional logic below.
Actually, in the context of the notification listener the entire thing can benefit from the builder pattern which actually transforms into a fluent pattern if you in corporate the notification itself.
DecisionNotification.builder()
.withUserId(userId)
.withAttributes(attributes)
.withFeatureKey(featureKey)
.withFeatureEnabled(featureEnabled)
...
.send();
A much cleaner interface :)
return variableValue; | ||
} | ||
|
||
// Helper method which takes type and variable value and convert it to object to use in Listener DecisionInfo object variable value | ||
private Object convertStringToType(String variableValue, FeatureVariable.VariableType type) { |
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.
Refactor so we're not doing String to Type conversion multiple times and in multiple places.
|
||
package com.optimizely.ab.notification; | ||
|
||
public class DecisionInfoEnums { |
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.
Remove Enum class in favor of something more appropriate. See previous comment about constants vs builder vs fluent approaches.
} | ||
|
||
@Override | ||
public abstract void onDecision(@Nonnull String type, |
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.
Would require a larger refactor, but we can generalize much better if we used actual notification Objects as opposed to positional arguments which as we can see in this example can lead to bugs since one can easily swap type for userId and attributes for decisionInfo. In this example if we had a DecisionNotification
object with members type
, userId
etc, then everything becomes much more explicit.
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.
Minor feedback. Looks good otherwise.
return variableValue; | ||
} catch (Exception exception) { | ||
logger.error("BooleanTypeException while trying to parse \"" + variableValue + | ||
"\" as Boolean. " + exception); | ||
} | ||
return 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.
You can just return variableValue
here
attributes, | ||
FeatureVariable.VariableType.DOUBLE | ||
); | ||
if (variableValue != 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.
This check seems redundant. You can just change last line to be return variableValue
… per new design (#280) * Changed DecisionSource experiment to feature-test and added source_info * Updated feature_variable to feature-variable * Update core-api/src/main/java/com/optimizely/ab/notification/DecisionNotification.java Co-Authored-By: mnoman09 <Muhammadnoman@folio3.com>
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.
Looks good. Lets make the change we talked about in a follow up.
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.
Going to merge it in its current form. We will have to follow up with changes proposed in the different PR.
Synced offline with Mike about going ahead for now.
return variableValue; | ||
} catch (Exception exception) { | ||
logger.error("NumberFormatException while trying to parse \"" + variableValue + | ||
"\" as Double. " + exception); |
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.
Summary
##Ticket:
OASIS-4228