Git Product home page Git Product logo

config-magic's Introduction

Example

Create an interface for your config object:

public interface MyConfig
{
    @Config("foo")
    String getFoo();

    @Config("blah")
    int getBlah();

    @Config("what")
    @Default("none")
    String getWhat();
}

Set the properties that we mapped with @Config above (or simply call System.getProperties()):

Properties props = new Properties();
props.setProperty("foo", "hello");
props.setProperty("blah", "123");

Then create the config object from the properties:

ConfigurationObjectFactory factory = new ConfigurationObjectFactory(props);
MyConfig conf = factory.build(MyConfig.class);

Default values

Using @Default() can set arbitrary default values. To set null as the default value, use the @DefaultNullannotation.

Advanced usage

    @Config({"what1", "what2"})
    @Default("none")
    String getWhat();

will look at what1 first, then at what2 and finally fall back to the default.

Parameterized configs

    enum StateType {
       FILESYSTEM,
       MEMORY
    }
    
    @Config("${state_type}.size")
    @DefaultNull
    String getParameterizedConfig(@Param("state_type") StateType e);
    
    @Config("${state_type}.${source}.path")
    @DefaultNull
    String getDoubleParameterizedConfig(@Param("state_type") StateType e, @Param("source") String source);

Use it like the following:

    myConfig.getParameterizedConfig(StateType.MEMORY);   // reads from MEMORY.size
    myConfig.getDoubleParameterizedConfig(StateType.FILESYSTEM, "backend");  // reads from FILESYSTEM.backend.path

Type support

Config-magic supports these types:

  • Primitive types: boolean, byte, short, integer, long, float, double.
  • Enums. Note that config-magic by default ignores the case for enum values.
  • java.lang.String.
  • java.net.URI.
  • java.lang.Class and simple wildcard extensions (java.lang.Class<?>, java.lang.Class<? extends Foo> - config-magic will type check that the type passed as a property conforms to the wildcard type), but not more complex wildcard or parameterized types (e.g. java.lang.Class<? super Bar> or java.lang.Class<? extends List<? super Bar>>).
  • org.skipe.config.TimeSpan: constructed from short textual representation like "5d" (or alias "5 days"); units supported are:
  • ms (alias 'milliseconds')
  • s ('seconds')
  • m ('minutes')
  • h ('hours')
  • d ('days')
  • Any instantiable class that has a public constructor with a single Object parameter. This is useful for instance for joda-time's DateTime objects.
  • Any instantiable class that has a public constructor with a single String parameter. This is useful for instance for java.lang.File.
  • Any class that has a static valueOf method with a single String parameter and the class as its return type.

Maven dependency

To use config-magic in Maven projects:

<dependency>
    <groupId>org.skife.config</groupId>
    <artifactId>config-magic</artifactId>
    <version>0.11</version>
</dependency>

Mailing List

We have a mailing list for development and users.

config-magic's People

Contributors

brianm avatar cowtowncoder avatar dependabot[bot] avatar divyekapoor avatar electrum avatar hgschmie avatar sebastiananu avatar stevenschlansker avatar tomdz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

config-magic's Issues

[Feature request] Recursive configs?

Brian - thank you for a wonderful config library. We are finding it of good use.

One snag we hit recently is that the library doesn't support recursive configurations:
(simplified example)

public interface KVConfig {
   @Config("dataset_name")
   public String datasetName();

   @Config("dataset_path")
   public String datasetPath();
}

public interface CommonConfigs {
   @Config("pin_impression")
   KVConfig getPinImpressionKVConfigs();

  @Config("pin_repin")
  KVConfig getPinRepinKVConfigs();
}

The above doesn't work because the type coercion does not recursively try to parse the KVConfig type (it tries to cast to it).
It might be that this is "user error" and that this is supported - a colleague of mine and I couldn't get it working if so and we had to use parameterized configs instead as a workaround (pull request to update the Readme is here -- #18)

Could you:

  1. Confirm if this is a supported or unsupported?
  2. If unsupported, is this "easy" to do? (eg. just reinstantiate (internally) a ConfigurationObjectBuilder and bind?) or are there other complexities?
  3. If easy to do, could you suggest next steps? (if this is a super easy one-liner, would you be open to implementing the request?)

Best,
Divye

Please include a LICENSE.txt file in the project

It requires a bit of looking to figure out that this software is licensed under APL 2.0. People wishing to use the software may take it as a kindness if that information were more readily available.

Warning on Java 9 and 10

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.skife.config.cglib.core.ReflectUtils$2 (file:/.m2/repository/org/skife/config/config-magic/0.17/config-magic-0.17.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of org.skife.config.cglib.core.ReflectUtils$2
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

Could you update the reference to cglib to use the last version please ?

Replace cglib with annotation processing

The use of cglib for code generation is increasingly causing problems with Java versions. Using an annotation processor to generate the classes instead of using runtime byte code generation seems like a more future-proof approach, and would help would help with debug-ability.

I propose keeping config-magic as a single jar, using an annotation processor in said jar to pick up config objects, and splatting out nice .java definitions using java-poet. This would ad java-poet as a compile time dependency, but not as a runtime dependency.

Any feeling?

Allow longer time unit definitions for TimeSpan

In addition to existing single-letter time unit definitions, it would be good to have longer aliases, so that "s"/"second"/"seconds" would all be allowed for second values; and similarly for other existing time units.

Doesn't work on protected methods

If an annotated method is protected, config-magic doesn't find the property. This is probably also the case for private, but I haven't tested it.

This isn't a big deal, just making an issue for posterity.

[Feature Request][Pull request following] Support @AutoDefault for "required-key-but-not-required-value" behavior

Hi Brian,
Thanks for making a fantastic config library. We (at Pinterest) have been using it extensively to set up our configuration infrastructure for our streaming applications.
One common pattern we have seen is that we often set up configs in the following manner:

code.java
interface ConfigIface {
  @Config("c")
  String getConfigInternal();

  default String getConfig() {
     if ("auto".equalsIgnoreCase(getConfigInternal())) {
       return "some-value-that-we-set-in-just-1-location-instead-of-50-configs-that-we-can-evolve";
     }
    return getConfigInternal();
  }
}

config.properties:
my.friendly.prefix.c=auto

The reason we do it this way is so that client teams know that the config actually exists (and can be overridden by them) but

The proposal is supporting this via a new annotation: @AutoDefault to make code like this:

interface ConfigIface {
  @Config("c")
  @AutoDefault("some-value-that-we-set-in-just-1-location-instead-of-50-configs-that-we-can-evolve")
  String getConfig();
}

config.properties:
my.friendly.prefix.c=auto

The difference with @Default is that the key is actually required in the config (so the configs all look the same and it's super clear where the framework is setting a value and where a user is setting a value). This is so common that we'd like to upstream it into the code so that we don't have to keep doing this.

Would you be open to accepting a pull request that implements this functionality?
It's a short change (10s of lines of code) - PR to follow.

downgrade logging from INFO to DEBUG or TRACE

Thanks for such a handy library - very useful!

The default log level in logging libs such as logback and log4j is INFO. This implies that by default the logger.info() calls in ConfigurationObjectFactory generate tons of distracting log messages on output. It seems to me folks only want to see those message only in debug or trace mode, and not by default. Having to switch this off manually (ala opt out) seems counter intuitive to me.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.