OptimizelyConfig

Overview

Full Stack SDKs open a well-defined set of public APIs, hiding all implementation details. However, some clients may need access to project configuration data within the datafile.

In this document, we extend our public APIs to define data models and access methods, which clients can use to access project configuration data.

OptimizelyConfig API

A public configuration data model (OptimizelyConfig) is defined below as a structured format of static Optimizely Project data.

Get OptimizelyConfig

OptimizelyConfig can be accessed from OptimizelyClient (top-level) with this public API call:

public OptimizelyConfig getOptimizelyConfig();

getOptimizelyConfig returns an OptimizelyConfig instance which includes

  • environment key
  • SDK key
  • the datafile revision number
  • all experiments mapped by their key values
  • all attributes
  • all audiences
  • all events
  • feature flags mapped by their key values

📘

Note

When the SDK datafile is updated (the client can add a notification listener for OPTIMIZELY_CONFIG_UPDATE to get notified), the client is expected to call the method to get the updated OptimizelyConfig data. See examples below.

Get datafile

To share the same datafile between multiple SDK instances (for example, in a client/server scenario), you can pass a JSON string representation of the config (the datafile) between the instances. To get the datafile, use the OptimizelyConfig object's getDatafile method. For more information, see Sharing the datafile with multiple SDK implementations.

Object model

The following shows the object model for OptimizelyConfig.

// OptimizelyConfig is an object describing the current project configuration data 
public class OptimizelyConfig {
  
    // This experimentsMap is for experiments of legacy projects only.
    // For flag projects, experiment keys are not guaranteed to be unique 
    // across multiple flags, so this map may not include all experiments 
    // when keys conflict.
    Map<String, OptimizelyExperiment> experimentsMap;
  
    Map<String, OptimizelyFeature> featuresMap;
    List<OptimizelyAttribute> attributes;
    List<OptimizelyEvent> events;
    List<OptimizelyAudience> audiences;
    String revision;
    String sdkKey;
    String environmentKey;
}

// OptimizelyFeature is an object describing a feature flag
public class OptimizelyFeature {
    String id;
    String key;
  
    /**
     * @deprecated use {@link #experimentRules} and {@link #deliveryRules} instead
     */
    @Deprecated
    Map<String, OptimizelyExperiment> experimentsMap;
  
    Map<String, OptimizelyVariable> variablesMap;
    List<OptimizelyExperiment> experimentRules;
    List<OptimizelyExperiment> deliveryRules;
}

// OptimizelyExperiment is an object describing an experiment
public class OptimizelyExperiment {
    String id;
    String key;
    String audiences;
    Map<String, OptimizelyVariation> variationsMap;
}

// OptimizelyVariation is an object describing a variation
public class OptimizelyVariation {
    String id;
    String key;
    Boolean featureEnabled;
    Map<String, OptimizelyVariable> variablesMap;
}

// OptimizelyVariable is an object describing a Variable
public class OptimizelyVariable {
    String id;
    String key;
    String type;
    String value;
}

// OptimizelyAttribute is an object describing an Attribute
public class OptimizelyAttribute {
  String id;
  String key;
}

// OptimizelyAudience is an object describing an Audience
public class OptimizelyAudience {
  String id;
  String name;
  String conditions;
}

// OptimizelyEvent is an object describing an Event
public class OptimizelyEvent {
  String id;
  String key;
  List<String> experimentIds;
}

Examples

OptimizelyConfig can be accessed from OptimizelyClient (top-level) like this:

val config = optimizelyClient.optimizelyConfig
            
Log.d("Optimizely", "[OptimizelyConfig] revision = " + config!!.revision)
Log.d("Optimizely", "[OptimizelyConfig] sdkKey = " + config.sdkKey)
Log.d("Optimizely", "[OptimizelyConfig] environmentKey = " + config.environmentKey)

Log.d("Optimizely", "[OptimizelyConfig] attributes:")
for (attribute in config.attributes) {
    Log.d("Optimizely", "[OptimizelyAttribute]  -- (id, key) = " + attribute.id + ", " + attribute.key)
}
            
Log.d("Optimizely", "[OptimizelyConfig] audiences:")
for (audience in config.audiences) {
    Log.d("Optimizely", "[OptimizelyAudience]  -- (id, name, conditions) = " + audience.id + ", " + audience.name + ", " + audience.conditions)
}
            
Log.d("Optimizely", "[OptimizelyConfig] events:")
for (event in config.events) {
    Log.d("Optimizely", "[OptimizelyEvent]  -- (id, key, experimentIds) = " + event.id + ", " + event.key + ", " + Arrays.toString(event.experimentIds.toTypedArray()))
}

