1414import io .split .client .dtos .SplitChange ;
1515import io .split .client .dtos .Status ;
1616import io .split .client .dtos .WhitelistMatcherData ;
17+ import io .split .client .dtos .RuleBasedSegment ;
18+ import io .split .client .dtos .ChangeDto ;
1719
1820import java .security .SecureRandom ;
1921import java .util .ArrayList ;
@@ -30,66 +32,136 @@ private LocalhostSanitizer() {
3032 public static SplitChange sanitization (SplitChange splitChange ) {
3133 SecureRandom random = new SecureRandom ();
3234 List <Split > splitsToRemove = new ArrayList <>();
33- if (splitChange .featureFlags .t < LocalhostConstants .DEFAULT_TS || splitChange .featureFlags .t == 0 ) {
34- splitChange .featureFlags .t = LocalhostConstants .DEFAULT_TS ;
35- }
36- if (splitChange .featureFlags .s < LocalhostConstants .DEFAULT_TS || splitChange .featureFlags .s > splitChange .featureFlags .t ) {
37- splitChange .featureFlags .s = splitChange .featureFlags .t ;
38- }
35+ List <RuleBasedSegment > ruleBasedSegmentsToRemove = new ArrayList <>();
36+ splitChange = sanitizeTillAndSince (splitChange );
37+
3938 if (splitChange .featureFlags .d != null ) {
40- for (Split split : splitChange .featureFlags .d ) {
41- if (split .name == null ){
39+ for (Split split : splitChange .featureFlags .d ) {
40+ if (split .name == null ) {
4241 splitsToRemove .add (split );
4342 continue ;
4443 }
45- if (split .trafficTypeName == null || split .trafficTypeName .isEmpty ()) {
46- split .trafficTypeName = LocalhostConstants .USER ;
47- }
44+ split .trafficTypeName = sanitizeIfNullOrEmpty (split .trafficTypeName , LocalhostConstants .USER );
45+ split .status = sanitizeStatus (split .status );
46+ split .defaultTreatment = sanitizeIfNullOrEmpty (split .defaultTreatment , LocalhostConstants .CONTROL );
47+ split .changeNumber = sanitizeChangeNumber (split .changeNumber , 0 );
48+
4849 if (split .trafficAllocation == null || split .trafficAllocation < 0 || split .trafficAllocation > LocalhostConstants .SIZE_100 ) {
4950 split .trafficAllocation = LocalhostConstants .SIZE_100 ;
5051 }
5152 if (split .trafficAllocationSeed == null || split .trafficAllocationSeed == 0 ) {
52- split .trafficAllocationSeed = - random .nextInt (10 ) * LocalhostConstants .MILLI_SECONDS ;
53+ split .trafficAllocationSeed = -random .nextInt (10 ) * LocalhostConstants .MILLI_SECONDS ;
5354 }
5455 if (split .seed == 0 ) {
55- split .seed = - random .nextInt (10 ) * LocalhostConstants .MILLI_SECONDS ;
56- }
57- if (split .status == null || split .status != Status .ACTIVE && split .status != Status .ARCHIVED ) {
58- split .status = Status .ACTIVE ;
59- }
60- if (split .defaultTreatment == null || split .defaultTreatment .isEmpty ()) {
61- split .defaultTreatment = LocalhostConstants .CONTROL ;
56+ split .seed = -random .nextInt (10 ) * LocalhostConstants .MILLI_SECONDS ;
6257 }
63- if (split .changeNumber < 0 ) {
64- split .changeNumber = 0 ;
65- }
66- if (split .algo != LocalhostConstants .ALGO ){
58+ if (split .algo != LocalhostConstants .ALGO ) {
6759 split .algo = LocalhostConstants .ALGO ;
6860 }
69- if (split .conditions == null ) {
70- split .conditions = new ArrayList <>();
71- }
72-
73- Condition condition = new Condition ();
74- if (!split .conditions .isEmpty ()){
75- condition = split .conditions .get (split .conditions .size () - 1 );
76- }
61+ split .conditions = sanitizeConditions ((ArrayList <Condition >) split .conditions , false , split .trafficTypeName );
62+ }
63+ splitChange .featureFlags .d .removeAll (splitsToRemove );
64+ } else {
65+ splitChange .featureFlags .d = new ArrayList <>();
66+ }
7767
78- if (split .conditions .isEmpty () || !condition .conditionType .equals (ConditionType .ROLLOUT ) ||
79- condition .matcherGroup .matchers == null ||
80- condition .matcherGroup .matchers .isEmpty () ||
81- !condition .matcherGroup .matchers .get (0 ).matcherType .equals (MatcherType .ALL_KEYS )) {
82- Condition rolloutCondition = new Condition ();
83- split .conditions .add (createRolloutCondition (rolloutCondition , split .trafficTypeName , null ));
68+ if (splitChange .ruleBasedSegments .d != null ) {
69+ for (RuleBasedSegment ruleBasedSegment : splitChange .ruleBasedSegments .d ) {
70+ if (ruleBasedSegment .name == null ) {
71+ ruleBasedSegmentsToRemove .add (ruleBasedSegment );
72+ continue ;
8473 }
74+ ruleBasedSegment .trafficTypeName = sanitizeIfNullOrEmpty (ruleBasedSegment .trafficTypeName , LocalhostConstants .USER );
75+ ruleBasedSegment .status = sanitizeStatus (ruleBasedSegment .status );
76+ ruleBasedSegment .changeNumber = sanitizeChangeNumber (ruleBasedSegment .changeNumber , 0 );
77+ ruleBasedSegment .conditions = sanitizeConditions ((ArrayList <Condition >) ruleBasedSegment .conditions , false ,
78+ ruleBasedSegment .trafficTypeName );
79+ ruleBasedSegment .excluded .segments = sanitizeExcluded ((ArrayList ) ruleBasedSegment .excluded .segments );
80+ ruleBasedSegment .excluded .keys = sanitizeExcluded ((ArrayList ) ruleBasedSegment .excluded .keys );
8581 }
86- splitChange .featureFlags .d .removeAll (splitsToRemove );
87- return splitChange ;
82+ splitChange .ruleBasedSegments .d .removeAll (ruleBasedSegmentsToRemove );
83+ } else {
84+ splitChange .ruleBasedSegments .d = new ArrayList <>();
85+ }
86+
87+ return splitChange ;
88+ }
89+
90+ private static ArrayList <Condition > sanitizeConditions (ArrayList <Condition > conditions , boolean createPartition , String trafficTypeName ) {
91+ if (conditions == null ) {
92+ conditions = new ArrayList <>();
93+ }
94+
95+ Condition condition = new Condition ();
96+ if (!conditions .isEmpty ()){
97+ condition = conditions .get (conditions .size () - 1 );
98+ }
99+
100+ if (conditions .isEmpty () || !condition .conditionType .equals (ConditionType .ROLLOUT ) ||
101+ condition .matcherGroup .matchers == null ||
102+ condition .matcherGroup .matchers .isEmpty () ||
103+ !condition .matcherGroup .matchers .get (0 ).matcherType .equals (MatcherType .ALL_KEYS )) {
104+ Condition rolloutCondition = new Condition ();
105+ conditions .add (createRolloutCondition (rolloutCondition , trafficTypeName , null , createPartition ));
106+ }
107+ return conditions ;
108+ }
109+ private static String sanitizeIfNullOrEmpty (String toBeSantitized , String defaultValue ) {
110+ if (toBeSantitized == null || toBeSantitized .isEmpty ()) {
111+ return defaultValue ;
112+ }
113+ return toBeSantitized ;
114+ }
115+
116+ private static long sanitizeChangeNumber (long toBeSantitized , long defaultValue ) {
117+ if (toBeSantitized < 0 ) {
118+ return defaultValue ;
119+ }
120+ return toBeSantitized ;
121+ }
122+
123+ private static Status sanitizeStatus (Status toBeSanitized ) {
124+ if (toBeSanitized == null || toBeSanitized != Status .ACTIVE && toBeSanitized != Status .ARCHIVED ) {
125+ return Status .ACTIVE ;
126+ }
127+ return toBeSanitized ;
128+
129+ }
130+
131+ private static ArrayList sanitizeExcluded (ArrayList excluded )
132+ {
133+ if (excluded == null ) {
134+ return new ArrayList <>();
135+ }
136+ return excluded ;
137+ }
138+
139+ private static SplitChange sanitizeTillAndSince (SplitChange splitChange ) {
140+ if (checkTillConditions (splitChange .featureFlags )) {
141+ splitChange .featureFlags .t = LocalhostConstants .DEFAULT_TS ;
142+ }
143+ if (checkSinceConditions (splitChange .featureFlags )) {
144+ splitChange .featureFlags .s = splitChange .featureFlags .t ;
145+ }
146+
147+ if (checkTillConditions (splitChange .ruleBasedSegments )) {
148+ splitChange .ruleBasedSegments .t = LocalhostConstants .DEFAULT_TS ;
149+ }
150+ if (checkSinceConditions (splitChange .ruleBasedSegments )) {
151+ splitChange .ruleBasedSegments .s = splitChange .ruleBasedSegments .t ;
88152 }
89- splitChange .featureFlags .d = new ArrayList <>();
90153 return splitChange ;
91154 }
92- public static SegmentChange sanitization (SegmentChange segmentChange ) {
155+
156+ private static <T > boolean checkTillConditions (ChangeDto <T > change ) {
157+ return change .t < LocalhostConstants .DEFAULT_TS || change .t == 0 ;
158+ }
159+
160+ private static <T > boolean checkSinceConditions (ChangeDto <T > change ) {
161+ return change .s < LocalhostConstants .DEFAULT_TS || change .s > change .t ;
162+ }
163+
164+ public static SegmentChange sanitization (SegmentChange segmentChange ) {
93165 if (segmentChange .name == null || segmentChange .name .isEmpty ()) {
94166 return null ;
95167 }
@@ -111,7 +183,7 @@ public static SegmentChange sanitization(SegmentChange segmentChange) {
111183 return segmentChange ;
112184 }
113185
114- public static Condition createRolloutCondition (Condition condition , String trafficType , String treatment ) {
186+ public static Condition createRolloutCondition (Condition condition , String trafficType , String treatment , boolean createPartition ) {
115187 condition .conditionType = ConditionType .ROLLOUT ;
116188 condition .matcherGroup = new MatcherGroup ();
117189 condition .matcherGroup .combiner = MatcherCombiner .AND ;
@@ -126,19 +198,21 @@ public static Condition createRolloutCondition(Condition condition, String traff
126198 condition .matcherGroup .matchers = new ArrayList <>();
127199 condition .matcherGroup .matchers .add (matcher );
128200
129- condition .partitions = new ArrayList <>();
130- Partition partition1 = new Partition ();
131- Partition partition2 = new Partition ();
132- partition1 .size = LocalhostConstants .SIZE_100 ;
133- partition2 .size = LocalhostConstants .SIZE_0 ;
134- if (treatment != null ) {
135- partition1 .treatment = treatment ;
136- } else {
137- partition1 .treatment = LocalhostConstants .TREATMENT_OFF ;
138- partition2 .treatment = LocalhostConstants .TREATMENT_ON ;
201+ if (createPartition ) {
202+ condition .partitions = new ArrayList <>();
203+ Partition partition1 = new Partition ();
204+ Partition partition2 = new Partition ();
205+ partition1 .size = LocalhostConstants .SIZE_100 ;
206+ partition2 .size = LocalhostConstants .SIZE_0 ;
207+ if (treatment != null ) {
208+ partition1 .treatment = treatment ;
209+ } else {
210+ partition1 .treatment = LocalhostConstants .TREATMENT_OFF ;
211+ partition2 .treatment = LocalhostConstants .TREATMENT_ON ;
212+ }
213+ condition .partitions .add (partition1 );
214+ condition .partitions .add (partition2 );
139215 }
140- condition .partitions .add (partition1 );
141- condition .partitions .add (partition2 );
142216 condition .label = DEFAULT_RULE ;
143217
144218 return condition ;
@@ -147,7 +221,7 @@ public static Condition createRolloutCondition(Condition condition, String traff
147221 public static Condition createCondition (Object keyOrKeys , String treatment ) {
148222 Condition condition = new Condition ();
149223 if (keyOrKeys == null ) {
150- return LocalhostSanitizer .createRolloutCondition (condition , "user" , treatment );
224+ return LocalhostSanitizer .createRolloutCondition (condition , "user" , treatment , true );
151225 } else {
152226 if (keyOrKeys instanceof String ) {
153227 List keys = new ArrayList <>();
0 commit comments