Return-Path: X-Original-To: apmail-tamaya-commits-archive@minotaur.apache.org Delivered-To: apmail-tamaya-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 8E30F19308 for ; Thu, 17 Mar 2016 00:28:51 +0000 (UTC) Received: (qmail 39507 invoked by uid 500); 17 Mar 2016 00:28:51 -0000 Delivered-To: apmail-tamaya-commits-archive@tamaya.apache.org Received: (qmail 39478 invoked by uid 500); 17 Mar 2016 00:28:51 -0000 Mailing-List: contact commits-help@tamaya.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@tamaya.incubator.apache.org Delivered-To: mailing list commits@tamaya.incubator.apache.org Received: (qmail 39469 invoked by uid 99); 17 Mar 2016 00:28:51 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd4-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 17 Mar 2016 00:28:51 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd4-us-west.apache.org (ASF Mail Server at spamd4-us-west.apache.org) with ESMTP id CEED9C0599 for ; Thu, 17 Mar 2016 00:28:50 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd4-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -3.221 X-Spam-Level: X-Spam-Status: No, score=-3.221 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-0.001] autolearn=disabled Received: from mx2-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd4-us-west.apache.org [10.40.0.11]) (amavisd-new, port 10024) with ESMTP id kyctrIVcTUtd for ; Thu, 17 Mar 2016 00:28:37 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx2-lw-eu.apache.org (ASF Mail Server at mx2-lw-eu.apache.org) with SMTP id E69F95FBA5 for ; Thu, 17 Mar 2016 00:28:33 +0000 (UTC) Received: (qmail 36712 invoked by uid 99); 17 Mar 2016 00:28:33 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 17 Mar 2016 00:28:33 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id DEAABDFA41; Thu, 17 Mar 2016 00:28:32 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: anatole@apache.org To: commits@tamaya.incubator.apache.org Date: Thu, 17 Mar 2016 00:28:35 -0000 Message-Id: <4c2d2f57cb5c44ddb1f071e7a58bc054@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [04/11] incubator-tamaya git commit: Moved documentation to site part. Moved documentation to site part. Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/078d93b4 Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/078d93b4 Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/078d93b4 Branch: refs/heads/master Commit: 078d93b49cabe4f62a62817d36d7f73a576d0517 Parents: b4c7ed2 Author: anatole Authored: Wed Mar 16 21:48:08 2016 +0100 Committer: anatole Committed: Wed Mar 16 21:48:08 2016 +0100 ---------------------------------------------------------------------- src/site/asciidoc/images/CoreDesign.png | Bin 0 -> 43759 bytes .../asciidoc/misc/PossibleContributions.adoc | 265 ++++++++ src/site/asciidoc/userguide/API.adoc | 659 +++++++++++++++++++ src/site/asciidoc/userguide/Core.adoc | 248 +++++++ .../asciidoc/userguide/HighLevelDesign.adoc | 209 ++++++ src/site/asciidoc/userguide/Requirements.adoc | 267 ++++++++ src/site/asciidoc/userguide/examples.adoc | 82 +++ src/site/asciidoc/userguide/index.adoc | 44 ++ .../asciidoc/userguide/uc/combine-configs.adoc | 14 + .../uc/context-dependent-configuration.adoc | 7 + .../userguide/uc/dynamic-provisioning.adoc | 18 + .../userguide/uc/external-configuration.adoc | 6 + src/site/asciidoc/userguide/uc/formats.adoc | 8 + src/site/asciidoc/userguide/uc/injection.adoc | 31 + src/site/asciidoc/userguide/uc/java8.adoc | 14 + src/site/asciidoc/userguide/uc/locations.adoc | 10 + src/site/asciidoc/userguide/uc/management.adoc | 7 + .../userguide/uc/minimal-propertysource.adoc | 6 + .../userguide/uc/multiple-configurations.adoc | 14 + .../userguide/uc/scannable-properties.adoc | 4 + .../asciidoc/userguide/uc/service-context.adoc | 15 + .../asciidoc/userguide/uc/simple-access.adoc | 25 + .../userguide/uc/simple-property-access.adoc | 9 + src/site/asciidoc/userguide/uc/templates.adoc | 12 + .../userguide/uc/type-safe-properties.adoc | 10 + .../userguide/uc/value-placeholders.adoc | 8 + src/site/asciidoc/userguide/usecases.adoc | 58 ++ 27 files changed, 2050 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/078d93b4/src/site/asciidoc/images/CoreDesign.png ---------------------------------------------------------------------- diff --git a/src/site/asciidoc/images/CoreDesign.png b/src/site/asciidoc/images/CoreDesign.png new file mode 100644 index 0000000..a84d8a6 Binary files /dev/null and b/src/site/asciidoc/images/CoreDesign.png differ http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/078d93b4/src/site/asciidoc/misc/PossibleContributions.adoc ---------------------------------------------------------------------- diff --git a/src/site/asciidoc/misc/PossibleContributions.adoc b/src/site/asciidoc/misc/PossibleContributions.adoc new file mode 100644 index 0000000..095a276 --- /dev/null +++ b/src/site/asciidoc/misc/PossibleContributions.adoc @@ -0,0 +1,265 @@ +Apache Tamaya - Possible Tasks +============================== +:name: Tamaya +:rootpackage: org.apache.tamaya +:title: Apache Tamaya +:revnumber: 0.1-SNAPSHOT +:revremark: Draft +:revdate: October 2014 +:longversion: {revnumber} ({revremark}) {revdate} +:authorinitials: ATR +:author: Anatole Tresch +:email: +:source-highlighter: coderay +:website: http://tamaya.apache.org/ +:toc: +:toc-placement: manual +:encoding: UTF-8 +:numbered: + +''' + +<<< + +-> add image : : https://raw.githubusercontent.com/JavaConfig/config-api/master/src/main/asciidoc/images/javaconfig.jpg[] + +toc::[] + +<<< +:numbered!: +----------------------------------------------------------- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +----------------------------------------------------------- + +:numbered: + +<<< + +== Introduction + +== What is Tamaya + +{name} is the Apache standard for flexible and powerful configuration. Objective is to provide flavors for +Java SE, ME as well as to ship with powerful features for Java EE and Cloud Solutions. All functions provided +is build on top of a small but very powerful, flexible and extendible API. This API is implemented by a core implementation, +which then can be extended or adapted for use in different runtime scenarios, such as SE, ME, EE, Spring, OSGI +and more. Similarly additional modules may be provided that help also existing solution to be plugged into +{name}, so you can start right away using {name} without having to rebuild/change your existing application. + + +=== Purpose of this Document + +The document should help to organize people and ideas around the Apache Tamaya Library. It list possible features, +ideas and tasks that need to be done. Everybody can have a look at and see, where hos contribution and capabilities +would fit best. + + +== Main Features + +=== Metadata Model + +Currently +MetaInfo+ models metadata as a separate constuct. It has been shown that this leads to more complex +handling when creating composites and makes the API overall more complex. The idea is to model metadata as simple +key/value pairs, that are part of the provider/configuration data as well, but handled separately. Metadata hereby +is identified by a starting '_' character in its key. For example refer to the following configuration properties: + +[source,listing] +.Basic Properties +---------------------------------------------------------------- +a.b.Foo=foo +a.b.Bar=bar +a.AnyOther=whatelse +Something=none +---------------------------------------------------------------- + +Now we can model meta-data as follows: + +[source,listing] +.Metadata Properties +---------------------------------------------------------------- +[a.b].info=An area info +[a.b.Foo].auth=role1,role2 +[a.b.Foo].encrypt=PGP +[a.b.Foo].sensitive=true +[].info=This is a test configuration example. +---------------------------------------------------------------- + +The above would model the following: + +* The area +a.b+ has the meta property +info+. +* The entry +a.b.Foo+ has three meta properties +auth,encrypt+ and +sensitive+. These could be interpreted by a security + view and used to encrypt the values returned by the configuration instance, if not the current user has one of the + specified roles. +* The last meta data defines an attribute +info+ for the whole provider/configuration (the root area). + +Given that the overall entries would be as follows: + +[source,listing] +.Full Properties with Meta Properties +---------------------------------------------------------------- +[a.b].info=An area info +a.b.Foo=foo +[a.b.Foo].auth=role1,role2 +[a.b.Foo].encrypt=PGP +[a.b.Foo].sensitive=true +a.b.Bar=bar +[].info=This is a test configuration example. +a.AnyOther=whatelse +Something=none +---------------------------------------------------------------- + +The current +MetaInfo+ class could be adapted, so it is reading data from the underlying configuration/provider, +instead of its own datastructure. This would make a later mapping of configuration and its metadata into DB table, JSON +etc, much more easier. +The providers on the other side may suppress any metadata from ordinary output, such +as +toString()+, Similarly accessing metadata using the official config API (+get, getOrDefault, getAreas+ etc) +should be disabled. The +MetaInfoBuilder+ must probably as well adapted or redesigned. + + + +=== Management Client + +A nice web-based client to manage configuration data would be nice as well. This also includes a UI for creating new +configurations. + +=== Mapping Configuration to a Database + +A flexible mechanism should be implemented that allows the use of databases (SQL/JPA as well as non-SQL) for +storing/retreiving/managing configuration: + +* JPA, Hibernate +* MongoDB +* ... + + +=== Integration with Jigsaw + +Once Jigsaw is mature and in a usable (still early) stage, examples are to be created and tested, where OSGI is used as +the basic runtime platform, e.g. Apache Felix, but as well others. + +== Distributed/Remote Configuration Support + +=== Configuration Distribution Policies + +Different configuration distribution policies should be defined any implemented, e.g. distributed cache, restful services, +web services, EJB/RMI calls, asynchronous queues, publish/subsribe models, ... + + +=== Preferences Support + +Write a +PreferencesFactory+ for +java.util.preferences+. + + +== Third Party Integration + +=== Integration with Deltaspike Config + +Integration with Deltaspike Config should be implemented and discussed with Deltaspike guys. + +=== Integration with Spring + +A {name} module should be created that allows Spring to be used either as client or configuration provider. + +=== Integration with Jetty + +A {name} module should be created that allows a Jetty instance to be deployed and started that is (completely) +configured based on configuration server. + +=== Integration with Tomcat + +A {name} module should be created that allows a Tomcat instance to be deployed and started that is (completely) +configured based on configuration server. + +=== Configuration of Java EE + +In the Java EE area there would be several options: + +=== Configuration of Application Servers (administrative resources) + +It should be possible to start a application server instance remotely and configure all administrative resources and the +deployments based on the configuration service, server to be considered maybe + +* Wildfly +* IBM +* Weblogic +* Glassfish +* Apache Geronimo + +==== Configuration of Bean Validation + +* Add configurable validators. +* Configure bean validation based on configuration +* ... + +=== JNDI Support + +Write a +JCA+ adapter to provide configuration data through JNDI. + +==== Configure JSF + +Use the JSF +XML Document+ event to completely configure JSF. + +==== Configure Web Services + +Provide a WebServiceProviderFactory that may be configured. + +==== Configure JPA + +Provide an implementation that allows configuration of persistence units. Talk with JPA EG people to see if we can +get an SPI to hook in a stadardized way. + +==== Configure EJBs + +Provide an implementation that allows configuration of EJBs and MDBs: + +* Register beans +* Unregister/disable beans +* Intercept beans +* Support Configuration Injection (in the worst case using a standard Interceptor, provide supporting artifacts to + help developers to achive this easily). +* Talk with EE8 Umbrella EG (Bill Shanon, Linda DeMichels) on a feasible SPI for EE8, if possible join the EG. + +==== Configure ... + +Just think of any Java EE aspects that might be worth to be configured. If it can be done, e.g. by managing CDI managed +resources, it might be easy. For others it is a good idea to discuss things with our matter of experts... + +== Special Goodies + +=== Maintenance Mode Servlet Filter + +Provide a servlet filter that is capable of switching to maintenance mode, based on configuration. Similarly also a forwarding +servlet could be useful, wehere only request based on configuration are forwarded, other might be rejected or dropped +as configured. + +=== Dynamic Camel Routes + +Provides dynamic (configurable) Camel routes, e.g. usable within ServiceMix or standalone. + +=== Dynamic CXF + +Provides dynamic (configurable) CXF adapters, e.g. usable within ServiceMix or standalone. + +=== Configurable Apache MQ + +Provides an implementation for configuring Apache MQ. + +=== Dynamic ... + +Interested to see what other ideas are around. Let us know! + http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/078d93b4/src/site/asciidoc/userguide/API.adoc ---------------------------------------------------------------------- diff --git a/src/site/asciidoc/userguide/API.adoc b/src/site/asciidoc/userguide/API.adoc new file mode 100644 index 0000000..be3cc38 --- /dev/null +++ b/src/site/asciidoc/userguide/API.adoc @@ -0,0 +1,659 @@ +Apache Tamaya -- API +==================== +:name: Tamaya +:rootpackage: org.apache.tamaya +:title: Apache Tamaya +:revnumber: 0.1-SNAPSHOT +:revremark: Incubator +:revdate: January 2014 +:longversion: {revnumber} ({revremark}) {revdate} +:authorinitials: ATR +:author: Anatole Tresch +:email: +:source-highlighter: coderay +:website: http://tamaya.incubator.apache.org/ +:toc: +:toc-placement: manual +:encoding: UTF-8 +:numbered: +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +''' + +<<< + +image::http://tamaya.incubator.apache.org/resources/images/logos/logo_wood.png[] + +toc::[] + +<<< +:numbered!: +----------------------------------------------------------- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +----------------------------------------------------------- + +:numbered: + +[[CoreDesign]] +== The Tamaya Core Design +Though Tamaya is a very powerful and flexible solution there are basically only a few simple core concepts required +that build the base of all the other mechanisms. As a starting point we recommend you read the corresponding +link:CoreDesign.html[Core Design Documentation] + +[[API]] +== The Tamaya API +The API provides the artifacts as described in the link:CoreDesign.html[Core Design Documentation], which are: + +* A simple but complete SE *API* for accessing key/value based _Configuration_: + ** +Configuration+ hereby models configuration, the main interface of Tamaya. +Configuration+ provides + *** access to literal key/value pairs. + *** functional extension points (+with, query+) using a unary +ConfigOperator+ or + a function +ConfigurationQuery+. + ** +ConfigurationProvider+ provides with +getConfiguration()+ the static entry point for accessing configuration. + ** +ConfigException+ defines a runtime exception for usage by the configuration system. + ** +TypeLiteral+ provides a possibility to type safely define the target type to be returned by a registered + +PropertyProvider+. + ** +PropertyConverter+, which defines conversion of configuration values (String) into any required target type. + +* Additionally the *SPI* provides: + ** _PropertySource:_ is the the SPI for adding configuration data. A +PropertySource+ hereby + *** is designed as a minimalistic interface that be implemented by any kind of data provider (local or remote) + *** provides single access for key/value pairs in raw format as String key/values only (+getPropertyValue+). + *** can optionally support scanning of its provided values, implementing +getProperties()+. + ** _PropertySourceProvider:_ allows to register multiple property sources dynamically, e.g. all config files found in + file system folder.. + ** +ConfigurationProviderSpi+ defines the SPI that is used as a backing bean for the +ConfigurationProvider+ + singleton. + ** +PropertyFilter+, which allows filtering of property values prior getting returned to the caller. + ** +ConfigurationContext+, which provides the container that contains the property sources and filters that form a + configuration. + ** +PropertyValueCombinationPolicy+ optionally can be registered to change the way how different key/value + pairs are combined to build up the final +Configuration+ passed over to the filters registered. + ** +ServiceContext+, which provides access to the components loaded, depending on the current runtime stack. + ** +ServiceContextManager+ provides static access to the +ServiceContext+ loaded. + +This is also reflected in the main packages of the API: + +* +org.apache.tamaya+ contains the main API abstractions used by users. +* +org.apache.tamaya.spi+ contains the SPI interfaces to be implemented by implementations and the +ServiceContext+ + mechanism. + + + +[[APIKeyValues]] +=== Key/Value Pairs + +Basically configuration is a very generic concept. Therefore it should be modelled in a generic way. The most simple +and most commonly used approach are simple literal key/value pairs. So the core building block of {name} are key/value pairs. +You can think of a common +.properties+ file, e.g. + +[source,properties] +.A simple properties file +-------------------------------------------- +a.b.c=cVal +a.b.c.1=cVal1 +a.b.c.2=cVal2 +a=aVal +a.b=abVal +a.b2=abVal +-------------------------------------------- + +Now you can use +java.util.Properties+ to read this file and access the corresponding properties, e.g. + +[source,properties] +-------------------------------------------- +Properties props = new Properties(); +props.readProperties(...); +String val = props.getProperty("a.b.c"); +val = props.getProperty("a.b.c.1"); +... +-------------------------------------------- + + +==== Why Using Strings Only + +There are good reason to keep of non String-values as core storage representation of configuration. Mostly +there are several huge advantages: + +* Strings are simple to understand +* Strings are human readable and therefore easy to prove for correctness +* Strings can easily be used within different language, different VMs, files or network communications. +* Strings can easily be compared and manipulated +* Strings can easily be searched, indexed and cached +* It is very easy to provide Strings as configuration, which gives much flexibility for providing configuration in + production as well in testing. +* and more... + +On the other side there are also disadvantages: + +* Strings are inherently not type safe, they do not provide validation out of the box for special types, such as +numbers, dates etc. +* In many cases you want to access configuration in a typesafe way avoiding conversion to the target types explicitly + throughout your code. +* Strings are neither hierarchical nor multi-valued, so mapping hierarchical and collection structures requires some + extra efforts. + +Nevertheless most of these advantages can be mitigated easily, hereby still keeping all the benefits from above: + +* Adding type safe adapters on top of String allow to add any type easily, that can be directly mapped out of Strings. + This includes all common base types such as numbers, dates, time, but also timezones, formatting patterns and more. +* Also multi-valued, complex and collection types can be defined as a corresponding +PropertyAdapter+ knows how to + parse and create the target instance required. +* String s also can be used as references pointing to other locations and formats, where configuration is + accessible. + + +[[API Configuration]] +=== Configuration + ++Configuration+ is the main API provided by Tamaya. It allows reading of single property values or the whole +property map, but also supports type safe access: + +[source,java] +.Interface Configuration +-------------------------------------------- +public interface Configuration{ + String get(String key); + String getOrDefault(String key, String value); + T get(String key, Class type); + T getOrDefault(String key, Class type, T defaultValue); + T get(String key, TypeLiteral type); + T getOrDefault(String key, TypeLiteral type, T defaultValue); + Map getProperties(); + + // extension points + Configuration with(ConfigOperator operator); + T query(ConfigQuery query); + + ConfigurationContext getContext(); +} +-------------------------------------------- + +Hereby + +* + T get(String, Class)+ provides type safe accessors for all basic wrapper types of the JDK. +* +with, query+ provide the extension points for adding additional functionality. +* +getProperties()+ provides access to all key/values, whereas entries from non scannable property sources may not + be included. +* +getOrDefault+ allows to pass default values as needed, returned if the requested value evaluated to +null+. + +The class +TypeLiteral+ is basically similar to the same class provided with CDI: + +[source,java] +-------------------------------------------- +public class TypeLiteral implements Serializable { + + [...] + + protected TypeLiteral(Type type) { + this.type = type; + } + + protected TypeLiteral() { } + + public static TypeLiteral of(Type type){...} + public static TypeLiteral of(Class type){...} + + public final Type getType() {...} + public final Class getRawType() {...} + + public static Type getGenericInterfaceTypeParameter(Class clazz, Class interfaceType){...} + public static Type getTypeParameter(Class clazz, Class interfaceType){...} + + [...] +} +-------------------------------------------- + +Instances of +Configuration+ can be accessed from the +ConfigurationProvider+ singleton: + +[source,java] +.Accessing Configuration +-------------------------------------------- +Configuration config = ConfigurationProvider.getConfiguration(); +-------------------------------------------- + +Hereby the singleton is backed up by an instance of +ConfigurationProviderSpi+. + + +[[PropertyConverter]] +==== Property Converters + +As illustrated in the previous section, +Configuration+ also to access non String types. Nevertheless internally +all properties are strictly modelled as pure Strings only, so non String types must be derived by converting the +configured String values into the required target type. This is achieved with the help of +PropertyConverters+: + +[source,java] +-------------------------------------------- +public interface PropertyConverter{ + T convert(String value, ConversionContext context); + //X TODO Collection getSupportedFormats(); +} +-------------------------------------------- + +The +ConversionContext+ contains additional meta-information for the accessed key, inclusing the key'a name and +additional metadata. + ++PropertyConverter+ instances can be implemented and registered by default using the +ServiceLoader+. Hereby +a configuration String value is passed to all registered converters for a type in order of their annotated +@Priority+ +value. The first non-null result of a converter is then returned as the current configuration value. + +Access to converters is provided by the current +ConfigurationContext+, which is accessible from +the +ConfigurationProvider+ singleton. + + +[[ExtensionPoints]] +=== Extension Points + +We are well aware of the fact that this library will not be able to cover all kinds of use cases. Therefore +we have added functional extension mechanisms to +Configuration+ that were used in other areas of the Java eco-system +as well: + +* +with(ConfigOperator operator)+ allows to pass arbitrary unary functions that take and return instances of + +Configuration+. Operators can be used to cover use cases such as filtering, configuration views, security + interception and more. +* +query(ConfigQuery query)+ allows to apply a function returning any kind of result based on a + +Configuration+ instance. Queries are used for accessing/deriving any kind of data based on of a +Configuration+ + instance, e.g. accessing a +Set+ of root keys present. + +Both interfaces hereby are functional interfaces. Because of backward compatibility with Java 7 we did not use ++UnaryOperator+ and +Function+ from the +java.util.function+ package. Nevertheless usage is similar, so you can +use Lambdas and method references in Java 8: + +[source,java] +.Applying a +ConfigurationQuery+ using a method reference +-------------------------------------------- +ConfigSecurity securityContext = ConfigurationProvider.getConfiguration().query(ConfigSecurity::targetSecurityContext); +-------------------------------------------- + +NOTE: +ConfigSecurity+ is an arbitrary class only for demonstration purposes. + + +Operator calls basically look similar: + +[source,java] +.Applying a +ConfigurationOperator+ using a lambda expression: +-------------------------------------------- +Configuration secured = ConfigurationProvider.getConfiguration() + .with((config) -> + config.get("foo")!=null?; + FooFilter.apply(config): + config); +-------------------------------------------- + + +[[ConfigException]] +=== ConfigException + +The class +ConfigException+ models the base *runtime* exception used by the configuration system. + + +[[SPI]] +== SPI + +[[PropertySource]] +=== Interface PropertySource + +We have seen that constraining configuration aspects to simple literal key/value pairs provides us with an easy to +understand, generic, flexible, yet expendable mechanism. Looking at the Java language features a +java.util.Map+ and +java.util.Properties+ basically model these aspects out of the box. + +Though there are advantages in using these types as a model, there are some severe drawbacks, notably implementation +of these types is far not trivial and the collection API offers additional functionality not useful when aiming +for modelling simple property sources. + +To render an implementation of a custom +PropertySource+ as convenient as possible only the following methods were +identified to be necessary: + +[source,java] +-------------------------------------------- +public interface PropertySource{ + int getOrdinal(); + String getName(); + String get(String key); + boolean isScannable(); + Map getProperties(); +} +-------------------------------------------- + +Hereby + +* +get+ looks similar to the methods on +Map+. It may return +null+ in case no such entry is available. +* +getProperties+ allows to extract all property data to a +Map+. Other methods like +containsKey, + keySet+ as well as streaming operations then can be applied on the returned +Map+ instance. +* But not in all scenarios a property source may be scannable, e.g. when looking up keys is very inefficient, it + may not make sense to iterator over all keys to collect the corresponding properties. + This can be evaluated by calling +isScannable()+. If a +PropertySource+ is defined as non scannable accesses to + +getProperties()+ may not return all key/value pairs that would be available when accessed directly using the + +String get(String)+ method. +* +getOrdinal()+ defines the ordinal of the +PropertySource+. Property sources are managed in an ordered chain, where + property sources with higher ordinals override the ones with lower ordinals. If ordinal are the same, the natural + ordering of the fulloy qualified class names of the property source implementations are used. The reason for + not using +@Priority+ annotations is that property sources can define dynamically their ordinals, e.g. based on + a property contained with the configuration itself. +* Finally +getName()+ returns a (unique) name that identifies the +PropertySource+ within the current + +ConfigurationContext+. + +This interface can be implemented by any kind of logic. It could be a simple in memory map, a distributed configuration +provided by a data grid, a database, the JNDI tree or other resources. Or it can be a combination of multiple +property sources with additional combination/aggregation rules in place. + ++PropertySources+ are by default registered using the Java +ServiceLoader+ or the mechanism provided by the current + active +ServiceContext+. + + +[[PropertySourceProvider]] +==== Interface PropertySourceProvider + +Instances of this type can be used to register multiple instances of +PropertySource+. + +[source,java] +-------------------------------------------- +// @FunctionalInterface in Java 8 +public interface PropertySourceProvider{ + Collection getPropertySources(); +} +-------------------------------------------- + +This allows to evaluate the property sources to be read/that are available dynamically. All property sources +are read out and added to the current chain of +PropertySource+ instances within the current +ConfigurationContext+, +refer also to [[ConfigurationContext]]. + ++PropertySourceProviders+ are by default registered using the Java +ServiceLoader+ or the mechanism provided by the +current active +ServiceContext+. + + +[[PropertyFilter]] +==== Interface PropertyFilter + +Also +PropertyFilters+ can be added to a +Configuration+. They are evaluated before a +Configuration+ instance is +passed to the user. Filters can hereby used for multiple purposes, such as + +* resolving placeholders +* masking sensitive entries, such as passwords +* constraining visibility based on the current active user +* ... + ++PropertyFilters+ are by default registered using the Java +ServiceLoader+ or the mechanism provided by the current +active +ServiceContext+. Similar to property sources they are managed in an ordered filter chain, based on the +applied +@Priority+ annotations. + +A +PropertyFilter+ is defined as follows: + +[source,java] +-------------------------------------------- +// Functional Interface +public interface PropertyFilter{ + String filterProperty(String value, FilterContext context); +} +-------------------------------------------- + +Hereby: + +* returning +null+ will remove the key from the final result +* non null values are used as the current value of the key. Nevertheless for resolving multi-step dependencies + filter evaluation has to be continued as long as filters are still changing some of the values to be returned. + To prevent possible endless loops after a defined number of loops evaluation is stopped. +* +FilterContext+ provides additional metdata, inclusing the key accessed, which is useful in many use cases. + +This method is called each time a single entry is accessed, and for each property in a full properties result. + + +[[PropertyValueCombinationPolicy]] +==== Interface PropertyValueCombinationPolicy + +This interface can be implemented optional. It can be used to adapt the way how property key/value pairs are combined to +build up the final Configuration to be passed over to the +PropertyFilters+. The default implementation is just +overriding all values read before with the new value read. Nevertheless for collections and other use cases it is +often useful to have alternate combination policies in place, e.g. for combining values from previous sources with the +new value. Finally looking at the method's signature it may be surprising to find a +Map+ for the value. The basic +value hereby is defined by +currentValue.get(key)+. Nevertheless the +Map+ may also contain additional meta entries, +which may be considered by the policy implementation. + +[source,java] +-------------------------------------------- +// FunctionalInterface +public interface PropertyValueCombinationPolicy{ + + PropertyValueCombinationPolicy DEFAULT_OVERRIDING_COLLECTOR = + new PropertyValueCombinationPolicy(){ + @Override + public Map collect(Map currentValue, String key, + PropertySource propertySource) { + PropertyValue value = propertySource.get(key); + return value!=null?value.getConfigEntries():currentValue; + } + }; + + String collect(Map currentValue currentValue, String key, + PropertySource propertySource); + +} +-------------------------------------------- + + +[[ConfigurationContext]] +==== The Configuration Context + +A +Configuration+ is basically based on a so called +ConfigurationContext+, which is +accessible from +Configuration.getContext()+: + +[source,java] +.Accessing the current +ConfigurationContext+ +-------------------------------------------- +ConfigurationContext context = ConfigurationProvider.getConfiguration().getContext(); +-------------------------------------------- + +The +ConfigurationContext+ provides access to the internal building blocks that determine the final +Configuration+: + +* +PropertySources+ registered (including the PropertySources provided from +PropertySourceProvider+ instances). +* +PropertyFilters+ registered, which filter values before they are returned to the client +* +PropertyConverter+ instances that provide conversion functionality for converting String values to any other types. +* the current +PropertyValueCombinationPolicy+ that determines how property values from different PropertySources are + combined to the final property value returned to the client. + + +[[Mutability]] +==== Changing the current Configuration Context + +By default the +ConfigurationContext+ is not mutable once it is created. In many cases mutability is also not needed +or even not wanted. Nevertheless there are use cases where the current +ConfigurationContext+ (and +consequently +Configuration+) must be adapted: + +* New configuration files where detected in a folder observed by Tamaya. +* Remote configuration, e.g. stored in a database or alternate ways has been updated and the current system must + be adapted to these changes. +* The overall configuration context is manually setup by the application logic. +* Within unit testing alternate configuration setup should be setup to meet the configuration requirements of the + tests executed. + +In such cases the +ConfigurationContext+ must be mutable, meaning it must be possible: + +* to add or remove +PropertySource+ instances +* to add or remove +PropertyFilter+ instances +* to add or remove +PropertyConverter+ instances +* to redefine the current +PropertyValueCombinationPolicy+ instances. + +This can be achieved by obtaining an instance of +ConfigurationContextBuilder+. Instances of this builder can be +accessed either + +* from the current +ConfigurationContext+, hereby returning a builder instance preinitialized with the values from the + current +ConfigurationContext+ +* from the current +ConfigurationProvider+ singleton. + +[source,java] +.Accessing a +ConfigurationContextBuilder+ +-------------------------------------------- +ConfigurationContextBuilder preinitializedContextBuilder = ConfigurationProvider.getConfiguration().getContext().toBuilder(); +ConfigurationContextBuilder emptyContextBuilder = ConfigurationProvider.getConfigurationContextBuilder(); +-------------------------------------------- + +With such a builder a new +ConfigurationContext+ can be created and then applied: + +[source,java] +.Creating and applying a new +ConfigurationContext+ +-------------------------------------------- +ConfigurationContextBuilder preinitializedContextBuilder = ConfigurationProvider.getConfiguration().getContext() + .toBuilder(); +ConfigurationContext context = preinitializedContextBuilder.addPropertySources(new MyPropertySource()) + .addPropertyFilter(new MyFilter()).build(); +ConfigurationProvider.setConfigurationContext(context); +-------------------------------------------- + +Hereby +ConfigurationProvider.setConfigurationContext(context)+ can throw an +UnsupportedOperationException+. +This can be checked by calling the method +boolean ConfigurationProvider.isConfigurationContextSettable()+. + + +[[ConfigurationProviderSpi]] +==== Implementing and Managing Configuration + +One of the most important SPI in Tamaya if the +ConfigurationProviderSpi+ interface, which is backing up the ++ConfigurationProvider+ singleton. Implementing this class allows + +* to fully determine the implementation class for +Configuration+ +* to manage the current +ConfigurationContext+ in the scope and granularity required. +* to provide access to the right +Configuration/ConfigurationContext+ based on the current runtime context. +* Performing changes as set with the current +ConfigurationContextBuilder+. + + +[[ServiceContext]] +==== The ServiceContext + +The +ServiceContext+ is also a very important SPI, which allows to define how components are loaded in Tamaya. +The +ServiceContext+ hereby defines access methods to obtain components, whereas itself it is available from the ++ServiceContextManager+ singleton: + +[source,java] +.Accessing the +ServiceContext+ +-------------------------------------------- +ServiceContext serviceContext = ServiceContextManager.getServiceContext(); + +public interface ServiceContext{ + int ordinal(); + T getService(Class serviceType); + List getServices(Class serviceType); +} +-------------------------------------------- + +With the +ServiceContext+ a component can be accessed in two different ways: + +. access as as a single property. Hereby the registered instances (if multiple) are sorted by priority and then finally + the most significant instance is returned only. +. access all items given its type. This will return (by default) all instances loadedable from the current + runtime context, ordered by priority, hereby the most significant components added first. + + +## Examples +### Accessing Configuration + +_Configuration_ is obtained from the ConfigurationProvider singleton: + +[source,java] +.Accessing +Configuration+ +-------------------------------------------- +Configuration config = ConfigurationProvider.getConfiguration(); +-------------------------------------------- + +Many users in a SE context will probably only work with _Configuration_, since it offers all functionality +needed for basic configuration with a very lean memory and runtime footprint. In Java 7 access to the keys is +very similar to *Map*, whereas in Java 8 additionally usage of _Optional_ is supported: + +[source,java] +-------------------------------------------- +Configuration config = ConfigurationProvider.getConfiguration(); +String myKey = config.get("myKey"); // may return null +int myLimit = config.get("all.size.limit", int.class); +-------------------------------------------- + + +### Environment and System Properties + +By default environment and system properties are included into the _Configuration_. So we can access the current +_PROMPT_ environment variable as follows: + +[source,java] +-------------------------------------------- +String prompt = ConfigurationProvider.getConfiguration().get("PROMPT"); +-------------------------------------------- + +Similary the system properties are directly applied to the _Configuration_. So if we pass the following system +property to our JVM: + +[source,java] +-------------------------------------------- +java ... -Duse.my.system.answer=yes +-------------------------------------------- + +we can access it as follows: + +[source,java] +-------------------------------------------- +boolean useMySystem = ConfigurationProvider.getConfiguration().get("use.my.system.answer", boolean.class); +-------------------------------------------- + + +### Adding a Custom Configuration + +Adding a classpath based configuration is simply as well: just implement an according _PropertySource_. With the +_tamaya-spi-support_ module you just have to perform a few steps: + +. Define a PropertySource as follows: + +[source,java] +-------------------------------------------- + public class MyPropertySource extends PropertiesResourcePropertySource{ + + public MyPropertySource(){ + super(ClassLoader.getSystemClassLoader().getResource("META-INF/cfg/myconfig.properties"), DEFAULT_ORDINAL); + } + } +-------------------------------------------- + +Then register +MyPropertySource+ using the +ServiceLoader+ by adding the following file: + +[source,listing] +-------------------------------------------- +META-INF/services/org.apache.tamaya.spi.PropertySource +-------------------------------------------- + +...containing the following line: + +[source,listing] +-------------------------------------------- +com.mypackage.MyPropertySource +-------------------------------------------- + + +[[APIImpl]] +== API Implementation + +The API is implemented by the Tamaya _Core_module. Refer to the link:Core.html[Core documentation] for +further details. http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/078d93b4/src/site/asciidoc/userguide/Core.adoc ---------------------------------------------------------------------- diff --git a/src/site/asciidoc/userguide/Core.adoc b/src/site/asciidoc/userguide/Core.adoc new file mode 100644 index 0000000..f45356e --- /dev/null +++ b/src/site/asciidoc/userguide/Core.adoc @@ -0,0 +1,248 @@ +Apache Tamaya -- Core +===================== +:name: Tamaya +:rootpackage: org.apache.tamaya.core +:title: Apache Tamaya Core +:revnumber: 0.1.1 +:revremark: Incubator +:revdate: March 2015 +:longversion: {revnumber} ({revremark}) {revdate} +:authorinitials: ATR +:author: Anatole Tresch +:email: +:source-highlighter: coderay +:website: http://tamaya.incubator.apache.org/ +:toc: +:toc-placement: manual +:encoding: UTF-8 +:numbered: +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +''' + +<<< +image::http://tamaya.incubator.apache.org/resources/images/logos/logo_wood.png[] + +toc::[] + +<<< +:numbered!: +<<< +[[Core]] +== Tamaya Core +=== Overview + +Tamaya Core provides an implementation of the link:API.html[Tamaya Configuration API] and adds additional functionality +and building blocks for supporting SPI implementations. + +Tamaya Core contains the following artifacts: + +* Implementations of +Configuration, ConfigurationContext, ConfigurationContextBuilder+ ConfigurationProviderSpi+ +* A +java.util.ServiceLoader+ based +ServiceContext+ implementation. Hereby it implements component priorization based + on the +@Priority+ annotations. +* A PropertyConverterManager+ that loads and stores references to all the preconfigured +PropertyConverter+ instances +hereby providing type conversion for all important types. +* A simple default configuration setup using the current classpath and an optional staging variable. +* It collects all +PropertySource+ and +PropertySourceProvider+ instances registered with the +ServiceLoader+ and + registers them in the global +ConfigurationContext+ +* It provides a +ConfigurationContextBuilder+ and allows changing the current +ConfigurationContext+. + +The overall size of the library is very small. All required components are implemented and registered, so basically the +Core module is a complete configuration solution. Nevertheless it is also very minimalistic, but fortunately is flexible +enough to be extended/accommodated with additional features as needed, such as + +* placeholder and resolution mechanisms +* dynamic resource path lookup, e.g. with ant styled patterns +* configuration injection and configuration templates +* abstraction for reusable formats +* integration with other existing solutions +* configuration and configuration isolation targeting Java EE +* dynamic configuration and configuration updates +* Configuration management extensions +* remote configuration +* and more + +For details about the extension modules available and their functionality refer to the link:modules.html[extension user guide]. + + +[[CorePropertyConverters]] +=== Default PropertyConverters in Core + +As mentioned the Core module delivers several default +PropertyConverter+ instances out of the box. Find below the +listing of converters automatically registered with the Core module: + +[width="100%",frame="1",options="header",grid="all"] +|======= +|_Target Type_ |_Class Name_ |_Supported Formats_ +|java.math.BigDecimal |BigDecimalConverter |1.2345, 0xFF +|java.math.BigInteger |BigIntegerConverter |0xFF, 1234 +|java.lang.Boolean |BooleanConverter |true, false, T, F, 1 ,0 +|java.lang.Byte |ByteConverter |0xFF, MIN_VALUE, MAX_VALUE, 123 +|java.lang.Character |CharConverter |0xFF, 'a', 'H', 123 +|java.lang.Class |ClassConverter | +|java.util.Currency |CurrencyConverter |CHF, 123 +|java.lang.Double |DoubleConverter |1, 0xFF, 1.2334, NaN, NEGATIVE_INFITIY, POSITIVE_INFINITY, MIN_VALUE, MAX_VALUE +|_Enums_ |EnumConverter | +|java.lang.Float |FloatConverter |1, 0xFF, 1.2334, NaN, NEGATIVE_INFITIY, POSITIVE_INFINITY, MIN_VALUE, MAX_VALUE +|java.lang.Integer |IntegerConverter |1, 0xD3, MIN_VALUE, MAX_VALUE +|LocalDate |LocalDateConverter | +|java.lang.Long |LongConverter |1, 0xD3, MIN_VALUE, MAX_VALUE +|java.lang.Number |NumberConverter |1, 0xFF, 1.2334, NaN, NEGATIVE_INFITIY, POSITIVE_INFINITY +|java.lang.Short |ShortConverter |1, 0xD3, MIN_VALUE, MAX_VALUE +|java.net.URI |URIConverter |http://localhost:2020/testresource?api=true +|java.net.URL |URLConverter |http://localhost:2020/testresource?api=true +|ZoneId |ZoneIdConverter |Europe/Zurich +|======= + + +=== Registering PropertyConverters + +Additional +PropertyConverters+ can be implemented easily. It is recommended to register then using the +java.util.ServiceLoader+, +meaning you add a file under +META-INF/service/org.apache.tamaya.spi.PropertyConverter+ containing the fully qualified +class names of the converters to be registered (one line per each). + +Alternatively you can also use a +ConfigurationContextBuilder+ to add additional converters programmatically. + +NOTE: API Implementations can be read-only thus not allowing adding additional converters programmatically. + + +[[ComponentLoadingAndPriorization]] +=== Component Loading and Priorization + +Tamaya Core in general loads all components using the +java.util.ServiceLoader+ mechanism. This means that new components +must be registered by adding a file under +META-INF/service/+ containing the fully qualified +implementation class names of the components to be registered (one line per each). +The +ServiceLoader+ itself does not provide any functionality for overriding or ordering of components. Tamaya +core adds this functionality by the possibility to add +@Priority+ annotations to the components registered. +By default, and if no annotation is added +0+ is used as priority. Hereby higher values preceed lower values, meaning + +* if a singleton component is accessed from the current +ServiceContext+ the component with the higher value + effectively _overrides/replaces_ any component with lower values. +* if a collection of components is obtained from the +ServiceContext+ the components are ordered in order, where the + ones with higher priority are before components with lower priority. +* if priorities match Tamaya Core additionally sorts them using the simple class name. This ensures that ordering is + still defined and predictable in almost all scenarios. + + +[[RegisteringPropertySources]] +=== Registering Property Sources + +PropertySources that provide configuration properties are registered as ordinary components as described in the previous +section. Nevertheless the priority is not managed based on +@Priority+ annotations, but based on an explicit ++int getOrdinal()+ method. This allows to define the ordinal/priority of a +PropertySource+ explicitly. This is useful +due to several reasons: + +* it allows to define the ordinal as part of the configuration, thus allowing new overriding property sources being + added easily. +* it allows to define the ordinal dynamically, e.g. based on the configuration location, the time of loading or + whatever may be appropriate. + + +[[CorePropertySources]] +== Configuration Setup in Core + +Tamaya Core provides a minimal configuration setting, that allows you to configure SE +applications already easily. Basically configuration is built up by default as follows: + +. Read environment properties and add them prefixed with +env.+ +. Read all files found at +META-INF/javaconfiguration.properties+ + + +=== Overview of Registered Default Property Sources and Providers + +The Tamaya Core implementation provides a couple of default +PropertySource+ implementations, which are automatically +registered. They are all in the package +org.apache.tamaya.core.propertysource+ and ++org.apache.tamaya.core.provider+: + +[width="100%",frame="1",options="header",grid="all"] +|======= +|_Type_ |_Class Name_ |_Ordinal Used_ +|META-INF/javaconfiguration.properties |JavaConfigurationProvider |0 +|Environment Properties |EnvironmentPropertySource |300 +|System Properties |SystemPropertySource |400 +|======= + + +=== Abstract Class PropertiesFilePropertySource + +The abstract class +PropertiesFilePropertySource+ can be used for implementing a +PropertySource+ based on a +URL+ +instance that points to a +.properites+ file. It requires a +URL+ to be passed on the constructor: + +[source,java] +-------------------------------------------- +PropertiesFilePropertySource(URL url); +-------------------------------------------- + + +==== Abstract Class PropertiesPropertySource + +The abstract class +PropertiesPropertySource+ can be used for implementing a +PropertySource+ based on a +Properties+ +instance. It requires a +PropertySource+ to be passed on the constructor: + +[source,java] +-------------------------------------------- +PropertiesPropertySource(Properties properties); +-------------------------------------------- + + +==== Abstract Class BasePropertySource + +The abstract class +BasePropertySource+ can be used for implementing custom +PropertySource+ classes. It requires only +one method to implemented: + +[source,java] +.Implementing a PropertySource using BasePropertySource +-------------------------------------------- +public class MyPropertySource extends BasePropertySource{ + + public String getName(){ + // return a unique name for the property source, e.g. based on the underlying resource. This name also + // allows to access the property source later + } + + public Map getProperties(){ + // Get a map with all properties provided by this property source + // If the property source is not scannable, the map returned may be empty. + // In the ladder case the +boolean isScannale()+ must be overridden, since + // by default property sources are assumed to be scannable. + } + +} +-------------------------------------------- + +By default the ordinal of the property sources will be 1000, unless the key +tamaya.ordinal+ asdefined in ++PropertySource.TAMAYA_ORDINAL+ is present in the current +PropertySource+. Of course it is also possible to override +the inherited +protected void initializeOrdinal(final int defaultOrdinal)+, or directly +int getOrdinal()+. + + +[[CorePropertySourceProviders]] +=== Default PropertySourceProvider in Core + +With +org.apache.tamaya.core.provider.JavaConfigurationProvider+ there is also a default +PropertySourceProvider+ +present that loads all .properties files found at +META-INF/javaconfiguration.properties+. + + +[[Extensions]] +== Adding Extensions + +The Core module only implements the link:API.html[API]. Many users require/wish additional functionality from a +configuration system. Fortunately there are numerous extensions available that add further functionality. +Loading extensions hereby is trivial: you only are required to add the corresponding dependency to the classpath. + +For detailed information on the extensions available refer to the link:../extensions/index.html[extensions documentation]. http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/078d93b4/src/site/asciidoc/userguide/HighLevelDesign.adoc ---------------------------------------------------------------------- diff --git a/src/site/asciidoc/userguide/HighLevelDesign.adoc b/src/site/asciidoc/userguide/HighLevelDesign.adoc new file mode 100644 index 0000000..a0c255b --- /dev/null +++ b/src/site/asciidoc/userguide/HighLevelDesign.adoc @@ -0,0 +1,209 @@ +Apache Tamaya -- High Level Design +================================== +:name: Tamaya +:rootpackage: org.apache.tamaya +:title: Apache Tamaya +:revnumber: 0.1-SNAPSHOT +:revremark: Incubator +:revdate: January 2014 +:longversion: {revnumber} ({revremark}) {revdate} +:authorinitials: ATR +:author: Anatole Tresch +:email: +:source-highlighter: coderay +:website: http://tamaya.incubator.apache.org/ +:toc: +:toc-placement: manual +:encoding: UTF-8 +:numbered: +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +''' + +<<< + +image::http://tamaya.incubator.apache.org/resources/images/logos/logo_wood.png[] + +toc::[] + +<<< +:numbered!: +----------------------------------------------------------- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +----------------------------------------------------------- + +:numbered: + +[[Core Concepts]] +== The Tamaya Core Parts +Though Tamaya is a very powerful and flexible solution there are basically only a few simple core concepts required +that build the base of all the other mechanisms: + +The *API* (package +org.apache.tamaya+) provides + +* A simple but complete SE *API* for accessing key/value based _Configuration_: + ** +Configuration+ hereby models configuration, the main interface of Tamaya, providing key/value pairs as raw + (String-based) key/value pairs, allowing also access to typed values. + ** +ConfigurationProvider+ provides the static entry point for accessing configuration. + +The *SPI* (package +org.apache.tamaya.spi+) provides: + ** A simple minimalistic model for configuration data, called _PropertySource_. + ** Several extension points for adding additional configuration property sources or adapting the internal workings + of the overall system. + ** A +ServiceContext / ServiceContextManager+ that controls the loading of the components in Tamaya. This allows to + adapt the behaviour depending on the runtime environment in use, e.g. a Java standalone application, an OSGI + container or a Java EE application server. + +Tamaya *Modules* finally allow to add additional functionality to customize your configuration solution with the +functionality you want. E.g. modules are providing features such as + +* Configuration _injection_ +* _Dynamic placeholders_ and resolution mechanism for configuration values +* Abstractions for reusable _configuration formats_ +* Dynamic configuration updates and change events +* Support for OSGI/Java EE Classloading +* A configuration server/client +* and more... + + +== How Tamaya organizes Configuration +=== Overview + +All the mentioned artifacts are used to organize configuration in a higly flexible and extendable way. Hereby the ++PropertySource+ is the key artifact. In general Tamaya organizes Configuration as follows: + +image::CoreDesign.png[] + +Key abstraction hereby is the +ConfigurationContext+, which basically + +* an ordered chain of +PropertySource+ instances. This chain is used to evaluate raw configuration values. +* a set of +PropertyFilter+ instances that filter the raw values evaluated from the property source chain. +* a set of +PropertyConverter+ that convert String values into typed values when needed. + +In most standalone use cases only one +ConfigurationContext+ will be active at a time. But in more complex scenarios, +such as Java EE also multiple contexts could be active that are active depending on the current runtime context +(e.g. attached to the corresponding classloader(s)). These aspects are basically handled by the ++ConfigurationProvider+ and its corresponding SPIs. + +=== Loading the current _ConfigurationContext_ + +The +ConfigurationContext+ is the core of Tamaya. It manages all configuration sources and additional components +required to evaluate a concrete configuration value: + +* Tamaya loads all available +PropertySource+ instances. Hereby +PropertySource+ instances can be + ** Directly registered (using the mechanism defined by the current +ServiceContext+ implementation, by default + the Java +ServiceLoader+. + ** Provided by a registered instance of +PropertySourceProvider+. +* All loaded property sources are _ordered based on each ordinal_, returned from +PropertySource.getOrdinal()+ as + an ordered chain of PropertySources, building up the ordered chain of +PropertySource+ instances used for raw + configuration value evaluation. +* Tamaya loads all available +PropertyFilter+ instances. Hereby +PropertyFilter+ instances can be registered + by default using the Java +ServiceLoader+ API. The +PropertyFilter+ instances loaded are ordered based on the + +@Priority+ annotations found on each filter. If no priority annotation is present, +0+ is assumed. +* Tamaya loads all available +PropertyConverter+ instances. Hereby +PropertyConverter+ instances can be registered + by default using the Java +ServiceLoader+ API. The +PropertyConverter+ instances loaded are ordered based on the + +@Priority+ annotations found on each filter. If no priority annotation is present, +0+ is assumed. It is + possible to register multiple converters for the same target type. + +=== Evaluating raw property values +When evaluating a concrete configuration value for a given key, Tamaya iterates through this chain of registered +PropertySources. Hereby the final value, by default, is determined by the last non-null value returned from a ++PropertySource+. + +Since the ladder may not always be appropriate, e.g. when values should be combined instead of overridden, a +instance of +PropertyValueCombinationPolicy+ can be registered, which allows to add more detailed behaviour how values +are combined. + +Access to the complete configuration +Map+ is performing the same resolution and combination algorithm, but for all +key/value pairs available. + +=== Filtering the raw properties: +Each raw configuration value evaluated is filtered by the ordered filter chain, as long as there are any changes +applied by any of the filters called. This ensures that also transitive replacements by filters are possible. +If, after a configurable number of evaluation loops still values are changes during each loop, the filtering +process is aborted, since a non-resolvable circular filter issue is assumed. + +The output is the final configuration value as type +String+. + +=== Applying type conversion: +Finally, if the required target type, does not match +Java.lang.String+, all registered +PropertyConverter+ +instances targeting the corresponding target type are asked to convert the given (String-based) configuration +entry to the required (non String) target type. + +Hereby the first _non-null_ value returned by a +PropertyConverter+ is used as the final typed configuration value and +returned to the caller. + +=== Advanced Features +Basically the bahaviour of Tamaya can be customized using the following mechanisms. Basically configuration can be +provided using the following mechanism: + +* Registering additional (default) +PropertySource+ instances. Depending on their _ordinal value_ they + will override or extend existing configuration. +* Registering additional (default) +PropertySourceProvider+ instances.that can provide multiple +PropertySource+ + instances. + +Additionally Tamaya provides hooks for further adapting the internal workings: + +* Adapting the way how multiple entries with the same key are combined (+PropertyValueCombinationPolicy+). This + may be useful, if overriding is not the way how entries of the same key should be combined. An example, where + such an alternate scenario is useful are list entries, that combine all entries encountered to a collecting + list entry. +* Adding additional support for new target types configurable by registering additional +PropertyConverter+ + instances. This can be used for adding support for new types as well as for adding support for additional + formats. +* Complex extensions may adapt the complete +ConfigurationContext+, using the +ConfigurationContextBuilder+ and + reapply the changed instance using +ConfigurationProvider.setConfigurationContext(ConfigurationContext)+. + This is one example how to react on dynamic changes detected on configuration files read. +* Registering additional +PropertyFilter+ instances, that filter the configuration values extracted. +* Registering an alternate +ServiceContext+ to support alternate runtime containers, e.g. a CDI container. +* A combination of all above. + +Additionally instances of +ConfigOperator, ConfigQuery+ can be provided that provide additional functionality +that should not be globally visible. It is recommended to provide them from a singleton accessor, hereby hiding +the effective implementation classes. + +== Component Loading + +As mentioned the component loading of Tamaya can be adapted. By default the JDK +ServiceLoader+ API is used to determine a +ServiceContext+ implementation that should control +Tamaya's overall component loading. If not found, a default implementation is registered, which relies on the +Java +hava.util.ServiceLoader+ mechanism. This behaviour can be changed by implementing your own version +of the +ServiceContext+ interface, annotating it with a +@Priority+ annotation and registering it using the ++java.util.ServiceLoader+ mechanism. + +== Compatibility + +The Tamaya API is compatible with Java 7 and beyond. + +== Further Documentation + +Being here we recommend to have a look at the more detailed documentation of Tamaya's link:API.html[API] and +link:SPI.html[SPI], and of its current available link:modules.html[modules]. http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/078d93b4/src/site/asciidoc/userguide/Requirements.adoc ---------------------------------------------------------------------- diff --git a/src/site/asciidoc/userguide/Requirements.adoc b/src/site/asciidoc/userguide/Requirements.adoc new file mode 100644 index 0000000..a59e802 --- /dev/null +++ b/src/site/asciidoc/userguide/Requirements.adoc @@ -0,0 +1,267 @@ +Apache Tamaya -- Requirements +============================= +:name: Tamaya +:rootpackage: org.apache.tamaya +:title: Apache Tamaya Requirements +:revnumber: 1.0 +:revremark: Incubator +:revdate: March 2015 +:longversion: {revnumber} ({revremark}) {revdate} +:authorinitials: OBF +:author: Oliver B. Fischer +:email: +:source-highlighter: coderay +:website: http://tamaya.incubator.apache.org/ +:toc: +:toc-placement: manual +:encoding: UTF-8 +:numbered: +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +toc::[] +<<< +[[Requirements]] +== Requirements +=== Core Configuration Requirements +==== General + +Tamaya must provide a Java SE API for accessing key/value based configuration. Hereby + +* +Configuration+ is modelled by an interface +* +Configuration+ is organized as key/value pairs, using a subset of functionality present on +Map+ as + follows: + ** access a value by key (+get+) + ** check if a value is present (+containsKey+) + ** get a set of all defined keys (+keySet+) + ** a configuration must be convertible to a +Map+, by calling +toMap()+ + ** a configuration must provide access to its meta information. +* +Configuration+ value access methods must never return null. +* The API must support undefined values. +* The API must support passing default values, to be returned if a value is undefined. +* The API must allow to throw exceptions, when a value is undefined. Customized exceptions hereby should be supported. +* Properties can be stored in the classpath, on a file or accessible by URL. +* Properties can be stored minimally in properties, xml-properties or ini-format. + + +==== Minimalistic Property Source + +For enabling easy integration of custom built configuration sources a minimalistic API/SPI must be defined, that + +* is modelled by an interface +* is a minimal subset of +Configuration+ necessary to implement a configuration. +* must be convertible to a "Configuration+. + +==== Extension Points + +For supporting more complex scenarios, +Configuration+ + +* must implement the composite pattern, meaning new +Configuration+ instances can be created by combining existing + configurations. +* must be adaptable, by creating a new configuration by applying a +UnaryOperator+ to it. +* must be queryable, by passing a +ConfigQuery+ to an +Configuration+ instance. + + +==== Type Safety + +Besides Strings +Configuration+ should also support the following types: + +* Primitive types +* Wrapper types +* All other types (by using a +PropertyAdapter+ + +Hereby type conversion should be done as follows: + +. Check if for the given target type an explicit adapter is registered, if so, use the registered adapter. +. If no adapter is present, check if the target type T has static methods called +T of(String), T getInstance(String), T valueOf(String), T from(String)+. If so +use this method to create the non value of T. +. Check if the target type has a constructor T(String). If so, try to instantiate an instance using the constructor. +. Give up, throw a IllegalArgument exception. + +=== Configuration Fomats + +By default Tamaya support the following configuration formats: + +* .properties +* .xml properties +* .ini files + +It must be possible to add additional formats by registering them with the current +ServiceContext+. + +=== Mutability + +* Configurations can be mutable, mutability can be accessed as a property. +* Configuration can be changed by collecting the changes into a +ConfigCHangeSet+ and apply this set to the + given +Configuration+ instance. +* Besides the points above, +Configuration+ is immutable. + +=== Serializability and Immutability of Configuration + +* Configuration is modelled as a service. Therefore serialization may not work. This can be mitigated by adding + a freeze feature, where the know key/value pairs are extracted into an immutable and serializable form. + +=== Configuration Combination Requirements + +At least the following composition policies must be supported: + +* override: subsequent entries override existing ones. +* aggregate-exception: key/values were added, in case of conflicts a +ConfigException+ must be thrown. +* aggregate-ignore-duplicates: similar to union, whereas duplicates are ignored (leaving the initial value loaded). +* aggregate-combine: conflicting entries were resolved by adding them both to the target configuration by + redefining partial keys. +* custom: any function determining the key/values to be kept must be possible + +When combining configuration it must also be possible to override (file/classpath) configuration by + +* system properties. +* command line arguments. + + +=== Configuration Injection + +As metnioned configuration can be injected by passing a unconfigured instance of an annotated class to the ++Configuration.configure+ static method: + +[source, java] +.Configuring a POJO +---------------------------------------------------- +MyPojo instance = new MyPojo(); +Configuration.configure(instance); +---------------------------------------------------- + +Hereby +* It must be possible to define default values to be used, if no valid value is present. +* It must be possible to define dynamic expressions, at least for default values. +* The values configured can be reinjected, if the underlying configuration changes. This should also be the case + for final classes, such as Strings. +* Reinjection should be controllable by an loading policy. +* It must be possible to evaluate multiple keys, e.g. current keys, and as a backup deprecated keys + from former application releases. +* It must be possible to evaluate multiple configurations. +* The type conversion of the properties injected must be configurable, by defining a +PropertyAdapter+. +* The value evaluated for a property (before type conversion) must be adaptable as well. +* It must be possible to observe configuration changes. + +The following annotations must be present at least: + +* *@ConfiguredProperty* defining the key of the property to be evaluated. It takes an optional value, defining the + property name. It must be possible to add multiple annotations of this kind to define an order of evaluation + of possible keys. +* *@DefaultValue* (optional) defines a default String value, to be used, when no other key is present. +* *@WithConfig* (optional) defines the name of the configuration to be used. Similar to +@ConfiguredProperty+ multiple + configuration can be defined for lookup. +* *@WithConfigOperator* allows to adapt the String value evaluated, *before* it is passed as input to injection or + type conversion. +* *@WithPropertyAdapter* allows to adapt the conversion to the required target type, hereby overriding any default + conversion in place. +* *@WithLoadPolicy* allows to define the policy for (re)injection of configured values. +* *@ObservesConfigChange* allows to annotate methods that should be called on configuration changes. +* *@DefaultAreas" allows to define a key prefix key to be used for the configured key, if no absolute key + is defined. + +=== Configuration Templates + +For type safe configuration clients should be able to define an interface and let it implement by the +configuration system based on +Configuration+ available: + +* Clients define an interface and annotate it as required (similar to above) +* The interface methods must not take any arguments +* The configuration system can be called to return such an interface implementation. +* The configuration system returns a proxy hereby providing type-safe access the values required. +* Similar to configured types also templates support multiple values and custom adapters. +* It is possible to listen on configuration changes for templates, so users of the templates + may react on configuration changes. + +The following snippet illustrates the requirements: + +[source, java] +.Type Safe Configuration Template Example +---------------------------------------------------- +public interface MyConfig { + + @ConfiguredProperty("myCurrency") + @DefaultValue("CHF") + String getCurrency(); + + @ConfiguredProperty("myCurrencyRate") + Long getCurrencyRate(); + + @ConfigChange + default configChanged(ConfigChange event){ + ... + } + +} +---------------------------------------------------- + +Templates can be accessed by calling the +Configuration.current(Class)+ method: + +[source, java] +.Accessing a type safe Configuration Template +---------------------------------------------------- +MyConfig config = Configuration.current(MyConfig.class); +---------------------------------------------------- + +[[RequirementsServer]] +=== Server Configuration Requirements + +* Ensure Configuration can be transferred over the network easily. +* Beside serializability text based formats for serialization in +XML+ and +JSON+ must be defined. +* A management API must be defined, which allows to inspect the configuration in place, e.g. using + JMX or REST services. + +[[RequirementsJavaEE]] + +Java EE leads to the following requirements: + +* Configuration must be contextual, depending on the current runtime context (e.g. boot level, ear, war, ...). +* Hereby contextual aspects can even exceed the levels described above, e.g. for SaaS scenarios. +* Resources can be unloaded, e.g. wars, ears can be restarted. +* The different contextual levels can also be used for overriding, e.g. application specific configuration +may override ear or system configuration. +* Configuration may be read from different sources (different classloaders, files, databases, remote locations). +* Configuration may be read in different formats (deployment descriptors, +ServiceLoader+ configuration, alt-DD feature, ...) +* JSF also knows the concept of stages. +* Many SPI's of Java EE require the implementation of some well defined Java interface, so it would be useful if the + configuration solution supports easy implementation of such instances. +* In general it would be useful to model the +Environment+ explicitly. +* Configuration used as preferences is writable as well. This requires mutability to be modelled in way, without the + need of synchronization. +* JNDI can be used for configuration as well. + +[[RequirementsMultitenancy]] + +Configurations made in the tenant or user layer override the default app configuration etc., so + +* It must be possible to structure Configuration in layers that can override/extend each other. +* The current environment must be capable of mapping tenant, user and other aspects, so a corresponding configuration + (or layer) can be derived. + +[[RequirementsExtensions]] +=== Extensions Requirements + +It must be possible to easily add additional functionality by implementing external functional interfaces operating +on +Configuration+. + +* +UnaryOperator+ for converting into other version of +Configuration+. +* +ConfigQuery+ extending +Function+. + +[[RequirementsNonFunctional]] +=== Non Functional Requirements +THe following non-functional requirements must be met: + +* tbd + http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/078d93b4/src/site/asciidoc/userguide/examples.adoc ---------------------------------------------------------------------- diff --git a/src/site/asciidoc/userguide/examples.adoc b/src/site/asciidoc/userguide/examples.adoc new file mode 100644 index 0000000..ab7e0de --- /dev/null +++ b/src/site/asciidoc/userguide/examples.adoc @@ -0,0 +1,82 @@ +Apache Tamaya -- Examples +========================= +:name: Tamaya +:rootpackage: org.apache.tamaya +:title: Apache Tamaya Examples +:revnumber: {tamayaVersion} +:revremark: Incubator +:revdate: March 2015 +:longversion: {revnumber} ({revremark}) {revdate} +:authorinitials: ATR +:author: Anatole Tresch +:email: +:source-highlighter: coderay +:website: http://tamaya.incubator.apache.org/ +:toc: +:toc-placement: manual +:encoding: UTF-8 +:numbered: +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +toc::[] + +== Tamaya Examples + +=== Minimal + +This example shows the basic functionality that is available when Tamaya is used without any further extensions. +It shows how configuration can be added to the classpath and how it can be accessed. + +=== Simple PropertySource + +This example shows how to write and register an additional +PropertySource+ and +PropertySourceProvider+, which is +the SPI to add your own configuration data and locations. For a more advanced example you may also have a look at +the provided default metamodels, e.g. the simple metamodel (currently in the experimental part and not shipped with +the current release). + +=== Resources + +This example shows how resources can be located using ANT-styled paths and this feature can help you to implement ++PropertySourceProvider+ instances that provide configuration for a set of files/folders at a certain (searchable) +location, as provided by the resource extension_. + +=== Resolver + +The resolver example defines a configuration file that illustrates the usage of placeholders that are resolved on +configuration access, as provided by the _resolver extension_. + +=== Injection + +The injection sample shows how to inject configuration into a created object instance, or how to instantiate a proxied +configuration template, which provides a type-safe configuration access mechanism. This functionality is provided +by the _injection extension_. Hereby neither JSR 330 nor 299 are used, so it is pure and minimal SE based +implementation. + +=== FileObserver + +This example shows how the +event extension+ can be used to automatically adapt the current configuration when +the underlying configuration data is changing, e.g. when new configuration is added to a file folder, or removed or +adapted. + +=== Builder + +This example shows how to build a +Configuration+ using a simple pure SE builder API as provided by the +_builder extension_. + +=== Remote + +THe remote example shows a simple setup where parts of the +Configuration+ are read remotedly. http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/078d93b4/src/site/asciidoc/userguide/index.adoc ---------------------------------------------------------------------- diff --git a/src/site/asciidoc/userguide/index.adoc b/src/site/asciidoc/userguide/index.adoc new file mode 100644 index 0000000..897477c --- /dev/null +++ b/src/site/asciidoc/userguide/index.adoc @@ -0,0 +1,44 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +Apache Tamaya -- User Guide +=========================== +:title: Apache Tamaya User Guide +:authorinitials: ATR +:author: Anatole Tresch +:email: +:source-highlighter: coderay +:website: http://tamaya.incubator.apache.org/ +:encoding: UTF-8 + +This user guide contains detailed documentation on Tamaya's architecture, design and core API. Also included are +references to additional project documentation such as use cases and derived requirements. + +== General Project Documentation + +* link:usecases.html[Use Cases] +* link:Requirements.html[Requirements] + +== Architecture, Design and Core API + +* link:HighLevelDesign.html[High Level Design] +* link:API.html[Core API design documentation] +* link:Core.html[Core implementation design documentation] + +== Examples + +Find link:examples.html[here] also an overview of Tamaya's example projects. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/078d93b4/src/site/asciidoc/userguide/uc/combine-configs.adoc ---------------------------------------------------------------------- diff --git a/src/site/asciidoc/userguide/uc/combine-configs.adoc b/src/site/asciidoc/userguide/uc/combine-configs.adoc new file mode 100644 index 0000000..2d83ab7 --- /dev/null +++ b/src/site/asciidoc/userguide/uc/combine-configs.adoc @@ -0,0 +1,14 @@ +=== Combine Configurations + +Users want to be able to combine different configurations to a new configuration instance. +Hereby the resulting configuration can be + +* a union of both, ignoring duplicates (and optionally log them) +* a union of both, duplicates are ignored +* a union of both, conflicts are thrown as ConfigException +* an intersection of both, containing only keys present and equal in both configurations +* an arbitrary mapping or filter, modelled by an +CombinationPolicy+, which basically can be modelled + as +BiFunction+, hereby + ** a result of +null+ will remove the key + ** any other result will use the value returned as final value of the combination. + http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/078d93b4/src/site/asciidoc/userguide/uc/context-dependent-configuration.adoc ---------------------------------------------------------------------- diff --git a/src/site/asciidoc/userguide/uc/context-dependent-configuration.adoc b/src/site/asciidoc/userguide/uc/context-dependent-configuration.adoc new file mode 100644 index 0000000..737232f --- /dev/null +++ b/src/site/asciidoc/userguide/uc/context-dependent-configuration.adoc @@ -0,0 +1,7 @@ +=== Context Dependent Configuration + +In multi tenancy setups or complex systems a hierarchical/graph model of contexts for configurations is required, or different runtime contexts are executed in parallel +within the same VN. What sounds normal for EE also may be the case for pure SE environments: + +* Users want to be able to model different layers of runtime context +* Users want to identiofy the current layer, so configuration used may be adapted. http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/078d93b4/src/site/asciidoc/userguide/uc/dynamic-provisioning.adoc ---------------------------------------------------------------------- diff --git a/src/site/asciidoc/userguide/uc/dynamic-provisioning.adoc b/src/site/asciidoc/userguide/uc/dynamic-provisioning.adoc new file mode 100644 index 0000000..1629914 --- /dev/null +++ b/src/site/asciidoc/userguide/uc/dynamic-provisioning.adoc @@ -0,0 +1,18 @@ +=== Dynamic Provisioning (UC8) + +In Cloud Computing, especially the PaaS and SaaS areas a typical use case would be that an application (or server) +is deployed, configured and started dynamically. Typically things are controlled by some "active controller components", +which are capable of + +* creating new nodes (using IaaS services) +* deploying and starting the required runtime platform , e.g. as part of a PaaS solution. +* deploying and starting the application modules. + +All these steps require some kind of configuration. As of today required files are often created on the target node +before the systems are started, using proprietary formats and mechanism. Similarly accessing the configuration in place +may require examining the file system or using again proprietary management functions. Of course, a configuration +solution should not try to solve that, but it can provide a significant bunch of functionality useful in such scenarios: + +* provide remote capabilities for configuration +* allow configuration to be updated remotely. +* allow client code to listen for configuration changes and react as needed. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/078d93b4/src/site/asciidoc/userguide/uc/external-configuration.adoc ---------------------------------------------------------------------- diff --git a/src/site/asciidoc/userguide/uc/external-configuration.adoc b/src/site/asciidoc/userguide/uc/external-configuration.adoc new file mode 100644 index 0000000..ea2e687 --- /dev/null +++ b/src/site/asciidoc/userguide/uc/external-configuration.adoc @@ -0,0 +1,6 @@ +=== External Configuration + +Users want to be able to replace, override, extend or adapt any parts or all of an existing configuration from +external sources. +This also must be the case for multi-context environments, where the context identifiers are +the only way to link to the correct remote configuration. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/078d93b4/src/site/asciidoc/userguide/uc/formats.adoc ---------------------------------------------------------------------- diff --git a/src/site/asciidoc/userguide/uc/formats.adoc b/src/site/asciidoc/userguide/uc/formats.adoc new file mode 100644 index 0000000..a5a1bf7 --- /dev/null +++ b/src/site/asciidoc/userguide/uc/formats.adoc @@ -0,0 +1,8 @@ +=== Configuration Formats + +Users want to be able to use the format they prefer. + +* properties, xml-properties and ini-format should be supported by default +* Other/custom formats should be easily addable by registering or providing the format on configuration evaluation (read). +* When possible Tamaya should figure out which format to be used and how the InputStream should be correctly + interpreted.