http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/extensions/mod_resolver.adoc ---------------------------------------------------------------------- diff --git a/content/extensions/mod_resolver.adoc b/content/extensions/mod_resolver.adoc deleted file mode 100644 index 366c97e..0000000 --- a/content/extensions/mod_resolver.adoc +++ /dev/null @@ -1,126 +0,0 @@ -: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/extensions/mod_resources.adoc ---------------------------------------------------------------------- diff --git a/content/extensions/mod_resources.adoc b/content/extensions/mod_resources.adoc deleted file mode 100644 index 3081149..0000000 --- a/content/extensions/mod_resources.adoc +++ /dev/null @@ -1,155 +0,0 @@ -: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/extensions/mod_server.adoc ---------------------------------------------------------------------- diff --git a/content/extensions/mod_server.adoc b/content/extensions/mod_server.adoc deleted file mode 100644 index 025da45..0000000 --- a/content/extensions/mod_server.adoc +++ /dev/null @@ -1,366 +0,0 @@ -: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/extensions/mod_spi-support.adoc ---------------------------------------------------------------------- diff --git a/content/extensions/mod_spi-support.adoc b/content/extensions/mod_spi-support.adoc deleted file mode 100644 index 7aca208..0000000 --- a/content/extensions/mod_spi-support.adoc +++ /dev/null @@ -1,57 +0,0 @@ -: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/extensions/mod_spring.adoc ---------------------------------------------------------------------- diff --git a/content/extensions/mod_spring.adoc b/content/extensions/mod_spring.adoc deleted file mode 100644 index 3960dc1..0000000 --- a/content/extensions/mod_spring.adoc +++ /dev/null @@ -1,134 +0,0 @@ -: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/extensions/mod_yaml.adoc ---------------------------------------------------------------------- diff --git a/content/extensions/mod_yaml.adoc b/content/extensions/mod_yaml.adoc deleted file mode 100644 index b7e53cb..0000000 --- a/content/extensions/mod_yaml.adoc +++ /dev/null @@ -1,112 +0,0 @@ -: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/quickstart.adoc ---------------------------------------------------------------------- diff --git a/content/quickstart.adoc b/content/quickstart.adoc deleted file mode 100644 index 14ab438..0000000 --- a/content/quickstart.adoc +++ /dev/null @@ -1,189 +0,0 @@ -: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. - -|=== http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/source.adoc ---------------------------------------------------------------------- diff --git a/content/source.adoc b/content/source.adoc deleted file mode 100644 index 441bec8..0000000 --- a/content/source.adoc +++ /dev/null @@ -1,23 +0,0 @@ -:jbake-type: page -:jbake-status: published - -:sectnums: yes - -= Apache Tamaya: Sources - -== Source Code Repositories - -The current source code can be found at: - - - http://git-wip-us.apache.org/repos/asf/incubator-tamaya.git (read-only) - - https://git-wip-us.apache.org/repos/asf/incubator-tamaya.git - -Alternatively there is also a GitHub read-only mirror at -https://github.com/apache/incubator-tamaya[https://github.com/apache/incubator-tamaya^]. - -The GitHub mirror also provides the project as downloadable zip archive. - -== Contributions - -If you like to contribute to Apache Tamaya please also refer also to our -<<devguide.adoc#contributing-workflow,section on contributing to Apache Tamaya>>. http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/content/usecases.adoc ---------------------------------------------------------------------- diff --git a/content/usecases.adoc b/content/usecases.adoc deleted file mode 100644 index 0d0d4e0..0000000 --- a/content/usecases.adoc +++ /dev/null @@ -1,488 +0,0 @@ -:jbake-type: page -:jbake-status: published - -== Apache Tamaya: Use Cases and Requirements - -toc::[] - -== Use Cases - -=== Simple Access - -Users want to be able to access configuration in a unified way both in SE and EE. EE may provide additional -mechanism, such as injection, but the SE mechanisms should work as well, so any code written in SE is fully -portable to EE as well. -This can only be achieved by providing a static accessor, e.g. - -[source,java] ------------------------------------------------------------- -Configuration config = Configuration.current(); ------------------------------------------------------------- - -The call above should work exactly the same in EE. To enable this the static call must be delegated in the -internals of the singleton, depending on the runtime. In EE the executing component can behave contextually, -or even be loaded within the CDI environment (at least for post loading, application runtime aspects, but not earlier). - -Additionally in EE it should also be possible to inject Configuration, which gives you the same results as the call -above: - -[source,java] ------------------------------------------------------------- -@Inject -private Configuration cfg; ------------------------------------------------------------- - - -=== Simple Lookup of Properties - -Users just want to create a configuration ad hoc, from given property files. The -files could be locally in the file system, on the classpath. - -Tamaya should provide a simple Java API for accessing key/value based configuration. Hereby users want to access -properties as simple String values. - -Hereby returning Java 8 Optional values must be considered as well, instead of returning +null+. - - -=== Value Placeholders - -Users just want to to be able to add placeholders to the values of configuration (not the keys). The mechanisms for -resolving the placeholders hereby should be not constraint to one single lanmguage like EL. Instead of different -replacement strategies should be selectable, e.g. by prefixing an expression with the name of the resolver that -should do the work (eg +"blabla ${env:HOME} using Java version ${sys:java.version}."+. -This allows resolution mechanism to be isolated easily and also allows to use simpler mechanisms, if no more complex -ones like EL are required. This is especially useful to deal with low resource environment like ME. - - -=== Type Safe Properties - -Users just want to access properties not only as Strings, but let Tamaya do the conversion to the required -or the configred target type. By defauklt all java.ui.lang wrapper and primitive types should be supported, but also -other common types like date/time types, math numeric types and more. - -It must be possible that users can register their own custom types. - -Finally users also want to be able to dynamically provide or override type adaption (conversion), when reading a value, -for a certain key/value pair. - - -=== Configuration Templates - -Users want to be able to let Tamaya implement an interface template based on configuration. -This use case is pretty similar to the injection use case. Basically the values are not injected, -but cached within the template proxy returned, e.g. as +DynamicValue+. -Similarly it could even be possible to define callback methods (default methods) -or register listeners to DynamicValue instances returned. - -Templates hereby can easily be managed, but provide a excellent mechanism to provide type-safe configuration -to clients in a very transparent way. Details can be controlled by using the same annotations as for -normal configuration injection. - - -=== Java 8 Functional Support - -Users want to be able to benefit from the new programming styles introduced with Java 8. Configuration -should provide extension points for different aspects, where additional code can be hooked in easily. -In short: were possible functional interfaces should be modelled. - -Examples: - -* code that converts a configuration to another kind of configuration: +UnaryOperator<Configuration>+ -* code that creates any kind of result based on a configuration: +Function<Configuration,T>+ -* Adapters for type conversion are defined as +Function<String,T>+ -* Key, value filters ccan be modelled as +BiFunction<String,String,String>+ -* etc. - - -=== Configuration Locations - -Users want to be able to - -* read configuration from different locations. -* By default classpath and file resources are - supported. But similarly remote access using a JSON ReST call should be possible. -* Tamaya should define a JSON and XML format for configuration. -* Configuration locations should be scannable using ant-styled resource patterns, if possible. -* Scanning and reading logic can be modularized by using a +ConfigReader+ interface. - - -=== Configuration Formats - -Users want to be able to use the format they prefer. - -* properties, xml-properties and ini-format should be supported by default -* Other/custom formats should be easily addable by registering or providing the format on configuration evaluation (read). -* When possible Tamaya should figure out which format to be used and how the InputStream should be correctly - interpreted. - - -=== Multiple Configurations - -When systems grow they must be modularized to keep control. Whereas that sounds not really fancy, it leads to additional -aspects to be considered by a configuration system. - -* Different code modules, libraries, plugins or products want to have their "own" separated configuration. -* Similar it should be possible to add fully specific additional configurations. - -The default configuration hereby should always be present, whereas additional configurations are optional. -Users want to be able to check the availability of such an additional configuration. - -Of course, additional configuration must be identifiable. The best way to do is to be discussed, nevertheless the -mechanism must not depend on Java EE and the identifying keys must be serializable easily. -Basically simple names are sufficient and woukld provide exact this required functionality. - - -=== External Configuration - -Users want to be able to replace, override, extend or adapt any parts or all of an existing configuration from -external sources. -This also must be the case for multi-context environments, where the context identifiers are -the only way to link to the correct remote configuration. - - -=== Context Dependent Configuration - -In multi tenancy setups or complex systems a hierarchical/graph model of contexts for configurations is required, or different runtime contexts are executed in parallel -within the same VN. What sounds normal for EE also may be the case for pure SE environments: - -* Users want to be able to model different layers of runtime context -* Users want to identify the current layer, so configuration used may be adapted. - - - -=== Dynamic Provisioning (UC8) - -In Cloud Computing, especially the PaaS and SaaS areas a typical use case would be that an application (or server) -is deployed, configured and started dynamically. Typically things are controlled by some "active controller components", -which are capable of - -* creating new nodes (using IaaS services) -* deploying and starting the required runtime platform , e.g. as part of a PaaS solution. -* deploying and starting the application modules. - -All these steps require some kind of configuration. As of today required files are often created on the target node -before the systems are started, using proprietary formats and mechanism. Similarly accessing the configuration in place -may require examining the file system or using again proprietary management functions. Of course, a configuration -solution should not try to solve that, but it can provide a significant bunch of functionality useful in such scenarios: - -* provide remote capabilities for configuration -* allow configuration to be updated remotely. -* allow client code to listen for configuration changes and react as needed. - - -=== Minimal Property Source SPI - -Users expect that implementing an additional configuration property source is as easy as possible. -So there should be an SPI defined that allows any kind of data source to be used for providing configuration data. -The interface to be implemented is expected to be minimal to reduce the implementation burden. Default -methods should be used where possible, so only a few methods are expected to be required to implement. - - -=== Scannable Properties - -If possible configuration should be scannable, meaning it should be possible to evaluate the keys available. -The corresponding capabilities should be accessible by a +isScannable()+ method. - - -=== Combine Configurations - -Users want to be able to combine different configurations to a new configuration instance. -Hereby the resulting configuration can be - -* a union of both, ignoring duplicates (and optionally log them) -* a union of both, duplicates are ignored -* a union of both, conflicts are thrown as ConfigException -* an intersection of both, containing only keys present and equal in both configurations -* an arbitrary mapping or filter, modelled by an +CombinationPolicy+, which basically can be modelled - as +BiFunction<String, String, String>+, hereby - ** a result of +null+ will remove the key - ** any other result will use the value returned as final value of the combination. - - -=== MX/ReST Management - -Users want to be have comprehensive management support, which should allow - -* to change configuration -* to remove configuration -* to view configuration and its provider details - - -=== Adaptable Service Context - -Tamaya should support an adaptable +ServiceContext+ to resolve any kind of implememntation services, both API services as core -framework services. The +ServiceContext+ should be dynamically replecable by configuring an alternate instance of -using the Java *ServiceContet+. - -This decouples component usage from its load and management part and als greatly simplifies integration with -new/alternate runtime environments. -The service context is exptected to provide - -* single singleton instances: these service can be cached. -* access to multiple instances which implement some commons SPI interface. -* as useful priorization of components is done by the model itself. - - -=== Configuration Injection - -Users want to be able to polulate configured items by injecting configured values. Hereby - -* the lifecycle of the instances is not managed by Tamaya -* all references to items configured are managed as weak references, to prevent memoryleaks. -* Injection should if possible evaluate the properties by defaults. Even properties without - any annotations are possible. -* Users expect to exclude certain properties from calculation -* Beside injection of properties it is also possible to call setter methods with one parameter similarly. -* Basically injection is performed, when the instance is passed to the Tamaya configuration system. It should also - be possible to inject/provide final values, especially Strings. Changes on configured values should be - reflected in the current value. Setters methods similarly can be called again, with the new values, on changes. -* Users expect to control dynamic values and recall of setter methods, basically the following strategies should be - supported: - ** inject only once and ignore further changes. - ** reinject/reinitialize on each change - -* Dynamic Values can easily be modeled as +ConfiguredValue+ instances, which should have the following functionality: - ** access the current value - ** access the new value - ** access the latest value access time in ms - ** access the latest value update time in ms - ** evaluate easily if the value has changed since the last access - ** accept the change - *** as a shortcut it should be possible to accept the change on access of the value implicitly, hereby always accessing - the latest valid value. - ** ignore the change - ** register +Consumer<DynamicValue>+ liasteners to listen on the changes (ans also removing them later again). - -All observing functionality can be done completely asynchronously and in parallel. - - -[[Requirements]] -== Requirements -=== Core Configuration Requirements -==== General - -Tamaya must provide a Java SE API for accessing key/value based configuration. Hereby - -* +Configuration+ is modelled by an interface -* +Configuration+ is organized as key/value pairs, using a subset of functionality present on +Map<String,String>+ as - follows: - ** access a value by key (+get+) - ** check if a value is present (+containsKey+) - ** get a set of all defined keys (+keySet+) - ** a configuration must be convertible to a +Map+, by calling +toMap()+ - ** a configuration must provide access to its meta information. -* +Configuration+ value access methods must never return null. -* The API must support undefined values. -* The API must support passing default values, to be returned if a value is undefined. -* The API must allow to throw exceptions, when a value is undefined. Customized exceptions hereby should be supported. -* Properties can be stored in the classpath, on a file or accessible by URL. -* Properties can be stored minimally in properties, xml-properties or ini-format. - - -==== Minimalistic Property Source - -For enabling easy integration of custom built configuration sources a minimalistic API/SPI must be defined, that - -* is modelled by an interface -* is a minimal subset of +Configuration+ necessary to implement a configuration. -* must be convertible to a "Configuration+. - -==== Extension Points - -For supporting more complex scenarios, +Configuration+ - -* must implement the composite pattern, meaning new +Configuration+ instances can be created by combining existing - configurations. -* must be adaptable, by creating a new configuration by applying a +UnaryOperator<COnfiguration>+ to it. -* must be queryable, by passing a +ConfigQuery+ to an +Configuration+ instance. - - -==== Type Safety - -Besides Strings +Configuration+ should also support the following types: - -* Primitive types -* Wrapper types -* All other types (by using a +PropertyAdapter+ - -Hereby type conversion should be done as follows: - -. Check if for the given target type an explicit adapter is registered, if so, use the registered adapter. -. If no adapter is present, check if the target type T has static methods called +T of(String), T getInstance(String), T valueOf(String), T from(String)+. If so -use this method to create the non value of T. -. Check if the target type has a constructor T(String). If so, try to instantiate an instance using the constructor. -. Give up, throw a IllegalArgument exception. - -=== Configuration Fomats - -By default Tamaya support the following configuration formats: - -* .properties -* .xml properties -* .ini files - -It must be possible to add additional formats by registering them with the current +ServiceContext+. - -=== Mutability - -* Configurations can be mutable, mutability can be accessed as a property. -* Configuration can be changed by collecting the changes into a +ConfigCHangeSet+ and apply this set to the - given +Configuration+ instance. -* Besides the points above, +Configuration+ is immutable. - -=== Serializability and Immutability of Configuration - -* Configuration is modelled as a service. Therefore serialization may not work. This can be mitigated by adding - a freeze feature, where the know key/value pairs are extracted into an immutable and serializable form. - -=== Configuration Combination Requirements - -At least the following composition policies must be supported: - -* override: subsequent entries override existing ones. -* aggregate-exception: key/values were added, in case of conflicts a +ConfigException+ must be thrown. -* aggregate-ignore-duplicates: similar to union, whereas duplicates are ignored (leaving the initial value loaded). -* aggregate-combine: conflicting entries were resolved by adding them both to the target configuration by - redefining partial keys. -* custom: any function determining the key/values to be kept must be possible - -When combining configuration it must also be possible to override (file/classpath) configuration by - -* system properties. -* command line arguments. - - -=== Configuration Injection - -As metnioned configuration can be injected by passing a unconfigured instance of an annotated class to the -+Configuration.configure+ static method: - -[source, java] -.Configuring a POJO ----------------------------------------------------- -MyPojo instance = new MyPojo(); -Configuration.configure(instance); ----------------------------------------------------- - -Hereby -* It must be possible to define default values to be used, if no valid value is present. -* It must be possible to define dynamic expressions, at least for default values. -* The values configured can be reinjected, if the underlying configuration changes. This should also be the case - for final classes, such as Strings. -* Reinjection should be controllable by an loading policy. -* It must be possible to evaluate multiple keys, e.g. current keys, and as a backup deprecated keys - from former application releases. -* It must be possible to evaluate multiple configurations. -* The type conversion of the properties injected must be configurable, by defining a +PropertyAdapter+. -* The value evaluated for a property (before type conversion) must be adaptable as well. -* It must be possible to observe configuration changes. - -The following annotations must be present at least: - -* *@ConfiguredProperty* defining the key of the property to be evaluated. It takes an optional value, defining the - property name. It must be possible to add multiple annotations of this kind to define an order of evaluation - of possible keys. -* *@DefaultValue* (optional) defines a default String value, to be used, when no other key is present. -* *@WithConfig* (optional) defines the name of the configuration to be used. Similar to +@ConfiguredProperty+ multiple - configuration can be defined for lookup. -* *@WithConfigOperator* allows to adapt the String value evaluated, *before* it is passed as input to injection or - type conversion. -* *@WithPropertyAdapter* allows to adapt the conversion to the required target type, hereby overriding any default - conversion in place. -* *@WithLoadPolicy* allows to define the policy for (re)injection of configured values. -* *@ObservesConfigChange* allows to annotate methods that should be called on configuration changes. -* *@DefaultAreas" allows to define a key prefix key to be used for the configured key, if no absolute key - is defined. - -=== Configuration Templates - -For type safe configuration clients should be able to define an interface and let it implement by the -configuration system based on +Configuration+ available: - -* Clients define an interface and annotate it as required (similar to above) -* The interface methods must not take any arguments -* The configuration system can be called to return such an interface implementation. -* The configuration system returns a proxy hereby providing type-safe access the values required. -* Similar to configured types also templates support multiple values and custom adapters. -* It is possible to listen on configuration changes for templates, so users of the templates - may react on configuration changes. - -The following snippet illustrates the requirements: - -[source, java] -.Type Safe Configuration Template Example ----------------------------------------------------- -public interface MyConfig { - - @ConfiguredProperty("myCurrency") - @DefaultValue("CHF") - String getCurrency(); - - @ConfiguredProperty("myCurrencyRate") - Long getCurrencyRate(); - - @ConfigChange - default configChanged(ConfigChange event){ - ... - } - -} ----------------------------------------------------- - -Templates can be accessed by calling the +Configuration.current(Class)+ method: - -[source, java] -.Accessing a type safe Configuration Template ----------------------------------------------------- -MyConfig config = Configuration.current(MyConfig.class); ----------------------------------------------------- - -[[RequirementsServer]] -=== Server Configuration Requirements - -* Ensure Configuration can be transferred over the network easily. -* Beside serializability text based formats for serialization in +XML+ and +JSON+ must be defined. -* A management API must be defined, which allows to inspect the configuration in place, e.g. using - JMX or REST services. - -[[RequirementsJavaEE]] - -Java EE leads to the following requirements: - -* Configuration must be contextual, depending on the current runtime context (e.g. boot level, ear, war, ...). -* Hereby contextual aspects can even exceed the levels described above, e.g. for SaaS scenarios. -* Resources can be unloaded, e.g. wars, ears can be restarted. -* The different contextual levels can also be used for overriding, e.g. application specific configuration -may override ear or system configuration. -* Configuration may be read from different sources (different classloaders, files, databases, remote locations). -* Configuration may be read in different formats (deployment descriptors, +ServiceLoader+ configuration, alt-DD feature, ...) -* JSF also knows the concept of stages. -* Many SPI's of Java EE require the implementation of some well defined Java interface, so it would be useful if the - configuration solution supports easy implementation of such instances. -* In general it would be useful to model the +Environment+ explicitly. -* Configuration used as preferences is writable as well. This requires mutability to be modelled in way, without the - need of synchronization. -* JNDI can be used for configuration as well. - -[[RequirementsMultitenancy]] - -Configurations made in the tenant or user layer override the default app configuration etc., so - -* It must be possible to structure Configuration in layers that can override/extend each other. -* The current environment must be capable of mapping tenant, user and other aspects, so a corresponding configuration - (or layer) can be derived. - -[[RequirementsExtensions]] -=== Extensions Requirements - -It must be possible to easily add additional functionality by implementing external functional interfaces operating -on +Configuration+. - -* +UnaryOperator<Configuration>+ for converting into other version of +Configuration+. -* +ConfigQuery<T>+ extending +Function<T, Configuration>+. - -[[RequirementsNonFunctional]] -=== Non Functional Requirements -THe following non-functional requirements must be met: - -* tbd http://git-wip-us.apache.org/repos/asf/incubator-tamaya-site/blob/ede865e4/templates/menu.thyme ---------------------------------------------------------------------- diff --git a/templates/menu.thyme b/templates/menu.thyme index 036d68c..eea628e 100644 --- a/templates/menu.thyme +++ b/templates/menu.thyme @@ -19,15 +19,29 @@ <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+'index.html'">Home</a></li> - <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+'quickstart.html'">Quickstart</a></li> - <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+'index.html'">Documentation</a></li> - <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+'/apidocs/index.html'">API</a></li> - <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+'index.html'">Development</a></li> - <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+'index.html'">Releases</a></li> <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+'about.html'">About</a></li> - <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+'sitemap.xml'">Sitemap</a></li> - <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+${config.feed_file}">Subscribe</a></li> -<!-- + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Documentation <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+'documentation/usecases.html'">Use Cases and Requirements</a></li> + <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+'documentation/quickstart.html'">Quickstart</a></li> + <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+'documentation/api.html'">API</a></li> + <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+'documentation/core.html'">Core</a></li> + <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+'documentation/extensions.html'">Extension Guide</a></li> + <li class="divider"></li> + <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+'apidocs/index.html'">Javadoc ${tamaya_version} (external)</a></li> + </ul> + </li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown">Development <b class="caret"></b></a> + <ul class="dropdown-menu"> + <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+'development/source.html'">Sources</a></li> + <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+'development/community.html'">Community</a></li> + <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+'devguide.html'">Development Guide</a></li> + <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+'release-guide.html'">Release Guide</a></li> + </ul> + </li> +<!-- Example: <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a> <ul class="dropdown-menu"> @@ -41,6 +55,8 @@ </ul> </li> --> + <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+'sitemap.xml'">Sitemap</a></li> + <li><a th:with="rootpath=(${content.rootpath != null} ? ${content.rootpath} : '')" th:href="${rootpath}+${config.feed_file}">Subscribe</a></li> </ul> </div><!--/.nav-collapse --> </div>
