DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Vibe Coding With GitHub Copilot: Optimizing API Performance in Fintech Microservices
  • Concourse CI/CD Pipeline: Webhook Triggers
  • Build a Stateless Microservice With GitHub Copilot in VSCode
  • Build Your Own GitHub-Like Tool With React in One Hour

Trending

  • Blue Skies Ahead: An AI Case Study on LLM Use for a Graph Theory Related Application
  • Concourse CI/CD Pipeline: Webhook Triggers
  • Immutable Secrets Management: A Zero-Trust Approach to Sensitive Data in Containers
  • From Zero to Production: Best Practices for Scaling LLMs in the Enterprise
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. Typesafe Config Features and Example Usage

Typesafe Config Features and Example Usage

Diving deeper into environment aware configuration, let's see how Typesafe Config can help with fallback configs, duration helpers, and more.

By 
Bill O'Neil user avatar
Bill O'Neil
·
Aug. 31, 17 · Tutorial
Likes (6)
Comment
Save
Tweet
Share
64.5K Views

Join the DZone community and get the full member experience.

Join For Free

Previously, we covered environment aware configurations for building a simple default config with overrides for local development and production. Let's dive a little deeper and show examples with some of the more useful features built into Typesafe Config. Some features include reading config values as lists, configuration resolution, fallback configs, memory helpers, duration helpers, and boolean helpers.

Example Configs

We will be using the following two configuration files: defaults.conf and overrides.conf.

defaults.conf

conf {
    name = "default"
    title = "Simple Title"
  nested {
        whitelistIds = [1, 22, 34]
    }

    combined = ${conf.name} ${conf.title} 
}

featureFlags {
    featureA = "yes"
    featureB = true
}

View on GitHub

overrides.conf

conf {
    name = "overrides"
}

redis {
    ttl = 5 minutes
}

uploadService {
    maxChunkSize = 512k
    maxFileSize = 5G
}

View on GitHub

Loading a Typesafe Config From a Resource

Loading a Typesafe Config from a resource on the classpath is a simple one liner. Typesafe Config has several default configuration locations it looks at when loading through ConfigFactory.load(); but we are big fans of making everything explicit. It's preferred if the configs that were being loaded are listed right there when we call it.

Config defaultConfig = ConfigFactory.parseResources("defaults.conf"); 

View on GitHub

Creating a Typesafe Config With Fallbacks

A great use case for this is environment specific overrides. You can set up one defaults file and have an override for local, dev, and prod. This can be seen in our environment aware configurations. In this case, we first load our overrides.conf , then set a fallback of our defaults.conf from above. When searching for any property, it will first search the original config, then traverse down the fallbacks until a value is found. This can be chained many times. We will come back to the resolve() method a little later.

Config fallbackConfig = ConfigFactory.parseResources("overrides.conf")
                                     .withFallback(defaultConfig)
                                     .resolve();

View on GitHub

Loading a Simple String Config Value

Probably one of the most common cases for configs is loading simple strings. Let's see what happens when we request name and title from both configs. Each has an entry for name but only the default.conf has an entry for title.

log.info("name: {}", defaultConfig.getString("conf.name"));
log.info("name: {}", fallbackConfig.getString("conf.name"));
log.info("title: {}", defaultConfig.getString("conf.title"));
log.info("title: {}", fallbackConfig.getString("conf.title"));

View on GitHub

2017-08-15 09:07:14.461 [main] INFO  TypesafeConfigExamples - name: default
2017-08-15 09:07:14.466 [main] INFO  TypesafeConfigExamples - name: overrides
2017-08-15 09:07:14.466 [main] INFO  TypesafeConfigExamples - title: Simple Title
2017-08-15 09:07:14.466 [main] INFO  TypesafeConfigExamples - title: Simple Title


As expected, each config returned its own value for name but for title , the fallback was called since overrides.confd does not have a config entry.

Config Value Resolution

