tamaya-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pottlin...@apache.org
Subject [1/5] incubator-tamaya-site git commit: TAMAYA-186: Add existing pages.
Date Mon, 31 Oct 2016 21:34:42 GMT
Repository: incubator-tamaya-site
Updated Branches:
  refs/heads/master 90f34d22f -> 3d91bad59

diff --git a/content/usecases.adoc b/content/usecases.adoc
new file mode 100644
index 0000000..19bbca6
--- /dev/null
+++ b/content/usecases.adoc
@@ -0,0 +1,506 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//   http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// include::temp-properties-files-for-site/attributes.adoc[]
+:jbake-type: page
+:jbake-status: published
+== Apache Tamaya: Use Cases and Requirements
+== 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.
+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
+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
+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
+=== 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
+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.
+should provide extension points for different aspects, where additional code can be hooked
in easily.
+In short: were possible functional interfaces should be modelled.
+* 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
+* 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
+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 identiofy 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
+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.
+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
+* 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
+=== 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
+. 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
+=== 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
+* 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();
+* 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
+  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+
+  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
+* *@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);
+=== 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
+* A management API must be defined, which allows to inspect the configuration in place, e.g.
+   JMX or REST services.
+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
+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.
+Configurations made in the tenant or user layer override the default app configuration etc.,
+* It must be possible to structure Configuration in layers that can override/extend each
+* The current environment must be capable of mapping tenant, user and other aspects, so a
corresponding configuration
+  (or layer) can be derived.
+=== 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>+.
+=== Non Functional Requirements
+THe following non-functional requirements must be met:
+* tbd

diff --git a/jbake.properties b/jbake.properties
index bebb298..ee53714 100644
--- a/jbake.properties
+++ b/jbake.properties
@@ -1,4 +1,4 @@

diff --git a/templates/menu.thyme b/templates/menu.thyme
index c4191c1..036d68c 100644
--- a/templates/menu.thyme
+++ b/templates/menu.thyme
@@ -19,11 +19,13 @@
         <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}+'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">
@@ -38,7 +40,7 @@
                 <li><a href="#">One more separated link</a></li>
         </div><!--/.nav-collapse -->

diff --git a/templates/post.thyme b/templates/post.thyme
index 986aa11..9752ff2 100644
--- a/templates/post.thyme
+++ b/templates/post.thyme
@@ -16,7 +16,6 @@
 			<p th:utext='${content.body}'>body</p>
 			<hr />
 	<div th:replace="footer.thyme::footer"></div>

diff --git a/templates/sitemap.thyme b/templates/sitemap.thyme
index 5180df9..dafdb93 100644
--- a/templates/sitemap.thyme
+++ b/templates/sitemap.thyme
@@ -4,4 +4,4 @@
         <loc th:text="${config.site_host+'/'+content.uri}">loc</loc>
         <lastmod th:text='${#dates.format(content.date,"yyyy-MM-dd")}'>lastmod</lastmod>
\ No newline at end of file

View raw message