IBM Cloud App Configuration SDK is used to perform feature flag and property evaluation based on the configuration on IBM Cloud App Configuration service.
IBM Cloud App Configuration is a centralized feature management and configuration service on IBM Cloud for use with web and mobile applications, microservices, and distributed environments.
Instrument your applications with App Configuration Android SDK, and use the App Configuration dashboard, CLI or API to define feature flags or properties, organized into collections and targeted to segments. Toggle feature flag states in the cloud to activate or deactivate features in your application or environment, when required. You can also manage the properties for distributed applications centrally.
- Android API level 22 or later
- Android Studio
- Gradle
Follow the below step
Choose to integrate the AppConfiguration Android client SDK package using either of the following options:
- Download and import the package to your Android Studio project
- Get the package through Gradle
-
Configure the Module level
build.gradle
and Project levelbuild.gradle
files.-
Add IBM Cloud AppConfiguration Android client SDK dependency to Project level
build.gradle
file.repositories { mavenCentral() }
-
Add IBM Cloud AppConfiguration Android client SDK dependency to Module level
build.gradle
file.dependencies { implementation "com.ibm.cloud:appconfiguration-android-sdk:0.3.3" }
-
-
Configure the
AndroidManifest.xml
file forInternet
permission.<uses-permission android:name="android.permission.INTERNET"/>
import com.ibm.cloud.appconfiguration.android.sdk.AppConfiguration
val collectionId = "airlines-webapp"
val environmentId = "dev"
val appConfigClient = AppConfiguration.getInstance()
//application is a member of the AppCompatActivity() class, if you have inherited the
//AppCompatActivity() class then you can call the application variable.
appConfigClient.init(application,
"region",
"guid",
"apikey")
appConfigClient.setContext(collectionId, environmentId)
🔴 Important 🔴
The init()
and setContext()
are the initialisation methods and should be invoked only
once using appConfigClient. The appConfigClient, once initialised, can be obtained across modules
using AppConfiguration.getInstance()
. See this example below.
- region : Region name where the service instance is created. Use
AppConfiguration.REGION_US_SOUTH
for DallasAppConfiguration.REGION_EU_GB
for LondonAppConfiguration.REGION_AU_SYD
for SydneyAppConfiguration.REGION_US_EAST
for Washington DCAppConfiguration.REGION_EU_DE
for FrankfurtAppConfiguration.REGION_CA_TOR
for TorontoAppConfiguration.REGION_JP_TOK
for TokyoAppConfiguration.REGION_JP_OSA
for Osaka
- guid : GUID of the App Configuration service. Get it from the service instance credentials section of the dashboard
- apikey : ApiKey of the App Configuration service. Get it from the service instance credentials section of the dashboard
- collectionId : Id of the collection created in App Configuration service instance under the Collections section.
- environmentId : Id of the environment created in App Configuration service instance under the Environments section.
val feature: Feature? = appConfigClient.getFeature("online-check-in")
if (feature != null) {
println("Feature Name : ${feature.getFeatureName()}")
println("Feature Id : ${feature.getFeatureId()}")
println("Feature Type : ${feature.getFeatureDataType()}")
println("Is feature enabled? : ${feature.isEnabled()}")
}
val features: HashMap<String, Feature>? = appConfigClient.getFeatures()
Use the feature.getCurrentValue(entityId, entityAttributes)
method to evaluate the value of the
feature flag. This method returns one of the Enabled/Disabled/Overridden value based on the
evaluation.
val entityId = "john_doe"
val entityAttributes = JSONObject()
try {
entityAttributes.put("city", "Bangalore")
entityAttributes.put("country", "India")
} catch (e: JSONException) {
e.printStackTrace()
}
val appConfigClient = AppConfiguration.getInstance()
val feature: Feature? = appConfigClient.getFeature("online-check-in")
if (feature != null) {
val value = feature.getCurrentValue(entityId, entityAttributes)
}
- entityId: Id of the Entity. This will be a string identifier related to the Entity against which the feature is evaluated. For example, an entity might be an instance of an app that runs on a mobile device, a microservice that runs on the cloud, or a component of infrastructure that runs that microservice. For any entity to interact with App Configuration, it must provide a unique entity ID.
- entityAttributes: A JSON object consisting of the attribute name and their values that defines the specified entity. This is an optional parameter if the feature flag is not configured with any targeting definition. If the targeting is configured, then entityAttributes should be provided for the rule evaluation. An attribute is a parameter that is used to define a segment. The SDK uses the attribute values to determine if the specified entity satisfies the targeting rules, and returns the appropriate feature flag value.
val property: Property? = appConfigClient.getProperty("check-in-charges")
if (property != null) {
println("Property Name : ${property.getPropertyName()}")
println("Property Id : ${property.getPropertyId()}")
println("Property Type : ${property.getPropertyDataType()}")
}
val properties: HashMap<String, Property>? = appConfigClient.getProperties()
Use the property.getCurrentValue(entityId, entityAttributes)
method to evaluate the value of the
property. This method returns the default property value or its overridden value based on the
evaluation.
val entityId = "john_doe"
val entityAttributes = JSONObject()
try {
entityAttributes.put("city", "Bangalore")
entityAttributes.put("country", "India")
} catch (e: JSONException) {
e.printStackTrace()
}
val appConfigClient = AppConfiguration.getInstance()
val property: Property? = appConfigClient.getProperty("check-in-charges")
if (property != null) {
val value = property.getCurrentValue(entityId, entityAttributes)
}
- entityId: Id of the Entity. This will be a string identifier related to the Entity against which the property is evaluated. For example, an entity might be an instance of an app that runs on a mobile device, a microservice that runs on the cloud, or a component of infrastructure that runs that microservice. For any entity to interact with App Configuration, it must provide a unique entity ID.
- entityAttributes: A JSON object consisting of the attribute name and their values that defines the specified entity. This is an optional parameter if the property is not configured with any targeting definition. If the targeting is configured, then entityAttributes should be provided for the rule evaluation. An attribute is a parameter that is used to define a segment. The SDK uses the attribute values to determine if the specified entity satisfies the targeting rules, and returns the appropriate property value.
Once the SDK is initialized, the appConfigClient can be obtained across other modules as shown below:
// **other modules**
import com.ibm.cloud.appconfiguration.android.sdk.AppConfiguration
val appConfigClient = AppConfiguration.getInstance()
val feature: Feature? = appConfigClient.getFeature("online-check-in")
val enabled = feature.isEnabled()
val featureValue = feature.getCurrentValue(entityId, entityAttributes)
App Configuration service allows to configure the feature flag and properties in the following data types : Boolean, Numeric, String. The String data type can be of the format of a text string , JSON or YAML. The SDK processes each format accordingly as shown in the below table.
View Table
Feature or Property value | DataType | DataFormat | Type of data returned by getCurrentValue() |
Example output |
---|---|---|---|---|
true |
BOOLEAN | not applicable | java.lang.Boolean |
true |
25 |
NUMERIC | not applicable | java.lang.Integer |
25 |
"a string text" | STRING | TEXT | java.lang.String |
a string text |
{ |
STRING | JSON | org.json.JSONObject |
{"firefox":{"name":"Firefox","pref_url":"about:config"}} |
men: |
STRING | YAML | java.lang.String |
"men:\n - John Smith\n - Bill Jones\nwomen:\n - Mary Smith\n - Susan Williams" |
Feature flag
val feature: Feature? = appConfigClient.getFeature("json-feature")
feature.getFeatureDataType() // STRING
feature.getFeatureDataFormat() // JSON
// Example below (traversing the returned JSONObject)
if (feature != null) {
val result = feature.getCurrentValue(entityId, entityAttributes) as JSONObject
result.get("key") // returns the value of the key
}
val feature: Feature? = appConfigClient.getFeature("yaml-feature")
feature.getFeatureDataType() // STRING
feature.getFeatureDataFormat() // YAML
feature.getCurrentValue(entityId, entityAttributes) // returns the stringified yaml (check above table)
Property
val property: Property? = appConfigClient.getProperty("json-property")
property.getPropertyDataType() // STRING
property.getPropertyDataFormat() // JSON
// Example below (traversing the returned JSONObject)
if (property != null) {
val result = property.getCurrentValue(entityId, entityAttributes) as JSONObject
result.get("key") // returns the value of the key
}
val property: Property? = appConfigClient.getProperty("yaml-property")
property.getPropertyDataType() // STRING
property.getPropertyDataFormat() // YAML
property.getCurrentValue(entityId, entityAttributes) // returns the stringified yaml (check above table)
The SDK provides mechanism to notify you in real-time when feature flag's or property's configuration changes. You can subscribe to configuration changes using the same appConfigClient.
import com.ibm.cloud.appconfiguration.android.sdk.configurations.ConfigurationUpdateListener
appConfigClient.registerConfigurationUpdateListener(object : ConfigurationUpdateListener {
override fun onConfigurationUpdate() {
println("Received updates on configurations")
// **add your code**
// To find the effect of any configuration changes, you can call the feature or property related methods
// val feature: Feature? = appConfigClient.getFeature("online-check-in")
// if (feature != null) {
// val newValue = feature.getCurrentValue(entityId, entityAttributes)
// }
}
})
Use this method to enable/disable the logging in SDK.
val appConfigClient = AppConfiguration.getInstance()
// Enable Logger
appConfigClient.enableDebug(true)
// Disable Logger
appConfigClient.enableDebug(false)
Fetch the latest configuration data.
appConfigClient.fetchConfigurations()
Choose to integrate the AppConfiguration Android client SDK package using either of the following options:
- Download and import the package to your Android Studio project
- Get the package through Gradle
-
Configure the Module level
build.gradle
and Project levelbuild.gradle
files.-
Add IBM Cloud AppConfiguration Android client SDK dependency to Project level
build.gradle
file.repositories { mavenCentral() }
-
Add IBM Cloud AppConfiguration Android client SDK dependency to Module level
build.gradle
file.dependencies { implementation "com.ibm.cloud:appconfiguration-android-sdk:0.3.3" }
-
-
Configure the
AndroidManifest.xml
file forInternet
permission.<uses-permission android:name="android.permission.INTERNET"/>
-
Add the Kotlin gradle plugin to the Project level
build.gradle
dependencies { classpath "com.android.tools.build:gradle:4.1.1" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" }
-
Add the following in the
buildscript
section in the Project levelbuild.gradle
buildscript { ext.kotlin_version = "1.4.31" }
-
Add
kotlin-android
plugin to the Module levelbuild.gradle
plugins { id 'com.android.application' id 'kotlin-android' }
import com.ibm.cloud.appconfiguration.android.sdk.AppConfiguration;
String collectionId = "airlines-webapp";
String environmentId = "dev";
AppConfiguration appConfigClient = AppConfiguration.getInstance();
appConfigClient.init(getApplication(),
"region", "guid", "apikey");
appConfigClient.setContext(collectionId, environmentId);
🔴 Important 🔴
The init()
and setContext()
are the initialisation methods and should be invoked only
once using appConfigClient. The appConfigClient, once initialised, can be obtained across modules
using AppConfiguration.getInstance()
. See this example below.
- region : Region name where the service instance is created. Use
AppConfiguration.REGION_US_SOUTH
for DallasAppConfiguration.REGION_EU_GB
for LondonAppConfiguration.REGION_AU_SYD
for SydneyAppConfiguration.REGION_US_EAST
for Washington DCAppConfiguration.REGION_EU_DE
for FrankfurtAppConfiguration.REGION_CA_TOR
for TorontoAppConfiguration.REGION_JP_TOK
for TokyoAppConfiguration.REGION_JP_OSA
for Osaka
- guid : GUID of the App Configuration service. Get it from the service instance credentials section of the dashboard
- apikey : ApiKey of the App Configuration service. Get it from the service instance credentials section of the dashboard
- collectionId : Id of the collection created in App Configuration service instance under the Collections section.
- environmentId : Id of the environment created in App Configuration service instance under the Environments section.
Feature feature = appConfigClient.getFeature("online-check-in"); // feature can be null incase of an invalid feature id
if (feature != null) {
System.out.println("Feature Name : " + feature.getFeatureName());
System.out.println("Feature Id : " + feature.getFeatureId());
System.out.println("Feature Type : " + feature.getFeatureDataType());
System.out.println("Is feature enabled? : " + feature.isEnabled());
}
HashMap<String,Feature> features = appConfigClient.getFeatures();
Use the feature.getCurrentValue(entityId, entityAttributes)
method to evaluate the value of the
feature flag. This method returns one of the Enabled/Disabled/Overridden value based on the
evaluation.
String entityId = "john_doe";
JSONObject entityAttributes = new JSONObject();
try {
entityAttributes.put("city", "Bengaluru");
entityAttributes.put("country", "India");
} catch (JSONException e) {
e.printStackTrace();
}
AppConfiguration appConfigClient = AppConfiguration.getInstance();
Feature feature = appConfigClient.getFeature("online-check-in");
if (feature != null) {
String value = (String) feature.getCurrentValue(entityId, entityAttributes);
}
- entityId: Id of the Entity. This will be a string identifier related to the Entity against which the feature is evaluated. For example, an entity might be an instance of an app that runs on a mobile device, a microservice that runs on the cloud, or a component of infrastructure that runs that microservice. For any entity to interact with App Configuration, it must provide a unique entity ID.
- entityAttributes: A JSON object consisting of the attribute name and their values that defines the specified entity. This is an optional parameter if the feature flag is not configured with any targeting definition. If the targeting is configured, then entityAttributes should be provided for the rule evaluation. An attribute is a parameter that is used to define a segment. The SDK uses the attribute values to determine if the specified entity satisfies the targeting rules, and returns the appropriate feature flag value.
Property property = appConfigClient.getProperty("check-in-charges"); // property can be null incase of an invalid property id
if (property != null) {
System.out.println("Property Name : " + property.getPropertyName());
System.out.println("Property Id : " + property.getPropertyId());
System.out.println("Property Type : " + property.getPropertyDataType());
}
HashMap<String,Property> properties = appConfigClient.getProperties();
Use the property.getCurrentValue(entityId, entityAttributes)
method to evaluate the value of the
property. This method returns the default property value or its overridden value based on the
evaluation.
String entityId = "john_doe";
JSONObject entityAttributes = new JSONObject();
try {
entityAttributes.put("city", "Bengaluru");
entityAttributes.put("country", "India");
} catch (JSONException e) {
e.printStackTrace();
}
AppConfiguration appConfigClient = AppConfiguration.getInstance();
Property property = appConfigClient.getProperty("check-in-charges");
if (property != null) {
String value = (String) property.getCurrentValue(entityId, entityAttributes);
}
- entityId: Id of the Entity. This will be a string identifier related to the Entity against which the property is evaluated. For example, an entity might be an instance of an app that runs on a mobile device, a microservice that runs on the cloud, or a component of infrastructure that runs that microservice. For any entity to interact with App Configuration, it must provide a unique entity ID.
- entityAttributes: A JSON object consisting of the attribute name and their values that defines the specified entity. This is an optional parameter if the property is not configured with any targeting definition. If the targeting is configured, then entityAttributes should be provided for the rule evaluation. An attribute is a parameter that is used to define a segment. The SDK uses the attribute values to determine if the specified entity satisfies the targeting rules, and returns the appropriate property value.
Once the SDK is initialized, the appConfigClient can be obtained across other modules as shown below:
// **other modules**
import com.ibm.cloud.appconfiguration.sdk.AppConfiguration;
AppConfiguration appConfigClient = AppConfiguration.getInstance();
Feature feature = appConfigClient.getFeature("string-feature");
boolean enabled = feature.isEnabled();
String featureValue = (String) feature.getCurrentValue(entityId, entityAttributes);
App Configuration service allows to configure the feature flag and properties in the following data types : Boolean, Numeric, String. The String data type can be of the format of a text string , JSON or YAML. The SDK processes each format accordingly as shown in the below table.
View Table
Feature or Property value | DataType | DataFormat | Type of data returned by getCurrentValue() |
Example output |
---|---|---|---|---|
true |
BOOLEAN | not applicable | java.lang.Boolean |
true |
25 |
NUMERIC | not applicable | java.lang.Integer |
25 |
"a string text" | STRING | TEXT | java.lang.String |
a string text |
{ |
STRING | JSON | org.json.JSONObject |
{"firefox":{"name":"Firefox","pref_url":"about:config"}} |
men: |
STRING | YAML | java.lang.String |
"men:\n - John Smith\n - Bill Jones\nwomen:\n - Mary Smith\n - Susan Williams" |
Feature flag
Feature feature = appConfigClient.getFeature("json-feature");
feature.getFeatureDataType(); // STRING
feature.getFeatureDataFormat(); // JSON
// Example below (traversing the returned JSONObject)
if (feature != null) {
JSONObject result = (JSONObject) feature.getCurrentValue(entityId, entityAttributes);
result.get("key") // returns the value of the key
}
Feature feature = appConfigClient.getFeature("yaml-feature");
feature.getFeatureDataType(); // STRING
feature.getFeatureDataFormat(); // YAML
feature.getCurrentValue(entityId, entityAttributes); // returns the stringified yaml (check above table)
Property
Property property = appConfigClient.getProperty("json-property");
property.getPropertyDataType(); // STRING
property.getPropertyDataFormat(); // JSON
// Example below (traversing the returned JSONObject)
if (property != null) {
JSONObject result = (JSONObject) property.getCurrentValue(entityId, entityAttributes);
result.get("key") // returns the value of the key
}
Property property = appConfigClient.getProperty("yaml-property");
property.getPropertyDataType(); // STRING
property.getPropertyDataFormat(); // YAML
property.getCurrentValue(entityId, entityAttributes); // returns the stringified yaml (check above table)
The SDK provides mechanism to notify you in real-time when feature flag's or property's configuration changes. You can subscribe to configuration changes using the same appConfigClient.
import com.ibm.cloud.appconfiguration.android.sdk.configurations.ConfigurationUpdateListener;
appConfigClient.registerConfigurationUpdateListener(new ConfigurationUpdateListener() {
@Override
public void onConfigurationUpdate() {
System.out.println("Received update on configurations");
// **add your code**
// To find the effect of any configuration changes, you can call the feature or property related methods
//
// Feature feature = appConfigClient.getFeature("numeric-feature");
// if (feature != null) {
// Integer newValue = (Integer) feature.getCurrentValue(entityId, entityAttributes);
// }
}
});
Use this method to enable/disable the logging in SDK.
AppConfiguration appConfigClient = AppConfiguration.getInstance();
// Enable Logger
appConfigClient.enableDebug(true);
// Disable Logger
appConfigClient.enableDebug(false);
Fetch the latest configuration data.
appConfigClient.fetchConfigurations();
The examples folder has the examples.
This project is released under the Apache 2.0 license. The license's full text can be found in LICENSE