Start updating documentation for Java 8. Signed-off-by: Anatole Tresch <[email protected]>
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/commit/8951b7be Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/tree/8951b7be Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/diff/8951b7be Branch: refs/heads/master Commit: 8951b7be465773792650c39482724afd1dd5893b Parents: 2feee69 Author: Anatole Tresch <[email protected]> Authored: Thu Apr 19 23:39:56 2018 +0200 Committer: Anatole Tresch <[email protected]> Committed: Sun Apr 22 18:22:08 2018 +0200 ---------------------------------------------------------------------- content/documentation-new/extensions.adoc | 65 ++ .../documentation-new/extensions/mod_camel.adoc | 132 +++ .../documentation-new/extensions/mod_cdi.adoc | 250 ++++++ .../extensions/mod_classloader_support.adoc | 79 ++ .../extensions/mod_collections.adoc | 244 ++++++ .../extensions/mod_consul.adoc | 66 ++ .../documentation-new/extensions/mod_etcd.adoc | 192 +++++ .../extensions/mod_events.adoc | 308 +++++++ .../extensions/mod_features.adoc | 87 ++ .../extensions/mod_filter.adoc | 124 +++ .../extensions/mod_formats.adoc | 290 +++++++ .../extensions/mod_functions.adoc | 110 +++ .../extensions/mod_hazelcast.adoc | 119 +++ .../extensions/mod_injection.adoc | 495 +++++++++++ .../documentation-new/extensions/mod_jndi.adoc | 68 ++ .../extensions/mod_jodatime.adoc | 80 ++ .../documentation-new/extensions/mod_json.adoc | 80 ++ .../extensions/mod_management.adoc | 97 +++ .../extensions/mod_metamodel.adoc | 632 ++++++++++++++ .../extensions/mod_microprofile.adoc | 93 +++ .../extensions/mod_mutable_config.adoc | 236 ++++++ .../extensions/mod_optional.adoc | 61 ++ .../documentation-new/extensions/mod_osgi.adoc | 814 +++++++++++++++++++ .../extensions/mod_remote.adoc | 111 +++ .../extensions/mod_resolver.adoc | 131 +++ .../extensions/mod_resources.adoc | 167 ++++ .../extensions/mod_server.adoc | 239 ++++++ .../extensions/mod_spring.adoc | 176 ++++ .../extensions/mod_usagetracker.adoc | 161 ++++ .../extensions/mod_validation.adoc | 104 +++ .../documentation-new/extensions/mod_vertx.adoc | 188 +++++ .../documentation-new/extensions/mod_yaml.adoc | 118 +++ content/documentation-new/quickstart.adoc | 224 +++++ content/documentation-new/spisupport.adoc | 63 ++ content/documentation-new/usecases.adoc | 488 +++++++++++ 35 files changed, 6892 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/8951b7be/content/documentation-new/extensions.adoc ---------------------------------------------------------------------- diff --git a/content/documentation-new/extensions.adoc b/content/documentation-new/extensions.adoc new file mode 100644 index 0000000..26b5832 --- /dev/null +++ b/content/documentation-new/extensions.adoc @@ -0,0 +1,65 @@ +:jbake-type: page +:jbake-status: published + +== Apache Tamaya: Extension Modules + +toc::[] + +=== Mature Extensions + +Mature extensions have a stable API and SPI, similar to the API and Implementations provided. + +[width="100%",frame="1",options="header",grid="all"] +|======= +|_Artifact_ |_Description_ |_Links_ +| | N/A: currently no extensions have reached that maturity level. | - +|+org.apache.tamaya.ext:tamaya-collections+ |Collections support. |link:extensions/mod_collections.html[Documentation] +|+org.apache.tamaya.ext:tamaya-events+ |Provides support for publishing configuration changes |link:extensions/mod_events.html[Documentation] +|+org.apache.tamaya.ext:tamaya-filter+ |Provides a programmatic filter for config entries. |link:extensions/mod_filter.html[Documentation] +|+org.apache.tamaya.ext:tamaya-features+ |Provides a simple feature check for loaded extensions. |link:extensions/mod_features.html[Documentation] +|+org.apache.tamaya.ext:tamaya-formats+ |Provides an abstract model for configuration formats |link:extensions/mod_formats.html[Documentation] +|+org.apache.tamaya.ext:tamaya-functions+ |Provides several functional extension points. |link:extensions/mod_functions.html[Documentation] +|+org.apache.tamaya.ext:tamaya-injection-api+ |Provides Tamaya's injection annotations API. |link:extensions/mod_injection.html[Documentation] +|+org.apache.tamaya.ext:tamaya-injection+ |Provides configuration injection services and configuration template support. |link:extensions/mod_injection.html[Documentation] +|+org.apache.tamaya.ext:tamaya-injection-cdi+ | Java EE/standalone compliant CDI integration using CDI for injection. | link:extensions/mod_cdi.html[Documentation] +|+org.apache.tamaya.ext:tamaya-jndi+ |Provides a JNDI based PropertySource. |link:extensions/mod_jndi.html[Documentation] +|+org.apache.tamaya.ext:tamaya-json+ |Provides format support for JSON based configuration. |link:extensions/mod_json.html[Documentation] +|+org.apache.tamaya.ext:tamaya-microprofile+ |Implemenation and Integration with the Microprofile API. | link:extensions/mod_microprofile.html[Documentation] +|+org.apache.tamaya.ext:tamaya-mutable-config+|Provides API/SPI for writing configuration |link:extensions/mod_mutable_config.html[Documentation] +|+org.apache.tamaya.ext:tamaya-optional+ |Lets a Tamaya configuration to be used as an optional project extension only. |link:extensions/mod_optional.html[Documentation] +|+org.apache.tamaya.ext:tamaya-osgi+ |Integration with OSGI containers. |link:extensions/mod_osgi.html[Documentation] +|+org.apache.tamaya.ext:tamaya-resolver+ |Provides placeholder and dynamic resolution functionality for configuration values. |link:extensions/mod_resolver.html[Documentation] +|+org.apache.tamaya.ext:tamaya-resources+ |Provides ant-style resource path resolution |link:extensions/mod_resources.html[Documentation] +|+org.apache.tamaya.ext:tamaya-spring+ |Integration for Spring / Spring Boot. | link:extensions/mod_spring.html[Documentation] +|+org.apache.tamaya.ext:tamaya-yaml+ |Support for using yaml as a configuration format. |link:extensions/mod_yaml.html[Documentation] +|======= + +=== Extensions Sandbox + +Extensions in _draft state_ rather experimental or not yet very mature. API changes may occurr at any time +and the may also have severe issues or even not work at all. So use at your own risk or join and help +us getting them stable and well tested! + +NOTE: All extensions currently require Java 8. + +[width="100%",frame="1",options="header",grid="all"] +|======= +|_Artifact_ |_Description_ |_Links_ +|+org.apache.tamaya.ext:tamaya-camel_beta+ |Integration with Apache Camel. | link:extensions/mod_camel.html[Documentation] +|+org.apache.tamaya.ext:tamaya-classloader-support+ |Configuration services considering classloaderas. |link:extensions/mod_classloader_support.html[Documentation] +|+org.apache.tamaya.ext:tamaya-commons_beta+ |Integration Support for Apache Commons. | - +|+org.apache.tamaya.ext:tamaya-configured-sysprops_beta+ | Tamaya configuration to be provided as +System.getProperties()+. | link:extensions/mod_sysprops.html[Documentation] +|+org.apache.tamaya.ext:tamaya-consul_beta+ |Integration with consul clusters. | link:extensions/mod_consul.html[Documentation] +|+org.apache.tamaya.ext:tamaya-etcd_beta+ |Integration with etcd clusters. | link:extensions/mod_etcd.html[Documentation] +|+org.apache.tamaya.ext:tamaya-hazelcast_beta+ |Integration with Hazelcast datagrids. | link:extensions/mod_hazelcast.html[Documentation] +|+org.apache.tamaya.ext:tamaya-jodatime_beta+ |Provides support for JodaTime. | link:extensions/mod_jodatime.html[Documentation] +|+org.apache.tamaya.ext:tamaya-management_alpha+ |Provides JMX support for inspecting configuration. |link:extensions/mod_management.html[Documentation] +|+org.apache.tamaya.ext:tamaya-metamodel_alpha+ |Provides an XML API for building configuration. |link:extensions/mod_metamodel-staged.html[Documentation] +|+org.apache.tamaya.ext:tamaya-remote_alpha+ |Remote configuration support using the server API. |link:extensions/mod_remote.html[Documentation] +|+org.apache.tamaya.ext:tamaya-server_alpha+ |Publishes configuration as a REST service. |link:extensions/mod_server.html[Documentation] +|+org.apache.tamaya.ext:tamaya-ui_alpha+ |Provides a web UI for a VM running Tamaya. |link:extensions/mod_ui.html[Documentation] +|+org.apache.tamaya.ext:tamaya-uom_beta+ |Provides additional converters based on the Units of Measurement JSR. |link:extensions/mod_uom.html[Documentation] +|+org.apache.tamaya.ext:tamaya-usagetracker_beta+ |Allows tracking of configuration usage. |link:extensions/mod_usagetracker.html[Documentation] +|+org.apache.tamaya.ext:tamaya-validation-alpha+ |Provides an XML API for validating configuration. |link:extensions/mod_validation.html[Documentation] +|+org.apache.tamaya.ext:tamaya-vertx-alpha+ |Provides Vertx integration. |link:extensions/mod_vertx.html[Documentation] +|======= http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/8951b7be/content/documentation-new/extensions/mod_camel.adoc ---------------------------------------------------------------------- diff --git a/content/documentation-new/extensions/mod_camel.adoc b/content/documentation-new/extensions/mod_camel.adoc new file mode 100644 index 0000000..828a8d2 --- /dev/null +++ b/content/documentation-new/extensions/mod_camel.adoc @@ -0,0 +1,132 @@ +:jbake-type: page +:jbake-status: published + += Apache Tamaya - Extension: Integration with Apache Camel + +toc::[] + + +[[Camel]] +== Integration with Apache Camel (Extension Module) + +Tamaya _Camel_ is an extension module. Refer to the link:../extensions.html[extensions documentation] for further details. + +=== What functionality this module provides ? + +The Tamaya _Camel_ module provides different artifacts which allows integration of Apachae Tamaya +configuration with Apache Camel. + + +=== Compatibility + +The module is based on Java 7, so it will not run on Java 7 and beyond. + + +=== Installation + +To benefit from configuration builder support you only must add the corresponding dependency to your module: + +[source, xml] +----------------------------------------------- +<dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-camel</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + + +=== The Functionality Provided + +Tamaya Camel comes basically with three artifacts: + +* A Camel +ResolverFunction+ implementation adding explicit property resolution + (+org.apache.tamaya.camel.TamayaPropertyResolver+). +* A Camel +PropertiesComponent+ implementation, which allows implicitly preconfigures the resolvers from above and + additionally allows using Tamaya configuration as Camel _overrides_ + (+org.apache.tamaya.camel.TamayaPropertiesComponent+). + + +=== Configuring using Camel Java DSL + +Camel integration using Java DSL is basically simple: + +[source, java] +----------------------------------------------- +import org.apache.tamaya.camel.TamayaPropertiesComponent; + +camelContext.addComponent("properties", new TamayaPropertiesComponent()); +----------------------------------------------- + +Given so you can then use +cfg+ or +tamaya+ as prefix for resolving entries with Tamaya as follows: + +[source, java] +----------------------------------------------- +RouteBuilder builder = new RouteBuilder() { + public void configure() { + from("direct:hello1").transform().simple("{{cfg:message}}"); + } +}; +camelContext.addRoutes(builder); +builder = new RouteBuilder() { + public void configure() { + from("direct:hello2").transform().simple("{{tamaya:message}}"); + } +}; +camelContext.addRoutes(builder); +----------------------------------------------- + + +Optionally you can also configure +TamayaPropertiesComponent+ that all currently known Tamaya properties are used +as Camel overrides, meaning they are evaluated prior to all other available resolver functions in the Camel ++PropertiesComponent+: + +[source, java] +----------------------------------------------- +TamayaPropertiesComponent props = new TamayaPropertiesComponent(); +props.setTamayaOverrides(true); +----------------------------------------------- + + +=== Configuring using Camel XML DSL + +Camel integration using XML DSL is basically very similar. You just have to add the +properties+ component as bean +as well. All other configuration parameters (e.g. file URIs are similar supported). In the example code below we +again use Tamaya as the main configuration solutions only using Camel's default behaviour as a fallback: + +[source, xml] +----------------------------------------------- +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd + "> + + <routeContext id="myCoolRoutes" xmlns="http://camel.apache.org/schema/spring"> + <route id="r1"> + <from uri="direct:hello1"/> + <transform> + <simple>{{message}}</simple> + </transform> + </route> + <route id="r2"> + <from uri="direct:hello2"/> + <transform> + <simple>{{cfg:message}}</simple> + </transform> + </route> + <route id="r3"> + <from uri="direct:hello3"/> + <transform> + <simple>{{tamaya:message}}</simple> + </transform> + </route> + </routeContext> + + <bean id="properties" class="org.apache.tamaya.camel.TamayaPropertiesComponent"> + <property name="tamayaOverrides" value="true"/> + </bean> + +</beans> +----------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/8951b7be/content/documentation-new/extensions/mod_cdi.adoc ---------------------------------------------------------------------- diff --git a/content/documentation-new/extensions/mod_cdi.adoc b/content/documentation-new/extensions/mod_cdi.adoc new file mode 100644 index 0000000..41e1fb4 --- /dev/null +++ b/content/documentation-new/extensions/mod_cdi.adoc @@ -0,0 +1,250 @@ +:jbake-type: page +:jbake-status: published + += Apache Tamaya - Extension: CDI Support + +toc::[] + + +[[CDI]] +== Tamaya CDI Integration (Extension Modules) + +Tamaya _CDI_ is an extension module. Refer to the link:../extensions.html[extensions documentation] for further details. + + +=== What functionality this module provides ? + +Apache _CDI_ provides integration with CDI: + +* Loading of CDI managed SPI components as configuration extensions such as +PropertySources, PropertySourceProviders, + PropertyFilters, etc+. This also includes SPI defined by any Tamaya submodules. + This is useful when Tamaya is used as an application module managed by the CDI implementation. +* Implement and enable Tamaya's configuration injection services (either using CDI injection or + Tamaya's standalone injection module. + +Hereby there are two implementations provided: + +* +tamaya-injection-cdi+ implements injection by using CDI's injection mechanism to inject configuration values into the + beans managed by the CDI systems. +* +tamaya-injection-standalone+ implements injection by integrating the +tamaya-injection+ SE based injection module (also used + for Spring and OSGI injection) with CDI. Injection hereby is performed by the Tamaya SE module, whereas + beans and injection control overall are still managed by CDI. +* One difference, of course, is that +tamaya-injection-standalone+ also provides an SE compatible API (+ConfigurationInjection, + ConfigurationInjector+), which is not available, when using the purely CDI based variant. + +The annotations used for all injection functionality in Tamaya is defined as a separate module. This allows you to +code against the injection API without dependency on the concrete injection implementation. As a consequence your +components will be compatible regardless if deployed in a pure SE or as Java EE (CDI) or Spring environment: + +----------------------------------------------- +<dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-injection-api</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + + +=== Compatibility + +All modules are based on Java 7, so they will not run on Java 7 and beyond. + + +=== Installation + +To benefit from Tamaya CDI integration you only must one of the following dependencies to your module. Ensure that +you never have installed both CDI extensions at the same time because this may be lead to unforseen side-effects. + +.CDI Java EE Application Configuration +[source, xml] +----------------------------------------------- +<dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-cdi</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + +.To use Tamaya's _standalone injection support_, you additionally should add the +following dependency. If this dependency is missing injection is purely based on +CDI injection features. + +[source, xml] +----------------------------------------------- +<dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-injection-standalone</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + +Both components will auto-register its components and override the default +ServicceContext+ in use. Additionally they +register CDI extensions that implement Configuration injection as described before. + +For working with a pure non Java EE environment have a look at the link:mod_injection-standalone.html[tamaya-injection-standalone module]. + +Additionally you have to register Tamaya's CDI extension modules into your `beans-xml`: + +Contents of `META-INF/services/javax.enterprise.inject.spi.Extension`: +[source, properties] +----------------------------------------------- +# Register Tamaya to perform injection +# org.apache.tamaya.cdi.TamayaCDIInjectionExtension +# org.apache.tamaya.cdi.TamayaSEInjectionExtension +org.apache.tamaya.cdi.TamayaCDIAccessor +----------------------------------------------- + +If you want to use CDI standard injection (using +@Inject @Config+), activate ++org.apache.tamaya.cdi.TamayaCDIInjectionExtension+ as a CDI extension. + +If you want to use +SE based injection+ (using +@Config+ *without* +@Inject+), +activate +org.apache.tamaya.cdi.TamayaSEInjectionExtension+ instead of. + +Though not recommended, it is possible to activate both extension at the same time. + + +=== Annotating your Classes + +Basically annotating your classes is stright forward. +@Config+ defines an additional CDI qualifier that is, depending +on the module deployed, handled by a CDI producer (+tamaya-cdi-ee+) or the Tamaya SE injection mechanism $ +(+tamaya-cdi-se+). All types injected by this module are injected using _dependent scope_. + + +[source, java] +-------------------------------------------------------- +@RequestScoped +public class ConfiguredClass{ + + @Config + private String testProperty; + + @Config({"a.b.c.key1","a.b.c.key2","a.b.c.key3"}, + defaultValue="The current \\${JAVA_HOME} env property is ${env:JAVA_HOME}.") + String value1; + + @Config({"foo","a.b.c.key2"}) + private String value2; + + @Config + @ConfigDefault("N/A") + private String runtimeVersion; + + @Config(defdaultValue="${sys:java.version}") + private String javaVersion2; + + @Config(defaultValue="5") + private Integer int1; + + ... + +} +-------------------------------------------------------- + + + +=== Registering CDI managed components into the Application's ConfigurationContext + +As mentioned both modules allow to provide Tamaya SPI extensions modules as ordinary CDI managed beans. By default +extensions should be registered using +@Singleton+ or +@ApplicationScoped+ scope annotations. So you can define/deploy +additional application specific +PropertySources+ and other artifacts simply by defining a CDI managed bean implementing +the required SPI interface: + +[source, java] +-------------------------------------------------------- +@Singleton +public class TestPropertySource implements PropertySource{ + + final Map<String,String> config = new HashMap<>(); + + public TestPropertySource(){ + config.put("a.b.c.key1", "keys current a.b.c.key1"); + config.put("a.b.c.key2", "keys current a.b.c.key2"); + config.put("{"+getName()+"}source", getClass().getName()); + } + + @Override + public int getOrdinal() { + return 10; + } + + @Override + public String getName() { + return getClass().getName(); + } + + @Override + public String get(String key) { + return config.get(key); + } + + @Override + public Map<String, String> getProperties() { + return config; + } + + @Override + public boolean isScannable() { + return true; + } +} +-------------------------------------------------------- + +To enable this (optional) feature you must replace Tamaya's +ServiceContext+ with the +CDI aware implementation: + +Contents of `META-INF/services/org.apache.tamaya.spi.ServiceContext`: +[source, properties] +----------------------------------------------- +# Registering a CDI aware service context +CDIAwareServiceContext +----------------------------------------------- + + +=== Advanced Use Cases + +Beside basic configuration Tamaya also covers additional requirements: + +* _Reading multiple keys, where the first successful one is determining the value of the configuration, is + simply possible, by adding multiple keys to the +@Configy+ annotation. + E.g. for trying first +a.b+ and then +new.b+ you would configure it as follows: + +[source,java] +-------------------------------------------------------------------------------------- +@Config({"a.b", "new.b"} +private String value; +-------------------------------------------------------------------------------------- + +* When you must apply a +ConfigOperator+ to your config, before reading the configuration, you can + configure one as follows: + +[source,java] +-------------------------------------------------------------------------------------- +@Config({"a.b", "new.b"} +@WithConfigOperator(MyOperator.class) +private String value; +-------------------------------------------------------------------------------------- + +* When you must apply a some special conversion, or you use a type that is not registered + for conversion, you can configure a custom converter to be applied as follows: + +[source,java] +-------------------------------------------------------------------------------------- +@Config({"a.b", "new.b"} +@WithPropertyConverter(MyConverter.class) +private MySpecialFooType value; +-------------------------------------------------------------------------------------- + +* Often multiple keys in a class belong to the same root section. So instead of copying this to + every entry you can define the most common root sections in the type's header: + +[source,java] +-------------------------------------------------------------------------------------- +@ConfigDefaultSections({"aaaa", "new"}); +public class MyType{ + +@Config({"b", "[legacy.bKey]"} // lookups: "aaaa.b", "new.b", legacy.bKey +private String value; +-------------------------------------------------------------------------------------- + +In the example above +legacy.bKey+ defines an absolute key, which is not combined with any defined +default section parts. http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/8951b7be/content/documentation-new/extensions/mod_classloader_support.adoc ---------------------------------------------------------------------- diff --git a/content/documentation-new/extensions/mod_classloader_support.adoc b/content/documentation-new/extensions/mod_classloader_support.adoc new file mode 100644 index 0000000..50a3e61 --- /dev/null +++ b/content/documentation-new/extensions/mod_classloader_support.adoc @@ -0,0 +1,79 @@ +:jbake-type: page +:jbake-status: published + += Apache Tamaya - Extension: Classloader Isolation Support + +toc::[] + +[[Classloader]] +== Tamaya Classloader Aware ServiceContext (Extension Module) + +Tamaya _Classloader_ is an extension module. Refer to the link:../extensions.html[extensions documentation] for further details. + +=== What functionality this module provides ? + +The Tamaya _Classloader_ support provides an alternative implementation of +java.util.ServiceLoader+, which is aware +of classloaders, hereby preventing multiple loading of components within a classloader hierarchy. + + +=== Compatibility + +The module is based on Java 7, so it will not run on Java 7 and beyond. + + +=== Installation + +To benefit from configuration server support you only must add the corresponding dependency to your module: + +[source, xml] +----------------------------------------------- +<dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-classloader-support</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + +The component will auto.register its components and override the default +ServiceContext+ in use by default +with an instance of type +org.apache.tamaya.clsupport.internal.CLAwareServiceContext+ with a precendence value +(component priority) of +10+. + + +=== How it works + +Basically the component manages a +Map+ of all classloaders encountered. When services are accessed, the component +will evaluate the services as follows: + +* the component walks up the class loader hierarchy. +* in a next step the hierarchy is traversed down from the parent to the current classloader. Hereby it is checked + if the service list for the required type has been loaded already. If not the service configuration files are + evaluated. +* This configuration file evaluation will ignore all resources already loaded by any of the already traversed parent + classloaders. +* For each configuration file newly visible to the classloader currently traversed, the corresponding services are + loaded unleyy, the same service class already has been loaded by one its parent classloaders or another file + loaded with this classloader. +* Finally all services found are returned as the full collection of services valid for the given context (classloader). + +This ensures no service is loaded multiple times, even when it is referenced multiple times in several service +configurations. Additionally every service is loaded on the classloader where it is also declared the first time. + + +=== Control Logging + +The service component by default only logs errors. But it is possible to change this by reconfiguring the logging +levels on the following logging names/path: +org.apache.tamaya.clsupport.internal.CLAwareServiceContext+ + +* _INFO_ logs additional info on the services accessed. +* _FINEST_ logs additional info on the services scanned and selected. + + +=== Classloader Aware Configuration + +The mechanism above is used to provide a classloader aware implementation of +ConfigurationContext+ +(+org.apache.tamaya.clsupport.internal.CLAwareConfigurationContext+). Similarly to the service variants +this class provides a context implementation that manages the core configuration aspects considering classloading +hierarchies: + +* +PropertySource+, +PropertySourceProviders+ +* +PropertyFilters+, +PropertyCombinationPolicy+ http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/8951b7be/content/documentation-new/extensions/mod_collections.adoc ---------------------------------------------------------------------- diff --git a/content/documentation-new/extensions/mod_collections.adoc b/content/documentation-new/extensions/mod_collections.adoc new file mode 100644 index 0000000..49cead4 --- /dev/null +++ b/content/documentation-new/extensions/mod_collections.adoc @@ -0,0 +1,244 @@ +:jbake-type: page +:jbake-status: published + += Apache Tamaya - Extension: Collection Support + +toc::[] + +[[Collections]] +== Tamaya Collections Support (Extension Module) + +Tamaya _Collections_ is an extension module. Refer to the link:../extensions.html[extensions documentation] for further details. + + +=== What functionality this module provides ? + +All configuration in Tamaya is expressed as simple key, value pairs. Nevertheless this concept allows similarly +the modelling of collection typed values such as lists, sets, maps or simple collections of things. The Tamaya +Collections extension adds this functionality to the Tamaya eco-system. + + +=== Compatibility + +The module is based on Java 7, so it will not run on Java 7 and beyond. + + +=== Installation + +To use Tamaya collection support you only must add the corresponding dependency to your module: + +[source, xml] +----------------------------------------------- +<dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-collections</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + + +=== Overview + +Tamaya Collections adds +PropertyConverter+ implementations that are able to access configuration data +as _lists, maps_ or _sets_. By default this works out of the box as easy as accessing any other type of +configuration data, e.g. + +[source, java] +----------------------------------------------- +Configuration config = ConfigurationProvider.getConfiguration(); + +// Without any content specification, a list of String is returned. +List<String> simpleList = config.get("my.list.config.entry", List.class); + +// Using a TypeLiteral allows to use every convertible sub type supported by the system. +List<Integer> intList = config.get("my.list.config.entry", new TypeLiteral<List<Integer>>(){}); +----------------------------------------------- + +Configuration in that case, by default, is a simple comma-separated list of entries, e.g. + +[source, properties] +----------------------------------------------- +my.list.config.entry=1,34454,23,344545,3445 +----------------------------------------------- + +Additionally the module allows adding additional meta-entries, which allows to tweak some of the +inner-workings, e.g. + +* using your own +PropertyConverter+ implementation for parsing entries. +* specifying a custom separator to split the items (default is {{','}}. +* specifying a custom separator to split key/value pairs when parsing map entries. +* specifying the implementation type of the collection item to be returned. +* specifying the implementation type of the collection to be returned. + +=== Supported Types + +This module currently supports the following types: + +* +java.util.Collection+ +* +java.util.List+ +* +java.util.ArrayList+ +* +java.util.LinkedList+ +* +java.util.Set+ +* +java.util.SortedSet+ +* +java.util.TreeSet+ +* +java.util.HashSet+ +* +java.util.Map+ +* +java.util.SortedMap+ +* +java.util.HashMap+ +* +java.util.TreeMap+ + +Hereby the collection type is determined by the parameter type accessed, e.g. ++config.get("mylist", ArrayList.class)+ will always return an +ArrayList+ +as result. + +NOTE: This means that depending on your use case you can access different +collection types based on the same configuration values, as long as their is +a +PropertyConverter+ that can convert the _raw configuration value_ to the +required target type. + + +==== Configuring the target implementation type + +Tamaya Collections allows you to configure the _default_ target collection type by adding the +following meta-configuration entry (shown for the +mylist+ entry). Hereby the package part +java.util.+ +can be ommitted: + +[ source, properties] +----------------------------------------------- +mylist=a,b,c +_mylist.collection-type=LinkedList +----------------------------------------------- + +When calling +config.get("mylist", ArrayList.class)+ this parameter does not have any effect, so you will still +get an +ArrayList+ as a result. However when you call +config.get("mylist", List.class)+ you will +get a +LinkedList+ as implementation type. + +This mechanism similarly applies to all kind of collections, so you can use it similarly to define the implementation +type returned when accessing +List+, +Map+ or +Collection+. + + +=== Collecting Configuration Entries instead of Overriding + +By default Tamaya applies always an overriding +CombinationPolicy+, where only the configuration entry for +the most significant configuration entry is used. In case of collections (and maybe also other use cases), +overriding is not always the mechanism of choice. E.g. when you want to have all entries added to your +configuration to be *combined* to a new entry containing all values provided by any property sources. + +Therefore _Tamaya Collections_ also provides a more sophistiated +CombinationPolicy+ (automatically configured) +that allows to adapt the way how configuration entries are combined. All you must do is declaring +the mechanism to be applied by an according _meta-configuration_ parameter, e.g. for +my.list+ your config may +look as follows: + +[source, properties] +----------------------------------------------- +# from PropertSource 1 +my.list=1,2,3 + +# from PropertSource 2, with higher precedence +my.list=4,5,6 + +# without any additional meta-info these entries would be combined to +my.list=4,5,6 +----------------------------------------------- + +With Tamaya Collections you can now configure the combination policy as follows: + +[source, properties] +----------------------------------------------- +# use one of the default policies: override / collect +_my.list.combination-policy=collect + +# or use your own custom CombinationPolicy to combine the values +_my.list.combination-policy=com.mycomp.app.MyCombincationPolicy +----------------------------------------------- + +So declaring the +collect+ policy the resulting raw output of the entry looks as follows: + +[source, properties] +----------------------------------------------- +# result when applying the collect policy: +my.list=1,2,3,4,5,6 +----------------------------------------------- + +The customizable policy mechanism of Tamaya Collections also honors the +item-separator+ meta-configuration +parameter explained later in this document. + + +=== Format of Collection Configuration + +By default collections are modelled as simple String values, that are tokenized into individual parts using a +defined +item-separator+ (by default +','+). So a given configuration entry of +1,2,3+ is mapped to +"1","2","3". +If the target context type is something different than String the smae conversion logic is used as when mapping +configuration parameters directly to non-String target types (implemented as +PropertyConverter+ classes, manahed +within the current +ConfigurationContext+. The procedure is identical for all collection types, including +Map+ types, +with the difference that each token in the list is parsed once more for separating it into a +key+ and a +value+. +The default separator for map entries hereby is +"::"+. Map keys, as of now, are always of type +String+, whereas +for values the same logic is applied as for non-map collection types. + +[source, properties] +----------------------------------------------- +# a list, using the default format +list=1,2,3,4,5,6 + +# a map, using the default format +map=a::b, c::d +----------------------------------------------- + + +==== Trimming of entries + +By default all tokens parsed are trimmed _before_ adding them to the final collection. In case of map entries this is +also the case for key/value entries. So the following configuration results in the identical values for ++list1,list2+ and +map1,map2+: + +[source, properties] +----------------------------------------------- +# a list, using the default format +list1=1,2,3,4,5,6 +list2=1, 2, 3, 4, 5, 6 + +# a map, using the default format +map1=a::b, c::d +map2=a :: b, c :: d +----------------------------------------------- + +Nevertheless truncation can be controlled by the usage of brackets, e.g. the last list or map entry will have a single +space character as value: + +[source, properties] +----------------------------------------------- +# a list, with a ' ' value at the end +list3=1, 2, 3, 4, 5, [ ] + +# a map, with a ' ' value for key '0' +map3=1 :: a, 2 :: b, 0::[ ] +----------------------------------------------- + +Hereby +\[+ escapes the sequence. + + +==== Customizing the format + +The item and entry separators (by default +','+ and +"::"+) can be customized by setting corresponding meta-data +entries as follows, resulting in the same values as in the prevoius listing: + +[source, properties] +----------------------------------------------- +# a list, with a ' ' value at the end +list3=1__2__3__ 4__ 5__[ ] +_list3.item-separator=__ + +# a map, with a ' ' value for key '0' +map3=1->a, 2->b, 0->[ ] +_map3.map-entry-separator=-> +----------------------------------------------- + +Of course these settings also can be combined: + +[source, properties] +----------------------------------------------- +# a reformatted map +redefined-map=0==none | 1==single | 2==any +_redefined-map.map-entry-separator=== +_redefined-map.item-separator=| +----------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/8951b7be/content/documentation-new/extensions/mod_consul.adoc ---------------------------------------------------------------------- diff --git a/content/documentation-new/extensions/mod_consul.adoc b/content/documentation-new/extensions/mod_consul.adoc new file mode 100644 index 0000000..8a988a5 --- /dev/null +++ b/content/documentation-new/extensions/mod_consul.adoc @@ -0,0 +1,66 @@ +:jbake-type: page +:jbake-status: published + += Apache Tamaya - Extension: Integration with consul (Hashicorp) + +toc::[] + + +[[Consul]] +== Integration with consul (Extension Module) + +Tamaya _Consul_ is an extension module. Refer to the link:../extensions.html[extensions documentation] for further details. + +=== What functionality this module provides ? + +Tamaya _Consul_ provides different artifacts which allows use of +link:http://www.consul.io[Consul from Hashicorp] as configuration backend. Basically the +module supports read-only integration (as a +ConsulPropertySource+ as well +as a writing configuration changes back (based on Tamaya's +MutableConfiguration+ API +defined by the link:mod_mutable_config.html[tamaya-mutable-config] extension module. + + +=== Compatibility + +The module is based on Java 7, so it will not run on Java 7 and beyond. + + +=== Installation + +To use _tamaya-consul_ you only must add the corresponding dependency to your module: + +[source, xml] +----------------------------------------------- +<dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-consul</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + + +=== The Extensions Provided + +Consul integration comes basically with 2 artifacts: + +* The +org.apache.tamaya.etcd.ConsulPropertySource+ is a +PropertySource+ with a default + ordinal of 100 and the name 'consul', which is automatically registered. +* If the +tamaya-mutable-config+ module is loaded it is possible to write property values back into the consul cluster, + by accessing a +MutableConfiguration+ using the URI +config:consul+. + +Access of consul key/value pairs is through the normal Tamaya API. + + +=== The ConsulPropertySource + +The +ConsulPropertySource+ is automatically registered and allows the consul servers to be used to be configured. This +enables to use e.g. in Docker environments the docker environment configuration mechanisms to configure Tamaya running +in microservice containers to connect with the according consul cluster: + +* The property source reads the +tamaya.consul.urls+ system and environment property to evaluate possible consul servers + (comma separated), which can be connected to. On failure the API just performs a Round-Robin through the list of + configured servers. Without any configuration +http://127.0.0.1:2400+ is used. If no connection to any consul + server can be established a warning will be logged, but deployment will not fail. +* The +ConsulPropertySource+ finally also allows the values read from the consul cluster to be mapped to prefixed + context. This can be activated by setting the `-Dtamaya.consul.prefix=<PREFIX>` system property. E.g. when the prefix is + set to `cluster-config.` a consul key of `host:known/all` is mapped to `cluster-config.host:known/all`. http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/8951b7be/content/documentation-new/extensions/mod_etcd.adoc ---------------------------------------------------------------------- diff --git a/content/documentation-new/extensions/mod_etcd.adoc b/content/documentation-new/extensions/mod_etcd.adoc new file mode 100644 index 0000000..3003a09 --- /dev/null +++ b/content/documentation-new/extensions/mod_etcd.adoc @@ -0,0 +1,192 @@ +:jbake-type: page +:jbake-status: published + += Apache Tamaya - Extension: Integration with etcd (Core OS) + +toc::[] + + +[[Etcd]] +== Integration with etcd (Extension Module) +Tamaya _Etcd_ is an extension module. Refer to the link:../extensions.html[extensions documentation] for further details. + +=== What functionality this module provides ? + +Tamaya _Etcd_ provides different artifacts which allows using link:https://github.com/coreos/etcd[etcd] as a +configuration backend. Basically the module adds a read-only property source (+EtcdPropertySource+). If +the _tamaya-mutable-config_ extension is loaded it is alos possible to write configuration +changes to _etcd_ using +MutableConfiguration+. + + +=== Compatibility + +The module is based on Java 7, so it will not run on Java 7 and beyond. + + +=== Installation + +To use _etcd_ as a configuration backend you only must add the corresponding dependency to +your module: + +[source, xml] +----------------------------------------------- +<dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-etcd</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + + +=== The Extensions Provided + +Tamaya's _etcd_ integration provides basically the following artifacts: + +* The +org.apache.tamaya.etcd.EtcdAccessor+ can be configured with a an url targeting an etcd server's REST endpoint + root. The accessor basically provides a simple Java API for communicating with the _etcd_ server. The + accessor hereby allows reading of single properties, or whole subtrees. Also the basic non + atomic write methods are implemented. +* The +org.apache.tamaya.etcd.EtcdPropertySource+ is a +PropertySource+ with a default ordinal of 100 and the name + 'etcd', which is automatically registered. +* If the +tamaya-mutable-config+ module is loaded it is possible to write property values back into the etcd cluster, + by accessing a +MutableConfiguration+ using the URI +config:etcd+. + +=== The EtcdAccessor + +The accessor implements the basic read and write API for communicating with an _etcd_ server. +Hereby the accessor also provides _etcd_ specific data such as +createdIndex, modifiedIndex, ttl+ in the +Map+ +returned. Hereby the concept of _etcd_ is used where keys starting with an '_' represent meta-configuration +that will be hidden from the overall properties map, being only directly/explicitly accessible: + +[source, java] +----------------------------------------------- +public class EtcdAccessor { + + /** + * Creates a new instance with the basic access url. + * @param server server url, e.g. {@code http://127.0.0.1:4001}. + * @throws MalformedURLException + */ + public EtcdAccessor(String server) throws MalformedURLException; + + /** + * Get the etcd server version. + * @return the etcd server version, never null. + */ + public String getVersion(); + + /** + * Ask etcd for s aingle key, value pair. Hereby the response returned from etcd: + * <pre> + * key=value + * _key.source=[etcd]http://127.0.0.1:4001 + * _key.createdIndex=12 + * _key.modifiedIndex=34 // optional + * _key.ttl=300 // optional + * _key.expiration=... // optional + * </pre> + * @param key the requested key + * @return the mapped result, including meta-entries. + */ + public Map<String,String> get(String key); + + /** + * Creates/updates an entry in etcd without any ttl set. + * The response is as follows: + * <pre> + * key=value + * _key.source=[etcd]http://127.0.0.1:4001 + * _key.createdIndex=12 + * _key.modifiedIndex=34 // optional + * _key.prevNode.createdIndex=12 // optional + * _key.prevNode.modifiedIndex=34 // optional + * </pre> + * @param key the property key, not null + * @param value the value to be set + * @return the result map as described above. + */ + public Map<String,String> set(String key, String value); + + /** + * Creates/updates an entry in etcd. The response is as follows: + * <pre> + * key=value + * _key.source=[etcd]http://127.0.0.1:4001 + * _key.createdIndex=12 + * _key.modifiedIndex=34 // optional + * _key.ttl=300 // optional + * _key.expiry=... // optional + * _key.prevNode.createdIndex=12 // optional + * _key.prevNode.modifiedIndex=34 // optional + * _key.prevNode.ttl=300 // optional + * _key.prevNode.expiration=... // optional + * </pre> + * @param key the property key, not null + * @param value the value to be set + * @param ttlSeconds the ttl in seconds (optional) + * @return the result map as described above. + */ + public Map<String,String> set(String key, String value, Integer ttlSeconds); + + + /** + * Deletes a given key. The response is as follows: + * <pre> + * _key.source=[etcd]http://127.0.0.1:4001 + * _key.createdIndex=12 + * _key.modifiedIndex=34 + * _key.ttl=300 // optional + * _key.expiry=... // optional + * _key.prevNode.createdIndex=12 // optional + * _key.prevNode.modifiedIndex=34 // optional + * _key.prevNode.ttl=300 // optional + * _key.prevNode.expiration=... // optional + * _key.prevNode.value=... // optional + * </pre> + * @param key the key to be deleted. + * @return the response mpas as described above. + */ + public Map<String,String> delete(String key); + + + /** + * Access regular Tamaya properties map as follows: + * <pre> + * key1=myvalue + * _key1.source=[etcd]http://127.0.0.1:4001 + * _key1.createdIndex=12 + * _key1.modifiedIndex=34 // optional + * _key1.ttl=300 // optional + * _key1.expiration=... // optional + * + * key2=myvaluexxx + * _key2.source=[etcd]http://127.0.0.1:4001 + * _key2.createdIndex=12 + * + * key3=val3 + * _key3.source=[etcd]http://127.0.0.1:4001 + * _key3.createdIndex=12 + * _key3.modifiedIndex=2 + * </pre> + */ + public Map<String,String> getProperties(String directory, boolean recursive); + +} +----------------------------------------------- + + +=== The EtcdPropertySource + +The +EtcdPropertySource+ is automatically registered and allows to configure the _etcd_ servers to be used. This +enables to use e.g. in Docker environments the docker environment configuration mechanisms to configure Tamaya running +in microservice containers to connect with the according etcd cluster: + +* The property source reads the +tamaya.etcd.server.urls+ system and environment property to evaluate possible etcd servers + (comma separated), which can be connected to. On error the API just performs a Round-Robin through the list of + configured servers. Without any configuration +http://127.0.0.1:4001+ is used. If no connection to any etcd + server can be established a warning will be logged, but deployment will not fail. +* Additionally also the accessor allows to configure the socket/connection timeouts by setting + +tamaya.etcd.timeout+ in seconds either as system or environment property. +* The +EtcdPropertySource+ finally also allows the values read from the _etcd_ cluster to be mapped to prefixed + context. This can be activated by setting the +-Dtamaya.etcd.prefix=<PREFIX>+ system property. E.g. when the prefix is + set to `cluster-config.` a etcd key of `host:known/all` is mapped to `cluster-config.host:known/all`. http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/8951b7be/content/documentation-new/extensions/mod_events.adoc ---------------------------------------------------------------------- diff --git a/content/documentation-new/extensions/mod_events.adoc b/content/documentation-new/extensions/mod_events.adoc new file mode 100644 index 0000000..ccba9d1 --- /dev/null +++ b/content/documentation-new/extensions/mod_events.adoc @@ -0,0 +1,308 @@ +:jbake-type: page +:jbake-status: published + += Apache Tamaya - Extension: Events + +toc::[] + + +[[Events]] +== Tamaya Events (Extension Module) + +Tamaya _Events_ is an extension module. Refer to the link:../extensions.html[extensions documentation] for further details. + +=== What functionality this module provides ? + +Tamaya _Events_ provides a mechanism to publish and subscribe to +ConfigEvent<T>+ instances. +This module implements +ConfigChange+ or +PropertySourceChange+ as possible payloads, but +the module itself is not constraint to this payload types. +These payload types describe detected changes of key/values of a +Configuration+ or a +PropertySource+. +The extension also provides a _Singleton accessor_ which allows to register/unregister +listeners for changes and the period, when configuration should be scanned for +any changes. + +Summarizing with the events module you can easily observe configuration changes, record the +state of any configuration and compare configuration states to create and publish related +change events. + +=== Compatibility + +The module is based on Java 7, so it can be used with Java 7 and beyond. + +=== Installation + +To benefit from configuration event support you only must add the corresponding dependency to your module: + +[source, xml] +----------------------------------------------- +<dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-events</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + + +=== Core Architecture + +The core of the module are the +ConfigEventListener+ and the +ConfigEvent+ interfaces, +which defines an abstraction for event handling and observation: + +[source,java] +.ConfigEvent +-------------------------------------------- +public interface ConfigEvent<T> { + + Class<T> getResourceType(); + T getResource(); + String getVersion(); + long getTimestamp(); +} + +// @FunctionalInterface +public interface ConfigEventListener { + + void onConfigEvent(ConfigEvent<?> event); + +} +-------------------------------------------- + +Hereby the payload _T_ can be basically of an arbitrary type as long as +it implements the +ConfigEvent+ interface. The next sections +give more details on the the event types provided by this extension +and their usage. + +Also the technology to be used for publishing these event types is adaptable. +In SE the module uses a simple in-memory implementation based on the +Google _Guava_ library. But users can replace this mechanism as needed. For +more details refer to the SPI section later in this guide. + + +=== The ConfigEventManager Singleton + +Main entry point of the events module is the +ConfigEventManager+ singleton class, which provides static accessor +methods to the extension's functionality: + +* _Adding/removing_ of +ConfigChangeListener+ instances, either globally or per event type. +* _Firing configuration events_ synchronously or asyncronously (mostly called by framework code). +* _Configuring the monitor_ that periodically checks for changes on the global +Configuration+ provided + by +ConfigurationProvider.getConfiguration()+. + +[source,java] +------------------------------------------------------- +public final class ConfigEventManager { + + private ConfigEventManager() {} + + public static void addListener(ConfigEventListener l); + public static <T extends ConfigEvent> void addListener(ConfigEventListener l, Class<T> eventType); + public static void removeListener(ConfigEventListener l); + public static <T extends ConfigEvent> void removeListener(ConfigEventListener l, Class<T> eventType); + public static <T extends ConfigEvent> + Collection<? extends ConfigEventListener> getListeners(); + public static <T extends ConfigEvent> + Collection<? extends ConfigEventListener> getListeners(Class<T> type); + + public static <T> void fireEvent(ConfigEvent<?> event); + public static <T> void fireEventAsynch(ConfigEvent<?> event); + + public static void enableChangeMonitoring(boolean enable); + public static boolean isChangeMonitoring(); + public long getChangeMonitoringPeriod(); + public void setChangeMonitoringPeriod(long millis); + +} +------------------------------------------------------- + + +=== Modelling configuration changes as events + +This module provides a serializable and thread-safe abstraction modelling a +configuration change, which is anything of the following + +* additional, _new_ configuration entries +* _removed_ configuration entries +* _changes_ on existing entries + + +A collection of changes + +* on a +Configuration+ is modelled by the +ConfigurationChange+ class +* on a +PropertySource+ is modelled by the +PropertySourceChange+ class + + +==== Configuration Changes + +A set of changes on a +Configuration+ is described by a +ConfigurationChange+ +as follows: + +[source,java] +------------------------------------------------------- +public final class ConfigurationChange implements ConfigEvent<Configuration>, Serializable{ + + public static ConfigurationChange emptyChangeSet(Configuration configuration); + + @Override + public Configuration getResource(); + @Override + public Class<Configuration> getResourceType(); + @Override + public String getVersion(); + @Override + public long getTimestamp(); + + // Event specific methods + + public Collection<PropertyChangeEvent> getChanges(); + public int getRemovedSize(); + public int getAddedSize(); + public int getUpdatedSize(); + + public boolean isKeyAffected(String key); + public boolean isRemoved(String key); + public boolean isAdded(String key); + public boolean isUpdated(String key); + public boolean containsKey(String key); + public boolean isEmpty(); +} + +------------------------------------------------------- + +New instances of +ConfigurationChange+ hereby can be created using a +fluent +ConfigurationChangeBuilder+: + +[source,java] +------------------------------------------------------- +Configuration config = ...; +ConfigurationChange change = ConfigurationChangeBuilder.of(config) + .addChange("MyKey", "newValue") + .removeKeys("myRemovedKey").build(); +------------------------------------------------------- + +Also it is possible to directly compare 2 instances of +Configuration+, +which results in a +ConfigurationChange+ that +reflects the differences between the two configurations passed: + +[source,java] +Comparing 2 configurations +------------------------------------------------------- +Configuration config = ...; +Configuration changedConfig = ...; +ConfigurationChange change = ConfigurationChangeBuilder.of(config) + .addChanges(changedConfig).build(); +------------------------------------------------------- + +So a +ConfigurationChange+ describes all the changes detected on a +Configuration+. +This allows you to publish instances of this class as events to all registered +listeners (observer pattern). +For listening to +ConfigurationChange+ events you must implement the ++ConfigEventListener+ functional interface: + +[source,java] +.Implementing a ConfigChangeListener +------------------------------------------------------- +public final class MyConfigChangeListener implements ConfigEventListener<ConfigurationChange>{ + + private Configuration config = ConfigurationProvider.getConfiguration(); + + public void onConfigEvent(ConfigEvent<?> event){ + if(event.getResourceType()==Configuration.class){ + if(event.getConfiguration()==config){ + // do something + } + } + } + +} +------------------------------------------------------- + +You can *register* your implementation as illustrated below: + +. Manually by calling +ConfigEventManager.addListener(new MyConfigChangeListener())+ +. Automatically by registering your listener using the +ServiceLoader+ under + +META-INF/services/org.apache.tamaya.events.ConfigEventListener+ + +Registering programmatically also allows you to define additional constraint, +to filter out all kind of events you are not interested in. + +NOTE: By default detection of configuration changes is not enabled. To enable it, call ++ConfigEventManager.enableChangeMonitoring(true)+. + + +=== PropertySource Changes + +Beside that a whole +Configuration+ changes, also a +PropertySource+ can change, +e.g. by a configuration file edited on the fly. This is similarly to a ++ConfigurationChange+ reflected by the classes +PropertySourceChange, +PropertySourceChangeBuilder+. + + +==== Monitoring of configuration changes + +The +ConfigEventManager+ supports *active monitoring of the current configuration* to trigger corresponding change +events to listeners registered. *This feature is deactivated by default*, but can be enabled by calling ++ConfigEventManager.enableChangeMonitoring(true);+. This feature avoids regularly polling your local +Configuration+ for +any kind of changes. If a change has been encountered Tamaya identifies it and triggers corresponding ++ConfigurationChange+ events automatically. + + +=== Freezing Configurations and PropertySources + ++Configuration+ instances as well as +PropertySources+ are explicitly not required to be serializable. To enable easy +serialization of these types a +Configuration+'s *current state can be frozen* (e.g. for later comparison with a newly +loaded version). Freezing hereby means + +* all key/values are read-out by calling the +getProperties()+ method. +* a meta data entry is added of the form +_frozenAt=223273777652325677+, whichdefines the UTC timestamp in + milliseconds when this instance was frozen. +* if not already defined an +_id+ property will be added to the +Configuration+ containing the + identifier of the configuration. + +In code freezing is a no-brainer: + +[source,java] +.Freezing the current Configuration +-------------------------------------------------- +Configuration config = ConfigurationProvider.getConfiguration(); +Configuration frozenConfig = FrozenConfiguration.of(config); +-------------------------------------------------- + +... and similarly for a +PropertySource+: + +[source,java] +.Freezing the current Configuration +-------------------------------------------------- +PropertySource propertySource = ...; +PropertySource frozenSource = FrozenPropertySource.of(propertySource); +-------------------------------------------------- + + + +=== SPIs + +This component also defines SPIs, which allows to adapt the implementation of the main +ConfigEventManager+ +singleton. This enables, for example, using external eventing systems, such as CDI, instead of the default provided +simple SE based implementation. By default implementations must be registered using the current +ServiceContext+ +active (by default using the Java +ServiceLoader+ mechanism). + +[source,java] +.SPI: ConfigEventSpi +-------------------------------------------------- +public interface ConfigEventManagerSpi { + + <T> void addListener(ConfigEventListener l); + <T extends ConfigEvent> void addListener(ConfigEventListener l, Class<T> eventType); + void removeListener(ConfigEventListener l); + <T extends ConfigEvent> void removeListener(ConfigEventListener l, Class<T> eventType); + Collection<? extends ConfigEventListener> getListeners(); + Collection<? extends ConfigEventListener> getListeners(Class<? extends ConfigEvent> eventType); + + void fireEvent(ConfigEvent<?> event); + void fireEventAsynch(ConfigEvent<?> event); + + long getChangeMonitoringPeriod(); + void setChangeMonitoringPeriod(long millis); + boolean isChangeMonitorActive(); + void enableChangeMonitor(boolean enable); +} +-------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/8951b7be/content/documentation-new/extensions/mod_features.adoc ---------------------------------------------------------------------- diff --git a/content/documentation-new/extensions/mod_features.adoc b/content/documentation-new/extensions/mod_features.adoc new file mode 100644 index 0000000..c3299bd --- /dev/null +++ b/content/documentation-new/extensions/mod_features.adoc @@ -0,0 +1,87 @@ +:jbake-type: page +:jbake-status: published + += Apache Tamaya - Extension: Features Check + +toc::[] + + +[[Features]] +== Tamaya Features Check (Extension Module) +Tamaya _Features_ is an extension module. Refer to the link:../extensions.html[extensions documentation] for further details. + +=== What functionality this module provides ? + +Tamaya _Features_ provides a simple +Features+ singleton that allows to check +which Tamaya Extensions are currently on the classpath. + +=== Compatibility + +The module is based on Java 7, so it will not run on Java 7 and beyond. + + +=== Installation + +To use Tamaya _Features_ you only must add the corresponding dependency to +your module: + +[source, xml] +----------------------------------------------- +<dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-features</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + + +=== The Functionality Provided + +Main artifact is the +Features+ singleton, which provides various static methods +to check, which Tamaya extensions are currently loaded. + +[source, java] +----------------------------------------------- +public final class Features { + + private Features(){} + + public static boolean eventsAvailable(); + public static boolean formatsAvailable(); + public static boolean tamayaCoreAvailable(); + public static boolean injectionAvailable(); + public static boolean injectionCDIAvailable(); + public static boolean mutableConfigAvailable(); + public static boolean optionalAvailable(); + public static boolean resolverAvailable(); + public static boolean resourcesAvailable(); + public static boolean spiSupportAvailable(); + public static boolean filterSupportAvailable(); + public static boolean springAvailable(); + public static boolean jndiAvailable(); + + public static boolean extSpringCoreAvailable(); + public static boolean extJndiAvailable(); + public static boolean extOSGIAvailable(); + + public static boolean checkClassIsLoadable(String classname); +} +----------------------------------------------- + +* +eventsAvailable();+ checks for the link:mod_events.html[_tamaya_events_] module. +* +formatsAvailable();+ checks for the link:mod_formats.html[_tamaya_formats_] module. +* +tamayaCoreAvailable();+ checks if the link:core.html[_Tamaya core_] implementation is loaded. +* +injectionAvailable();+ checks for the link:mod_injection.html[_tamaya_injection_] SE module. +* +injectionCDIAvailable();+ checks for the link:mod_cdi.html[_tamaya CDI_] modules. +* +mutableConfigAvailable();+ checks for the link:mod_mutableconfig.html[_tamaya_mutableconfig_] module. +* +optionalAvailable();+ checks for the link:mod_optional.html[_tamaya_optional_] module. +* +resolverAvailable();+ checks for the link:mod_resolver.html[_tamaya_resolver_] module. +* +resourcesAvailable();+ checks for the link:mod_reources.html[_tamaya_resources_] module. +* +spiSupportAvailable();+ checks for the link:mod_spisupport.html[_tamaya_spisupport_] module. +* +filterSupportAvailable();+ checks for the link:mod_filter.html[_tamaya_filter_] module. +* +springAvailable();+ checks for the link:mod_spring.html[_tamaya_spring_] module. +* +jndiAvailable();+ checks for the link:mod_jndi.html[_tamaya_jndi_] module. +* +extJndiAvailable();+ checks if creation of a new `InitialContext` is successful. +* +extSpringCoreAvailable();+ checks if Spring Core is on the classpath. +* +extOSGIAvailable();+ checks the OSGI framework is on the classpath. +* Finally +checkClassIsLoaded(String)+ tries to load a class. If it fails, `false` is returned. http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/8951b7be/content/documentation-new/extensions/mod_filter.adoc ---------------------------------------------------------------------- diff --git a/content/documentation-new/extensions/mod_filter.adoc b/content/documentation-new/extensions/mod_filter.adoc new file mode 100644 index 0000000..bce6947 --- /dev/null +++ b/content/documentation-new/extensions/mod_filter.adoc @@ -0,0 +1,124 @@ +:jbake-type: page +:jbake-status: published + += Apache Tamaya - Extension: User Filtering + +toc::[] + + +[[Filter]] +== User Filtering (Extension Module) + +Tamaya _Filter_ is an extension module. Refer to the link:../extensions.html[extensions documentation] for further details. + + +=== What functionality this module provides ? + +Tamaya _Filter_ provides a simple singleton accessor that allows to explicitly add +PropertyFilter+ instances +active on the current thread only. This can be very useful in many scenarios, especially within +Java EE web filters or similar. Additionally this module adds +standard filters that hide metadata entries when the full configuration map is accessed. When keys are accessed +explicitily no filtering is applied and everything is visible. + +=== Compatibility + +The module is based on Java 7, so it will not run on Java 7 and beyond. + + +=== Installation + +To benefit from filter support you only must add the corresponding dependency to your module: + +[source, xml] +----------------------------------------------- +<dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-filter</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + + +=== The Extensions Provided + +Tamaya Filter comes basically with 3 artifacts: + +* The +org.apache.tamaya.filter.ConfigurationFilter+ provides several static methods to register +PropertyFilter+ +instances on the current thread. +* The +org.apache.tamaya.filter.DefaultMetdataFilter+ is a +PropertyFilter+ with hides all entries starting with + an underscore ('_'), when a full property map is accessed. + + +==== The ConfigurationFilter + +The accessor mentioned implements the API for for adding +PropertyFilters+ to the current thread (as thread local): + +[source, java] +----------------------------------------------- +public final class ConfigurationFilter implements PropertyFilter{ + + ... + + /** + * Seactivates metadata filtering also on global map access for this thread. + * @see #clearFilters() + * @param active true,to enable metadata filtering (default). + */ + public static void setFilterMetadata(boolean active); + + /** + * Access the filtering configuration that is used for filtering single property values accessed. + * @return the filtering config, never null. + */ + public static FilterContext getSingleFilterContext(); + + /** + * Access the filtering configuration that is used for filtering configuration properties accessed as full + * map. + * @return the filtering config, never null. + */ + public static FilterContext getMapFilters(); + + /** + * Removes all programmable filters active on the current thread. + */ + public static void clearFilters(); + + ... + +} +----------------------------------------------- + +For using regular expression when filtering configuration keys a corresponding implementation of a +PropertyFilter+ +is part of this module, So you can add a customized filter as follows: + +[source, java] +----------------------------------------------- +try { + ConfigurationFilter.getMapFilters().addFilter(new myFilter()); + + // do your code with filtering active +} +finally { + // cleanup + ConfigurationFilter.clearFilters(); +} +----------------------------------------------- + +The +FilterContext+ is a simple structure just providing some handy accessors to the dynamic thread-local +managed filters: + +[source, java] +----------------------------------------------- +public final class FilterContext implements PropertyFilter { + + public void addIncludes(PropertyFilter filter); + public void addExcludes(int pos, PropertyFilter filter); + public PropertyFilter removeFilter(int pos); + public void clearFilters(); + public void setIncludes(PropertyFilter... filters); + public void setExcludes(Collection<PropertyFilter> filters); + public List<PropertyFilter> getFilters(); + +} +----------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/8951b7be/content/documentation-new/extensions/mod_formats.adoc ---------------------------------------------------------------------- diff --git a/content/documentation-new/extensions/mod_formats.adoc b/content/documentation-new/extensions/mod_formats.adoc new file mode 100644 index 0000000..aa7d559 --- /dev/null +++ b/content/documentation-new/extensions/mod_formats.adoc @@ -0,0 +1,290 @@ +:jbake-type: page +:jbake-status: published + += Apache Tamaya - Extension: Formats + +toc::[] + + +[[Formats]] +== Tamaya Formats (Extension Module) + +Tamaya _Formats_ is an extension module. Refer to the link:../extensions.html[extensions documentation] for further details. + + +=== What functionality this module provides ? + +Tamaya _Formats_ provides an abstraction for configuration formats provding the following benefits: + +* Parsing of resources in can be implemented separately from interpreting the different aspects/parts parsed. As an + example a file format can define different sections. Depending on the company specific semantics of the sections + a different set of +PropertySource+ instances must be created. +* Similarly the configuration abstraction can also be used as an interface for integrating Tamaya with alternate + frameworks that provide logic for reading configuration files, such as Apache commons.configuration. + +=== Compatibility + +The module is based on Java 7, so it can be used with Java 7 and beyond. + +=== Installation + +To use the formats module you only must add the corresponding dependency to your module: + +[source, xml] +----------------------------------------------- +<dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-formats</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + + +=== Basic Concept + +Formats should be reusable, meaning you should have to write a format parser only once and then be able to map the data read into whatever +data structure (in our cases: property sources). So it is useful to separate concerns into + +* an arbitrary configuration format (textual or binary) +* a parser (+ConfigurationFormat+) that transfers a given format into an intermediate + representation (+ConfigurationData+). +* an optional customization, implemented by a _factory method pattern_ to adapt the mapping of +ConfigurationData+ read + to a collection of +PropertySources+ (they can have different ordinal semantics). + + +==== ConfigurationData + +Configuration formats can be very different. Some are simple key/value pairs, whereas other also consist of multiple sections (e.g. ini-files) or +hierarchical data (e.g. yaml, xml). This is solved in Tamaya by mapping the configuration read into a normalized intermediary format called ++ConfigurationData+: + +[source,java] +.ConfigurationData +------------------------------------------------------- +public final class ConfigurationData { + + public ConfigurationFormat getFormat(); + public String getResource(); + + public Set<String> getSectionNames(); + public Map<String,String> getSection(String name); + + public boolean hasDefaultProperties(); + public Map<String,String> getDefaultProperties(); + public Map<String,String> getCombinedProperties(); + + public boolean isEmpty(); +} +------------------------------------------------------- + +In detail the data read from a file is organized into _sections_ as follows: + +* with +getResource()+ and +getFormat()+ the underlying resource and the format that read this data can be accessed. +* properties can be owned by + ** named sections + ** an (unnamed) default section +* each section section contains a map of properties. Hereby the same key can be part of the default section and multiple + named sections, depending on the configuration format. +* The method +getSectionNames()+ returns a set of all section names. +* With +getSection(String name)+ a named section can be accessed. +* With +getDefaultSection()+ the 'default' section can be accessed. This is a convenience method. +* With +getCombinedProperties()+ a flattened entry map can be accessed built up (by default) out of + ** all entries from the default section, without any changes. + ** all entries from named sections, where the key for each entry is prefix with the section name and a '::' separator. +* The configuration format used determines the mapping of configuration data read into this structure. The format + implementation can as well provide alternate implementations of how the data read should be mapped into the + combined properties map. + + +==== ConfigurationFormat + +A ConfigurationFormat is basically an abstraction that reads a configuration resource (modelled by an InputStream) and +creates a corresponding +ConfigurationData+ instance. + +[source,java] +------------------------------------------------------- +public interface ConfigurationFormat { + + String getName(); + boolean accepts(URL url); + ConfigurationData readConfiguration(String resource, InputStream inputStream); +} +------------------------------------------------------- + +=== Creating a default PropertySource for a ConfigurationFormat + +The module defines a singleton +ConfigurationFormats+ which provides +an easy to use API for creating +ConfigurationData+ and +PropertySources+ +using abstract +ConfigurationFormat+ implementations: + +[source,java] +------------------------------------------------------- +public final class ConfigurationFormats { + + public static List<ConfigurationFormat> getFormats(); + public static List<ConfigurationFormat> getFormats(String... formatNames); + public static List<ConfigurationFormat> getFormats(final URL url); + + public static ConfigurationData readConfigurationData(final URL url) + throws IOException; + public static ConfigurationData readConfigurationData(URL url, ConfigurationFormat... formats) + throws IOException; + public static ConfigurationData readConfigurationData(URL url, Collection<ConfigurationFormat> formats) + throws IOException; + public static Collection<ConfigurationData> readConfigurationData(Collection<URL> urls, ConfigurationFormat... formats); + public static Collection<ConfigurationData> readConfigurationData(Collection<URL> urls, Collection<ConfigurationFormat> formats); + public static ConfigurationData readConfigurationData(String resource, InputStream inputStream, + ConfigurationFormat... formats) + throws IOException; + public static ConfigurationData readConfigurationData(String resource, InputStream inputStream, + Collection<ConfigurationFormat> formats) + throws IOException; + + public static PropertySource createPropertySource(URL url, ConfigurationFormat... formats) + throws IOException; + public static PropertySource createPropertySource(URL url, Collection<ConfigurationFormat> formats) + throws IOException; + public static PropertySource createPropertySource(String resource, InputStream inputStream, + ConfigurationFormat... formats); + public static PropertySource createPropertySource(String resource, InputStream inputStream, + Collection<ConfigurationFormat> formats); +} +------------------------------------------------------- + +* +getFormats()+ returns all registered formats. +* +getFormats(String...)+ allows to access all formats with a given name. +* +getFormats(URL url)+ allows to access all formats that declare that can optionally read an input from + a given `URL`. +* +readConfigurationData(...)+ reads data from an input and creates a corresponding +ConfigurationData+, + either trying all known formats that declare its compatibility with the given input or the formats + passed explicitly. +* +createPropertySource(...)+ allows to create a +PropertySource+ reading a given input and the formats + to be used or known. Hereby a default property mapping is applied. + +So creating a +PropertySource+ from a resource is basically a one liner: + +[source,java] +------------------------------------------------------- +URL url = ...; +PropertySource propertySource = ConfigurationFormats.createPropertySource(url); + +// constraining the formats to be used (assumption: json and yaml extensions are loaded) +PropertySource propertySource = ConfigurationFormats.createPropertySource( + url, + ConfigurationFormats.getFormats("json", "yaml")); +------------------------------------------------------- + + +=== Customize how ConfigurationData maps to PropertySource + +For for the conversion of +ConfigurationData+ into a +PropertySource+ different approaches can be useful: + +. The +ConfigurationFormat+ that reads the data can provides all properties read either as sectioned properties + or/and as default properties. The most simple cases is, where all properties have been added as 'default' + properties. In this case the default properties can be used as the property sources properties without any change. +. If the format did also add section based properties, the combined properties returned can be used, hereby + replacing the '::' separator with a '.' separator. +. In all other cases a custom mapping is useful, which can be acomplished by using the +MappedConfigurationDataPropertySource+ + and overriding the +Map<String,String> populateData(ConfigurationData data)+ method. + +In most cases the usage of a +MappedConfigurationDataPropertySource+, is a good choice to start. This class +provides a convenient default mapping and also allows to customized the mapping easily: + +[source,java] +------------------------------------------------------- +ConfigurationData data = ...; +MappedConfigurationDataPropertySource ps = + new MappedConfigurationDataPropertySource(data){ + protected Map<String, String> populateData(ConfigurationData data) { + ... + } + }; +------------------------------------------------------- + +Nevertheless, depending on the context, where a configuration source was read (classloader, time, source etc.) the +resulting properties can have different semnatics, especially different priorities. Also section +names may be mapped into different ordinals instead of using them as key prefixes (e.g. imagine configuration formats +with a 'default', 'main', and 'overrides' sections). For such more complex or custom cases no simple mapping +can be defined. Consequently the functionality mapping the normalized +ConfigurationData+ read to the +appropriate collection of +PropertySource+ instances must be implemented. + +For this scenario the +BaseFormatPropertySourceProvider+ can be used, defining the following mapping +function that mus be implemented: + +[source,java] +------------------------------------------------------- +/** + * Method to create a {@link org.apache.tamaya.spi.PropertySource} based on the given entries read. + * + * @param data the configuration data, not null. + * @return the {@link org.apache.tamaya.spi.PropertySource} instance ready to be registered. + */ +protected abstract Collection<PropertySource> getPropertySources(ConfigurationData data); +------------------------------------------------------- + +When using Java 8 these mappings can be asily passed as parameters to the +createPropertySource+ +methods. + + +=== Predefined formats + +The _formats_ module ships with 3 predefined formats: + +* `.ini` files, commonly known from Microsoft based systems, registered as `ini`. +* `.properties` files, as defined by `java.util.Properties`, registered as `properties`. +* `.xml` properties files, as defined by `java.util.Properties`, registered as `xml-properties`. + + +==== ini Configuration File Mapping + +This module implements the ini file format with the class ++org.apache.tamaya.format.formats.IniConfigurationFormat+. + +The default mapping is bext illustrated by a small example, so consider the +following `.ini` file: + +[source,listing] +------------------------------------------------------- +a=valA +a.b=valB + +[section1] +aa=sectionValA +aa.b.c=SectionValC + +[section2] +a=val2Section2 +------------------------------------------------------- + +This file content by default is mapped to the following Tamaya properties: + +[source,listing] +------------------------------------------------------- +a=valA +a.b=valB +section1::valA=sectionValA +section1::a.b.c=SectionValC +section2::a=val2Section2 +------------------------------------------------------- + +Summarizing + +* entries without a section are mapped to the _default_ section. +* entries with a section are mapped to a corresponding section, hereby everything between + the brackets is used as section name (trimmed). +* section names are separated using a double colon (`::`). + ++ConfigurationData+ allows to access all the different parts: + +* the _default_ properties (a, a.b) +* the section +section1+, with properties +aa, aa.b.c+ +* the section +section2+, with properties +a+ + + +==== XML Property and ordinary Property Files + +This module also ships with +ConfigurationFormat+ implementations that reuse the parsing +functionality provided with +java.util.Properties+: + +* `org.apache.tamaya.format.formats.PropertiesFormat` uses `Properties.read(InputStream)`. +* `org.apache.tamaya.format.formats.PropertiesXmlFormat` uses `Properties.readFromXml(InputStream)`.
