blob: 025da4527082c1d9940ded3f9c7fe2b866cdbc82 [file] [log] [blame]
: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();
}
-----------------------------------------------