http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_mutable_config.adoc ---------------------------------------------------------------------- diff --git a/content/documentation/extensions/mod_mutable_config.adoc b/content/documentation/extensions/mod_mutable_config.adoc new file mode 100644 index 0000000..cb8869d --- /dev/null +++ b/content/documentation/extensions/mod_mutable_config.adoc @@ -0,0 +1,267 @@ +:jbake-type: page +:jbake-status: published + += Apache Tamaya -- Extension: Mutable Configuration + +toc::[] + + +[[Core]] +== Tamaya Mutable Configuration (Extension Module) +=== Overview + +Tamaya Configuration by default is read-only, which covers must of the use cases. But there are many legit scenarios +where configuration should be written back to some backend systems or the local file system. This module adds this +functionality. + +=== Compatibility + +The module is based on Java 7, so it can be used with Java 7 and beyond. + +=== Installation + +To benefit from configuration mutability support you only must add the corresponding dependency to your module: + +[source, xml] +----------------------------------------------- +<dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-mutable-config</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + +=== Core Architecture + +==== Accessing MutableConfiguration + +The core of the module is the +MutableConfigurationProvider+ singleton, which provides access to +MutableConfiguration+ +instance, which extends +Configuration+. This interface adds additional methods to add/update or remove property values. +Hereby changes applied are managed in a transaction like context, called +ConfigChangeContext+. Each context defines +a UUID that identifes a change. +Backends for writing changes applied are of type +MutablePropertySource+, similarly extending the +PropertySource+ +SPI with methods for writing changes back. Registrations and ordering policies are like with ordinary property sources, +with one important difference. Mutable property source can be targeted by write operations. + +The example below shows how a +MutableConfiguration+ can be obtained the simplest way: + +[source,java] +.Accessing and changing configuration +-------------------------------------------- +MutableConfiguration config = MutableConfigurationProvider + .createMutableConfiguration(); +config.put("newKey", "newValue") + .put("anotherKey", "updatedValue") + .remove("valueNotValid") + .store(); +-------------------------------------------- + +In the above scenario we use the overall system's configuration as the backend to be used. +We can also pass any +Configuration+ to render it into a mutable instance, e.g. + +[source,java] +.Explicitly passing the backing configuration +-------------------------------------------- +Configuration config = ...; +MutableConfiguration config = MutableConfigurationProvider + .createMutableConfiguration(config); +-------------------------------------------- + +NOTE: If a configuration does not contain any +MutablePropertySource+ instances, + a +MutableConfiguration+ built from it will not be able to accept any changes. + + +Following you see the options how to create a +MutableConfiguration+ using the ++MutableConfigurationProvider+ singleton: + +[source, java] +--------------------------------------------- +public final class MutableConfigurationProvider { + + private MutableConfigurationProvider(){} + + public static MutableConfiguration createMutableConfiguration(); + public static MutableConfiguration createMutableConfiguration( + ChangePropagationPolicy changePropgationPolicy); + public static MutableConfiguration createMutableConfiguration(Configuration configuration); + public static MutableConfiguration createMutableConfiguration( + Configuration configuration, + ChangePropagationPolicy changePropgationPolicy); + + [...] +} +--------------------------------------------- + +Hereby +MutableConfiguration+ is defined as follows: + +[source, java] +--------------------------------------------- +public interface MutableConfiguration extends Configuration { + + void store(); + + ConfigChangeRequest getConfigChangeRequest(); + ChangePropagationPolicy getChangePropagationPolicy(); + + MutableConfiguration put(String key, String value); + MutableConfiguration putAll(Map<String, String> properties); + MutableConfiguration remove(Collection<String> keys); + MutableConfiguration remove(String... keys); + +} +--------------------------------------------- + + +==== Targeting the right MutablePropertySources + +A +Configuration+ may have multiple +MutablePropertySource+ instances present. These are members of Tamaya's oredered list of ++PropertySources+ to evaluate the configuration. Nevertheless writing back changes requires additional aspects to +be considered: +* Should changes being written back to all mutable property sources? Or should a key that could be added or removed + on a more significant instance not be written/removed on less significant property source instances? +* Should a change be applied only to a specific mutable property source, regardless its position in the + processing chain? + +Therefore a +ChangePropagationPolicy+ can be set on a +MutableConfiguration+ instance, which allows to control +this aspect: + +[source,java] +.Explicitly passing the backing configuration +-------------------------------------------- +public interface ChangePropagationPolicy { + /** + * Method being called when a multiple key/value pairs are added or updated. + * @param propertySources the property sources, including readable property sources of the current configuration, + * never null. + * @param configChange the configuration change, not null. + */ + void applyChange(ConfigChangeRequest configChange, Collection<PropertySource> propertySources); +} +-------------------------------------------- + +By default, changes are applied to all registered +MutablePropertySources+ similarly. + + +Also the +MutableConfigurationProvider+ provides access to the most commonly used change propagation policies: + +[source, java] +--------------------------------------------- +public final class MutableConfigurationProvider { + + [...] + + public static ChangePropagationPolicy getApplyAllChangePolicy(); + public static ChangePropagationPolicy getApplyMostSignificantOnlyChangePolicy(); + public static ChangePropagationPolicy getApplySelectiveChangePolicy(String... propertySourceNames); + public static ChangePropagationPolicy getApplyNonePolicy(); +} +--------------------------------------------- + + +==== Some Aspects to consider + +Due to Tamaya's design the effective effect of your changes to the overall configuration, cannot +be sometimes a bit tricky to be predicted, since it depends on several aspects: + +. is the corresponding configuration resource configured as part of the current system's configuration? +. what is the +PropertySource's+ priority within the configuration context? Is it overriding or overridden + by other sources? +. is the change directly visible to the configuration system? E.g. injected values are normally not updated, + whereas injecting a +DynamicValue<T>+ instance allows to detect and react single value changes. Also the + +PropertySources+ implementation must be able to detect any configuration changes and adapt its values returned + accordingly. Finally values also can be marked as immutable or being cached. +. Is configuration cached, or written/collected directly on access? +. can the changes applied be committed at all? + +So it is part of your application configuration design to clearly define, which property sources may be read-only, which +may be mutable, how overriding should work and to which backends finally any changes should be written back. Nevertheless +changing or adding value is very easy: + +[source,java] +.Changing a configuration +-------------------------------------------- +MutableConfiguration config = MutableConfigurationProvider.createMutableConfiguration(); +config.put("newKey", "newValue"); +config.remove("mycluster.myapp.myKey"); +config.store(); +-------------------------------------------- + + +=== Configuration Changes + +This module does not handle detection of changes to the overall system's +Configuration+. This can be done in +several ways, e.g. by: + +* using the _tamaya-events_ extension, which can be used to observe the system's configuration and + publishing events when things have been changed. +* The SPI implementing the +MutableConfigurationBackendSpi+ may inform/update any affected +PropertySource, + PropertySourceProvider+ instances about the changes applied. + + +=== Supported Backends + +Multiple backends are supported. E.g. the _etcd_ integration module of Tamaya also registers +corresponding SPI implementations/backends. By default this module comes with +the following +MutablePropertySource+ implementations: + +* +MutablePropertySource+ resources, targeting local +.properties+ files, using the +java.util.Properties+ + format. +* +MutableXmlPropertySource+ resources, targeting local +.xml+ property files, using the +java.util.Properties+ + XML format. + +==== Refreshable Property Sources + +Somehow similar to configuration changes applied explicitly is the case, where values of underlying +configuration backends change and must be reflected in the new configuration tree. Examples are: + +* Configuration files being edited, added or removed. +* Changes on remote servers like etcd, consul +* etc. + +For having a common API for refreshable items a +Refreshable+ interface is defined: + +[source,java] +.Refreshable interface +-------------------------------------------- +/** + * Interface to be implemented by items that can be refreshed. By default + * these are property sources, but more types may be supported at a later + * point in time. + */ +public interface Refreshable { + + /** + * Refreshes the item by reloading its internal state. + */ + void refresh(); + +} +-------------------------------------------- + + +==== Refreshable Property Sources + +=== SPIs + +The module defines +MutableConfigurationProviderSpi+, that is used as a delegate by the +MutableConfigurationProvider+ +singleton accessor: + +[source,java] +.SPI: MutableConfigurationProviderSpi +-------------------------------------------------- +public interface MutableConfigurationProviderSpi { + /** + * Creates a new {@link MutableConfiguration} with {@code autoCommit = false} as default. + * + * @param configuration the configuration, not null. + * @param propagationPolicy policy that defines how changes are published to the property + * sources. + * @return a new mutable configuration instance. + */ + MutableConfiguration createMutableConfiguration(Configuration configuration, + ChangePropagationPolicy propagationPolicy); +} +-------------------------------------------------- + +Implementations are registered with the current +ServiceContext+ (using by default the + +java.util.ServiceLoader+ service).
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_optional.adoc ---------------------------------------------------------------------- diff --git a/content/documentation/extensions/mod_optional.adoc b/content/documentation/extensions/mod_optional.adoc new file mode 100644 index 0000000..1a4b967 --- /dev/null +++ b/content/documentation/extensions/mod_optional.adoc @@ -0,0 +1,54 @@ +:jbake-type: page +:jbake-status: published + += Apache Tamaya -- Extension: Optional Tamaya Configuration + +toc::[] + + +[[Optional]] +== Tamaya Optional Configuration (Extension Module) +=== Overview + +The Tamaya optional module provides contains three types only. It is for projects that want to benefit from Tamaya +configuration optionally only. E.g. doing an OSS project you can declare to support configuration with Tamaya as +an optional extension. This module can be added as a hard dependency to your code, hereby adding only three artofacts. +It automatically checks the availability of Tamaya on the classpath and only if available tries to access it for +configuration evaluation. Additionally an EvaluationPolicy lets you define the precedence of configured values +(yours, or Tamaya ones if present). + + +=== 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-optional</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + + +=== Reading configuration using the Tamaya Optional Module + +The optional module allows reading configuration with a small subset of functionality only. For extended of full +featured config please consider using the Apache Tamaya as a full configuration backend. + +[source, java] +----------------------------------------------- +BigDecimal interestRate = + OptionalConfiguration.of( + EvaluationPolicy.TAMAYA_OVERRIDES_OTHER, + (k) -> MyConfigMechanism.get(k) // String get(String key); + ) + .get("com.mycomp.ratecalculator.rate", BigDecimal.class)) + .orElse(BigDecimal.of(0.05d)); +----------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_osgi.adoc ---------------------------------------------------------------------- diff --git a/content/documentation/extensions/mod_osgi.adoc b/content/documentation/extensions/mod_osgi.adoc new file mode 100644 index 0000000..3a3ffd4 --- /dev/null +++ b/content/documentation/extensions/mod_osgi.adoc @@ -0,0 +1,116 @@ +:jbake-type: page +:jbake-status: published + += Apache Tamaya -- Extensions: OSGI Integrations + +toc::[] + + +[[Optional]] +== Tamaya OSGI Support +=== Overview + +Tamaya provides also support for integration with OSGI. Hereby several options are available how Tamaya can be used in +an OSGI context: + +. All Tamaya modules, its API and core library are actually valid OSGI bundles. So adding them into your OSGI modules + and using Tamaya is basically directly supported. Nevertheless OSGI works rather differently from a class- and + resource loading perspective. As long as you rely on Tamaya's mechanisms for resource loading things should work + out of the box. In the back Tamaya's core module actually comes with implicit OSGI support, which is automatically + activated, if Tamaya is running in an OSGI context. This support actually + ** Listens on deployed bundles and actively reads all resources configured as +java.util.ServiceLoader+ services and + registers them as OSGI services. Hereby integration is complete meaning you can also register Tamaya services + as normal OSGI services, e.g. your own +PropertySource+ instances. + ** Uses the OSGI bundle to resolve for resources, because accessing them from the classloader directly + typically fails in an OSGI context. +. Adding Tamaya's OSGI integration module replaces the existing OSGI +ConfigAdmin+ service with an istance based on + Tamaya. Hereby several aspects can be configured using system properties: + ** +org.tamaya.integration.osgi.cm.ranking+ (int) allows to configure the OSGI service ranking used by the Tamaya + BundleActivator to register Tamaya's +ConfigAdmin+ service. In OSGI higher ranking precede lower rankings. By default + Tamaya's OSGI extending service registration mechanism is reusing any annotated +@Priority+ priority values as + corresponsing rankings. + ** +org.tamaya.integration.osgi.cm.override+ (boolean) allows to configure if Tamaya is overriding any existing + values from the default +ConfigAdmin+ instance, or only extending them. In other words this setting allows you to + define, which configuration subsystem has precedence for evaluating the final values, either Tamaya based + configuration (default) or the configuration mechanisms provided by default from your OSGI container (when this flag + is set to +false+). + ** +org.tamaya.integration.osgi.cm.inject+ allows you to deactivate injection of configuration values into your + OSGI services (by default injection is enabled). In all cases accessing the OSGI +ConfigAdmin+ service to + read your configuration is working as usual. But Tamaya adds additional injection functionality, which allows + to inject typed configuration as described by the Tamaya injection api. + +It is also possible to combine things, e.g. when you only define a low ranking for Tamaya's configuration service and +the same time allow injection to be active, you will have Tamaya's injection support based on your default +OSGI configuration. + + +=== Compatibility + +All module described are based on Java 7, so it will run on Java 7 and beyond. +The modules are built against OSGI Compendium version 5.0. + + +=== Installation + +To benefit from Tamaya in an OSGI context you must deploy at least the following modules to your OSGI runtime +environment: + +[source, listing] +----------------------------------------------- +# API and core +org.apache.tamaya:tamaya-api:{tamaya_version} +org.apache.tamaya:tamaya-core:{tamaya_version} +org.apache.geronimo.specs:geronimo-annotation_1.2_spec:1.0-alpha-1 +# injection API. SE injection module and dependencies +org.apache.tamaya.ext:tamaya-injection-api:{tamaya_version} +org.apache.tamaya.ext:tamaya-injection:{tamaya_version} +org.apache.geronimo.specs:geronimo-atinject_1.0_spec:1.0 +org.apache.geronimo.specs:geronimo-el_2.2_spec:1.0.4 +org.apache.geronimo.specs:geronimo-interceptor_1.1_spec:1.0 +org.apache.geronimo.specs:geronimo-jcdi_1.1_spec:1.0 +# OSGI integration and dependencies +org.apache.tamaya.ext:tamaya-osgi:{tamaya_version} +org.apache.tamaya.ext:tamaya-functions:{tamaya_version} +----------------------------------------------- + + +=== Usage + +As an example, what is possible you can implement an OSGI service as a normal POJO and publish it as an OSGI service. +Given that configuration can be injected very easily: + +[source, java] +----------------------------------------------- +public class HelloServiceImpl implements HelloService{ + + @Config("example.message") + @ConfigDefault("A Tamaya default.") + private String message; + + @Override + public String sayHello() { + System.err.println("HELLO: " + message); + return message; + } +} +----------------------------------------------- + + +=== SPI + +By default the OSGI pid or factory pid is mapped to a corresponding root section in Tamaya's configuration. We are +well aware that this might not always be the desired approach. Therefore there as an SPI service provided that allows +to determine this mapping: + +[source, java] +.OSGIConfigRootMapper +----------------------------------------------- +public interface OSGIConfigRootMapper { + + String getTamayaConfigRoot(String pid, String factoryPid); +} +----------------------------------------------- + +Registering your own implementation as an OSGI service allows you to redefine the key mapping. +By default a configuration mapping for +pid/factoryPid==myBundle+ is mapped to +[bundle:myBundle]+. +This mapping is used as a prefix when collecting the corresponding entries for the OSGI configuration. http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_remote.adoc ---------------------------------------------------------------------- diff --git a/content/documentation/extensions/mod_remote.adoc b/content/documentation/extensions/mod_remote.adoc new file mode 100644 index 0000000..ce303ed --- /dev/null +++ b/content/documentation/extensions/mod_remote.adoc @@ -0,0 +1,115 @@ +:jbake-type: page +:jbake-status: published + += Apache Tamaya -- Extension: Remote Configuration + +toc::[] + + +[[Remote]] +== Tamaya Remote Configuration (Extension Module) +=== Overview + +The Tamaya remote module provides support for reading configuration from remote resources. It provides +especially out-of-the-box support for reading scoped configuration from a configuration server as +provided with the _Tamaya server module_ . + + +=== 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-remote</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + + +=== Reading Remote configuration from a Tamaya Configuration Server + +The remote module allows reading JSON formatted configuration as provided by the _Tamaya server extension_ . The JSON +format used looks as follows: + +[source, json] +----------------------------------------------- +{ + "java.vendor.url": "http://java.oracle.com/", + "java.vendor.url.bug": "http://bugreport.sun.com/bugreport/", + "java.vm.info": "mixed mode", + "java.vm.name": "Java HotSpot(TM) 64-Bit Server VM", + "java.vm.specification.name": "Java Virtual Machine Specification", + "java.vm.specification.vendor": "Oracle Corporation", + "java.vm.specification.version": "1.8", + "java.vm.vendor": "Oracle Corporation", + "java.vm.version": "25.45-b02", + "sun.arch.data.model": "64", + "sun.boot.class.path": "C:\apps\jdk18\jre\lib\resources.jar;C:\apps\jdk18\jre\lib\rt.jar;C:\apps\jdk18\jre\lib\sunrsasign.jar;C:\apps\jdk18\jre\lib\jsse.jar;C:\apps\jdk18\jre\lib\jce.jar;C:\apps\jdk18\jre\lib\charsets.jar;C:\apps\jdk18\jre\lib\jfr.jar;C:\apps\jdk18\jre\classes", + "sun.boot.library.path": "C:\apps\jdk18\jre\bin", + "sun.cpu.endian": "little", + "sun.cpu.isalist": "amd64", + "sun.desktop": "windows", + "sun.io.unicode.encoding": "UnicodeLittle", + "sun.java.command": "com.intellij.rt.execution.application.AppMain org.apache.tamaya.examples.remote.server.Start", + "sun.java.launcher": "SUN_STANDARD", + "sun.jnu.encoding": "Cp1252", + "sun.management.compiler": "HotSpot 64-Bit Tiered Compilers", + "sun.os.patch.level": "", + "{meta}class": "org.apache.tamaya.functions.FilteredConfiguration", + "{meta}info.filter": "java.v,sun", + "{meta}info.format": "application/json", + "{meta}info.timestamp": "1441463200571", + "{meta}timestamp": "1441463200571", + "{meta}type": "Configuration" +} +----------------------------------------------- + +Basically there are no constraints about they keys provided. By default Tamaya uses keys prefixed with ++{xxx}+ to identify meta-data entries, but this is not a required precondition. + +Finally such a remote configuration can be easily integrated by inheriting from the provided base +class. Hereby a default ordinal must be defined and the +protected Collection<URL> getAccessURLs()+ +method must be implemented to define the URL from where the configuration should be accessible. Hereby +multiple URLs can be provided, which are accesed in order as provided by the collection's iterator. The +first URL that is successfully accessed determines the configuration read and imported into the ++PropertySource+. + +[source, java] +----------------------------------------------- +public class RemotePropertySource extends BaseRemotePropertySource{ + /** Current remote property source default ordinal. */ + private static final int REMOTE_ORDINAL = 15000; + + @Override + public int getDefaultOrdinal(){ + return REMOTE_ORDINAL; + } + + @Override + protected Collection<URL> getAccessURLs() { + try { + String configServerUrl = System.getenv("CONFIG_SERVER"); + if(configServerUrl==null){ + configServerUrl = System.getProperty("configServer"); + } + if(configServerUrl==null){ + configServerUrl = "http://localhost:8888/config?scope=CLIENT&scopeId={clientId}&format=application/json"; + } + System.out.println("Reading config from " + configServerUrl.replace("{clientId}", Client.getClientId())); + return Arrays.asList(new URL[]{new URL(configServerUrl.replace("{clientId}", Client.getClientId()))}); + } catch (MalformedURLException e) { + Logger.getLogger(getClass().getName()).log(Level.WARNING, "Failed to configure remote config location,", e); + return Collections.emptySet(); + } + } + +} +----------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_resolver.adoc ---------------------------------------------------------------------- diff --git a/content/documentation/extensions/mod_resolver.adoc b/content/documentation/extensions/mod_resolver.adoc new file mode 100644 index 0000000..366c97e --- /dev/null +++ b/content/documentation/extensions/mod_resolver.adoc @@ -0,0 +1,126 @@ +:jbake-type: page +:jbake-status: published + += Apache Tamaya -- Extension: Resolver + +[[Core]] +== Tamaya Resolver (Extension Module) + +=== Overview + +Tamaya Resolver is an extension module. Refer to the +// @todo Fix the link to the modules documentation +link:modules.html[extensions documentation] +for further details about modules. + +Tamaya Resolver provides a dynamic resolution mechanism, which allows to use UNIX-styled (+${...}+ placeholder +expressions in your configuration values. The resolver hereby supports transitive resolution and also prevents +cycles to loop endlessly. + +=== Compatibility + +The module is based on Java 7, so it can be used with Java 7 and beyond. + +=== Installation + +To benefit from dynamic value resolution you only must add the corresponding dependency to your module: + +[source, xml, subs="verbatim,attributes"] +----------------------------------------------- +<dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-resolver</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + +The module automatically registers an according +PropertyFilter+ that is automatically called, whenever a value +is accessed. + +=== Available Resolvers + +Currently the module defined the following resolvers: + +.Available Resolvers +[cols="<.1,<.2,<.1"] +|======= +| _Expression_ +| _Description_ +| _Example_ + +| +conf:<configKey>+ +| Reads another configKey and replaces the expression with the value found. +| conf-ref=${conf:anotherConf.entryKey} + +| +resource:<resourceRef>+ +| Reads a resource from the current classpath and replaces the expression with the given text content. +| cp-ref=${resource:Testresource.txt} + +| +file:<fileRef>+ +| Reads a resource from the current classpath and replaces the expression with the given text content. +| file-ref=${file:c:\myFile.txt} + +|+url:<url>+ +|Reads an URL and replaces the expression with the given text content. +| url-ref=${url:http://www.google.com} + +|======= + +=== SPI: Implementing your own Resolvers + +The module also provides an easy but powerful SPI for adding your own resolver implementations. Basically the +first and most important thing to do is implementing the +ExpressionResolver+ interface: + +.Implementing a Custom Resolver +[source, java] +----------------------------------------------- +public class PwdDecrypter implements ExpressionResolver { + + @Override + public String getResolverPrefix() { + return "decrypt:"; + } + + @Override + public String evaluate(String expression) { + return decrypt(expression); + } + + private String decrypt(String s) { + ... + } +} +----------------------------------------------- + +Basically that is all you must do, after having registered the class with the +ServiceLoader+ it will be found +and loaded by the implementation. With that all expressions that start with the given prefix are passed to the +resolver, so all the following expressions will be sent to the implementation: + +[source,listing] +----------------------------------------------- +blabla ${decrypt:myname} +blabla ${decrypt:myname} foo blabla ${decrypt:myname} +----------------------------------------------- + +Hereby evaluation is repeated until no further change of values could be detetced. In case of a endless loop +the evaluation is broken after a (configurable) number of cycles. + + +Under the hood instances of +ExpressionResolver+ are managed by an implementation of the +ExpressionEvaluator+ +interface: + +[source, java] +----------------------------------------------- +public interface ExpressionEvaluator { + /** + * Evaluates the current expression. + * @param key the key, not null. + * @param value the value to be filtered/evaluated. + * @return the filtered/evaluated value, including null. + */ + String evaluateExpression(String key, String value); +} +----------------------------------------------- + +Implementing and registering this interface gives you full control, but in most cases yhou should be fine with +the default implementation in place. http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_resources.adoc ---------------------------------------------------------------------- diff --git a/content/documentation/extensions/mod_resources.adoc b/content/documentation/extensions/mod_resources.adoc new file mode 100644 index 0000000..3081149 --- /dev/null +++ b/content/documentation/extensions/mod_resources.adoc @@ -0,0 +1,155 @@ +:jbake-type: page +:jbake-status: published + += Apache Tamaya -- Extension: Resources + +[[Core]] +== Tamaya Resources (Extension Module) +=== Overview + +Tamaya Resources is an extension module. Refer to the +// @todo Fix the link to the modules page +link:modules.html[extensions documentation] for further details +about modules. + +Tamaya Resources defines some additional tools to locate resources in your classpath or file system based on descriptive +ant-styled resource patterns. To use this module add the following dependency: + +[source, listing, subs="verbatim,attributes"] +----------------------------------------------- +<dependency> + <grooupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-resources</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + + +The module's main entry point is the singleton class +org.apache.tamaya.resource.ConfigResources+. This class +provides access to a +ResourceResolver+ instance: + +[source,java] +----------------------------------------------- +ResourceResolver resolver = ConfigResources.getResourceResolver(); +----------------------------------------------- + +[source,java] +----------------------------------------------- +public interface ResourceResolver { + Collection<URL> getResources(Collection<String> expressions) {...} + Collection<URL> getResources(String... expressions) {...} + Collection<URL> getResources(ClassLoader classLoader, String... expressions){...} + Collection<URL> getResources(ClassLoader classLoader, Collection<String> expressions); +} +----------------------------------------------- + +Hereby the methods allow to resolve expressions to a collection of URLs. In case the expression is also targeting the +current classpath the target +ClassLoader+ to be used can be passed additionally. + +The default implementation provides resource resolution mechanism similar to the functionality offered by Spring. +So by default resources can be looked up + +* from files +* from the classpath +* optionally ant-styled expressions can be used. + +=== Valid Expression Examples + +There are numerous ways how a resource pattern can be defined. Following the most important variants +are listed: + +[source,listing] +----------------------------------------------- +// explicitly searching the file system +file:myroot/aa?a/*.file +file:myroot/b*/b?/*.file +file:myroot/**/*.file + +// explicitly searching the classpath +classpath:myroot/**/*.file +classpath:javax/annotation/*.class +classpath:javax/**/sql/*.class +classpath:javax/annotation/**/R*.class +classpath:javax/annotation/R?so*.class +classpath:META-INF/maven/org.apache.geronimo.specs/**/* + +// search both classpath and files +javax/annotation/*.class +javax/**/sql/*.class +javax/annotation/**/R*.class +javax/annotation/R?so*.class +META-INF/maven/org.apache.geronimo.specs/**/* +myroot/**/*.file +myroot/aa?a/*.file +myroot/b*/b?/*.file +----------------------------------------------- + +Summarizing the resources module provides useful functionality that helps to locate resources on the file system and +in the classpath. This can be used to implement +PropertySourceProvider+ implementations that are based on +corresponding resource path patterns instead of concrete files. + + +=== Overall Usage Example + +Given the functionality we can easily implement a +PropertySourceProvider+ that reads all files from a classpath +location, hereby traversing down all folders: + + +[source, java] +------------------------------------------------------------- +public class PathBasedPropertySourceProvider implements PropertySourceProvider { + + @Override + public Collection<PropertySource> getPropertySources() { + List<PropertySource> propertySources = new ArrayList<>(); + Collection<URL> resources = Resources.getResourceResolver().getResources("META-INF/cfg/**/*.properties"); + for(URL url:resources){ + Properties props = new Properties(); + try(InputStream is = url.openStream()){ + props.load(is); + propertySources.add(new PropertiesBasedPropertySource(url.toString(), props)); + } + catch(Exception e){ + e.printStackTrace(); + } + } + + return propertySources; + } + + private final static class PropertiesBasedPropertySource implements PropertySource { + private String name; + private Map<String,String> properties = new HashMap<>(); + + public PropertiesBasedPropertySource(String name, Properties props) { + this.name = name; + props.forEach((k,v) -> this.properties.put(k.toString(), v.toString())); + } + + @Override + public String getName() { + return name; + } + + @Override + public String get(String key) { + return properties.get(key); + } + + @Override + public Map<String, String> getProperties() { + return properties; + } + } +} +------------------------------------------------------------- + + +=== SPI + +The +ResourceResolver+ that is returned by the +ConfigResources+ singleton is determined by the +current +ServiceContext+, by default you can replace the default implementation by registering an +alternate implementation with an overriding +@Priority+ annotation added using the +ServiceLoader+. + +Additionally a +BaseResourceResolver+ class can be used to reduce the amount of code to be written +on your own. http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_server.adoc ---------------------------------------------------------------------- diff --git a/content/documentation/extensions/mod_server.adoc b/content/documentation/extensions/mod_server.adoc new file mode 100644 index 0000000..025da45 --- /dev/null +++ b/content/documentation/extensions/mod_server.adoc @@ -0,0 +1,366 @@ +:jbake-type: page +:jbake-status: published + += Apache Tamaya -- Extension: Configuration Server + +toc::[] + + +[[Remote]] +== Tamaya Configuration Server (Extension Module) +=== Overview + +The Tamaya server module provides support for providing scoped configuration using a http server serving JSON formatted +configuration properties. + + +=== 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-server</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + + +=== Providing configuration using the Tamaya Built-in Configuration Server + +THe most simple way for providing onfiguration ist to start the internal server: + +[source, java] +----------------------------------------------- +Server server = org.apache.tamaya.server.ConfigServer.createServer(); +server.start(port); +----------------------------------------------- + +This will start a simple server instance that serves the following URL patterns: + +* +GET /config+ provides access to the full configuration tree. +* +GET /config/filtered/${path}+ let you filter the configuration returned using regular expression (comma separated). + E.g. +/config/filtered/java,sun+ will return all configuration entries starting with _java_ and _sun_. + +Additionally the server module has the following options implemented, which can be passed as additional, optional +parameters: + +* +format+ allows to define the target format. By default the +ACCEPT+ header of the http request is checked, but this + setting can be explicitly controlled by passing tis parameter explicitly. The value is the expected MIME type to be + returned. By default the service supports the following types (refer to the SPI section later in this document for + options to adapt this): + ** text/html + ** text/plain + ** application/xml + ** text/json + +* +scope,scopeId+ allows to use a server-side preconfigured filter/combination policy to be applied for + evaluating the entries to be returned. Hereby the +scopeId+ paramter allows to address a certain scope. + As an example think of a scope +?scope=CLIENT&scopeId=client1+ to be passed as request parameters. This + tells the server module to lookup a configured scope named 'CLIENT' and access a +ConfigOperator+ for the + given scopeId 'client1'. The returned operator then can filter and combine any kind of entries to the + required client configuration (for client1). Refer to the scopes section for more details. + + +=== Using the Configuration Servlets + +Additionally to the fully built-in solution, it is also possible to integrate the Tamaya server module with a standard +Java EE servlet container. Tamaya provides 2 servlet implementations: + +* the servlet +org.apache.tamaya.server.FilteredConfigServlet+ can be used to register access to configurations + that also support filtering of the keys. The URL looks like + +---------------------------------------------------------- +http(s)://HOST/SERVLET_CONTEXT/PATHS?params + +where + HOST = host name incl port, e.g. 127.0.0.2:234 + SERVLET_CONTEXT = the base context and servlet context, e.g. /client/config/filtered + PATHS = A comma separated number of key paths to be filtered for being returned, e.g. + java,sun,client + params = the optional parameters (scope, scopeId and format) +---------------------------------------------------------- + +* the servlet +org.apache.tamaya.server.FullConfigServlet+ can be used to register access to configurations + that alwyas returns all items known. The URL looks like + +---------------------------------------------------------- +http(s)://HOST/SERVLET_CONTEXT?params + +where + HOST = host name incl port, e.g. 127.0.0.2:234 + SERVLET_CONTEXT = the base context and servlet context, e.g. /client/config/filtered + params = the optional parameters (scope, scopeId and format) +---------------------------------------------------------- + +==== Formatting used by Default + +The server module formats the configuration returned by default in thw following variants: + +.Formatting for +text/json+ + +[source, json] +----------------------------------------------- +{ + "java.vendor.url": "http://java.oracle.com/", + "java.vendor.url.bug": "http://bugreport.sun.com/bugreport/", + "java.vm.info": "mixed mode", + "java.vm.name": "Java HotSpot(TM) 64-Bit Server VM", + "java.vm.specification.name": "Java Virtual Machine Specification", + "java.vm.specification.vendor": "Oracle Corporation", + "java.vm.specification.version": "1.8", + "java.vm.vendor": "Oracle Corporation", + "java.vm.version": "25.45-b02", + "sun.arch.data.model": "64", + "sun.boot.class.path": "C:\apps\jdk18\jre\lib\resources.jar;C:\apps\jdk18\jre\lib\rt.jar;C:\apps\jdk18\jre\lib\sunrsasign.jar;C:\apps\jdk18\jre\lib\jsse.jar;C:\apps\jdk18\jre\lib\jce.jar;C:\apps\jdk18\jre\lib\charsets.jar;C:\apps\jdk18\jre\lib\jfr.jar;C:\apps\jdk18\jre\classes", + "sun.boot.library.path": "C:\apps\jdk18\jre\bin", + "sun.cpu.endian": "little", + "sun.cpu.isalist": "amd64", + "sun.desktop": "windows", + "sun.io.unicode.encoding": "UnicodeLittle", + "sun.java.command": "com.intellij.rt.execution.application.AppMain org.apache.tamaya.examples.remote.server.Start", + "sun.java.launcher": "SUN_STANDARD", + "sun.jnu.encoding": "Cp1252", + "sun.management.compiler": "HotSpot 64-Bit Tiered Compilers", + "sun.os.patch.level": "", + "{meta}class": "org.apache.tamaya.functions.FilteredConfiguration", + "{meta}info.filter": "java.v,sun", + "{meta}info.format": "application/json", + "{meta}info.timestamp": "1441463200571", + "{meta}timestamp": "1441463200571", + "{meta}type": "Configuration" +} +----------------------------------------------- + + +.Formatting for +application/xml+ + +[source, xml] +----------------------------------------------- +<configuration> + <entry key="java.vendor.url">http://java.oracle.com/</entry> + <entry key="java.vendor.url.bug">http://bugreport.sun.com/bugreport/</entry> + <entry key="java.vm.info">mixed mode</entry> + <entry key="java.vm.name">Java HotSpot(TM) 64-Bit Server VM</entry> + <entry key="java.vm.specification.name">Java Virtual Machine Specification</entry> + <entry key="java.vm.specification.vendor">Oracle Corporation</entry> + <entry key="java.vm.specification.version">1.8</entry> + <entry key="java.vm.vendor">Oracle Corporation</entry> + <entry key="java.vm.version">25.45-b02</entry> + <entry key="sun.arch.data.model">64</entry> + <entry key="sun.boot.class.path">C:\apps\jdk18\jre\lib\resources.jar;C:\apps\jdk18\jre\lib\rt.jar;C:\apps\jdk18\jre\lib\sunrsasign.jar;C:\apps\jdk18\jre\lib\jsse.jar;C:\apps\jdk18\jre\lib\jce.jar;C:\apps\jdk18\jre\lib\charsets.jar;C:\apps\jdk18\jre\lib\jfr.jar;C:\apps\jdk18\jre\classes</entry> + <entry key="sun.boot.library.path">C:\apps\jdk18\jre\bin</entry> + <entry key="sun.cpu.endian">little</entry> + <entry key="sun.cpu.isalist">amd64</entry> + <entry key="sun.desktop">windows</entry> + <entry key="sun.io.unicode.encoding">UnicodeLittle</entry> + <entry key="sun.java.command">com.intellij.rt.execution.application.AppMain org.apache.tamaya.examples.remote.server.Start</entry> + <entry key="sun.java.launcher">SUN_STANDARD</entry> + <entry key="sun.jnu.encoding">Cp1252</entry> + <entry key="sun.management.compiler">HotSpot 64-Bit Tiered Compilers</entry> + <entry key="sun.os.patch.level"></entry> + <entry key="{meta}class">org.apache.tamaya.functions.FilteredConfiguration</entry> + <entry key="{meta}info.filter">java.v,sun</entry> + <entry key="{meta}info.format">application/xml</entry> + <entry key="{meta}info.timestamp">1441463383687</entry> + <entry key="{meta}timestamp">1441463383687</entry> + <entry key="{meta}type">Configuration</entry> +</configuration> +----------------------------------------------- + + +.Formatting for +text/plain+ + +[source, text] +----------------------------------------------- + +Configuration: + java.vendor.url: http://java.oracle.com/, + java.vendor.url.bug: http://bugreport.sun.com/bugreport/, + java.vm.info: mixed mode, + java.vm.name: Java HotSpot(TM) 64-Bit Server VM, + java.vm.specification.name: Java Virtual Machine Specification, + java.vm.specification.vendor: Oracle Corporation, + java.vm.specification.version: 1.8, + java.vm.vendor: Oracle Corporation, + java.vm.version: 25.45-b02, + sun.arch.data.model: 64, + sun.boot.class.path: C:\apps\jdk18\jre\lib\resources.jar;C:\apps\jdk18\jre\lib\rt.jar;C:\apps\jdk18\jre\lib\sunrsasign.jar;C:\apps\jdk18\jre\lib\jsse.jar;C:\apps\jdk18\jre\lib\jce.jar;C:\apps\jdk18\jre\lib\charsets.jar;C:\apps\jdk18\jre\lib\jfr.jar;C:\apps\jdk18\jre\classes, + sun.boot.library.path: C:\apps\jdk18\jre\bin, + sun.cpu.endian: little, + sun.cpu.isalist: amd64, + sun.desktop: windows, + sun.io.unicode.encoding: UnicodeLittle, + sun.java.command: com.intellij.rt.execution.application.AppMain org.apache.tamaya.examples.remote.server.Start, + sun.java.launcher: SUN_STANDARD, + sun.jnu.encoding: Cp1252, + sun.management.compiler: HotSpot 64-Bit Tiered Compilers, + sun.os.patch.level: , + {meta}class: org.apache.tamaya.functions.FilteredConfiguration, + {meta}info.filter: java.v,sun, + {meta}info.format: text/plain, + {meta}info.timestamp: 1441463082020, + {meta}timestamp: 1441463082021, + {meta}type: Configuration +----------------------------------------------- + + +.Formatting for +application/html+ + +[source, html] +----------------------------------------------- +<html> +<head><title>System Configuration</title></head> +<body> +<h1>Sysem Configuration</h1> +<p>This view shows the system configuration of devbox-win at Sat Sep 05 16:30:59 CEST 2015.</p><pre> +Configuration: + java.vendor.url: http://java.oracle.com/, + java.vendor.url.bug: http://bugreport.sun.com/bugreport/, + java.vm.info: mixed mode, + java.vm.name: Java HotSpot(TM) 64-Bit Server VM, + java.vm.specification.name: Java Virtual Machine Specification, + java.vm.specification.vendor: Oracle Corporation, + java.vm.specification.version: 1.8, + java.vm.vendor: Oracle Corporation, + java.vm.version: 25.45-b02, + sun.arch.data.model: 64, + sun.boot.class.path: C:\apps\jdk18\jre\lib\resources.jar;C:\apps\jdk18\jre\lib\rt.jar;C:\apps\jdk18\jre\lib\sunrsasign.jar;C:\apps\jdk18\jre\lib\jsse.jar;C:\apps\jdk18\jre\lib\jce.jar;C:\apps\jdk18\jre\lib\charsets.jar;C:\apps\jdk18\jre\lib\jfr.jar;C:\apps\jdk18\jre\classes, + sun.boot.library.path: C:\apps\jdk18\jre\bin, + sun.cpu.endian: little, + sun.cpu.isalist: amd64, + sun.desktop: windows, + sun.io.unicode.encoding: UnicodeLittle, + sun.java.command: com.intellij.rt.execution.application.AppMain org.apache.tamaya.examples.remote.server.Start, + sun.java.launcher: SUN_STANDARD, + sun.jnu.encoding: Cp1252, + sun.management.compiler: HotSpot 64-Bit Tiered Compilers, + sun.os.patch.level: , + {meta}class: org.apache.tamaya.functions.FilteredConfiguration, + {meta}info.filter: java.v,sun, + {meta}info.format: text/html, + {meta}info.timestamp: 1441463459653, + {meta}timestamp: 1441463459654, + {meta}type: Configuration + +</pre> +</body> +</html> +----------------------------------------------- + +=== SPI + +==== Scopes + +As mentioned earlier in this document scopes can be used to define the exact configuration tree to be returned, e.g. +as a result of combining multiple sub trees. Following an example of the code to be written to return a configuration +that combines common client default entries with client specific entries: + +[source, java] +----------------------------------------------- +public class ClientScopeProvider implements ScopeProvider{ + + /** + * Access the unique scope name. + * @return the unique scope name. + */ + public String getScopeType(){ + return "CLIENT"; + } + + @Override + public ConfigOperator getScope(String scopeId) { + return c -> + ConfigurationFunctions.combine("Scoped Config CLIENT="+scopeId, + c.with(ConfigurationFunctions.sectionRecursive(true, "client.default")), + c.with(ConfigurationFunctions.sectionRecursive(true, "client." + scopeId)) + ); + } +} +----------------------------------------------- + +This class can be registered using the +ServiceContext+ in place. By default the +ServiceLoader+ is used, so you will +have to add the following to +META-INF/services/org.apache.tamaya.server.spi.ScopeProvider+: + +[source, listing] +----------------------------------------------- +my.full.packagename.ClientScopeProvider +----------------------------------------------- + +==== Adapting the Way Configuration is Derived + +Finally the effective readong and configuration handling logic can also be replaced or improved. This can be +done by registering your own implementation of the interface +ConfigProviderService+: + +[source, java] +------------------------------------------------ +public interface ConfigProviderService { + String getConfigurationWithPath(String path, String format, String scope, String scopeId, HttpServletRequest request); + String getConfiguration(String format, String scope, String scopeId, HttpServletRequest request); + void updateConfiguration(String payload, HttpServletRequest request); + void deleteConfiguration(String paths, HttpServletRequest request); +} +------------------------------------------------ + +By default the +ServiceContextManager+ uses the +java.util.ServiceLoader+ for component loading, so to replace the +default server code you must register a higher +@Priority+ implementation. + + +==== Replacing the Built-In Server + +We have seen earlier that starting a configuration server is pretty easy: + +[source, java] +----------------------------------------------- +Server server = org.apache.tamaya.server.ConfigServer.createServer(); +server.start(port); +----------------------------------------------- + +Nevertheless one may want to replace the used implementation of +Server+. This can be done easily by simply +registering an overriding implementation if the corresponding interface: + +[source, java] +----------------------------------------------- +public interface Server { + void start(int port); + boolean isStarted(); + void stop(); + void destroy(); +} +----------------------------------------------- + +==== The ScopeManager Singleton + +Finally whe implementing your own server, you might also benefit from the +ScopeManager+ singleton. Basically this +class loads all registered +ScopeProvider+ and manages the configured scope instances: + +[source, java] +----------------------------------------------- +public final class ScopeManager { + ... + + private ScopeManager(){} + + /** + * Get the scope given its name. + * @param scopeId the scope name + * @return the scope matching + * @throws ConfigException, if nos such scope is defined. + */ + public static ConfigOperator getScope(String scopeId, String target); + + /** + * Get the defined scope names. + * @return the defined scope names, never null. + */ + public static Set<String> getScopes(); + +} +----------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_spi-support.adoc ---------------------------------------------------------------------- diff --git a/content/documentation/extensions/mod_spi-support.adoc b/content/documentation/extensions/mod_spi-support.adoc new file mode 100644 index 0000000..7aca208 --- /dev/null +++ b/content/documentation/extensions/mod_spi-support.adoc @@ -0,0 +1,57 @@ +:jbake-type: page +:jbake-status: published + += Apache Tamaya -- Extension: Classloader Isolation Support + +toc::[] + + +[[SPISupport]] +== Tamaya SPI Support (Extension Module) +=== Overview + +The Tamaya SPI support module provides a few helpful base classes that can be used to implement some of the often +used SPI parts in Tamaya: + +* +BasePropertySource+ provides an abstract base class for implementation of your own PropertySources. +* +DefaultConfiguration+ provides you with a simple implementation of the +Configuration+ interface based on a + +ConfigurationContext+ provided. This is also very useful for mocking configuration during test execution, but + not only constraint to that use case. +* +DefaultConfigurationContext+ provides you with a working implementation of the +ConfigurationContext+. +* +EnumConverter+ is a converter implementation that can automatically select the currect enumeration values based + on a configured entry. +* +MapPropertySource+ implements a static property source based on +java.util.Map+. +* +PriorityServiceComparator+ compares arbitrary services based on their +@Priority+ annotations (also handling the + case, where no such annotation is present). +* +PropertiesResourcePropertySource+ is an implementation of a +PropertySource+ based on a +Properties+ instance, + lodable from any +URL+. ++ +PropertyConverterManager+ is a service class very useful, when implementing instances of +ConfigurationContext+. + It manages registered instances of +PropertyConverter+ and provides easy to use type conversion logic. ++ +PropertyFiltering+ provides another helpful class that manages +PropertyFilter+ instances and provides an + easy to use high level API. ++ +PropertySourceComparator+ provides an implementation that compares +PropertySources+ based on their +getOrdinal()+ + values and their class names. + + + +=== Compatibility + +The module is based on Java 7, so it will run on Java 7 and beyond. + + +=== Installation + +To benefit from Tamaya CDI integration you only must add the corresponding dependency to your module: + +[source, xml] +----------------------------------------------- +<dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-spisupport</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + +The component will not register any components but only providing portable base classes for some common SPI +implementation tasks. It only depends on the API, so it should be safely reusable also with other implementations +of the Tamaya API similarly. http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_spring.adoc ---------------------------------------------------------------------- diff --git a/content/documentation/extensions/mod_spring.adoc b/content/documentation/extensions/mod_spring.adoc new file mode 100644 index 0000000..3960dc1 --- /dev/null +++ b/content/documentation/extensions/mod_spring.adoc @@ -0,0 +1,134 @@ +:jbake-type: page +:jbake-status: published + += Apache Tamaya -- Extension: Spring Integration + +toc::[] + + +[[Remote]] +== Tamaya Spring Integration (Extension Module) +=== Overview + +Apache Tamaya currently provides two implementations also full integration for Spring: + +* A Spring +@Configuration+ implementation that also provides a Tamaya based version of + +org.springframework.context.support.PropertySourcesPlaceholderConfigurer+. +* +org.apache.tamaya.integration.spring.TamayaEnvironment+ is the Tamaya based implementation of the Spring + +Environment+ interface. +* +TamayaSpringPropertySource+ implements an additional Spring +PropertySource+. +* Finally +org.apache.tamaya.integration.spring.SpringConfigInjectionPostProcessor+ implements a Bean +PostProcessor+, + which adds all the full fledged Tamaya configuration capabilities to Spring. + + +=== Compatibility + +Both modules are based on Java 7, so they will run on Java 7 and beyond. The extension shown here works similarly +with Spring Framework as well as Spring Boot. + + +=== Installation + +To benefit from Tamaya Spring integration you only must one of the following dependencies to your module: + +[source, xml] +----------------------------------------------- +<dependency> + <groupId>org.apache.tamaya.ext</groupId> + <artifactId>tamaya-spring</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + + +=== Registering Tamaya Spring Configuration + +Basically to activate the Tamaya Spring support the most simple thing is to a enable the Tamaya package for being +scanned for Spring components, e.g. + +[source, xml] +-------------------------------------------------------- +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:context="http://www.springframework.org/schema/context" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> + + <context:annotation-config /> + <context:component-scan base-package="org.apache.tamaya.integration.spring"/> + + ... + +</beans> +-------------------------------------------------------- + +NOTE: Of course you can also use the newer +@ComponentScan+ annotation as described by the Spring documentation. + + +Similarly if you dont want to use component scanning you can configure things using plain old XML. Simply add the +following lines somewhere into one of your application context configuration files. + +[source, xml] +-------------------------------------------------------- +<bean id="tamayaInjectionProcessor" name="tamayaInjectionProcessor" class="org.apache.tamaya.integration.spring.SpringConfigInjectionPostProcessor"/> +<bean id="tamayaConfigProvider" name="tamayaConfigProvider" class="org.apache.tamaya.integration.spring.TamayaSpringConfig"/> +-------------------------------------------------------- + +=== Configuring your Context + +Done so enables you to use Tamaya as a backend for property resolution, e.g. +propertyValue+ as illustrated below +is resolved from the current Tamaya configuration. + +[source, xml] +-------------------------------------------------------- +<bean id="configuredBean" name="configuredBean" class="org.apache.tamaya.integration.spring.ConfiguredSpringBean"> + <property name="message" value="${propertyValue}"/> +</bean> +-------------------------------------------------------- + +=== Configuring your Beans + +Similarly you can inject any kind of configuration as supported by Tamaya into your Spring managed beans: + +[source, java] +-------------------------------------------------------- +** + * Created by Anatole on 25.09.2015. + */ +@ConfigDefaultSections +public class ConfiguredSpringBean { + + private String message; + + @Autowired + private Environment env; + + @Config("java.version") + private String javaVersion; + + @Config + @ConfigDefault("23") + private int testNumber; + + public String getJavaVersion(){ + return javaVersion; + } + + public int getTestNumber(){ + return testNumber; + } + + public Environment getEnv(){ + return env; + } + + public void setMessage(String message){ + this.message = message; + } + + public String getMessage() { + return message; + } +} +-------------------------------------------------------- + +Summarizing you get all the nice features of Tamaya out of the box running with your Spring code. http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/extensions/mod_yaml.adoc ---------------------------------------------------------------------- diff --git a/content/documentation/extensions/mod_yaml.adoc b/content/documentation/extensions/mod_yaml.adoc new file mode 100644 index 0000000..b7e53cb --- /dev/null +++ b/content/documentation/extensions/mod_yaml.adoc @@ -0,0 +1,112 @@ +:jbake-type: page +:jbake-status: published + += Apache Tamaya -- Extension: Builder + +toc::[] + + +[[BuilderCore]] +== Tamaya YAML (Extension Module) +=== Overview + +The Tamaya YAML module provides support for reading configuration using the YAML format (yaml.org). YAML hereby +use intendation for expressing hierarchy, which makes yaml configuration files very easily readable and compact. + + +=== Compatibility + +The YAML module is based on Java 7, so it will 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-yaml</artifactId> + <version>{tamaya_version}</version> +</dependency> +----------------------------------------------- + +This extension also transitively requires the +tamaya.formats+ module. + +=== Reading configuration in YAML + +For reading YAML based onfiguration most easily a +YAMLFormat+ can be provided: + +[source, java] +----------------------------------------------- +ConfigurationData dataRead = ConfigurationFormats.readConfig( + getClassLoader().getResource("myFileConfig.yaml"), new YAMLFormat())); +----------------------------------------------- + +=== Examples + +The YAML module adds instances of +ConfigurationFormat+ so YAML configuration can be read and mapped to the +according property values. E.g. the following file is a simple and correct YAML configuration: + +[source,yaml] +---------------------------------------------------------------- +invoice: 34843 +date : 2001-01-23 +bill-to: &id001 + given : Chris + family : Dumars + address: + lines: | + 458 Walkman Dr. + Suite #292 + city : Royal Oak + state : MI + postal : 48046 +ship-to: *id001 +product: + - sku : BL394D + quantity : 4 + description : Basketball + price : 450.00 + - sku : BL4438H + quantity : 1 + description : Super Hoop + price : 2392.00 +tax : 251.42 +total: 4443.52 +comments: + Late afternoon is best. + Backup contact is Nancy + Billsmer @ 338-4338. +---------------------------------------------------------------- + +Hereby the above file, by default is mapped as follows into +Map<String,String>+ typed properties: + +[source,listing] +---------------------------------------------------------------- +invoice -> 34843 +date -> Tue Jan 23 01:00:00 CET 2001 +bill-to.family -> Dumars +bill-to.given -> Chris +bill-to.address.state -> MI +bill-to.address.postal -> 48046 +bill-to.address.city -> Royal Oak +bill-to.address.lines -> 458 Walkman Dr. +Suite #292 + +ship-to.given -> Chris +ship-to.address.state -> MI +ship-to.family -> Dumars +ship-to.address.postal -> 48046 +ship-to.address.city -> Royal Oak +ship-to.address.lines -> 458 Walkman Dr. +Suite #292 + +product -> {sku=BL394D, quantity=4, description=Basketball, price=450.0},{sku=BL4438H, quantity=1, description=Super Hoop, price=2392.0} +_product.collection-type -> List + +tax -> 251.42 +total -> 4443.52 +comments -> Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338. +---------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/documentation/quickstart.adoc ---------------------------------------------------------------------- diff --git a/content/documentation/quickstart.adoc b/content/documentation/quickstart.adoc new file mode 100644 index 0000000..14ab438 --- /dev/null +++ b/content/documentation/quickstart.adoc @@ -0,0 +1,189 @@ +:jbake-type: page +:jbake-status: published + +== Apache Tamaya: Quickstart + + +The fastest way to start with Tamaya is just using the _Core_ implementation, +implementing the **API** in small, minimalistic way. For that add the following +Maven dependency to your project: + + +[source,xml,subs="verbatim,attributes"] +---- +<dependency> + <groupId>{tamaya_mvn_group_id}</groupId> + <artifactId>tamaya-core</artifactId> + <version>{tamaya_version}</version> +</dependency> +---- + +Given that you can add your configuration properties to the following locations in your classpath: + +[source] +---- +META-INF/javaconfiguration.properties +---- + +Additionally also system properties are taken into account, hereby overriding the default properties. Overall +Tamaya by default defines the following configuration model per default (most significant first): + +. System Properties +. `META-INF/javaconfiguration.properties` + +There many modules that extend the capabilities of Tamaya. +These modules doe not depend on core, so alternative +implementations of the Tamaya API should work similarly. + + +=== Multiple configuration files + +By default you can provide multiple `javaconfig.properties` files, e.g. as part +of multiple jars loaded into your system. The system internally creates one +`PropertySource` for each file found on the classpath. All `PropertySource` +instances created are ordered by their ordinal value (an int). + +Tamaya Core defines the following default ordinals (used, if no custom ordinal is defined): + +[width=70] +[cols="3,1", option="headers"] +|=== +| Source | Ordinal +| System Properties | 400 +| Environment Variables | 300 +| Java Configuration Properties | 100 +|=== + +That means that the value of a configuration variable `x` overhanded via `-Dx=yes` has +a higher precedence then the entry for configuration variable `x` specified in a `javaconfig.properties` +as `x=no`. + +These ordinal values can be either hardcoded, or be dynamically +configurable as key within each configuration resource. The ladder can be done by defining a special +Tamaya ordinal value as follows: + + +[source] +---- +# override default Tamaya ordinal for property files +tamaya.ordinal=123 +---- + +This assigns an ordinal of 123 to each entry in that configuration resource. + +=== Using additional features of Tamaya + +There many modules that extend the capabilities of +Tamaya. These modules doe not depend on core, so alternative +implementations of the Tamaya API should work similarly. Following a +small extract of most important modules available (or available soon): + +==== Dynamic Resolution and Value Placeholders + +[source,xml,subs="verbatim,attributes"] +---- +<dependency> + <artifactId>org.apache.tamaya.ext</id> + <artifactId>tamaya-resolver</artifactId> + <version>{tamaya_version}</version> +</dependency> +---- + +// @todo Auf Modulliste verweisen für vollständigen Ãberblick +With that it is possible to define values with Unix styled placeholders that are +resolved on configuration access, e.g. +`mykey=my${dynamicValue}´. For further details refer to the module documentation. +This module also provides a `Resolver` singleton: + +[source,java] +---- +String myExpression = ...; +String resolved = Resolver.evaluateExpression(myExpression); +---- + + +==== Ant-styled Path Resolution of Resources + +[source,xml,subs="verbatim,attributes"] +---- +<dependency> + <artifactId>org.apache.tamaya.ext</id> + <artifactId>tamaya-resolution</artifactId> + <version>{tamaya_version}</version> +</dependency> +---- + +This module provides a `Resolver` singleton that allows to +resolve configuration resources using a ant-styled resource +description, e.g. + + +[source,xml,subs="verbatim,attributes"] +---- +Collection<URL> urls = ResourceResolver.getResources("META-INF/cfg/**/*.properties"); +---- + +For further details refer to the module documentation. + + +==== Configuration Injection + +[source,xml,subs="verbatim,attributes"] +---- +<dependency> + <artifactId>org.apache.tamaya.ext</id> + <artifactId>tamaya-inject</artifactId> + <version>{tamaya_version_development}</version> +</dependency> +---- + +With this extension you can let Tamaya inject configuration into instances of +annotated classes or let Tamaya implement a configuration template. + +Corresponding configuration: + +[source,xml,subs="verbatim,attributes"] +---- +public class MyType { + @ConfiguredProperty("name") + private String typeName; + + public String getName() { + return name; + } +} + +MyType type = new MyType(); +ConfigurationInjector.configure(type); +---- + +Or the same as template: + +[source,xml,subs="verbatim,attributes"] +---- +public interface MyTypeTemplate { + @ConfiguredProperty("name") + public String getName(); +} + +MyTypeTemplate type = ConfigurationInjector.createTemplate(MyTypeTemplate.class); +---- + +Currently the following resolvers are available: + +[width="60"] +[cols="1,4"] +|=== +| Conf +| Cross-reference to another configuration entry + +| URL +| Referencing a resource addressable by an URL. + +| File +| Reference to a file, replacing the expression with the file's text value. + +| Resource +| Reference to classpath resource, replacing the expression with the resource's text value. + +|===