matteobaccan / owner

Get rid of the boilerplate code in properties based configuration.
https://matteobaccan.github.io/owner/
BSD 3-Clause "New" or "Revised" License
915 stars 212 forks source link

Support for a convention and flexible @Sources configuration: @AutoSources #173

Open rrialq opened 8 years ago

rrialq commented 8 years ago

It should be interesting adding a flexible convention feature about @Sources to the library. This would allow a loosely coupled configuration mechanism, with the following additional benefits:

When you develop software following guidelines about configuration maybe you need a way to configure a flexible way to "wrap" the @Sources definition, with a simple set of rules, something like a @AutoSources annotation, which may be combined with **@Sources** annotation.

For example, the rules should be the following, from lower to higher priority:

Imagine now that we have a way to support automatically this kind of configurations in all of our applications without writing specific @Sources annotation, so we can get the following code equivalence:

@Sources( {
    "file:${configurationPath}/global.properties",
    "file:${configurationPath}/myHostName.host.properties",
    "file:${configurationPath}/myServerName.server.properties",
    "file:${configurationPath}/org/aeonbits/owner/demo.properties",
    "classpath:org/aeonbits/owner/demo.properties"
})
public interface Demo extends Config {
...
}

only writing the following code:

@AutoSources
public interface Demo extends Config {
...
}

or better yet:

@AutoSources( "myid" )
public interface Demo extends Config {
...
}

So you can write a few properties in a file in a way similar to:

# Global rules for managing all configurations
# Prepend to uris
global.sources.prepend=file:${configurationPath}/global.properties,\
file:${configurationPath}/myhost.host.properties,\
file:${configurationPath}/myserver.server.properties,\
file:${configurationPath}/myinstance.instance.properties
# Append to uris
global.sources.append=file:${configurationPath}/global.append.properties
#Exclude applying this rule for classes which name matches following regular expression:
global.sources.exclude=org\.aeonbits\.owner\.demo24

#Rules for envolving the configurations annotated with @AutoSources( "myid" )
myid.sources.prepend=file:${user.home}/autosource/myid.properties
#Set to true if you want to disable the autosources on myid
myid.sources.disable=false

I am working on this feature, and when I finish my tests I will do a pull to propose add this feature into Owner.

lviggiano commented 8 years ago

Hi.

I'll review your message above more in detail later, but my first thoughts are that when you don't specify the @Sources annotation, owner already has some default behavior (loading from the classpath a properties file with same name and package as the driving interface). So, maybe, it would be better to extend the default paths loading, instead of creating a new @AutoSource annotation, that checks if some system properties are specified.

Also I don't see much of advantage to have an external properties file to define what at the moment is specified by the @sources annotation.

I would go for an extension of the default loading sources instead of making it more complex and difficult to understand for the end users.

Eventually, if the end user needs a more complex strategy to identify from where to load the properties files, maybe we can let him to specify a @SourcesLocatorClass(MySourceLocator) and have the end user implement the algorithm to identify a single URI or a list of URI to load the properties.

At the moment, new features added are lacking documentation (and this means that they are incomplete for a release), and unfortunately I don't have much time to dedicate to this project.

Also, I think it is important to keep things simple.