Skip to content

Commit 158bee4

Browse files
mnoman09aliabbasrizvi
authored andcommitted
Refact: Added builder pattern in decision listener (#275)
1 parent 3dde5da commit 158bee4

File tree

8 files changed

+333
-224
lines changed

8 files changed

+333
-224
lines changed

core-api/src/main/java/com/optimizely/ab/Optimizely.java

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
import com.optimizely.ab.event.internal.BuildVersionInfo;
3636
import com.optimizely.ab.event.internal.EventFactory;
3737
import com.optimizely.ab.event.internal.payload.EventBatch.ClientEngine;
38-
import com.optimizely.ab.notification.DecisionInfoEnums;
38+
import com.optimizely.ab.notification.DecisionNotification;
3939
import com.optimizely.ab.notification.NotificationCenter;
4040
import org.slf4j.Logger;
4141
import org.slf4j.LoggerFactory;
@@ -653,7 +653,7 @@ <T extends Object> T getFeatureVariableValueForType(@Nonnull String featureKey,
653653
Map<String, ?> copiedAttributes = copyAttributes(attributes);
654654
FeatureDecision featureDecision = decisionService.getVariationForFeature(featureFlag, userId, copiedAttributes);
655655
Boolean featureEnabled = false;
656-
if (featureDecision.variation != null && featureDecision.variation.getFeatureEnabled()) {
656+
if (featureDecision.variation != null) {
657657
FeatureVariableUsageInstance featureVariableUsageInstance =
658658
featureDecision.variation.getVariableIdToFeatureVariableUsageInstanceMap().get(variable.getId());
659659
if (featureVariableUsageInstance != null) {
@@ -670,26 +670,20 @@ <T extends Object> T getFeatureVariableValueForType(@Nonnull String featureKey,
670670
}
671671

672672
Object convertedValue = convertStringToType(variableValue, variableType);
673-
Map<String, Object> decisionInfo = new HashMap<>();
674-
decisionInfo.put(DecisionInfoEnums.FeatureVariableDecisionInfo.FEATURE_KEY.toString(), featureKey);
675-
decisionInfo.put(DecisionInfoEnums.FeatureVariableDecisionInfo.FEATURE_ENABLED.toString(), featureEnabled);
676-
decisionInfo.put(DecisionInfoEnums.FeatureVariableDecisionInfo.VARIABLE_KEY.toString(), variableKey);
677-
decisionInfo.put(DecisionInfoEnums.FeatureVariableDecisionInfo.VARIABLE_TYPE.toString(), variableType);
678-
decisionInfo.put(DecisionInfoEnums.FeatureVariableDecisionInfo.VARIABLE_VALUE.toString(), convertedValue);
679-
if (featureDecision.decisionSource != null && featureDecision.decisionSource.equals(FeatureDecision.DecisionSource.EXPERIMENT)) {
680-
decisionInfo.put(DecisionInfoEnums.FeatureVariableDecisionInfo.SOURCE_EXPERIMENT_KEY.toString(), featureDecision.experiment.getKey());
681-
decisionInfo.put(DecisionInfoEnums.FeatureVariableDecisionInfo.SOURCE_VARIATION_KEY.toString(), featureDecision.variation.getKey());
682-
decisionInfo.put(DecisionInfoEnums.FeatureVariableDecisionInfo.SOURCE.toString(), featureDecision.decisionSource);
683-
} else {
684-
decisionInfo.put(DecisionInfoEnums.FeatureVariableDecisionInfo.SOURCE_EXPERIMENT_KEY.toString(), null);
685-
decisionInfo.put(DecisionInfoEnums.FeatureVariableDecisionInfo.SOURCE_VARIATION_KEY.toString(), null);
686-
decisionInfo.put(DecisionInfoEnums.FeatureVariableDecisionInfo.SOURCE.toString(), FeatureDecision.DecisionSource.ROLLOUT);
687-
}
688-
notificationCenter.sendNotifications(NotificationCenter.NotificationType.Decision,
689-
NotificationCenter.DecisionNotificationType.FEATURE_VARIABLE.toString(),
690-
userId,
691-
copiedAttributes,
692-
decisionInfo);
673+
674+
DecisionNotification decisionNotification = DecisionNotification.newFeatureVariableBuilder()
675+
.withUserId(userId)
676+
.withAttributes(copiedAttributes)
677+
.withFeatureKey(featureKey)
678+
.withFeatureEnabled(featureEnabled)
679+
.withVariableKey(variableKey)
680+
.withVariableType(variableType)
681+
.withVariableValue(convertedValue)
682+
.withFeatureDecision(featureDecision)
683+
.build();
684+
685+
686+
notificationCenter.sendNotifications(decisionNotification);
693687

694688
return (T) convertedValue;
695689
}

core-api/src/main/java/com/optimizely/ab/notification/DecisionInfoEnums.java

Lines changed: 0 additions & 41 deletions
This file was deleted.
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/****************************************************************************
2+
* Copyright 2019, Optimizely, Inc. and contributors *
3+
* *
4+
* Licensed under the Apache License, Version 2.0 (the "License"); *
5+
* you may not use this file except in compliance with the License. *
6+
* You may obtain a copy of the License at *
7+
* *
8+
* http://www.apache.org/licenses/LICENSE-2.0 *
9+
* *
10+
* Unless required by applicable law or agreed to in writing, software *
11+
* distributed under the License is distributed on an "AS IS" BASIS, *
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
13+
* See the License for the specific language governing permissions and *
14+
* limitations under the License. *
15+
***************************************************************************/
16+
17+
package com.optimizely.ab.notification;
18+
19+
20+
import com.optimizely.ab.bucketing.FeatureDecision;
21+
import com.optimizely.ab.config.FeatureVariable;
22+
23+
import javax.annotation.Nonnull;
24+
import javax.annotation.Nullable;
25+
import java.util.HashMap;
26+
import java.util.Map;
27+
28+
public class DecisionNotification {
29+
protected String type;
30+
protected String userId;
31+
protected Map<String, ?> attributes;
32+
protected Map<String, ?> decisionInfo;
33+
34+
protected DecisionNotification() {
35+
}
36+
37+
protected DecisionNotification(@Nonnull String type,
38+
@Nonnull String userId,
39+
@Nullable Map<String, ?> attributes,
40+
@Nonnull Map<String, ?> decisionInfo) {
41+
this.type = type;
42+
this.userId = userId;
43+
if (attributes == null) {
44+
attributes = new HashMap<>();
45+
}
46+
this.attributes = attributes;
47+
this.decisionInfo = decisionInfo;
48+
}
49+
50+
public String getType() {
51+
return type;
52+
}
53+
54+
public String getUserId() {
55+
return userId;
56+
}
57+
58+
public Map<String, ?> getAttributes() {
59+
return attributes;
60+
}
61+
62+
public Map<String, ?> getDecisionInfo() {
63+
return decisionInfo;
64+
}
65+
66+
public static FeatureVariableDecisionNotificationBuilder newFeatureVariableBuilder() {
67+
return new FeatureVariableDecisionNotificationBuilder();
68+
}
69+
70+
public static class FeatureVariableDecisionNotificationBuilder {
71+
72+
public static final String FEATURE_KEY = "feature_key";
73+
public static final String FEATURE_ENABLED = "feature_enabled";
74+
public static final String SOURCE = "source";
75+
public static final String SOURCE_EXPERIMENT_KEY = "source_experiment_key";
76+
public static final String SOURCE_VARIATION_KEY = "source_variation_key";
77+
public static final String VARIABLE_KEY = "variable_key";
78+
public static final String VARIABLE_TYPE = "variable_type";
79+
public static final String VARIABLE_VALUE = "variable_value";
80+
81+
private String featureKey;
82+
private Boolean featureEnabled;
83+
private FeatureDecision featureDecision;
84+
private String variableKey;
85+
private FeatureVariable.VariableType variableType;
86+
private Object variableValue;
87+
private String userId;
88+
private Map<String, ?> attributes;
89+
private Map<String, Object> decisionInfo;
90+
91+
protected FeatureVariableDecisionNotificationBuilder() {
92+
}
93+
94+
public FeatureVariableDecisionNotificationBuilder withUserId(String userId) {
95+
this.userId = userId;
96+
return this;
97+
}
98+
99+
public FeatureVariableDecisionNotificationBuilder withAttributes(Map<String, ?> attributes) {
100+
this.attributes = attributes;
101+
return this;
102+
}
103+
104+
public FeatureVariableDecisionNotificationBuilder withFeatureKey(String featureKey) {
105+
this.featureKey = featureKey;
106+
return this;
107+
}
108+
109+
public FeatureVariableDecisionNotificationBuilder withFeatureEnabled(boolean featureEnabled) {
110+
this.featureEnabled = featureEnabled;
111+
return this;
112+
}
113+
114+
public FeatureVariableDecisionNotificationBuilder withFeatureDecision(FeatureDecision featureDecision) {
115+
this.featureDecision = featureDecision;
116+
return this;
117+
}
118+
119+
public FeatureVariableDecisionNotificationBuilder withVariableKey(String variableKey) {
120+
this.variableKey = variableKey;
121+
return this;
122+
}
123+
124+
public FeatureVariableDecisionNotificationBuilder withVariableType(FeatureVariable.VariableType variableType) {
125+
this.variableType = variableType;
126+
return this;
127+
}
128+
129+
public FeatureVariableDecisionNotificationBuilder withVariableValue(Object variableValue) {
130+
this.variableValue = variableValue;
131+
return this;
132+
}
133+
134+
public DecisionNotification build() {
135+
decisionInfo = new HashMap<>();
136+
decisionInfo.put(FEATURE_KEY, featureKey);
137+
decisionInfo.put(FEATURE_ENABLED, featureEnabled);
138+
decisionInfo.put(VARIABLE_KEY, variableKey);
139+
decisionInfo.put(VARIABLE_TYPE, variableType);
140+
decisionInfo.put(VARIABLE_VALUE, variableValue);
141+
if (featureDecision != null && featureDecision.decisionSource != null && FeatureDecision.DecisionSource.EXPERIMENT.equals(featureDecision.decisionSource)) {
142+
decisionInfo.put(SOURCE_EXPERIMENT_KEY, featureDecision.experiment.getKey());
143+
decisionInfo.put(SOURCE_VARIATION_KEY, featureDecision.variation.getKey());
144+
decisionInfo.put(SOURCE, featureDecision.decisionSource);
145+
} else {
146+
decisionInfo.put(SOURCE_EXPERIMENT_KEY, null);
147+
decisionInfo.put(SOURCE_VARIATION_KEY, null);
148+
decisionInfo.put(SOURCE, FeatureDecision.DecisionSource.ROLLOUT);
149+
}
150+
151+
return new DecisionNotification(
152+
NotificationCenter.DecisionNotificationType.FEATURE_VARIABLE.toString(),
153+
userId,
154+
attributes,
155+
decisionInfo);
156+
}
157+
}
158+
}

core-api/src/main/java/com/optimizely/ab/notification/DecisionNotificationListener.java

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,37 +17,17 @@
1717
package com.optimizely.ab.notification;
1818

1919
import javax.annotation.Nonnull;
20-
import java.util.HashMap;
21-
import java.util.Map;
2220

23-
public abstract class DecisionNotificationListener implements NotificationListener, DecisionNotificationListenerInterface {
21+
public interface DecisionNotificationListener {
2422

2523
/**
26-
* Base notify called with var args. This method parses the parameters and calls the abstract method.
24+
* onDecision called when an activate was triggered
2725
*
28-
* @param args - variable argument list based on the type of notification.
26+
* @param decisionNotification - The decision notification object containing:
27+
* type - The notification type.
28+
* userId - The userId passed to the API.
29+
* attributes - The attribute map passed to the API.
30+
* decisionInfo - The decision information containing all parameters passed in API.
2931
*/
30-
@Override
31-
public final void notify(Object... args) {
32-
assert (args[0] instanceof String);
33-
String type = (String) args[0];
34-
assert (args[1] instanceof String);
35-
String userId = (String) args[1];
36-
Map<String, ?> attributes = null;
37-
if (args[2] != null) {
38-
assert (args[2] instanceof java.util.Map);
39-
attributes = (Map<String, ?>) args[2];
40-
} else {
41-
attributes = new HashMap<>();
42-
}
43-
assert (args[3] instanceof java.util.Map);
44-
Map<String, ?> decisionInfo = (Map<String, ?>) args[3];
45-
onDecision(type, userId, attributes, decisionInfo);
46-
}
47-
48-
@Override
49-
public abstract void onDecision(@Nonnull String type,
50-
@Nonnull String userId,
51-
@Nonnull Map<String, ?> attributes,
52-
@Nonnull Map<String, ?> decisionInfo);
32+
void onDecision(@Nonnull DecisionNotification decisionNotification);
5333
}

core-api/src/main/java/com/optimizely/ab/notification/DecisionNotificationListenerInterface.java

Lines changed: 0 additions & 36 deletions
This file was deleted.

0 commit comments

Comments
 (0)