// all features
for (flagKey in config.featuresMap.keys) {
    val flag = config.featuresMap.get(flagKey)!!
                
    for (experiment in flag.experimentRules) {
        Log.d("Optimizely", "[OptimizelyExperiment]  -- Experiment Rule Key: " + experiment.key)
        Log.d("Optimizely", "[OptimizelyExperiment]  -- Experiment Audiences: " + experiment.audiences)
 
        val variationsMap = experiment.variationsMap
        for (variationKey in variationsMap.keys) {
            val variation = variationsMap.get(variationKey)!!
            Log.d("Optimizely", "[OptimizelyVariation]    -- variation = { key: " + variationKey + ", id: " + variation.id + ", featureEnabled: " + variation.featureEnabled + " }")
            // use variation data here...
                        
            val optimizelyVariableMap = variation.variablesMap
            for (variableKey in optimizelyVariableMap.keys) {
                val variable = optimizelyVariableMap.get(variableKey)!!
                Log.d("Optimizely", "[OptimizelyVariable]      -- variable = key: " + variableKey + ", value: " + variable.value)
                // use variable data here...
                            
            }
        }
    }

    for (delivery in flag.deliveryRules) {
        Log.d("Optimizely", "[OptimizelyExperiment]  -- Delivery Rule Key: " + delivery.key)
        Log.d("Optimizely", "[OptimizelyExperiment]  -- Delivery Audiences: " + delivery.audiences)
    }

    // use experiments and other feature flag data here...

}

// listen to OPTIMIZELY_CONFIG_UPDATE to get updated data
optimizelyClient.notificationCenter?.addNotificationHandler(
    UpdateConfigNotification::class.java,
    NotificationHandler { handler: UpdateConfigNotification? ->
        val newConfig = optimizelyClient.optimizelyConfig
    }
)
OptimizelyConfig config = optimizelyClient.getOptimizelyConfig();

Log.d("Optimizely", "[OptimizelyConfig] revision = " + config.getRevision());
Log.d("Optimizely", "[OptimizelyConfig] sdkKey = " + config.getSdkKey());
Log.d("Optimizely", "[OptimizelyConfig] environmentKey = " + config.getEnvironmentKey());

Log.d("Optimizely", "[OptimizelyConfig] attributes:");
for (OptimizelyAttribute attribute: config.getAttributes()) {
  Log.d("Optimizely", "[OptimizelyAttribute]  -- (id, key) = " + attribute.getId() + ", " + attribute.getKey());
}

Log.d("Optimizely", "[OptimizelyConfig] audiences:");
for (OptimizelyAudience audience: config.getAudiences()) {
  Log.d("Optimizely", "[OptimizelyAudience]  -- (id, name, conditions) = " + audience.getId() + ", " +  audience.getName() + ", " + audience.getConditions());
}

Log.d("Optimizely", "[OptimizelyConfig] events:");
for (OptimizelyEvent event: config.getEvents()) {
  Log.d("Optimizely", "[OptimizelyEvent]  -- (id, key, experimentIds) = " + event.getId() + ", "  + event.getKey() + ", "  + Arrays.toString(event.getExperimentIds().toArray()));
}

// all features
for (String flagKey: config.getFeaturesMap().keySet()) {
  OptimizelyFeature flag = config.getFeaturesMap().get(flagKey);

  for (OptimizelyExperiment experiment: flag.getExperimentRules()) {
    Log.d("Optimizely", "[OptimizelyExperiment]  -- Experiment Rule Key: " + experiment.getKey());
    Log.d("Optimizely", "[OptimizelyExperiment]  -- Experiment Audiences: " + experiment.getAudiences());

    Map<String, OptimizelyVariation> variationsMap = experiment.getVariationsMap();
    for (String variationKey: variationsMap.keySet()) {
      OptimizelyVariation variation = variationsMap.get(variationKey);
      Log.d("Optimizely", "[OptimizelyVariation]    -- variation = { key: " + variationKey + ", id: " + variation.getId() + ", featureEnabled: " + variation.getFeatureEnabled() + " }");
      // use variation data here...

      Map<String, OptimizelyVariable> optimizelyVariableMap = variation.getVariablesMap();
      for (String variableKey: optimizelyVariableMap.keySet()) {
        OptimizelyVariable variable = optimizelyVariableMap.get(variableKey);
        Log.d("Optimizely", "[OptimizelyVariable]      -- variable = key: " + variableKey + ", value: " + variable.getValue());
        // use variable data here...

      }
    }

  }

  for (OptimizelyExperiment delivery: flag.getDeliveryRules()) {
    Log.d("Optimizely", "[OptimizelyExperiment]  -- Delivery Rule Key: " + delivery.getKey());
    Log.d("Optimizely", "[OptimizelyExperiment]  -- Delivery Audiences: " + delivery.getAudiences());
  }

  // use experiments and other feature flag data here...

}

// listen to OPTIMIZELY_CONFIG_UPDATE to get updated data
optimizelyClient.getNotificationCenter().addNotificationHandler(UpdateConfigNotification.class, handler -> {
  OptimizelyConfig newConfig = optimizelyClient.getOptimizelyConfig();
});

Did this page help you?