Asimov-flagz-kt - Feature flags library based on Togglz library

Overview

Maven License: MIT CI Status

Asimov Flagz

Feature flags library based on Togglz library.

Installation

Gradle (Kotlin)

repositories {
    mavenCentral()
}

dependencies {
    implementation("com.nbottarini:asimov-flagz:0.2.1")
}

Gradle (Groovy)

repositories {
    mavenCentral()
}

dependencies {
    implementation 'com.nbottarini:asimov-flagz:0.2.1'
}

Maven

<dependency>
    <groupId>com.nbottarini</groupId>
    <artifactId>asimov-flagz</artifactId>
    <version>0.2.1</version>
</dependency>

Quick start

  1. Define an enum with your feature flags (it must implement the Feature interface):
enum class Features: Feature {
    MY_FEATURE,
    MY_OTHER_FEATURE
}
  1. Initialize the library by configuring your enum:
initFlagz {
    featureEnum<Features>()
    repository(EnvironmentFeatureRepository())
}

You'll have to configure a feature repositories. A repository provides a way to store and search for feature flag states (enabled or disabled).

In this example the EnvironmentFeatureRepository looks for features in the system environment variables. The environment variable must be prefixed with 'FEATURE_'. For example 'FEATURE_MY_FEATURE=1', 'FEATURE_MY_OTHER_FEATURE=0'.

  1. Use that flags in your code:
    if (Features.MY_FEATURE.isEnabled) {
        // Do something...
    }

EnabledByDefault

By default, if a feature flag is not set is disabled. You can change this behaviour per-feature with the EnabledByDefault annotation.

enum class Features: Feature {
    MY_FEATURE,
    
    @EnabledByDefault
    MY_OTHER_FEATURE
}

Feature repositories

Feature repositories allows you to store and retrieve feature flags state.

InMemoryFeatureRepository

Store features state in memory.

initFlagz {
    featureEnum<Features>()
    repository(InMemoryFeatureRepository())
}

EnvironmentFeatureRepository

This is a read-only repository. This repository read feature's state from environment variables. Each variable must be prefixed with "FEATURE_". For example "FEATURE_MY_AWESOME_FEATURE".

initFlagz {
    featureEnum<Features>()
    repository(EnvironmentFeatureRepository())
}

Values '1', 'true' and 'TRUE' are interpreted as enabled. '0', 'false' and 'FALSE' indicates that the feature is disabled.

By default, this repository uses the asimov-environment library to access the environment variables, so you can create a .env file to store your feature flags states for development.

FEATURE_ALLOW_REGISTRATION=1
FEATURE_NEW_BLOG=0

You can use a different environment variables provider by implemented the interface EnvironmentProvider and passing you implementation on repository construction.

class MyEnvProvider: EnvironmentProvider {
    override fun get(name: String) = MyEnvironmentLibrary.get[name]
}

initFlagz {
    featureEnum<Features>()
    repository(EnvironmentFeatureRepository(MyEnvProvider))
}

JdbcFeatureRepository

Store feature states in a database.

To use this repository you have to pass a jdbc datasource for your database.

val datasource = MysqlDataSource()
datasource.setURL(/* jdbc url */)
datasource.setUser(/* username */)
datasource.setPassword(/* password */)

initFlagz {
    featureEnum<Features>()
    repository(JdbcFeatureRepository(datasource))
}

By default, it creates a feature_flags table in the database if it doesn't exist. You can customize the table name:

JdbcFeatureRepository(datasource, "flags")

You can also disable the schema generation and create the schema by yourself:

JdbcFeatureRepository(datasource, generateSchema = false)
CREATE TABLE feature_flags (
    name                VARCHAR(100) PRIMARY KEY,
    is_enabled          INTEGER NOT NULL,
    strategy_id         VARCHAR(200),
    strategy_params     VARCHAR(2000)
)

This repository uses ansi sql so is compatible with most database providers.

CachedFeatureRepository

Wraps another repository by introducing a cache.

initFlagz {
    featureEnum<Features>()
    repository(CachedFeatureRepository(JdbcFeatureRepository(datasource)))
}

/** or **/

initFlagz {
    featureEnum<Features>()
    repository(JdbcFeatureRepository(datasource).cached())
}

You can specify the TTL in milliseconds for the cache:

initFlagz {
    featureEnum<Features>()
    repository(CachedFeatureRepository(JdbcFeatureRepository(datasource), 60_000))
}

/** or **/

initFlagz {
    featureEnum<Features>()
    repository(JdbcFeatureRepository(datasource).cached(60_000))
}

CompositeFeatureRepository

Allows to use more than one repository. The features are retrieved from the first matching repository.

initFlagz {
    featureEnum<Features>()
    repository(
        CompositeFeatureRepository(
            JdbcFeatureRepository(datasource),
            EnvironmentFeatureRepository()
        )
    )
}

