Configuration service
The configuration service provides authorized publication and consumption of identified configuration data with metadata. The service supports bootstrapping.
A pluggable Ruby API is provided in ConfigurationService::Base.
The declarative specification of the service is implemented with cucumber, using a pluggable imperative orchestration providers. This allows for implementations that are not providers to the Ruby API. See ConfigurationService::Test.
A stub service provider is provided in ConfigurationService::Provider::Stub. This is used to validate the test framework architecture, and may be used as a stub configuration service in tests. Other providers are available as gems.
Service providers are registered against the ConfigurationService::ProviderRegistry.
Factories for creating and configuring service instances are provided in ConfigurationService::Factory.
Usage
The recommended approach to creating a configuration service client is to use a Factory.
For example, we can use the EnvironmentContext factory to create and configure a configuration service client backed by the vault provider as follows.
Our main.rb
(or config.ru
or whatever) is simple:
require 'bundler'
Bundler.require(:default)
service = ConfigurationService::Factory::EnvironmentContext.create
configuraton = service.request_configuration
AcmeApplication.new(configuration.data).run
This relies on a / bundler Gemfile to load the gem that contains whatever service provider we configure in the environment:
source 'https://rubygems.org'
gem 'configuration_service-provider-vault'
gem 'acme_application'
Now we use the process environment to configure the EnvironmentContext factory:
CFGSRV_IDENTIFIER="acme" \
CFGSRV_TOKEN="0b2a80f4-54ce-45f4-8267-f6558fee64af" \
CFGSRV_PROVIDER="vault" \
CFGSRV_PROVIDER_ADDRESS="http://127.0.0.1:8200" \
bundle exec main.rb
Note that main.rb
is completely decoupled from the selection of provider and provider configuration. We could swap and/or reconfigure the provider by manipulating only the Gemfile
and the environment.
If you prefer to hard-code everything, or if your strategy for bootstrapping the configuration service isn’t expressed by an existing factory yet, you can construct the service yourself:
# Bad example (hardcoding token into source):
require 'configuration_service/provider/vault'
require 'acme_application'
service = ConfigurationService.new(
"acme",
"0b2a80f4-54ce-45f4-8267-f6558fee64af",
ConfigurationService::Provider::Vault.new(
address: "http://127.0.0.1:8200"
)
)
configuraton = service.request_configuration
AcmeApplication.new(configuration.data).run