@mark: +1 regards, gerhard
2014-12-04 11:07 GMT+01:00 Mark Struberg <strub...@yahoo.de>: > I think I need a bit time to understand this. I've tried to grasp it for 2 > days now and this might mean that it is too complicated if not even I get > it. Why are we doing this so complicated? Pulling in all the database logic > into a tool which main target is that it should be really easy to use? > What benefit does this add over hiding those details? e.g. in DeltaSpike I > would just add a DatabaseConfigSource and be done. The user would not even > see that it magically picks up the values from the db then. > > > LieGrue, > strub > > > > > > > On Tuesday, 2 December 2014, 14:02, Anatole Tresch <anat...@apache.org> > wrote: > > > Hi all > > find following an additional part of use cases for comment. Note that > this > > area IMO definitively may be improved in several ways. Always keep in > mind > > that I try to setup the design guide similarly in parallel. It can be > > easily accessed from the GH mirror: > > > > > https://github.com/apache/incubator-tamaya/blob/master/docs/design/2_CoreConcepts.adoc > > > > Cheers, > > Anatole > > > > Combining Property Providers > > > > Looking at the structures of configuration system used by large companies > > we typically encounter some kind of configuration hierarchies that are > > combined in arbitrary ways. Users of the systems are typically not aware > of > > the complexities in this area, since they simply know the possible > > locations, formats and the overriding policies. Framework providers on > the > > other side must face the complexities and it would be very useful if > Tamaya > > can support here by providing prebuilt functionality that helps > > implementing these aspects. All this leads to the feature set of > combining > > property providers. Hereby the following strategies are useful: > > > > - > > > > aggregating providers, hereby later providers added > > - > > > > override any existing entries from earlier providers > > - > > > > combine conflicting entries from earlier providers, e.g. into a > > comma-separated structure. > > - > > > > may throw a ConfigExcepotion ig entries are conflicting > > - > > > > may only add entries not yet defined by former providers, > preventing > > entries that are already present to be overwritte > > - > > > > any custom aggregation strategy, which may be a mix of above > > - > > > > intersecting providers > > - > > > > subtracting providers > > - > > > > filtering providers > > > > These common functionality is provided by the PropertyProviders > > singleton. Additionally to the base strategies above a MetaInfo instance > > can be passed optionally as well to define the meta information for the > > newly created provider instances. Let’s assume we have two property > > providers with the following data: > > Provider 1 > > > > a=a > > b=b > > c=c > > g=g > > h=h > > i=i > > > > Provider 2 > > > > a=A > > b=B > > c=C > > d=D > > e=E > > f=F > > > > Looking in detail you see that the entries a,b,c are present in both > > providers, whereas d,e,f are only present in provider 1, and g,h,i only > in > > provider 2. > > Example Combining PropertyProviders > > > > PropertyProvider provider1 = ... > > PropertyProvider provider2 = ... > > // aggregate, hereby values from provider 2 override values from > provider 1 > > PropertyProvider unionOverriding = > > PropertyProviders.aggregate(AggregationPolicy.OVERRIDE(), provider1, > > provider2);*System*.out.println("unionOverriding: " + > > unionOverriding); > > // ignore duplicates, values present in provider 1 are not overriden > > by provider 2 > > PropertyProvider unionIgnoringDuplicates = > > PropertyProviders.aggregate(AggregationPolicy.IGNORE_DUPLICATES(), > > provider1, provider2);*System*.out.println("unionIgnoringDuplicates: " > > + unionIgnoringDuplicates); > > // this variant combines/maps duplicate values into a new value > > PropertyProvider unionCombined = > > PropertyProviders.aggregate(AggregationPolicy.COMBINE(), provider1, > > provider2);*System*.out.println("unionCombined: " + unionCombined); > > // This variant throws an exception since there are key/value paris in > > both providers, but with different values*try*{ > > PropertyProviders.aggregate(AggregationPolicy.EXCEPTION(), > > provider1, provider2); > > }*catch*(ConfigException e){ > > // expected! > > } > > > > The example above produces the following outpout: > > Example Combining PropertyProviders > > > > AggregatedPropertyProvider{ > > (name = dynamicAggregationTests) > > a = "[a][A]" > > b = "[b][B]" > > c = "[c][C]" > > d = "[D]" > > e = "[E]" > > f = "[F]" > > g = "[g]" > > h = "[h]" > > i = "[i]" > > } > > unionOverriding: AggregatedPropertyProvider{ > > (name = <noname>) > > a = "A" > > b = "B" > > c = "C" > > d = "D" > > e = "E" > > f = "F" > > g = "g" > > h = "h" > > i = "i" > > } > > unionIgnoringDuplicates: AggregatedPropertyProvider{ > > (name = <noname>) > > a = "a" > > b = "b" > > c = "c" > > d = "D" > > e = "E" > > f = "F" > > g = "g" > > h = "h" > > i = "i" > > } > > unionCombined: AggregatedPropertyProvider{ > > (name = <noname>) > > a = "a,A" > > b = "b,B" > > c = "c,C" > > d = "D" > > e = "E" > > f = "F" > > g = "g" > > h = "h" > > i = "i" > > } > > > > No AggregationPolicy is also an interface that can be implemented: > > AggregationPolicy Interface > > > > @FunctionalInterface*public* *interface* *AggregationPolicy* { > > *String* aggregate(*String* key, *String* value1, *String* value2); > > } > > > > So we can also define our own aggregation strategy using a Lambda > > expression: > > Use a Custom AggregationPolicy > > > > PropertyProvider provider1 = ...; > > PropertyProvider provider2 = ...; > > PropertyProvider props = PropertyProviders.aggregate( > > (k, v1, v2) -> (v1 != null ? v1 : "") + '[' + v2 + > > "]", > > MetaInfo.of("dynamicAggregationTests"), > > props1, props2);*System*.out.println(props); > > > > Additionally we also pass here an instance of MetaInfo. The output of > > this code snippet is as follows: > > Listing of dynamic aggregation policy > > > > AggregatedPropertyProvider{ > > (name = dynamicAggregationTests) > > a = "[a][A]" > > b = "[b][B]" > > c = "[c][C]" > > d = "[D]" > > e = "[E]" > > f = "[F]" > > g = "[g]" > > h = "[h]" > > i = "[i]" > > } > > > > Summarizing the PropertyProviders singleton allows to combine providers > > in various forms: > > Methods provided on PropertyProviders > > > > public final class PropertyProviders { > > > > private PropertyProviders() {} > > > > public static PropertyProvider fromArgs(String... args) { > > public static PropertyProvider fromArgs(MetaInfo metaInfo, String... > args) > > { > > public static PropertyProvider fromPaths(AggregationPolicy > > aggregationPolicy, String... paths) { > > public static PropertyProvider fromPaths(String... paths) { > > public static PropertyProvider fromPaths(List<String> paths) { > > public static PropertyProvider fromPaths(AggregationPolicy > > aggregationPolicy, List<String> paths) { > > public static PropertyProvider fromPaths(MetaInfo metaInfo, > > List<String> paths) { > > public static PropertyProvider fromPaths(AggregationPolicy > > aggregationPolicy, MetaInfo metaInfo, List<String> paths) { > > public static PropertyProvider fromUris(URI... uris) { > > public static PropertyProvider fromUris(AggregationPolicy > > aggregationPolicy, URI... uris) { > > public static PropertyProvider fromUris(List<URI> uris) { > > public static PropertyProvider fromUris(AggregationPolicy > > aggregationPolicy, List<URI> uris) { > > public static PropertyProvider fromUris(MetaInfo metaInfo, URI... > uris) > > { > > public static PropertyProvider fromUris(AggregationPolicy > > aggregationPolicy, MetaInfo metaInfo, URI... uris) { > > public static PropertyProvider fromUris(MetaInfo metaInfo, List<URI> > > uris) { > > public static PropertyProvider fromUris(AggregationPolicy > > aggregationPolicy, MetaInfo metaInfo, List<URI> uris) { > > public static PropertyProvider fromMap(Map<String, String> map) { > > public static PropertyProvider fromMap(MetaInfo metaInfo, > > Map<String, String> map) { > > public static PropertyProvider empty() { > > public static PropertyProvider emptyMutable() { > > public static PropertyProvider empty(MetaInfo metaInfo) { > > public static PropertyProvider emptyMutable(MetaInfo metaInfo) { > > public static PropertyProvider fromEnvironmentProperties() { > > public static PropertyProvider fromSystemProperties() { > > public static PropertyProvider freezed(PropertyProvider provider) { > > public static PropertyProvider aggregate(AggregationPolicy > > mapping, MetaInfo metaInfo, PropertyProvider... providers){ > > public static PropertyProvider aggregate(PropertyProvider... > providers) > > { > > public static PropertyProvider aggregate(List<PropertyProvider> > > providers) { > > public static PropertyProvider aggregate(AggregationPolicy > > mapping, PropertyProvider... propertyMaps) { > > public static PropertyProvider aggregate(AggregationPolicy > > mapping, List<PropertyProvider> providers) { > > public static PropertyProvider mutable(PropertyProvider provider) { > > public static PropertyProvider intersected(AggregationPolicy > > aggregationPolicy, PropertyProvider... providers) { > > public static PropertyProvider intersected(PropertyProvider... > providers) > > { > > public static PropertyProvider subtracted(PropertyProvider target, > > PropertyProvider... providers) { > > public static PropertyProvider filtered(Predicate<String> filter, > > PropertyProvider provider) { > > public static PropertyProvider > > contextual(Supplier<PropertyProvider> mapSupplier, > > Supplier<String> > > isolationKeySupplier) { > > public static PropertyProvider delegating(PropertyProvider > > mainMap, Map<String, String> parentMap) { > > public static PropertyProvider replacing(PropertyProvider mainMap, > > Map<String, String> replacementMap) { > > } > > >