Flaggr – Ou comment activer / désactiver des fonctionnalités à distance

Le but de ce tutoriel est de présenter une bibliothèque : Flaggr, elle est utilisée en interne chez BlaBlaCar afin de :

  • Activer / Désactiver des fonctionnalités sans soumissions
  • Déploiement progressif de fonctionnalités par pays

Nous allons expliquer comment utiliser cette bibliothèque ainsi que son fonctionnement.

Flaggr est disponible sur GitHub : https://github.com/blablacar/flaggr-android

Comment fonctionne Flaggr

Flaggr utilisera un context que vous allez passer en paramètre afin de savoir si une fonctionnalité est activé.

L’implémentation par défaut de flaggr possède différentes propriétés pour chaque fonctionnalité :

  • Un nom : Le nom de la fonctionnalité
  • Un status : Définit le status d’une fonctionnalité, par défaut dans la bibliothèque il existe trois status – always-active (la fonctionnalité est toujours activée), always-inactive (la fonctionnalité est toujours désactivée), conditionally-active (la fonctionnalité est activée à certaines conditions)
  • Une stratégie : Définit la règle qui sera utilisée pour savoir si une fonctionnalité est activé ou pas. Il existe 3 stratégies – affirmative (si une des conditions est validée la fonctionnalité sera activée), unanimous (il faut que toutes les conditions soient valides pour qu’une fonctionnalité soit activée) et Majority (la majorité des conditions doivent être valides pour que la fonctionnalité soit activée)

Pour calculer l’état d’une fonctionnalité on déclare des conditions. Chaque condition est composée :

  • D’un nom
  • Une clé identifiant la condition
  • D’un opérateur qui permet de calculer l’état d’une condition

Comment l’utiliser ?

L’utilisation de Flaggr est très simple, il suffit de l’inclure en dépendance de votre projet.

compile 'com.comuto:flaggr:0.2'

Flaggr se basera sur un fichier (json par exemple) afin de charger et stocker les différents flags dont vous avez besoin.

Prenons l’exemple de ce fichier JSON :

[
  {
    "name": "messaging",
    "conditions": [],
    "status": "always-active",
    "strategy": "affirmative"
  },
  {
    "name": "wordpress_signup",
    "conditions": [
      {
        "name": "operator-condition",
        "key": "user_locale",
        "operator": {
          "name": "in-set",
          "values": [
            "es_ES",
            "fr_FR"
          ]
        }
      }
    ],
    "status": "conditionally-active ",
    "strategy": "affirmative"
  },
  {
    "name": "duplicate_profile",
    "conditions": [],
    "status": "always-inactive",
    "strategy": "affirmative"
  }
]

Ce fichier possède trois fonctionnalités :

  • Messaging : Avec un status activé
  • WordPress signup : Activé uniquement pour la France et l’Espagne
  • Dupliquer un profil : Désactivé

L’initialisation de Flaggr se fait facilement (en général dans le fichier Application de votre projet)

public class FlaggrSampleApplication extends Application {

    public static final String FLAGGR_CONFIG_URI =
        "http://www.tutos-android.com/JSON/features.json";
    
    @Override
    public void onCreate() {
        super.onCreate();

        Flaggr.with(this).loadConfig(FLAGGR_CONFIG_URI);
    }
}

Une fois initialisée, la bibliothèque téléchargera le fichier, le parsera et stockera les différents flag déclarés.

A chaque lancement de l’application, Flaggr vérifiera si une nouvelle version du fichier est disponible, si oui elle sera téléchargée et remplacera l’existante.

La deuxième brique essentielle à Flaggr est le contexte qui fournit à la bibliothèque les données nécessaires pour déterminer si un flag est activé (par exemple, le pays de l’utilisateur …)

Cette classe doit implémenter la classe FlagContextInterface et surcharger les méthodes

  • getFlagContext : Qui retourne une map pour chaque clé et valeur du contexte
  • getValue : Qui retourne la valeur du contexte en fonction de la clé

Voici par exemple pour un contexte qui contient la locale utilisateur

public class FlagContext implements FlagContextInterface<String> {

    public static final String USER_LOCALE = "USER_LOCALE";
    private HashMap<String, String> contextValues;

    public FlagContext(final String userLocale) {
        contextValues = new HashMap<>();
        contextValues.put(USER_LOCALE, userLocale);
    }

    @Override
    @Nullable
    public Map<String, String> getFlagContext() {
        return contextValues;
    }

    @Override
    @Nullable
    public String getValue(String key) {
        if (null != contextValues && 1 < contextValues.size()) {
            return contextValues.get(key);
        }
        return null;
    }
}

Pour finir il suffit d’appeler Flaggr avec le nom d’une fonctionnalité pour savoir si elle est activée

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FlagContext flagContext = new FlagContext(Locale.getDefault().toString());
        boolean isWordpressSignupEnabled = Flaggr.with(this).isActive("wordpress_signup", flagContext);
    }
}

Vous pouvez créer vos propres stratégies, status et operateur tout en respectant les interfaces définies par la bibliothèque.

N’Hésitez pas à tester la bibliothèque, nous faire vos retours, vos suggestions … etc

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *