Skip to content

Users Guide

allenxwang edited this page Feb 16, 2013 · 77 revisions

This document outlines how to use certain advanced features of Archaius.

Provide your own configuration source or polling scheduler

As explained in previous section, by default Archaius uses a set of URLs as configuration sources and polls them at a fixed delay. However, you can also provide your own configuration source and/or polling scheduler. For example, you may define your own configuration source from a relational database, a distributed key-value store like Cassandra, or third party service like AWS SimpleDB.

To provide your own configuration source, follow these steps:

1. Implement com.netflix.config.PolledConfigurationSource

public class DBConfigurationSource implements PolledConfigurationSource {
    // ...
    @Override
    public PollResult poll(boolean initial, Object checkPoint)
            throws Exception {
        // implement logic to retrieve properties from DB
    }  
}

2. (Optional) Provide your own scheduler by extending com.netflix.config.AbstractScheduler

public class MyScheduler extends AbstractPollingScheduler {
    // ...
    @Override
    protected synchronized void schedule(Runnable runnable) {
        // schedule the runnable
    }

    @Override
    public void stop() {
        // stop the scheduler
    }
}

3. Create an instance of com.netflix.config.DynamicConfiguration

  PolledConfigurationSource source = ...
  AbstractPollingScheduler scheduler = ...
  DynamicConfiguration configuration = new DynamicConfiguration(source, scheduler);

4. Register your configuration with com.netflix.config.ConfigurationManager

  ConfigurationManager.install(configuration);

5. Create dynamic properties from com.netflix.config.DynamicPropertyFactory

  DynamicStringProperty myprop = DynamicPropertyFactory.getInstance().createStringProperty(...);

6. (Optional) Disable the default configuration source for DynamicPropertyFactory

You can set this system property so that DynamicPropertyFactory will not try to use the URL based default configuration source upon the getInstance() call:


archaius.dynamicProperty.disableDefaultConfig=true

Declaring dynamic properties before registering your own configuration source with DynamicPropertyFactory

You can declare dynamic properties before registering your own configuration source with DynamicPropertyFactory. For example:

public class MyApplication {
    // declaring the property first
    public static final MY_PROP = DynamicPropertyFactory.getInstance().getIntProperty("myIntPropertyName", 0);
    // ...
    public static void main(String[] args) {
        // ...
        DynamicPropertyFactory.initWithConfigurationSource(myConfiguration);
        // MY_PROP.get() will reflect the value from myConfiguration above
        callMyMethod(MY_PROP.get());
       // ...
    }

Using JConsole to view and update your properties at Runtime

If you set the following system property,


archaius.dynamicPropertyFactory.registerConfigWithJMX=true

the configuration registered with DynamicPropertyFactory will be automatically exposed to JMX, where you can update the properties via jconsole.

Alternatively, you can programmaically register your own configuration with an MBean:

  AbstractConfiguration config = ...
  ConfigJMXManager.registerConfigMbean(config);

JConsole

The image above shows a screen capture of a view of the properties when the operation obtainProperties() is invoked.

Operations available are:

  • obtainProperties() : Obtain all properties in the composite configuration
  • getProperty(String key) : Obtain a particular property value given a key
  • addProperty(String key, String value) : Add a new property into the CompositeConfiguration
  • updateProperty(String key, String value) : Update the value of an existing property
  • clearProperty(String key) : clear the property (delete)

Use Archaius with your own Apache Commons Configuration implementation

If you already use or extend any type of AbstractConfiguration from Apache Commons Configuration, but would like to take advantage of Archaius to feed your application with dynamic properties, you can do this in two ways using ConfigurationManager:

1. Use an implementation of com.netflix.config.AbstractPollingScheduler to poll the dynamic configuration source and put them into your own Configuration

  AbstractConfiguration myConfiguration = ...; // this is your original configuration
  // ...
  AbstractPollingScheduler scheduler = new FixedDelayPollingScheduler(); // or use your own scheduler
  PolledConfigurationSource source = new URLConfigurationSource(); // or use your own source
  scheduler.setIgnoreDeletesFromSource(true); // don't treat properties absent from the source as deletes
  scheduler.startPolling(source, myConfiguration);
  // ...
  ConfigurationManager.install(myConfiguration);

Now the original configuration becomes dynamic at runtime as properties from the polled configuration source will override their values in the original configuration. Note: In the above example, myConfiguration will be accessed from different threads and updates may not be visible immediately depending how the configuration is implemented. You can utilize com.netflix.config.ConcurrentMapConfiguration to ensure visibility of updates.

2. Use com.netflix.config.ConcurrentCompositeConfiguration

  AbstractConfiguration myConfiguration = ...; // this is your original configuration

  // create the dynamic configuration
  AbstractPollingScheduler scheduler = new FixedDelayPollingScheduler(); // or use your own scheduler
  PolledConfigurationSource source = new URLConfigurationSource(); // or use your own source
  DynamicConfiguration dynamicConfig = new DynamicConfiguration(source, scheduler);
      
  ConcurrentCompositeConfiguration finalConfig = new ConcurrentCompositeConfiguration();
  // add them in this order to make dynamicConfig override myConfiguration
  finalConfig.addConfiguration(dynamicConfig);
  finalConfig.addConfiguration(myConfiguration);
  
  ConfigurationManager.install(finalConfig);

The later approach gives you the flexibility to add more types configurations down the road.


Using ConfigurationManager

The configuration manager is a central place where it manages the system wide Configuration and deployment context. If you use your own AbstractConfiguration for configuration management, you can install it with the ConfigurationManager which takes care of initializing DynamicPropertyFactory with your AbstractConfiguration. If no configuration is installed programmatically by your application, a ConcurrentCompositeConfiguration that includes system property and a DynamicURLConfiguration will be installed lazily.

A deployment context contains attribute related to application deployment. For example, DeploymentContext.getDeploymentEnvironment() can return strings like “test”, “dev”, “prod”. This is useful to determine the set of properties used in a specific deployment context. If no deployment context is set programmatically with ConfigurationManager, a default ConfigurationBasedDeploymentContext will be installed. The return values of the APIs in ConfigurationBasedDeploymentContext is based on a set of property values obtained from the configuration installed with ConfigurationManager.


Running the sample applications

Two sample applications are provided in archaius-core. There sources are available in the archaius-core-sources.jar.

  • com.netflix.config.samples.SampleApplication: a Java main application to show usage of customized Configuration, DynamicPropertyFactory and dynamic properties
  • com.netflix.config.samples.SampleApplicationWithDefaultConfiguration: a Java main application to show usage of the default ConcurrentCompositeConfiguration, DynamicPropertyFactory and dynamic properties.

To run the applications, you need the following in your classpath

  • archaius-core-xxx.jar (latest release/snapshot of archaius-core)
  • commons-configuration-1.8.jar
  • commons-lang-2.6.jar
  • commons-logging-1.1.1.jar

Using the DeploymentContext and load cascaded configuration files

DeploymentContext defines a set of deployment context based properties. The values of these properties are optional and can be any string. For example, environment is one property of deployment context and can be “prod”, “test” or any other string that makes sense to an organization.

Deployment context properties can be used in many ways. Archaius uses deployment context to load cascaded configuration files. Here is the use case:

  • Application defines a set of default properties
  • At runtime, those properties should be overridden by deployment context specific values.

For example, an application has a configuration file database.properties, which contains default set of database properties. It has two other properties file

  • database-prod.properties, which contains overridden values for “prod” environment
  • database-test.properties, which contains overridden values for “test” environment

To load any one of the above file, the ConfigurationManager will consult with DeploymentContext object set with it to determine what environment it is in (through DeploymentContext.getDeploymentEnvironment() method), and load additional database-${environment} file to override the default values.

DeploymentContext is pluggable in Archaius. ConfigurationManager will instantiate DeploymentContext implementation class given as value for system property “archaius.default.deploymentContext.class”. If that is not defined, Archaius will by default install a DeploymentContext instance that determine its return values based on a set of predefined properties:

  • archaius.deployment.environment
  • archaius.deployment.region
  • archaius.deployment.datacenter
  • archaius.deployment.applicationId
  • archaius.deployment.serverId
  • archaius.deployment.stack

The value of these properties can be set as system properties.

Another feature of Archaius is that you can define the way cascaded property files are loaded. For example, you want Archaius to load an EC2 region specific properties file database-us-east-1.properties to override the default database.properties. To do that, you can define this property at the end of the database.properties file:


@next=database-${@region}.properties

“@next” is a special property to define next file to load. “@region” is a automatically set property and will expand to correct value at runtime. You can prepend “@” to any DeploymentContext.ContextKey enum to get its value as a property. For example,

  // this will return the same value as DepolymentContext.getValue(ContextKey.environment)
  // or DeploymentContext.getDeploymentEnvironment()
  ConfigurationManager.getConfigInstance().getString("@environment");