Sometimes, it's useful to reuse a config value inside of other config values. This is achieved through configuration resolution by calling the resolve() method on a Typesafe Config. An example of this use case could be if all hostnames are scoped per environment ({env}.yourdomain.com). It would be nicer to only override the env property and have all other values reference it. Let's use the above name and title again just for an example. If you look at the example configs, we have the following combined = ${conf.name} ${conf.title}.

log.info("combined: {}", fallbackConfig.getString("conf.combined"));

View on GitHub

2017-08-15 09:07:14.466 [main] INFO  TypesafeConfigExamples - combined: overrides Simple Title

Duration Helpers

How often do you open a config and see something like timeout = 300; // five minutes in seconds 5 * 60. Typesafe Config is able to parse many durations and allows you to convert it to any other duration using TimeUnit. Let's look at the example ttl = 5 minutes from the above configs.

log.info("redis.ttl minutes: {}", fallbackConfig.getDuration("redis.ttl", TimeUnit.MINUTES));
log.info("redis.ttl seconds: {}", fallbackConfig.getDuration("redis.ttl", TimeUnit.SECONDS));

View on GitHub

2017-08-15 09:07:14.472 [main] INFO  TypesafeConfigExamples - redis.ttl minutes: 5
2017-08-15 09:07:14.472 [main] INFO  TypesafeConfigExamples - redis.ttl seconds: 300

Memory Size Helpers

Just like durations its not uncommon to see confusing values for bytes. Typesafe Config provides us with the getMemorySize method which can read values like maxChunkSize = 512k and maxFileSize = 5G. Don't forget to call toBytes().

// Any path in the configuration can be treated as a separate Config object.
Config uploadService = fallbackConfig.getConfig("uploadService");
log.info("maxChunkSize bytes: {}", uploadService.getMemorySize("maxChunkSize").toBytes());
log.info("maxFileSize bytes: {}", uploadService.getMemorySize("maxFileSize").toBytes());

View on GitHub

2017-08-15 09:07:14.479 [main] INFO  TypesafeConfigExamples - maxChunkSize bytes: 524288
2017-08-15 09:07:14.479 [main] INFO  TypesafeConfigExamples - maxFileSize bytes: 5368709120

Handling Lists/Arrays

A quick example of for a list of config options would be a configurable whitelist/blacklist.

List whiteList = fallbackConfig.getIntList("conf.nested.whitelistIds");
log.info("whitelist: {}", whiteList);
List whiteListStrings = fallbackConfig.getStringList("conf.nested.whitelistIds");
log.info("whitelist as Strings: {}", whiteListStrings);

View on GitHub

2017-08-15 09:07:14.480 [main] INFO  TypesafeConfigExamples - whitelist: [1, 22, 34]
2017-08-15 09:07:14.480 [main] INFO  TypesafeConfigExamples - whitelist as Strings: [1, 22, 34]

Boolean Helpers

This one is a little questionable. Do we really need to allow values such as yes and no instead of true or false? It's there if you prefer it.

log.info("yes: {}", fallbackConfig.getBoolean("featureFlags.featureA"));
log.info("true: {}", fallbackConfig.getBoolean("featureFlags.featureB"));

View on GitHub

2017-08-15 09:07:14.480 [main] INFO  TypesafeConfigExamples - yes: true
2017-08-15 09:07:14.480 [main] INFO  TypesafeConfigExamples - true: true

Summary

Typesafe Config has many useful features out of the box for free. There are more than the ones simply listed here. A more advanced one could be shown in our Database Connection Pooling in Java with HikariCP example, which uses configuration inheritance to create two similar config objects and only override a few properties.

GitHub

Published at DZone with permission of Bill O'Neil. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Vibe Coding With GitHub Copilot: Optimizing API Performance in Fintech Microservices
  • Concourse CI/CD Pipeline: Webhook Triggers
  • Build a Stateless Microservice With GitHub Copilot in VSCode
  • Build Your Own GitHub-Like Tool With React in One Hour

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: