33import com .google .gson .GsonBuilder ;
44import io .split .client .api .Key ;
55import io .split .client .api .SplitResult ;
6- import io .split .client .dtos .DecoratedImpression ;
7- import io .split .client .dtos .EvaluationOptions ;
8- import io .split .client .dtos .Event ;
6+ import io .split .client .dtos .*;
97import io .split .client .events .EventsStorageProducer ;
108import io .split .client .impressions .Impression ;
119import io .split .client .impressions .ImpressionsManager ;
1412import io .split .engine .evaluator .Evaluator ;
1513import io .split .engine .evaluator .EvaluatorImp ;
1614import io .split .engine .evaluator .Labels ;
17- import io .split .grammar .Treatments ;
1815import io .split .inputValidation .EventsValidator ;
1916import io .split .inputValidation .KeyValidator ;
2017import io .split .inputValidation .SplitNameValidator ;
4946 * @author adil
5047 */
5148public final class SplitClientImpl implements SplitClient {
52- public static final SplitResult SPLIT_RESULT_CONTROL = new SplitResult (Treatments .CONTROL , null );
49+ // public static final SplitResult SPLIT_RESULT_CONTROL = new SplitResult(Treatments.CONTROL, null);
5350 private static final String CLIENT_DESTROY = "Client has already been destroyed - no calls possible" ;
5451 private static final String CATCHALL_EXCEPTION = "CatchAll Exception" ;
5552 private static final String MATCHING_KEY = "matchingKey" ;
@@ -66,6 +63,7 @@ public final class SplitClientImpl implements SplitClient {
6663 private final TelemetryEvaluationProducer _telemetryEvaluationProducer ;
6764 private final TelemetryConfigProducer _telemetryConfigProducer ;
6865 private final FlagSetsFilter _flagSetsFilter ;
66+ private final FallbackTreatmentCalculator _fallbackTreatmentCalculator ;
6967
7068 public SplitClientImpl (SplitFactory container ,
7169 SplitCacheConsumer splitCacheConsumer ,
@@ -76,7 +74,8 @@ public SplitClientImpl(SplitFactory container,
7674 Evaluator evaluator ,
7775 TelemetryEvaluationProducer telemetryEvaluationProducer ,
7876 TelemetryConfigProducer telemetryConfigProducer ,
79- FlagSetsFilter flagSetsFilter ) {
77+ FlagSetsFilter flagSetsFilter ,
78+ FallbackTreatmentCalculator fallbackTreatmentCalculator ) {
8079 _container = container ;
8180 _splitCacheConsumer = checkNotNull (splitCacheConsumer );
8281 _impressionManager = checkNotNull (impressionManager );
@@ -87,6 +86,7 @@ public SplitClientImpl(SplitFactory container,
8786 _telemetryEvaluationProducer = checkNotNull (telemetryEvaluationProducer );
8887 _telemetryConfigProducer = checkNotNull (telemetryConfigProducer );
8988 _flagSetsFilter = flagSetsFilter ;
89+ _fallbackTreatmentCalculator = fallbackTreatmentCalculator ;
9090 }
9191
9292 @ Override
@@ -492,31 +492,31 @@ private SplitResult getTreatmentWithConfigInternal(String matchingKey, String bu
492492
493493 if (_container .isDestroyed ()) {
494494 _log .error (CLIENT_DESTROY );
495- return SPLIT_RESULT_CONTROL ;
495+ return checkFallbackTreatment ( featureFlag ) ;
496496 }
497497
498498 if (!KeyValidator .isValid (matchingKey , MATCHING_KEY , _config .maxStringLength (), methodEnum .getMethod ())) {
499- return SPLIT_RESULT_CONTROL ;
499+ return checkFallbackTreatment ( featureFlag ) ;
500500 }
501501
502502 if (!KeyValidator .bucketingKeyIsValid (bucketingKey , _config .maxStringLength (), methodEnum .getMethod ())) {
503- return SPLIT_RESULT_CONTROL ;
503+ return checkFallbackTreatment ( featureFlag ) ;
504504 }
505505
506506 Optional <String > splitNameResult = SplitNameValidator .isValid (featureFlag , methodEnum .getMethod ());
507507 if (!splitNameResult .isPresent ()) {
508- return SPLIT_RESULT_CONTROL ;
508+ return checkFallbackTreatment ( featureFlag ) ;
509509 }
510510 featureFlag = splitNameResult .get ();
511511 long start = System .currentTimeMillis ();
512512
513513 EvaluatorImp .TreatmentLabelAndChangeNumber result = _evaluator .evaluateFeature (matchingKey , bucketingKey , featureFlag , attributes );
514514
515- if (result .treatment . equals ( Treatments . CONTROL ) && result .label .equals (Labels .DEFINITION_NOT_FOUND ) && _gates .isSDKReady ()) {
515+ if (result .label != null && result .label .contains (Labels .DEFINITION_NOT_FOUND ) && _gates .isSDKReady ()) {
516516 _log .warn (String .format (
517517 "%s: you passed \" %s\" that does not exist in this environment, " +
518518 "please double check what feature flags exist in the Split user interface." , methodEnum .getMethod (), featureFlag ));
519- return SPLIT_RESULT_CONTROL ;
519+ return checkFallbackTreatment ( featureFlag ) ;
520520 }
521521
522522 recordStats (
@@ -541,10 +541,19 @@ private SplitResult getTreatmentWithConfigInternal(String matchingKey, String bu
541541 } catch (Exception e1 ) {
542542 // ignore
543543 }
544- return SPLIT_RESULT_CONTROL ;
544+ return checkFallbackTreatment ( featureFlag ) ;
545545 }
546546 }
547547
548+ private SplitResult checkFallbackTreatment (String featureName ) {
549+ FallbackTreatment fallbackTreatment = _fallbackTreatmentCalculator .resolve (featureName , "" );
550+ String config = null ;
551+ if (fallbackTreatment .getConfig () != null ) {
552+ config = fallbackTreatment .getConfig ().toString ();
553+ }
554+ return new SplitResult (fallbackTreatment .getTreatment (), config );
555+ }
556+
548557 private String validateProperties (Map <String , Object > properties ) {
549558 if (properties == null ){
550559 return null ;
@@ -563,6 +572,7 @@ private Map<String, SplitResult> getTreatmentsWithConfigInternal(String matching
563572 _log .error (String .format ("%s: featureFlagNames must be a non-empty array" , methodEnum .getMethod ()));
564573 return new HashMap <>();
565574 }
575+
566576 try {
567577 checkSDKReady (methodEnum , featureFlagNames );
568578 Map <String , SplitResult > result = validateBeforeEvaluate (featureFlagNames , matchingKey , methodEnum , bucketingKey );
@@ -623,17 +633,17 @@ private Map<String, SplitResult> getTreatmentsBySetsWithConfigInternal(String ma
623633 return createMapControl (featureFlagNames );
624634 }
625635 }
636+
626637 private Map <String , SplitResult > processEvaluatorResult (Map <String , EvaluatorImp .TreatmentLabelAndChangeNumber > evaluatorResult ,
627638 MethodEnum methodEnum , String matchingKey , String bucketingKey , Map <String ,
628639 Object > attributes , long initTime , String properties ){
629640 List <DecoratedImpression > decoratedImpressions = new ArrayList <>();
630641 Map <String , SplitResult > result = new HashMap <>();
631642 evaluatorResult .keySet ().forEach (t -> {
632- if (evaluatorResult .get (t ).treatment .equals (Treatments .CONTROL ) && evaluatorResult .get (t ).label .
633- equals (Labels .DEFINITION_NOT_FOUND ) && _gates .isSDKReady ()) {
643+ if (evaluatorResult .get (t ).label != null && evaluatorResult .get (t ).label .contains (Labels .DEFINITION_NOT_FOUND ) && _gates .isSDKReady ()) {
634644 _log .warn (String .format ("%s: you passed \" %s\" that does not exist in this environment please double check " +
635645 "what feature flags exist in the Split user interface." , methodEnum .getMethod (), t ));
636- result .put (t , SPLIT_RESULT_CONTROL );
646+ result .put (t , checkFallbackTreatment ( t ) );
637647 } else {
638648 result .put (t , new SplitResult (evaluatorResult .get (t ).treatment , evaluatorResult .get (t ).configurations ));
639649 decoratedImpressions .add (
@@ -735,7 +745,7 @@ private void checkSDKReady(MethodEnum methodEnum) {
735745
736746 private Map <String , SplitResult > createMapControl (List <String > featureFlags ) {
737747 Map <String , SplitResult > result = new HashMap <>();
738- featureFlags .forEach (s -> result .put (s , SPLIT_RESULT_CONTROL ));
748+ featureFlags .forEach (s -> result .put (s , checkFallbackTreatment ( s ) ));
739749 return result ;
740750 }
741751}
0 commit comments