On Tuesday, 2 December 2014, 14:02, Anatole Tresch <anat...@apache.org> wrote:
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) {
}