/** or **/

initFlagz {
    featureEnum<Features>()
    repositories(
        JdbcFeatureRepository(datasource),
        EnvironmentFeatureRepository()
    )
}

When a feature flag is set you can customize if it is persisted in the first repository, the last or all of them.

initFlagz {
    featureEnum<Features>()
    repository(
        CompositeFeatureRepository(
            JdbcFeatureRepository(datasource),
            EnvironmentFeatureRepository()
        ),
        SetStrategies.ALL
    )
}

Activation strategies

You can provide different strategies to enable/disable features dynamically based on dates, gradual rollout, per user, per user roles or attributes, etc. You can also create your own strategies.

To define a strategy for a feature you have to annotate it with the Activation annotation. For example:

enum class Features: Feature {
    MY_FEATURE,

    @Activation(ReleaseDateActivationStrategy.ID, [ActivationParam(PARAM_DATE, "2020-09-06T10:00:00Z")])
    MY_OTHER_FEATURE
}

ReleaseDateActivationStrategy

This strategy allows you to enable a feature in a certain date. The provided date must be in ISO 8601 format.

UsersActivationStrategy

This strategy allows you to enable a feature only to certain users.

enum class Features: Feature {
    MY_FEATURE,

    @Activation(UsersActivationStrategy.ID, [ActivationParam(PARAM_USERS, "alice, bob")])
    MY_OTHER_FEATURE
}

Users must be set by using a userProvider. Read next section for details.

User providers

Allows the customization of feature flags per user or user's attributes.

You can pass a userProvider implementation to the initialization function. The default userProvider is ThreadLocalUserProvider.

initFlagz {
    featureEnum<Features>()
    repository(EnvironmentFeatureRepository())
    userProvider(MyUserProvider())
}

ThreadLocalUserProvider

This implementation allows you to set the current user per thread.

You can access the current user provider by calling FlagzContext.manager.userProvider.

val userProvider = FlagzContext.manager.userProvider as ThreadLocalUserProvider

userProvider.bind(SimpleFeatureUser("alice", mapOf("roles" to "admin")))

// Do something and use feature flags

userProvider.release()

Users have to implement the FeatureUser interface, or you can use SimpleFeatureUser implementation.

If you are using a mediator / command-bus like CQBus you can add a middleware to set the current user.

class SetFeatureFlagsUserMiddleware: Middleware {
    override fun <T: Request<R>, R> execute(request: T, next: (T) -> R, context: ExecutionContext): R {
        val userProvider = FlagzContext.manager.userProvider as? ThreadLocalUserProvider ?: return next(request)
        val user = SimpleFeatureUser(context.identity.name, mapOf("roles", context.identity.roles.joinToString(", ")))
        userProvider.bind(user)
        val response = next(request)
        userProvider.release()
        return response
    }
}
You might also like...
KotlinX multiplatform date/time library

kotlinx-datetime A multiplatform Kotlin library for working with date and time. See Using in your projects for the instructions how to setup a depende

Multiplatform Date and time library for Kotlin
Multiplatform Date and time library for Kotlin

Klock is a Date & Time library for Multiplatform Kotlin. It is designed to be as allocation-free as possible using Kotlin inline classes, to be consis

A Kotlin Multiplatform library for working with dates and times

Island Time A Kotlin Multiplatform library for working with dates and times, heavily inspired by the java.time library. Features: A full set of date-t

Additions for Kotlin's date & time library kotlinx-datetime

fluid-time Additions for Kotlin's date & time library kotlinx-datetime. kotlinx-datetime is very early stage and not as actively developed as other of

java.time Kotlin extension functions library.
java.time Kotlin extension functions library.

Java Time Kotlin extension functions. Background Java Time became integrated to the JDK as of Java 8. It was a huge improvement over its Date predeces

Kmpcalendar - A calendar library and views written for kotlin multiplatform
Kmpcalendar - A calendar library and views written for kotlin multiplatform

KMPCalendarView Minimal Kotlin Multiplatform project with SwiftUI, Jetpack Compo

A Jetpack Compose library for handling calendar component rendering.
A Jetpack Compose library for handling calendar component rendering.

Compose Calendar Compose Calendar is a composable handling all complexity of rendering calendar component and date selection. Due to flexibility provi

📅 Minimal Calendar - This calendar library is built with jetpack compose. Easy, simple, and minimal.
📅 Minimal Calendar - This calendar library is built with jetpack compose. Easy, simple, and minimal.

📅 Minimal Calendar This calendar library is built with jetpack compose. Easy, simple, and minimal. Latest version The stable version of the library i

Simple application to log your mood through the day and explain feature flags.

Mood Logger App (Android version) This Repo This repository contains code for building a very basic application to log your mood through the days. The

Feature flags solution that is fast, lean, and open-source.

