Skip to content

Getting started

Ramesh Malla edited this page Jan 20, 2024 · 5 revisions

Integrating baigan-config

Step 1: Install baigan-config dependencies

Add the following dependency to your project:

For maven build

<dependency>
    <groupId>org.zalando</groupId>
    <artifactId>baigan-config</artifactId>
    <version>${baigan.version}</version>
</dependency>

For gradle build

implementation 'org.zalando:baigan-config:${baigan.version}'

Step 2: Creating configurations

Baigan configurations follow a specific schema and can be stored on any of the supported repositories.

Configuration schema

Configurations are stored in its simplest form as key values. A configuration is a pair of a dot(.) separated key and a value objects in JSON format.

A configuration object should conform to the following JSON Schema:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Configuration",
    "description": "A baigan configuration object value.",
    "type": "object",
    "properties": {
        "alias": {
            "description": "The identifier for the configuration, same as its key.",
            "type": "string"
        },
         "description": {
            "description": "Summary of the configuration.",
            "type": "string"
        },
         "defaultValue": {
            "description": "Default configuration if none of the condition is satisfied.",
            "type": {}
        },
         "conditions": {
            "description": "List of conditions to check",
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "value": {
                        "description": "Configuration value if this condition evaluates to true.",
                        "type": {}
                    },
                    "conditionType": {
                        "description": "Type of condition to evaluate. This can be custom defined, with custom defined properties.",
                        "type": "object"
                    }
                }
            }
        }
    },
    "required": ["defaultValue"]
}

Example configurations

This sample JSON defines a configuration for the key express.feature.enabled with the value true when the country_code is 3, and a default value of false.

[
  {
    "alias": "express.feature.enabled",
    "description": "Feature toggle",
    "defaultValue": false,
    "conditions": [
      {
        "value": true,
        "conditionType": {
          "onValue": "3",
          "type": "Equals"
        },
        "paramName": "country_code"
      }
    ]
  }
]

Step 3: Configure application to read baigan configurations (created in Step 2)

Setup Baigan Spring configurations

Application.java

@ComponentScan(basePackageClasses = { BaiganSpringContext.class })
@ConfigurationServiceScan(basePackages = { "com.foo.configurations" })
public class Application {

@Bean
    public ConfigurationRepository configurationRepository(RepositoryFactory factory) {
        return factory.fileSystemConfigurationRepository()
                      .fileName("configs.json")
                      .build();
    }

}
  • @ComponentScan(basePackageClasses = { BaiganSpringContext.class }) loads BaiganSpringContext, which, in turn, loads all the necessary Spring beans required by baigan.

  • @ConfigurationServiceScan(basePackages = { "com.foo.configurations" }) scans the provided packages to check for baigan-config interfaces (explained below). Baigan uses these interfaces to parse simple JSON configurations into concrete types. In this example, baigan will scan the com.foo.configurations package to identify baigan-config interfaces.

Define baigan-config interface

ExpressFeature.java

@BaiganConfig
public interface ExpressFeature {
    Boolean enabled();
}

Baigan follows structured configurations, where JSON configurations are automatically parsed into a specific type. @BaiganConfigannotation serves as a hint to Baigan to map simple JSON configurations to a specific type in the client's application. Configuration interfaces should adhere to specific conventions.

  • The interface should be annotated with @BaiganConfig.
  • The interface name and the interface method should match the key name of the JSON configuration. For example, to map a express.feature.enabled key, Baigan takes the interface name ExpressFeature and the interface method enabled to map the value.

Note: Primitives are not supported as return types, as they cannot be null and therefore cannot express a missing configuration value.

Caution

Primitives are not supported as return types as they cannot be null and therefore cannot express a missing configuration value. If you use Baigan with Kotlin, it means you need to use nullable primitive types, e.g. Int? instead of Int.

Step 4: Use the configurations

@Component
public class ExpressServiceImpl implements ExpressService {

    @Inject
    private ExpressFeature expressFeature;

    @Override
    public void sendShipment(final Shipment shipment) {
        if (expressFeature.enabled()) {
            final String serviceUrl = expressFeature.serviceUrl();
            // Use the configuration
        }
    }
}