You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by an...@apache.org on 2016/11/01 23:47:24 UTC
[2/5] incubator-tamaya-sandbox git commit: Added missing files,
synched Workspace.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/metamodel/src/main/java/org/apache/tamaya/metamodel/spi/PropertySourceProviderFactory.java
----------------------------------------------------------------------
diff --git a/metamodel/src/main/java/org/apache/tamaya/metamodel/spi/PropertySourceProviderFactory.java b/metamodel/src/main/java/org/apache/tamaya/metamodel/spi/PropertySourceProviderFactory.java
new file mode 100644
index 0000000..717f075
--- /dev/null
+++ b/metamodel/src/main/java/org/apache/tamaya/metamodel/spi/PropertySourceProviderFactory.java
@@ -0,0 +1,50 @@
+/*
+ * 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
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.metamodel.spi;
+
+import org.apache.tamaya.metamodel.internal.SourceConfig;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertySourceProvider;
+
+import java.util.Map;
+
+
+/**
+ * {@link PropertySource} and {@link SourceConfig} instances that
+ * implement configurable are configured with the according configuration
+ * settings provided in the {@code tamaya-config.xml} meta-configuration.
+ */
+public interface PropertySourceProviderFactory {
+
+ /**
+ * Resolve the given expression (without the key part).
+ * @param config the source configuration text, or null.
+ * @param extendedConfig any further extended configuration, not null, but may be
+ * empty.
+ * @return the property source, or null.
+ */
+ PropertySourceProvider create(String config, Map<String, String> extendedConfig);
+
+ /**
+ * Get the property source type. The type is used to identify the correct factory instance
+ * to resolve a configured property source.
+ * @return the (unique) type key, never null and not empty.
+ */
+ String getType();
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/metamodel/src/test/resources/tamaya-config.json
----------------------------------------------------------------------
diff --git a/metamodel/src/test/resources/tamaya-config.json b/metamodel/src/test/resources/tamaya-config.json
new file mode 100644
index 0000000..b926c25
--- /dev/null
+++ b/metamodel/src/test/resources/tamaya-config.json
@@ -0,0 +1,39 @@
+// 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 current 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
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+{
+ "context": {
+ "stage": "DEV"
+ },
+ "config-sources":{
+ "env-properties": {
+ "enabled": "${stage=TEST || stage=PTA || stage=PROD}",
+ "ordinal": 200
+ },
+ "sys-properties": {},
+ "file": "./config.json",
+ "resource": {
+ "path": "/META-INF/application-config.yml",
+ "multiple": true
+ },
+ "include":{
+ "path": "TEST.properties",
+ "enabled": "${context.cstage==TEST}"
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/metamodel/src/test/resources/tamaya-config.xml
----------------------------------------------------------------------
diff --git a/metamodel/src/test/resources/tamaya-config.xml b/metamodel/src/test/resources/tamaya-config.xml
new file mode 100644
index 0000000..ee36e0e
--- /dev/null
+++ b/metamodel/src/test/resources/tamaya-config.xml
@@ -0,0 +1,62 @@
+<!--
+// 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 current 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
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// -->
+<configuration>
+ <formats>
+ <format name="yaml"/>
+ <format name="json"/>
+ </formats>
+ <!--<converters>-->
+ <!--<converter type="AllInOneConverter"/>-->
+ <!--</converters>-->
+ <filters>
+ <filter type="UsageTrackerFilter"/>
+ </filters>
+
+ <context>
+ <context-entry name="stage">${properties:system:STAGE?default=DEV}</context-entry>
+ <context-entry name="app">${properties:system.APP?default=NONE}</context-entry>
+ <context-entry name="context">${java:org.apache.tamaya.context.Context#id()}</context-entry>
+ <context-entry name="company">Trivadis</context-entry>
+ </context>
+
+ <sources>
+ <source enabled="${stage=TEST || stage=PTA || stage=PROD}"
+ uri="properties:environment">
+ <decorator name="maped-to">ENV.</decorator>
+ <decorator name="secured">
+ <param name="roles">admin,power-user</param>
+ <param name="policy">mask</param>
+ </decorator>
+ </source>
+ <source uri="properties:system"/>
+ <source name="FILE:config.json" observe="true" observe-period="20000"
+ uri="file:/./config.json" />
+ <source name="CP:config.yml" uri="classpath*://META-INF/application-config.yml"/>
+ <source name="MINE" uri="propertysource:ch.mypack.MyClassSource">
+ <param name="locale">de</param>
+ </source>
+ <include enabled="${context.cstage==TEST}">TEST-config.xml</include>
+ <source name="CONFIG-DIR" uri="dir:/${CONFIG-DIR}/**/*.json"/>
+ <source name="SERVER" uri="https://www.confdrive.com/cfg/customerId=${}">
+ <param name="locale">de</param>
+ </source>
+ </sources>
+
+</configuration>
+
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/metamodel/src/test/resources/tamaya-config.yaml
----------------------------------------------------------------------
diff --git a/metamodel/src/test/resources/tamaya-config.yaml b/metamodel/src/test/resources/tamaya-config.yaml
new file mode 100644
index 0000000..4851c97
--- /dev/null
+++ b/metamodel/src/test/resources/tamaya-config.yaml
@@ -0,0 +1,87 @@
+#
+# 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 current 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
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+<!--
+// 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 current 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
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// -->
+------
+configuration:
+ formats:
+ - format: yaml
+ - format: json
+ converters:
+ - converter: AllInOneConverter
+ filters:
+ - filter: UsageTrackerFilter
+
+ context:
+ - stage: ${properties:system:STAGE?default=DEV}
+ - app: ${properties:system.APP?default=NONE}
+ - context: ${java:org.apache.tamaya.context.Context#id()}
+ - company: Trivadis
+
+ sources:
+ - ENVIRONMENT:
+ uri: properties:environment
+ enabled: ${stage=TEST || stage=PTA || stage=PROD}
+ decorator:
+ - maped-to: ENV.
+ - secured:
+ roles: admin,power-user
+ policy: mask
+ - SYSPROPS:
+ uri: properties:system
+ - FILE:config.json:
+ uri: file:/./config.json
+ name: FILE:config.json
+ observe: true
+ observe-period: 20000
+ - CP:config.yml:
+ uri: classpath*://META-INF/application-config.yml
+ - MINE:
+ uri: propertysource:ch.mypack.MyClassSource
+ locale=de
+ - <include>:
+ resource: TEST-config.xml
+ enabled: ${context.cstage==TEST}
+ - CONFIG-DIR:
+ uri: dir:/${CONFIG-DIR}/**/*.json
+ - SERVER:
+ uri: https://www.confdrive.com/cfg/customerId=${}
+ params:
+ - locale: de
+
+
+
+
+
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/osgi/pom.xml
----------------------------------------------------------------------
diff --git a/osgi/pom.xml b/osgi/pom.xml
new file mode 100644
index 0000000..9d3682a
--- /dev/null
+++ b/osgi/pom.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <!--
+
+ 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 "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-sandbox</artifactId>
+ <version>0.3-incubating-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <artifactId>tamaya-osgi</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Tamaya Integration - OSGi Services :: Tamaya Config</name>
+ <description>Tamaya Based OSGI Implementation of ConfigAdmin and Config Injection</description>
+
+ <properties>
+ <felix.plugin.version>2.5.4</felix.plugin.version>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>${felix.plugin.version}</version>
+ <inherited>true</inherited>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Activator>
+ org.apache.tamaya.integration.osgi.Activator
+ </Bundle-Activator>
+ <Export-Service>
+ org.osgi.service.cm.ConfigurationAdmin
+ </Export-Service>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.configadmin</artifactId>
+ <version>1.8.8</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>6.0.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya</groupId>
+ <artifactId>tamaya-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-functions</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-spisupport</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-injection</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>java-hamcrest</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/osgi/src/main/java/org/apache/tamaya/integration/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/osgi/src/main/java/org/apache/tamaya/integration/osgi/Activator.java b/osgi/src/main/java/org/apache/tamaya/integration/osgi/Activator.java
new file mode 100644
index 0000000..7425dfb
--- /dev/null
+++ b/osgi/src/main/java/org/apache/tamaya/integration/osgi/Activator.java
@@ -0,0 +1,134 @@
+/*
+ * 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
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.integration.osgi;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.inject.ConfigurationInjection;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.util.tracker.ServiceTracker;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Activator that registers the Tamaya based Service Class for {@link ConfigurationAdmin},
+ * using a default service priority of {@code 0}. This behaviour is configurable based on OSGI properties:
+ * <ul>
+ * <li><p><b>org.tamaya.integration.osgi.cm.ranking, type: int</b> allows to configure the OSGI service ranking for
+ * Tamaya based ConfigurationAdmin instance. The default ranking used is 10.</p></li>
+ * <li><p><b>org.tamaya.integration.osgi.cm.override, type: boolean</b> allows to configure if Tamaya should
+ * register its ConfigAdmin service. Default is true.</p></li>
+ * </ul>
+ */
+public class Activator implements BundleActivator {
+
+ private static final String SERVICE_RANKING_PROP = "org.tamaya.integration.osgi.cm.ranking";
+
+ private static final String SERVICE_OVERRIDE_PROP = "org.tamaya.integration.osgi.cm.override";
+
+ private static final String SERVICE_INJECT_PROP = "org.tamaya.integration.osgi.cm.inject";
+
+ private static final Integer DEFAULT_RANKING = 10;
+
+ private static final Logger LOG = Logger.getLogger(Activator.class.getName());
+
+ private ServiceRegistration<ConfigurationAdmin> registration;
+
+ private ServiceTracker<Object, Object> injectionTracker;
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ String val = context.getProperty(SERVICE_OVERRIDE_PROP);
+ if(val == null || Boolean.parseBoolean(val)){
+ Dictionary<String, Object> props = new Hashtable<>();
+ String ranking = context.getProperty(SERVICE_RANKING_PROP);
+ if (ranking == null) {
+ props.put(Constants.SERVICE_RANKING, DEFAULT_RANKING);
+ } else {
+ props.put(Constants.SERVICE_RANKING, Integer.valueOf(ranking));
+ }
+ TamayaConfigAdminImpl cm = new TamayaConfigAdminImpl(context);
+ registration = context.registerService(ConfigurationAdmin.class, cm, props);
+ }
+
+ // register injection mechanisms, if not configured otherwise
+ val = context.getProperty(SERVICE_INJECT_PROP);
+ if(val == null || Boolean.parseBoolean(val)){
+ injectionTracker = new ServiceTracker<Object, Object>(context, Object.class, null) {
+ @Override
+ public Object addingService(ServiceReference<Object> reference) {
+ Object service = context.getService(reference);
+ Object pidObj = reference.getProperty(Constants.SERVICE_PID);
+ if (pidObj instanceof String) {
+ String pid = (String) pidObj;
+ ConfigurationAdmin configAdmin = null;
+ ServiceReference<ConfigurationAdmin> adminRef =
+ context.getServiceReference(ConfigurationAdmin.class);
+ if(adminRef!=null){
+ configAdmin = context.getService(adminRef);
+ }
+ try {
+ Configuration targetConfig = null;
+ if(configAdmin != null){
+ org.osgi.service.cm.Configuration osgiConfig = configAdmin.getConfiguration(pid);
+ if(osgiConfig!=null){
+ targetConfig = new OSGIEnhancedConfiguration(osgiConfig);
+ }
+ }
+ if(targetConfig==null){
+ targetConfig = ConfigurationProvider.getConfiguration();
+ }
+ ConfigurationInjection.getConfigurationInjector().configure(service, targetConfig);
+ } catch (Exception e) {
+ LOG.log(Level.WARNING, "Error configuring Service: " + service, e);
+ }
+ } else {
+ LOG.log(Level.SEVERE, "Unsupported pid: " + pidObj);
+ }
+ return service;
+ }
+
+ @Override
+ public void removedService(ServiceReference<Object> reference, Object service) {
+ context.ungetService(reference);
+ }
+ };
+ injectionTracker.open();
+ }
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ if (registration != null) {
+ registration.unregister();
+ }
+ if(injectionTracker!=null){
+ injectionTracker.close();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/osgi/src/main/java/org/apache/tamaya/integration/osgi/OSGIConfigRootMapper.java
----------------------------------------------------------------------
diff --git a/osgi/src/main/java/org/apache/tamaya/integration/osgi/OSGIConfigRootMapper.java b/osgi/src/main/java/org/apache/tamaya/integration/osgi/OSGIConfigRootMapper.java
new file mode 100644
index 0000000..836df8b
--- /dev/null
+++ b/osgi/src/main/java/org/apache/tamaya/integration/osgi/OSGIConfigRootMapper.java
@@ -0,0 +1,36 @@
+/*
+ * 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
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.integration.osgi;
+
+/**
+ * Mapping function for mapping Tamaya configuration sections to OSGI pids.
+ */
+public interface OSGIConfigRootMapper {
+
+ /**
+ * Map the given OSGI pid to a corresponding configuration section in Tamaya. Es an example (and this is also the
+ * default implemented) a configuration mapping for {@code pid/factoryPid==myBundle} could be {@code [bundle:myBundle]}.
+ * This mapping is used as a prefix when collecting the corresponding entries for the OSGI configuration.
+ * @param pid the OSGI pid, or null
+ * @param factoryPid the OSGI factoryPid, or null
+ * @return return the corresponding config root section. For ommitting any root section simply return an empty
+ * String.
+ */
+ String getTamayaConfigRoot(String pid, String factoryPid);
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/osgi/src/main/java/org/apache/tamaya/integration/osgi/OSGIEnhancedConfiguration.java
----------------------------------------------------------------------
diff --git a/osgi/src/main/java/org/apache/tamaya/integration/osgi/OSGIEnhancedConfiguration.java b/osgi/src/main/java/org/apache/tamaya/integration/osgi/OSGIEnhancedConfiguration.java
new file mode 100644
index 0000000..5e813af
--- /dev/null
+++ b/osgi/src/main/java/org/apache/tamaya/integration/osgi/OSGIEnhancedConfiguration.java
@@ -0,0 +1,117 @@
+/*
+ * 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
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.integration.osgi;
+
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spisupport.BasePropertySource;
+import org.apache.tamaya.spisupport.DefaultConfiguration;
+import org.apache.tamaya.spisupport.DefaultConfigurationContext;
+
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Configuration object that also reflects the values provided by the OSGI ConfigAdmin Configuration.
+ * Similar to other tamaya areas adding a tamaya.ordinal into the corresponding OSGI configuration for
+ * a pif/factoryPid allows to control the ordinal/priority of the OSGI configuration related to other
+ * configured Tamaya Property Sources. Overall the configuration evaluation for Tamaya follows the
+ * same rules, with the difference that each bunldle owns its own ConfigAdmin based part. From
+ * Tamaya, the granularity depends on the implementation of the ConfigurationProviderSpi. By default
+ * Tamaya configuration is managed as a global resource/config tree, wheres bundle specific sections are
+ * selected only.
+ */
+public class OSGIEnhancedConfiguration extends DefaultConfiguration{
+ /** The default ordinal used for the OSGI config, */
+ private static final int OSGI_DEFAULT_ORDINAL = 0;
+
+ /**
+ * Constructor.
+ *
+ * @param osgiConfiguration The OSGI configuration found.
+ */
+ public OSGIEnhancedConfiguration(org.osgi.service.cm.Configuration osgiConfiguration) {
+ super(new OSGIConfigurationContext(osgiConfiguration));
+ }
+
+ /**
+ * Class that models a Tamaya ConfigurationContext, which implicitly contains the bundle specific
+ * Configuration wrapped into a Tamaya PropertySource.
+ */
+ private static final class OSGIConfigurationContext extends DefaultConfigurationContext{
+ private OSGIPropertySource osgiPropertySource;
+
+ public OSGIConfigurationContext(org.osgi.service.cm.Configuration osgiConfiguration){
+ if(osgiConfiguration!=null) {
+ this.osgiPropertySource = new OSGIPropertySource(osgiConfiguration);
+ }
+ }
+
+ @Override
+ public List<PropertySource> getPropertySources() {
+ List<PropertySource> sources = super.getPropertySources();
+ if(osgiPropertySource!=null){
+ sources.add(osgiPropertySource);
+ }
+ return sources;
+ }
+ }
+
+ /**
+ * Tamaya PropertySource providing the values from an OSGI Configuration.
+ */
+ private static final class OSGIPropertySource extends BasePropertySource{
+
+ private final org.osgi.service.cm.Configuration osgiConfiguration;
+
+ public OSGIPropertySource(org.osgi.service.cm.Configuration osgiConfiguration){
+ this.osgiConfiguration = Objects.requireNonNull(osgiConfiguration);
+ }
+
+ @Override
+ public int getDefaultOrdinal() {
+ String val = System.getProperty("osgi.defaultOrdinal");
+ if(val!=null){
+ return Integer.parseInt(val.trim());
+ }
+ return OSGI_DEFAULT_ORDINAL;
+ }
+
+ @Override
+ public String getName() {
+ return "OSGIConfig:pid="+
+ (osgiConfiguration.getPid()!=null?osgiConfiguration.getPid():osgiConfiguration.getFactoryPid());
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ Map<String, String> map = new HashMap<>();
+ Dictionary<String,Object> dict = osgiConfiguration.getProperties();
+ Enumeration<String> keys = dict.keys();
+ while(keys.hasMoreElements()){
+ String key = keys.nextElement();
+ map.put(key,String.valueOf(dict.get(key)));
+ }
+ return map;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/osgi/src/main/java/org/apache/tamaya/integration/osgi/TamayaConfigAdminImpl.java
----------------------------------------------------------------------
diff --git a/osgi/src/main/java/org/apache/tamaya/integration/osgi/TamayaConfigAdminImpl.java b/osgi/src/main/java/org/apache/tamaya/integration/osgi/TamayaConfigAdminImpl.java
new file mode 100644
index 0000000..7bf4da7
--- /dev/null
+++ b/osgi/src/main/java/org/apache/tamaya/integration/osgi/TamayaConfigAdminImpl.java
@@ -0,0 +1,196 @@
+/*
+ * 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
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.integration.osgi;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ManagedService;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * Tamaya based implementation of an OSGI {@link ConfigurationAdmin}.
+ */
+public class TamayaConfigAdminImpl implements ConfigurationAdmin {
+ /** the logger. */
+ private static final Logger LOG = Logger.getLogger(TamayaConfigAdminImpl.class.getName());
+
+ /** The OSGI context. */
+ private final BundleContext context;
+ /** THe optional OSGI parent service. */
+ private ConfigurationAdmin parent;
+ /** The cached configurations. */
+ private Map<String,Configuration> configs = new ConcurrentHashMap<>();
+ /** The configuration section mapper. */
+ private OSGIConfigRootMapper configRootMapper;
+
+ /**
+ * Create a new config.
+ * @param context the OSGI context
+ */
+ TamayaConfigAdminImpl(BundleContext context) {
+ this.context = context;
+ this.configRootMapper = loadConfigRootMapper();
+ ServiceReference<ConfigurationAdmin> ref = context.getServiceReference(ConfigurationAdmin.class);
+ this.parent = ref!=null?context.getService(ref):null;
+ ServiceTracker<ManagedService, ManagedService> serviceTracker = new ServiceTracker<ManagedService,
+ ManagedService>(context, ManagedService.class, null) {
+ @Override
+ public ManagedService addingService(ServiceReference<ManagedService> reference) {
+ ManagedService service = context.getService(reference);
+ Object pidObj = reference.getProperty(Constants.SERVICE_PID);
+ if (pidObj instanceof String) {
+ String pid = (String) pidObj;
+ try {
+ Configuration config = getConfiguration(pid);
+ if(config==null){
+ service.updated(null);
+ } else{
+ service.updated(config.getProperties());
+ }
+ } catch (Exception e) {
+ LOG.log(Level.WARNING, "Error configuring ManagedService: " + service, e);
+ }
+ } else {
+ LOG.log(Level.SEVERE, "Unsupported pid: " + pidObj);
+ }
+ return service;
+ }
+
+ @Override
+ public void removedService(ServiceReference<ManagedService> reference, ManagedService service) {
+ context.ungetService(reference);
+ }
+ };
+ serviceTracker.open();
+
+ ServiceTracker<ServiceFactory, ServiceFactory> factoryTracker
+ = new ServiceTracker<ServiceFactory, ServiceFactory>(context, ServiceFactory.class, null) {
+ @Override
+ public ServiceFactory addingService(ServiceReference<ServiceFactory> reference) {
+ ServiceFactory factory = context.getService(reference);
+ if(factory instanceof ManagedServiceFactory) {
+ Object pidObj = reference.getProperty(Constants.SERVICE_PID);
+ if (pidObj instanceof String) {
+ String pid = (String) pidObj;
+ try {
+ Configuration config = getConfiguration(pid);
+ if (config != null) {
+ ((ManagedServiceFactory) factory).updated(config.getFactoryPid(), config.getProperties());
+ }
+ } catch (Exception e) {
+ LOG.log(Level.WARNING, "Error configuring ManagedServiceFactory: " + factory, e);
+ }
+ } else {
+ LOG.log(Level.SEVERE, "Unsupported pid: " + pidObj);
+ }
+ }
+ return factory;
+ }
+
+ @Override
+ public void removedService(ServiceReference<ServiceFactory> reference, ServiceFactory service) {
+ super.removedService(reference, service);
+ }
+ };
+ factoryTracker.open();
+ }
+
+ @Override
+ public Configuration createFactoryConfiguration(String factoryPid) throws IOException {
+ return createFactoryConfiguration(factoryPid, null);
+ }
+
+ @Override
+ public Configuration createFactoryConfiguration(String factoryPid, String location) throws IOException {
+ return new TamayaConfigurationImpl(factoryPid, null, configRootMapper, this.parent);
+ }
+
+ @Override
+ public Configuration getConfiguration(String pid, String location) throws IOException {
+ return getConfiguration(pid);
+ }
+
+ @Override
+ public Configuration getConfiguration(String pid) throws IOException {
+ return new TamayaConfigurationImpl(pid, null, configRootMapper, this.parent);
+ }
+
+ @Override
+ public Configuration[] listConfigurations(String filter) throws IOException, InvalidSyntaxException {
+ Collection<Configuration> result;
+ if (filter == null) {
+ result = this.configs.values();
+ } else {
+ result = new ArrayList<>();
+ Filter flt = context.createFilter(filter);
+ for (Configuration config : this.configs.values()) {
+ if (flt.match(config.getProperties())) {
+ result.add(config);
+ }
+ }
+ }
+ return result.isEmpty() ? null : result.toArray(new Configuration[configs.size()]);
+ }
+
+ /**
+ * Loads the configuration toor mapper using the OSGIConfigRootMapper OSGI service resolving mechanism. If no
+ * such service is available it loads the default mapper.
+ * @return the mapper to be used, bever null.
+ */
+ private OSGIConfigRootMapper loadConfigRootMapper() {
+ OSGIConfigRootMapper mapper = null;
+ ServiceReference<OSGIConfigRootMapper> ref = context.getServiceReference(OSGIConfigRootMapper.class);
+ if(ref!=null){
+ mapper = context.getService(ref);
+ }
+ if(mapper==null){
+ mapper = new OSGIConfigRootMapper() {
+ @Override
+ public String getTamayaConfigRoot(String pid, String factoryPid) {
+ if(pid!=null) {
+ return "[bundle:" + pid +']';
+ } else{
+ return "[bundle:" + factoryPid +']';
+ }
+ }
+ @Override
+ public String toString(){
+ return "Default OSGIConfigRootMapper(pid -> [bundle:pid], factoryPid -> [bundle:factoryPid]";
+ }
+ };
+ }
+ return mapper;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/osgi/src/main/java/org/apache/tamaya/integration/osgi/TamayaConfigurationImpl.java
----------------------------------------------------------------------
diff --git a/osgi/src/main/java/org/apache/tamaya/integration/osgi/TamayaConfigurationImpl.java b/osgi/src/main/java/org/apache/tamaya/integration/osgi/TamayaConfigurationImpl.java
new file mode 100644
index 0000000..c7b0864
--- /dev/null
+++ b/osgi/src/main/java/org/apache/tamaya/integration/osgi/TamayaConfigurationImpl.java
@@ -0,0 +1,127 @@
+/*
+ * 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
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.integration.osgi;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.functions.PropertyMatcher;
+import org.apache.tamaya.functions.ConfigurationFunctions;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+/**
+ * Tamaya based implementation of an OSGI {@link Configuration}.
+ */
+public class TamayaConfigurationImpl implements Configuration {
+ private static final Logger LOG = Logger.getLogger(TamayaConfigurationImpl.class.getName());
+ private final String pid;
+ private final String factoryPid;
+ private Map<String, String> properties = new HashMap<>();
+ private org.apache.tamaya.Configuration config;
+
+ /**
+ * Constructor.
+ * @param confPid the OSGI pid
+ * @param factoryPid the factory pid
+ * @param configRootMapper the mapper that maps the pids to a tamaya root section.
+ * @param parent the (optional delegating parent, used as default).
+ */
+ TamayaConfigurationImpl(String confPid, String factoryPid, OSGIConfigRootMapper configRootMapper,
+ ConfigurationAdmin parent) {
+ this.pid = confPid;
+ this.factoryPid = factoryPid;
+ if(parent!=null){
+ try {
+ Dictionary<String, Object> conf = parent.getConfiguration(confPid, factoryPid).getProperties();
+ if(conf!=null) {
+ LOG.info("Configuration: Adding default parameters from parent: " + parent.getClass().getName());
+ Enumeration<String> keys = conf.keys();
+ while (keys.hasMoreElements()) {
+ String key = keys.nextElement();
+ this.properties.put(key, conf.get(key).toString());
+ }
+ }
+ } catch (IOException e) {
+ LOG.log(Level.WARNING, "Error reading parent OSGI config.", e);
+ }
+ }
+ this.config = ConfigurationProvider.getConfiguration();
+ final String rootKey = configRootMapper.getTamayaConfigRoot(pid, factoryPid);
+ LOG.info("Configuration: Evaluating Tamaya configuration for '" + rootKey + "'.");
+ this.properties.putAll(
+ config.with(ConfigurationFunctions.section(rootKey, true)).getProperties());
+ }
+
+ @Override
+ public String getPid() {
+ return pid;
+ }
+
+ @Override
+ public Dictionary<String, Object> getProperties() {
+ return new Hashtable<String, Object>(properties);
+ }
+
+ @Override
+ public void update(Dictionary<String, ?> properties) throws IOException {
+ throw new UnsupportedOperationException("Nuatability not yet supported.");
+ // ConfigChangeProvider.createChangeRequest(this.config)
+ }
+
+ @Override
+ public void delete() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getFactoryPid() {
+ return factoryPid;
+ }
+
+ @Override
+ public void update() throws IOException {
+ this.config = ConfigurationProvider.getConfiguration();
+ this.properties = config.with(ConfigurationFunctions.filter(new PropertyMatcher() {
+ @Override
+ public boolean test(String key, String value) {
+// TODO define name space / SPI
+ return false;
+ }
+ })).getProperties();
+ }
+
+ @Override
+ public void setBundleLocation(String location) {
+ }
+
+ @Override
+ public String getBundleLocation() {
+ return null;
+ }
+
+ @Override
+ public long getChangeCount() {
+ return 0;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/osgi/src/test/resources/META-INF/javaconfiguration.properties
----------------------------------------------------------------------
diff --git a/osgi/src/test/resources/META-INF/javaconfiguration.properties b/osgi/src/test/resources/META-INF/javaconfiguration.properties
new file mode 100644
index 0000000..0f09ce9
--- /dev/null
+++ b/osgi/src/test/resources/META-INF/javaconfiguration.properties
@@ -0,0 +1,18 @@
+# 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
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+[bundle:tamaya]my.testProperty=success!
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/osgi/src/test/resources/arquillian.xml
----------------------------------------------------------------------
diff --git a/osgi/src/test/resources/arquillian.xml b/osgi/src/test/resources/arquillian.xml
new file mode 100644
index 0000000..a4c885a
--- /dev/null
+++ b/osgi/src/test/resources/arquillian.xml
@@ -0,0 +1,27 @@
+<!--
+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 current 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
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<arquillian xmlns="http://jboss.org/schema/arquillian" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
+
+ <container qualifier="osgi" default="true">
+ <configuration>
+ <property name="frameworkProperties">src/test/resources/felix.properties</property>
+ </configuration>
+ </container>
+</arquillian>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/osgi/src/test/resources/felix.properties
----------------------------------------------------------------------
diff --git a/osgi/src/test/resources/felix.properties b/osgi/src/test/resources/felix.properties
new file mode 100644
index 0000000..de50401
--- /dev/null
+++ b/osgi/src/test/resources/felix.properties
@@ -0,0 +1,23 @@
+# 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
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# org.osgi.service.cm;org.apache.felix.cm;org.apache.tamaya;org.apache.tamaya.spi;
+org.osgi.framework.bootdelegation=org.apache.tamaya,org.apache.tamaya.integration.osgi,org.apache.tamaya.integration.osgi.test
+felix.log.level=4 #debug logging
+# felix.auto.deploy.dir=../test-bundles
+org.osgi.framework.storage=target/felix-cache
+felix.fileinstall.dir=./test-bundles
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/propertysources/src/test/java/org/apache/tamaya/propertysources/MetainfConfigPropertySourceProviderTest.java
----------------------------------------------------------------------
diff --git a/propertysources/src/test/java/org/apache/tamaya/propertysources/MetainfConfigPropertySourceProviderTest.java b/propertysources/src/test/java/org/apache/tamaya/propertysources/MetainfConfigPropertySourceProviderTest.java
new file mode 100644
index 0000000..0250ff6
--- /dev/null
+++ b/propertysources/src/test/java/org/apache/tamaya/propertysources/MetainfConfigPropertySourceProviderTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.propertysources;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by atsticks on 30.10.16.
+ */
+public class MetainfConfigPropertySourceProviderTest {
+
+ @Test
+ public void getPropertySources_Default() throws Exception {
+ MetainfConfigPropertySourceProvider provider = new MetainfConfigPropertySourceProvider();
+ assertNotNull(provider.getPropertySources());
+ // TODO add test for containing property sources.
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/server/pom.xml
----------------------------------------------------------------------
diff --git a/server/pom.xml b/server/pom.xml
new file mode 100644
index 0000000..d2abf18
--- /dev/null
+++ b/server/pom.xml
@@ -0,0 +1,203 @@
+<!--
+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 current 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
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-sandbox</artifactId>
+ <version>0.3-incubating-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <artifactId>tamaya-server</artifactId>
+ <name>Apache Tamaya Modules - Server Extension</name>
+ <packaging>bundle</packaging>
+
+ <properties>
+ <jdkVersion>1.7</jdkVersion>
+ <tomcat.version>7.0.57</tomcat.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tamaya</groupId>
+ <artifactId>tamaya-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tomcat.embed</groupId>
+ <artifactId>tomcat-embed-core</artifactId>
+ <version>${tomcat.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tomcat.embed</groupId>
+ <artifactId>tomcat-embed-jasper</artifactId>
+ <version>${tomcat.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tomcat.embed</groupId>
+ <artifactId>tomcat-embed-logging-juli</artifactId>
+ <version>${tomcat.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-jaxrs_2.0_spec</artifactId>
+ <version>1.0-alpha-1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+ <version>3.1.6</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya</groupId>
+ <artifactId>tamaya-core</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>tamaya-json</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>tamaya-functions</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>java-hamcrest</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>${project.basedir}/src/main/resources</directory>
+ <filtering>true</filtering>
+ <includes>
+ <include>META-INF/server-version.properties</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>${project.basedir}/src/main/resources</directory>
+ <filtering>false</filtering>
+ <excludes>
+ <exclude>META-INF/server-version.properties</exclude>
+ </excludes>
+ </resource>
+
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>com.spotify</groupId>
+ <artifactId>docker-maven-plugin</artifactId>
+ <version>0.3.258</version>
+ <configuration>
+ <imageName>apache/tamaya/config-server</imageName>
+ <imageTags>
+ <imageTag>${project.version}</imageTag>
+ </imageTags>
+ <baseImage>java:8-jre</baseImage>
+ <entryPoint>["java", "-jar", "/${project.build.finalName}.jar", "server", "/config-server.yml"]</entryPoint>
+ <exposes>
+ <expose>8080</expose>
+ </exposes>
+ <resources>
+ <resource>
+ <targetPath>/</targetPath>
+ <directory>${project.build.directory}</directory>
+ <include>${project.build.finalName}.jar</include>
+ </resource>
+ <resource>
+ <targetPath>/</targetPath>
+ <directory>${project.build.directory}/classes</directory>
+ <include>config-server.yml</include>
+ </resource>
+ </resources>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>2.3</version>
+ <configuration>
+ <createDependencyReducedPom>true</createDependencyReducedPom>
+ <filters>
+ <filter>
+ <artifact>*:*</artifact>
+ <excludes>
+ <exclude>META-INF/*.SF</exclude>
+ <exclude>META-INF/*.DSA</exclude>
+ <exclude>META-INF/*.RSA</exclude>
+ </excludes>
+ </filter>
+ </filters>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <transformers>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+ <mainClass>org.apache.tamaya.server.ConfigServiceApp</mainClass>
+ </transformer>
+ </transformers>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.apache.tamaya.server,
+ org.apache.tamaya.server.spi
+ </Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/server/src/main/java/org/apache/tamaya/server/ConfigServiceApp.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/tamaya/server/ConfigServiceApp.java b/server/src/main/java/org/apache/tamaya/server/ConfigServiceApp.java
new file mode 100644
index 0000000..1db06f3
--- /dev/null
+++ b/server/src/main/java/org/apache/tamaya/server/ConfigServiceApp.java
@@ -0,0 +1,77 @@
+/*
+ * 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
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.server;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Wrapper;
+import org.apache.catalina.startup.Tomcat;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+
+import javax.ws.rs.core.Application;
+import java.io.File;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Main Application for the Tamaya Configuration Server.
+ */
+public class ConfigServiceApp {
+
+ /**
+ * Utility class.
+ */
+ private ConfigServiceApp(){}
+
+ /**
+ * JAX RS Application.
+ */
+ public static class ResourceLoader extends Application{
+
+ @Override
+ public Set<Class<?>> getClasses() {
+ final Set<Class<?>> classes = new HashSet<>();
+ // register root resource
+ classes.add(ConfigurationResource.class);
+ return classes;
+ }
+ }
+
+ public static void main(String... args) throws Exception {
+ Configuration config = ConfigurationProvider.getConfiguration();
+ String contextPath = config.getOrDefault("tamaya.server.contextPath", "/");
+ String appBase = ".";
+ Tomcat tomcat = new Tomcat();
+ tomcat.setPort(config.getOrDefault("tamaya.server.port", Integer.class, 8085));
+
+ // Define a web application context.
+ Context context = tomcat.addWebapp(contextPath, new File(
+ appBase).getAbsolutePath());
+ // Add servlet that will register Jersey REST resources
+ String servletName = "cxf-servlet";
+ Wrapper wrapper = tomcat.addServlet(context, servletName,
+ org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet.class.getName());
+ wrapper.addInitParameter("javax.ws.rs.Application", ResourceLoader.class.getName());
+ context.addServletMapping("/*", servletName);
+ tomcat.start();
+ tomcat.getServer().await();
+ }
+
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/server/src/main/java/org/apache/tamaya/server/ConfigurationResource.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/tamaya/server/ConfigurationResource.java b/server/src/main/java/org/apache/tamaya/server/ConfigurationResource.java
new file mode 100644
index 0000000..f13446a
--- /dev/null
+++ b/server/src/main/java/org/apache/tamaya/server/ConfigurationResource.java
@@ -0,0 +1,310 @@
+/*
+ * 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
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.server;
+
+import java.io.StringWriter;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonWriter;
+import javax.json.stream.JsonGenerator;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.functions.ConfigurationFunctions;
+
+/**
+ * Configuration resource with an etcd compatible REST API
+ * (excluding the blocking API calls).
+ */
+@Path("/")
+@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
+public class ConfigurationResource {
+ private final AtomicLong readCounter = new AtomicLong();
+ private final AtomicLong writeCounter = new AtomicLong();
+ private final AtomicLong deleteCounter = new AtomicLong();
+
+
+ @GET
+ @Path("/version")
+ @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
+ public String version() {
+ String product = VersionProperties.getProduct().replace("\"", "\\\"");
+ String version = VersionProperties.getVersion().replace("\"", "\\\"");
+
+ return String.format("{ \"version\" : \"%s: %s\" }", product, version);
+ }
+
+ @GET
+ @Path("/v2/keys")
+ public String readEtcdConfig(@QueryParam("recursive") Boolean recursive) {
+ return readConfig(recursive);
+ }
+
+ /**
+ * This models a etcd2 compliant access point for getting a property value.
+ *
+ * @param recursive NOT YET IMPLEMENTED!
+ * @return all configuration property values.
+ */
+ @GET
+ @Path("/keys")
+ public String readConfig(@QueryParam("recursive") Boolean recursive) {
+ readCounter.incrementAndGet();
+ final Configuration config = ConfigurationProvider.getConfiguration();
+ final Map<String, String> children = config.getProperties();
+ final JsonArrayBuilder ab = Json.createArrayBuilder();
+ for (final Map.Entry<String, String> en : children.entrySet()) {
+ final Node node = new Node(config, en.getKey(), "node");
+ ab.add(node.createJsonObject());
+ }
+ final Node node = new Node(config, null, "node", ab.build());
+ final JsonObjectBuilder root = Json.createObjectBuilder().add("action", "get")
+ .add("node", node.createJsonObject());
+ final StringWriter writer = new StringWriter();
+ final JsonWriter jwriter = Json.createWriter(writer);
+ jwriter.writeObject(root.build());
+ return writer.toString();
+ }
+
+ /**
+ * This models a etcd2 compliant access point for getting a property value.
+ *
+ * @param key name of the key to show
+ * @param recursive NOT YET IMPLEMENTED!
+ * @return specific configuration key derived from the given key name.
+ */
+ @GET
+ @Path("/v2/keys/{key}")
+ public String readEtcdConfig(@PathParam("key") String key, @QueryParam("recursive") Boolean recursive) {
+ return readConfig(key, recursive);
+ }
+
+ /**
+ * This models a etcd2 compliant access point for getting a property value.
+ *
+ * @param key name of the key to show
+ * @param recursive NOT YET IMPLEMENTED!
+ * @return configuration value of the given key.
+ */
+ @GET
+ @Path("/keys/{key}")
+ public String readConfig(@PathParam("key") String key, @QueryParam("recursive") Boolean recursive) {
+ readCounter.incrementAndGet();
+ final Configuration config = ConfigurationProvider.getConfiguration();
+ if (key != null) {
+ if (key.startsWith("/")) {
+ key = key.substring(1);
+ }
+ if (config.get(key) != null && !recursive) {
+ final Node node = new Node(config, key, "node");
+ final JsonObjectBuilder root = Json.createObjectBuilder().add("action", "get")
+ .add("node", node.createJsonObject());
+ final StringWriter writer = new StringWriter();
+ final JsonGenerator gen = Json.createGenerator(writer);
+ gen.write(root.build());
+ return writer.toString();
+ }
+ }
+ Map<String, String> children = null;
+ if (key == null) {
+ children = config.getProperties();
+ } else {
+ children = config.with(ConfigurationFunctions.section(key)).getProperties();
+ }
+ final JsonArrayBuilder ab = Json.createArrayBuilder();
+ for (final Map.Entry<String, String> en : children.entrySet()) {
+ final Node node = new Node(config, en.getKey(), "node");
+ ab.add(node.createJsonObject());
+ }
+ final Node node = new Node(config, key, "node", ab.build());
+ final JsonObjectBuilder root = Json.createObjectBuilder().add("action", "get")
+ .add("node", node.createJsonObject());
+ final StringWriter writer = new StringWriter();
+ final JsonWriter jwriter = Json.createWriter(writer);
+ jwriter.writeObject(root.build());
+ return writer.toString();
+ }
+
+ @PUT
+ @Path("/v2/keys/{key}")
+ public String writeEtcdConfig(@PathParam("key") String key, @javax.ws.rs.FormParam("value") String value,
+ @FormParam("ttl") Integer ttl) {
+ return writeConfig(key, value, ttl);
+ }
+
+ /**
+ * This models a etcd2 compliant access point for setting a property value:
+ * <pre>
+ * {
+ * "action": "set",
+ * "node": {
+ * "createdIndex": 3,
+ * "key": "/message",
+ * "modifiedIndex": 3,
+ * "value": "Hello etcd"
+ * },
+ * "prevNode": {
+ * "createdIndex": 2,
+ * "key": "/message",
+ * "value": "Hello world",
+ * "modifiedIndex": 2
+ * }
+ * }
+ * </pre>
+ *
+ * @param key name of the key to show
+ * @param value configuration value for the given key
+ * @param ttl time to live
+ * @return written configuration value.
+ */
+ @PUT
+ @Path("/keys/{key}")
+ public String writeConfig(@PathParam("key") String key, @javax.ws.rs.FormParam("value") String value,
+ @FormParam("ttl") Integer ttl) {
+ writeCounter.incrementAndGet();
+ final Configuration config = ConfigurationProvider.getConfiguration();
+ if (key.startsWith("/")) {
+ key = key.substring(1);
+ }
+ final Node prevNode = new Node(config, key, "prevNode");
+ // TODO implement write! value and ttl as input
+ final Node node = new Node(config, key, "node");
+ final JsonObjectBuilder root = Json.createObjectBuilder().add("action", "set")
+ .add("node", node.createJsonObject())
+ .add("prevNode", prevNode.createJsonObject());
+ final StringWriter writer = new StringWriter();
+ final JsonWriter jwriter = Json.createWriter(writer);
+ jwriter.writeObject(root.build());
+ return writer.toString();
+ }
+
+ @DELETE
+ @Path("/v2/keys/{key}")
+ public String deleteEtcdConfig(@PathParam("key") String key) {
+ return deleteConfig(key);
+ }
+
+ @DELETE
+ @Path("/keys/{key}")
+ public String deleteConfig(@PathParam("key") String key) {
+ deleteCounter.incrementAndGet();
+ final Configuration config = ConfigurationProvider.getConfiguration();
+ if (key.startsWith("/")) {
+ key = key.substring(1);
+ }
+ final Node prevNode = new Node(config, key, "prevNode");
+ // TODO implement write! value and ttl as input
+ final Node node = new Node(config, key, "node");
+ final JsonObjectBuilder root = Json.createObjectBuilder().add("action", "delete")
+ .add("node", node.createJsonObject())
+ .add("prevNode", prevNode.createJsonObject());
+ final StringWriter writer = new StringWriter();
+ final JsonWriter jwriter = Json.createWriter(writer);
+ jwriter.writeObject(root.build());
+ return writer.toString();
+ }
+
+ public long getDeleteCounter() {
+ return deleteCounter.get();
+ }
+
+ public long getReadCounter() {
+ return readCounter.get();
+ }
+
+ public long getWriteCounter() {
+ return writeCounter.get();
+ }
+
+ /**
+ * Internal representation of a configuration node as modeled by etc.
+ */
+ private static final class Node {
+ private Integer createdIndex;
+ private Integer modifiedIndex;
+ private final String key;
+ private String value;
+ private final String nodeId;
+ private Integer ttl;
+ private String expiration;
+ private final JsonArray nodes;
+
+ Node(Configuration config, String key, String nodeId) {
+ this(config, key, nodeId, null);
+ }
+
+ Node(Configuration config, String key, String nodeId, JsonArray nodes) {
+ this.key = key;
+ this.nodeId = Objects.requireNonNull(nodeId);
+ if (key != null) {
+ value = config.get(key);
+ createdIndex = config.getOrDefault("_" + key + ".createdIndex", Integer.class, null);
+ modifiedIndex = config.getOrDefault("_" + key + ".modifiedIndex", Integer.class, null);
+ ttl = config.getOrDefault("_" + key + ".ttl", Integer.class, null);
+ expiration = config.getOrDefault("_" + key + ".expiration", null);
+ }
+ this.nodes = nodes;
+ }
+
+ JsonObject createJsonObject() {
+ final JsonObjectBuilder nodeBuilder = Json.createObjectBuilder();
+ if (key != null) {
+ nodeBuilder.add("key", '/' + key);
+ } else {
+ nodeBuilder.add("dir", true);
+ }
+ if (value != null) {
+ nodeBuilder.add("value", value);
+ }
+ if (createdIndex != null) {
+ nodeBuilder.add("createdIndex", createdIndex.intValue());
+ }
+ if (modifiedIndex != null) {
+ nodeBuilder.add("modifiedIndex", modifiedIndex.intValue());
+ }
+ if (ttl != null) {
+ nodeBuilder.add("ttl", ttl.intValue());
+ }
+ if (expiration != null) {
+ nodeBuilder.add("expiration", value);
+ }
+ if (nodes != null) {
+ nodeBuilder.add("nodes", nodes);
+ }
+ return nodeBuilder.build();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/server/src/main/java/org/apache/tamaya/server/VersionProperties.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/tamaya/server/VersionProperties.java b/server/src/main/java/org/apache/tamaya/server/VersionProperties.java
new file mode 100644
index 0000000..e271694
--- /dev/null
+++ b/server/src/main/java/org/apache/tamaya/server/VersionProperties.java
@@ -0,0 +1,68 @@
+/*
+ * 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
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * <p>This class gives access to the current name and the current version information
+ * at runtime.</p>
+ *
+ * <p>All information offered by this is loaded from a properties file at
+ * {@link VersionProperties#VERSION_PROPERTY_FILE}.</p>
+ */
+public class VersionProperties {
+ private static final String VERSION_PROPERTY_FILE = "/META-INF/tamaya-server-version.properties";
+
+ static {
+ try (InputStream resource = VersionProperties.class.getResourceAsStream(VERSION_PROPERTY_FILE)) {
+ if (null == resource) {
+ throw new ExceptionInInitializerError("Failed to version information resource. " +
+ VERSION_PROPERTY_FILE + " not found.");
+ }
+
+ Properties properties = new Properties();
+ properties.load(resource);
+
+ product = properties.getProperty("server.product", "n/a");
+ version = properties.getProperty("server.version", "n/a");
+
+ } catch (IOException e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ private static String product;
+ private static String version;
+
+ private VersionProperties() {
+ }
+
+ public static String getProduct() {
+ return product;
+ }
+
+ public static String getVersion() {
+ return version;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/server/src/main/java/org/apache/tamaya/server/spi/ScopeManager.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/tamaya/server/spi/ScopeManager.java b/server/src/main/java/org/apache/tamaya/server/spi/ScopeManager.java
new file mode 100644
index 0000000..3d2757a
--- /dev/null
+++ b/server/src/main/java/org/apache/tamaya/server/spi/ScopeManager.java
@@ -0,0 +1,84 @@
+/*
+ * 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
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.server.spi;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.ConfigOperator;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+/**
+ * Singleton manager for scopes, used by the server component to filtering returned configurations.
+ */
+public final class ScopeManager {
+ /** The logger used. */
+ private static final Logger LOG = Logger.getLogger(ScopeManager.class.getName());
+
+ private static Map<String, ScopeProvider> scopeProviders = initProviders();
+
+ /**
+ * Singleton constructor.
+ */
+ private static Map<String, ScopeProvider> initProviders(){
+ final Map<String, ScopeProvider> result = new ConcurrentHashMap<>();
+ for(final ScopeProvider prov: ServiceContextManager.getServiceContext().getServices(ScopeProvider.class)){
+ try{
+ result.put(prov.getScopeType(), prov);
+ } catch(final Exception e){
+ LOG.log(Level.WARNING, "Error loading scopes from " + prov, e);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Singleton constructor.
+ */
+ private ScopeManager(){}
+
+ /**
+ * Get the scope given its id and provider.
+ *
+ * @param scopeId the scope name
+ * @param targetScope name of the targetScope
+ * @return the scope matching
+ * @throws ConfigException if no such scope is defined
+ */
+ public static ConfigOperator getScope(String scopeId, String targetScope)
+ throws ConfigException {
+ final ScopeProvider prov = scopeProviders.get(scopeId);
+ if(prov==null){
+ throw new ConfigException("No such scope: " + scopeId);
+ }
+ return prov.getScope(targetScope);
+ }
+
+ /**
+ * Get the defined scope names.
+ * @return the defined scope names, never null.
+ */
+ public static Set<String> getScopes(){
+ return scopeProviders.keySet();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/server/src/main/java/org/apache/tamaya/server/spi/ScopeProvider.java
----------------------------------------------------------------------
diff --git a/server/src/main/java/org/apache/tamaya/server/spi/ScopeProvider.java b/server/src/main/java/org/apache/tamaya/server/spi/ScopeProvider.java
new file mode 100644
index 0000000..5c247d8
--- /dev/null
+++ b/server/src/main/java/org/apache/tamaya/server/spi/ScopeProvider.java
@@ -0,0 +1,40 @@
+/*
+ * 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
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.server.spi;
+
+import org.apache.tamaya.ConfigOperator;
+
+/**
+ * Simple registrable provider class to register scopes for the server extension.
+ */
+public interface ScopeProvider {
+
+ /**
+ * Access the unique scope name.
+ * @return the unique scope name.
+ */
+ String getScopeType();
+
+ /**
+ * Return the scope operator that implements the scope for the given scope id.
+ * @param scopeId target scope id.
+ * @return the scope operator, never null.
+ */
+ ConfigOperator getScope(String scopeId);
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/server/src/main/resources/META-INF/tamaya-server-version.properties
----------------------------------------------------------------------
diff --git a/server/src/main/resources/META-INF/tamaya-server-version.properties b/server/src/main/resources/META-INF/tamaya-server-version.properties
new file mode 100644
index 0000000..ef0ca70
--- /dev/null
+++ b/server/src/main/resources/META-INF/tamaya-server-version.properties
@@ -0,0 +1,22 @@
+
+#
+# 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 current 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
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+server.product=Apache Tamaya
+server.version=${project.version}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/server/src/main/resources/banner.txt
----------------------------------------------------------------------
diff --git a/server/src/main/resources/banner.txt b/server/src/main/resources/banner.txt
new file mode 100644
index 0000000..4e2714b
--- /dev/null
+++ b/server/src/main/resources/banner.txt
@@ -0,0 +1,14 @@
+
+ \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557
+\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255d\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255d \u255a\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255d\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u255a\u2588\u2588\u2557 \u2588\u2588\u2554\u255d\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557
+\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255d\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u255a\u2588\u2588\u2588\u2588\u2554\u255d \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551
+\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u255d \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255d \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551\u255a\u2588\u2588\u2554\u255d\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551 \u255a\u2588\u2588\u2554\u255d \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551
+\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u255a\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255a\u2550\u255d \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551
+\u255a\u2550\u255d \u255a\u2550\u255d\u255a\u2550\u255d \u255a\u2550\u255d \u255a\u2550\u255d \u255a\u2550\u2550\u2550\u2550\u2550\u255d\u255a\u2550\u255d \u255a\u2550\u255d\u255a\u2550\u2550\u2550\u2550\u2550\u2550\u255d \u255a\u2550\u255d \u255a\u2550\u255d \u255a\u2550\u255d\u255a\u2550\u255d \u255a\u2550\u255d\u255a\u2550\u255d \u255a\u2550\u255d \u255a\u2550\u255d \u255a\u2550\u255d \u255a\u2550\u255d
+ \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557
+ \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255d\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255d\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255d\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557
+ \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255d\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255d
+ \u255a\u2550\u2550\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255d \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u255a\u2588\u2588\u2557 \u2588\u2588\u2554\u255d\u2588\u2588\u2554\u2550\u2550\u255d \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557
+ \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 \u255a\u2588\u2588\u2588\u2588\u2554\u255d \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551
+ \u255a\u2550\u2550\u2550\u2550\u2550\u2550\u255d\u255a\u2550\u2550\u2550\u2550\u2550\u2550\u255d\u255a\u2550\u255d \u255a\u2550\u255d \u255a\u2550\u2550\u2550\u255d \u255a\u2550\u2550\u2550\u2550\u2550\u2550\u255d\u255a\u2550\u255d \u255a\u2550\u255d
+
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/358828fe/server/src/main/resources/config-server.yml
----------------------------------------------------------------------
diff --git a/server/src/main/resources/config-server.yml b/server/src/main/resources/config-server.yml
new file mode 100644
index 0000000..2e210a6
--- /dev/null
+++ b/server/src/main/resources/config-server.yml
@@ -0,0 +1,31 @@
+#
+# 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 current 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
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+scope: java
+
+server:
+ applicationConnectors:
+ - type: http
+ port: 4001
+ adminConnectors:
+ - type: http
+ port: 4099
+
+ # ${project.version}
+