FFS Feature flags solution that is fast, lean, and open-source. Documentation Full documentation available at https://doist.github.io/ffs/. Project FF

Asimov-time-kt - Useful time and date related functions and extensions

asimov/time Useful time and date related functions and extensions. Installation

A customizable debug screen to view and edit flags that can be used for development in Jetpack Compose applications
A customizable debug screen to view and edit flags that can be used for development in Jetpack Compose applications

Tweaks A customizable debug screen to view and edit flags that can be used for development in Jetpack Compose applications To include the library add

Vbmeta Patcher is an Android app that toggles the disable flags of the vbmeta partitions.

Vbmeta Patcher Vbmeta Patcher is an Android app that toggles the disable flags of the vbmeta partitions. Usage If either vbmeta_a or vbmeta_b are unpa

Tweaks - A customizable debug screen to view and edit flags that can be used for development
Tweaks - A customizable debug screen to view and edit flags that can be used for development

A customizable debug screen to view and edit flags that can be used for developm

A Paper fork with secure feature seed based on Secure Seed mod by Earthcomputer
A Paper fork with secure feature seed based on Secure Seed mod by Earthcomputer

GitHub | Download | Discord Matter Matter is a Paper fork that currently only adds what we call a secure feature seed. Based on Secure Seed mod by Ear

Feature toggle library for Android
Feature toggle library for Android

FeatureToggle Feature toggle library for Android. Overview FeatureToggle library allows to configure features of Android application in runtime using

Regret is an Android library for apps that wants to implement an undo/redo feature

Regret I've been developing on an editor for my Android App recently, using Jetpack Compose, but Google doesn't implement a built-in undo / redo for d

An implementation of tap targets from the Material Design guidelines for feature discovery.
An implementation of tap targets from the Material Design guidelines for feature discovery.

TapTargetView An implementation of tap targets from Google's Material Design guidelines on feature discovery. Min SDK: 14 JavaDoc Installation TapTar

Twidere-Android Twidere is a powerful twitter client for Android 1.6+ 1 , which gives you a full Holo experience and nearly full Twitter's feature.
Twidere-Android Twidere is a powerful twitter client for Android 1.6+ 1 , which gives you a full Holo experience and nearly full Twitter's feature.

Twidere for Android Material Design ready and feature rich Twitter/Mastodon/Fanfou app for Android 4.1+. Enjoy Fediverse now! Twidere-Android is maint

Owner
Nicolas Bottarini
Nicolas Bottarini
Tanya Gupta 1 Aug 16, 2022
An Android platform component management tool chain, based on Kotlin language.

Rubik Rubik是一套解决Android平台组件化的综合方案,提供gradle project之间的路由通讯能力,以及对gradle project的组件定义、版本控制、maven发布、aar/jar与源码之间的切换以及组件的自由组合等能力。 Rubik由两部分组成: Rubik Router

Baidu 135 Jan 3, 2023
Joda-Time library with Android specialization

Android has built-in date and time handling - why bother with a library? If you've worked with Java's Date and Calendar classes you can probably answer this question yourself, but if not, check out Joda-Time's list of benefits.

Daniel Lew 2.6k Dec 9, 2022
Android NTP time library. Get the true current time impervious to device clock time changes

TrueTime for Android Make sure to check out our counterpart too: TrueTime, an NTP library for Swift. NTP client for Android. Calculate the date and ti

Instacart 1.3k Jan 4, 2023
Android library for better Picker DialogFragments

DialogFragments modeled after the AOSP Clock and Calendar apps to improve UX for picking time, date, numbers, and other things.

Code-Troopers 2.7k Dec 29, 2022
Android Week View is an android library to display calendars (week view or day view) within the app. It supports custom styling.

Android Week View Android Week View is an android library to display calendars (week view or day view) within the app. It supports custom styling. Fea

Raquib-ul Alam (Kanak) 3.4k Jan 3, 2023
An android library which provides a compact calendar view much like the one used in google calenders.

CompactCalendarView CompactCalendarView is a simple calendar view which provides scrolling between months. It's based on Java's Date and Calendar clas

SundeepK 1.5k Jan 7, 2023
CustomizableCalendar is a library that allows you to create your calendar, customizing UI and behaviour

CustomizableCalendar This library allows you to create a completely customizable calendar. You can use CustomizableCalendar to create your calendar, c

MOLO17 216 Dec 6, 2022
android library dialog month picker

RackMonthPicker android library dialog month picker Download Download via Maven: Add the JitPack repository to your build file <repositories> <rep

Kristiawan Adi L 41 Aug 13, 2022
A simple library which gives you custom design CalendarView with dialog functionality and event handlers.

CalendarView A simple library which gives you custom design CalendarView with dialog functionality and event handlers. 1: CalendarView Demo Screen 1.1

Shahzad Afridi (Opriday) 49 Oct 28, 2022