This is an automated email from the ASF dual-hosted git repository.

anatole pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-tamaya-sandbox.git

commit 1732596ccd39702a2858059e14a2f688d88f9855
Author: Anatole Tresch <[email protected]>
AuthorDate: Thu Feb 21 19:11:34 2019 +0100

    Added kube integration project.
---
 kubernetes/bnd.bnd                                 |  32 ++
 kubernetes/pom.xml                                 |  71 +++
 .../tamaya/k8s/AbstractEtcdPropertySource.java     | 273 +++++++++++
 .../java/org/apache/tamaya/k8s/EtcdAccessor.java   | 520 +++++++++++++++++++++
 .../org/apache/tamaya/k8s/EtcdBackendConfig.java   |  95 ++++
 .../org/apache/tamaya/k8s/EtcdPropertySource.java  |  52 +++
 .../java/org/apache/tamaya/k8s/K8SAccessor.java    |  44 ++
 .../org/apache/tamaya/k8s/EtcdAccessorTest.java    | 116 +++++
 .../apache/tamaya/k8s/EtcdPropertySourceTest.java  |  75 +++
 9 files changed, 1278 insertions(+)

diff --git a/kubernetes/bnd.bnd b/kubernetes/bnd.bnd
new file mode 100644
index 0000000..f5d0908
--- /dev/null
+++ b/kubernetes/bnd.bnd
@@ -0,0 +1,32 @@
+-buildpath: \
+       osgi.annotation; version=6.0.0,\
+       osgi.core; version=6.0,\
+       osgi.cmpn; version=6.0
+
+-testpath: \
+       ${junit}
+
+javac.source: 1.8
+javac.target: 1.8
+
+Automatic-Module-Name: org.apache.tamaya.k8s
+Bundle-Version: ${version}.${tstamp}
+Bundle-Name: Apache Tamaya - Kubernetes Config
+Bundle-SymbolicName: org.apache.tamaya.etcd
+Bundle-Description: Apacha Tamaya Config - Kubernetes PropertySources
+Bundle-Category: Implementation
+Bundle-Copyright: (C) Apache Foundation
+Bundle-License: Apache Licence version 2
+Bundle-Vendor: Apache Software Foundation
+Bundle-ContactAddress: [email protected]
+Bundle-DocURL: https://tamaya.apache.org
+Export-Package: \
+       org.apache.tamaya.k8s
+Import-Package: \
+    org.apache.tamaya,\
+    org.apache.tamaya.spi,\
+    org.apache.tamaya.mutableconfig\
+    org.apache.tamaya.mutableconfig.spi
+Export-Service: \
+    org.apache.tamaya.spi.PropertySource
+    
diff --git a/kubernetes/pom.xml b/kubernetes/pom.xml
new file mode 100644
index 0000000..6f11b18
--- /dev/null
+++ b/kubernetes/pom.xml
@@ -0,0 +1,71 @@
+<!-- 
+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-extensions</artifactId>
+        <version>0.4-incubating-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>tamaya-k8s</artifactId>
+    <name>Apache Tamaya Modules - Kubernetes PropertySources</name>
+    <packaging>jar</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>java-hamcrest</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-core</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-functions</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-mutable-config</artifactId>
+            <version>${project.parent.version}</version>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>io.kubernetes</groupId>
+            <artifactId>client-java</artifactId>
+            <version>3.0.0</version>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git 
a/kubernetes/src/main/java/org/apache/tamaya/k8s/AbstractEtcdPropertySource.java
 
b/kubernetes/src/main/java/org/apache/tamaya/k8s/AbstractEtcdPropertySource.java
new file mode 100644
index 0000000..d425b72
--- /dev/null
+++ 
b/kubernetes/src/main/java/org/apache/tamaya/k8s/AbstractEtcdPropertySource.java
@@ -0,0 +1,273 @@
+///*
+// * 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.etcd;
+//
+//import org.apache.tamaya.mutableconfig.ConfigChangeRequest;
+//import org.apache.tamaya.mutableconfig.spi.MutablePropertySource;
+//import org.apache.tamaya.spi.ChangeSupport;
+//import org.apache.tamaya.spi.PropertyValue;
+//import org.apache.tamaya.spisupport.propertysource.BasePropertySource;
+//
+//import java.util.*;
+//import java.util.concurrent.TimeUnit;
+//import java.util.concurrent.atomic.AtomicLong;
+//import java.util.logging.Level;
+//import java.util.logging.Logger;
+//
+///**
+// * Propertysource that is reading configuration from a configured etcd 
endpoint. Setting
+// * {@code etcd.prefix} as system property maps the etcd based configuration
+// * to this prefix namespace. Etcd servers are configured as {@code 
etcd.server.urls} system or environment property.
+// * Etcd can be disabled by setting {@code tamaya.etcdprops.disable} either 
as environment or system property.
+// */
+//public abstract class AbstractEtcdPropertySource extends BasePropertySource
+//        implements MutablePropertySource{
+//
+//    private static final Logger LOG = 
Logger.getLogger(AbstractEtcdPropertySource.class.getName());
+//
+//    private String directory ="";
+//
+//    private List<String> servers = new ArrayList<>();
+//
+//    private List<EtcdAccessor> etcdBackends = new ArrayList<>();
+//
+//    private Map<String,String> metaData = new HashMap<>();
+//
+//    private AtomicLong timeoutDuration = new 
AtomicLong(TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES));
+//
+//    private AtomicLong timeout = new AtomicLong();
+//
+//    /** The Hazelcast config map used. */
+//    private Map<String, PropertyValue> configMap = new HashMap<>();
+//
+//    public AbstractEtcdPropertySource(){
+//        this("etcd");
+//    }
+//
+//    public AbstractEtcdPropertySource(String name){
+//        super(name);
+//        metaData.put("source", "etcd");
+//    }
+//
+//    /**
+//     * Get the current timeout, when a reload will be triggered on access.
+//     * @return the current timeout, or 0 if no data has been loaded at all.
+//     */
+//    public long getValidUntil(){
+//        return timeout.get();
+//    }
+//
+//    /**
+//     * Get the current cache timeout.
+//     * @return the timeout duration after which data will be reloaded.
+//     */
+//    public long getCachePeriod(){
+//        return timeoutDuration.get();
+//    }
+//
+//    /**
+//     * Set the duration after which the data cache will be reloaded.
+//     * @param millis the millis
+//     */
+//    public void setCacheTimeout(long millis){
+//        this.timeoutDuration.set(millis);
+//    }
+//
+//    /**
+//     * Get the etc directora accessed.
+//     * @return the etc director, not null.
+//     */
+//    public String getDirectory() {
+//        return directory;
+//    }
+//
+//    /**
+//     * Sets the etcd directory to read from.
+//     * @param directory the directory, not null.
+//     */
+//    public void setDirectory(String directory) {
+//        if(!Objects.equals(this.directory, directory)) {
+//            this.directory = Objects.requireNonNull(directory);
+//            refresh();
+//        }
+//    }
+//
+//    public void setServer(List<String> servers) {
+//        if(!Objects.equals(this.servers, servers)) {
+//            List<EtcdAccessor> etcdBackends = new ArrayList<>();
+//            for (String s : servers) {
+//                etcdBackends.add(new EtcdAccessor(s));
+//            }
+//            this.servers = Collections.unmodifiableList(servers);
+//            this.etcdBackends = etcdBackends;
+//            metaData.put("backends", servers.toString());
+//            refresh();
+//        }
+//    }
+//
+//    /**
+//     * Get the underlying servers this instance will try to connect to.
+//     * @return the server list, not null.
+//     */
+//    public List<String> getServer(){
+//        return servers;
+//    }
+//
+//    /**
+//     * Checks for a cache timeout and optionally reloads the data.
+//     */
+//    public void checkRefresh(){
+//        if(this.timeout.get() < System.currentTimeMillis()){
+//            refresh();
+//        }
+//    }
+//
+//    /**
+//     * Reloads the data and updated the cache timeouts.
+//     */
+//    public void refresh() {
+//        for(EtcdAccessor accessor: this.etcdBackends){
+//            try{
+//                Map<String, String> props = 
accessor.getProperties(directory);
+//                if(!props.containsKey("_ERROR")) {
+//                    this.configMap = mapPrefix(props);
+//                    this.timeout.set(System.currentTimeMillis() + 
timeoutDuration.get());
+//                } else{
+//                    LOG.log(Level.FINE, "etcd error on " + accessor.getUrl() 
+ ": " + props.get("_ERROR"));
+//                }
+//            } catch(Exception e){
+//                LOG.log(Level.FINE, "etcd access failed on " + 
accessor.getUrl() + ", trying next...", e);
+//            }
+//        }
+//    }
+//
+//    @Override
+//    public int getOrdinal() {
+//        PropertyValue configuredOrdinal = get(TAMAYA_ORDINAL);
+//        if(configuredOrdinal!=null){
+//            try{
+//                return Integer.parseInt(configuredOrdinal.getValue());
+//            } catch(Exception e){
+//                Logger.getLogger(getClass().getName()).log(Level.WARNING,
+//                        "Configured ordinal is not an int number: " + 
configuredOrdinal, e);
+//            }
+//        }
+//        return getDefaultOrdinal();
+//    }
+//
+//    @Override
+//    public PropertyValue get(String key) {
+//        checkRefresh();
+//        return configMap.get(key);
+//    }
+//
+//    @Override
+//    public Map<String, PropertyValue> getProperties() {
+//        checkRefresh();
+//        return configMap;
+//    }
+//
+//    @Override
+//    public ChangeSupport getChangeSupport(){
+//        return ChangeSupport.SUPPORTED;
+//    }
+//
+//    private Map<String, PropertyValue> mapPrefix(Map<String, String> props) {
+//
+//        Map<String, PropertyValue> values = new HashMap<>();
+//        // Evaluate keys
+//        for(Map.Entry<String,String> entry:props.entrySet()) {
+//            if (!entry.getKey().startsWith("_")) {
+//                PropertyValue val = values.get(entry.getKey());
+//                if (val == null) {
+//                    val = PropertyValue.createValue(entry.getKey(), 
"").setMeta("source", getName()).setMeta(metaData);
+//                    values.put(entry.getKey(), val);
+//                }
+//            }
+//        }
+//        // add getMeta entries
+//        for(Map.Entry<String,String> entry:props.entrySet()) {
+//            if (entry.getKey().startsWith("_")) {
+//                String key = entry.getKey().substring(1);
+//                for(String field:new String[]{".createdIndex", 
".modifiedIndex", ".ttl",
+//                        ".expiration", ".source"}) {
+//                    if (key.endsWith(field)) {
+//                        key = key.substring(0, key.length() - 
field.length());
+//                        PropertyValue val = values.get(key);
+//                        if (val != null) {
+//                            val.setMeta(field, entry.getValue());
+//                        }
+//                    }
+//                }
+//            }
+//        }
+//        // Map to createValue map.
+////        Map<String, PropertyValue> values = new HashMap<>();
+//        for(Map.Entry<String,PropertyValue> en:values.entrySet()) {
+//            values.put(en.getKey(), en.getValue());
+//        }
+//        return values;
+//    }
+//
+//    @Override
+//    public void applyChange(ConfigChangeRequest configChange) {
+//        for(EtcdAccessor accessor: etcdBackends){
+//            try{
+//                for(String k: configChange.getRemovedProperties()){
+//                    Map<String,String> res = accessor.delete(k);
+//                    if(res.get("_ERROR")!=null){
+//                        LOG.info("Failed to remove key from etcd: " + k);
+//                    }
+//                }
+//                for(Map.Entry<String,String> 
en:configChange.getAddedProperties().entrySet()){
+//                    String key = en.getKey();
+//                    Integer ttl = null;
+//                    int index = en.getKey().indexOf('?');
+//                    if(index>0){
+//                        key = en.getKey().substring(0, index);
+//                        String rawQuery = en.getKey().substring(index+1);
+//                        String[] queries = rawQuery.split("&");
+//                        for(String query:queries){
+//                            if(query.contains("ttl")){
+//                                int qIdx = query.indexOf('=');
+//                                ttl = 
qIdx>0?Integer.parseInt(query.substring(qIdx+1).trim()):null;
+//                            }
+//                        }
+//                    }
+//                    Map<String,String> res = accessor.set(key, 
en.getValue(), ttl);
+//                    if(res.get("_ERROR")!=null){
+//                        LOG.info("Failed to add key to etcd: " + en.getKey() 
 + "=" + en.getValue());
+//                    }
+//                }
+//                // success, stop here
+//                break;
+//            } catch(Exception e){
+//                LOG.log(Level.FINE, "etcd access failed on " + 
accessor.getUrl() + ", trying next...", e);
+//            }
+//        }
+//    }
+//
+//
+//    @Override
+//    protected String toStringValues() {
+//        return  super.toStringValues() +
+//                "  directory=" + directory + '\n' +
+//                "  servers=" + this.servers + '\n';
+//    }
+//}
diff --git a/kubernetes/src/main/java/org/apache/tamaya/k8s/EtcdAccessor.java 
b/kubernetes/src/main/java/org/apache/tamaya/k8s/EtcdAccessor.java
new file mode 100644
index 0000000..1e66590
--- /dev/null
+++ b/kubernetes/src/main/java/org/apache/tamaya/k8s/EtcdAccessor.java
@@ -0,0 +1,520 @@
+///*
+// * 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.etcd;
+//
+//import java.io.StringReader;
+//import java.util.ArrayList;
+//import java.util.HashMap;
+//import java.util.List;
+//import java.util.Map;
+//import java.util.logging.Level;
+//import java.util.logging.Logger;
+//
+//import javax.json.Json;
+//import javax.json.JsonArray;
+//import javax.json.JsonObject;
+//import javax.json.JsonReader;
+//import javax.json.JsonReaderFactory;
+//
+//import org.apache.http.HttpEntity;
+//import org.apache.http.HttpStatus;
+//import org.apache.http.NameValuePair;
+//import org.apache.http.client.config.RequestConfig;
+//import org.apache.http.client.entity.UrlEncodedFormEntity;
+//import org.apache.http.client.methods.CloseableHttpResponse;
+//import org.apache.http.client.methods.HttpDelete;
+//import org.apache.http.client.methods.HttpGet;
+//import org.apache.http.client.methods.HttpPut;
+//import org.apache.http.impl.client.CloseableHttpClient;
+//import org.apache.http.impl.client.HttpClients;
+//import org.apache.http.message.BasicNameValuePair;
+//import org.apache.http.util.EntityUtils;
+//
+///**
+// * Accessor for reading to or writing from an etcd endpoint.
+// */
+//class EtcdAccessor {
+//
+//    private static final Logger LOG = 
Logger.getLogger(EtcdAccessor.class.getName());
+//
+//    /**
+//     * Timeout in seconds.
+//     */
+//    private int timeout = 2;
+//    /**
+//     * Timeout in seconds.
+//     */
+//    private final int socketTimeout = 1000;
+//    /**
+//     * Timeout in seconds.
+//     */
+//    private final int connectTimeout = 1000;
+//
+//    /**
+//     * Property that makes Johnzon accept comments.
+//     */
+//    public static final String JOHNZON_SUPPORTS_COMMENTS_PROP = 
"org.apache.johnzon.supports-comments";
+//    /**
+//     * The JSON reader factory used.
+//     */
+//    private final JsonReaderFactory readerFactory = initReaderFactory();
+//
+//
+//    /**
+//     * Initializes the factory to be used for creating readers.
+//     */
+//    private JsonReaderFactory initReaderFactory() {
+//        final Map<String, Object> config = new HashMap<>();
+//        config.put(JOHNZON_SUPPORTS_COMMENTS_PROP, true);
+//        return Json.createReaderFactory(config);
+//    }
+//
+//    /**
+//     * The base server url.
+//     */
+//    private final String serverURL;
+//    /**
+//     * The http client.
+//     */
+//    private final CloseableHttpClient httpclient = 
HttpClients.createDefault();
+//
+//    /**
+//     * Creates a new instance with the basic access url.
+//     *
+//     * @param server server url, e.g. {@code http://127.0.0.1:4001}, not 
null.
+//     */
+//    public EtcdAccessor(String server) {
+//        this(server, 2);
+//    }
+//
+//    public EtcdAccessor(String server, int timeout) {
+//        this.timeout = timeout;
+//        if (server.endsWith("/")) {
+//            serverURL = server.substring(0, server.length() - 1);
+//        } else {
+//            serverURL = server;
+//        }
+//    }
+//
+//    /**
+//     * Get the etcd server version.
+//     *
+//     * @return the etcd server version, never null.
+//     */
+//    public String getVersion() {
+//        String version = "<ERROR>";
+//        try {
+//            final CloseableHttpClient httpclient = 
HttpClients.createDefault();
+//            final HttpGet httpGet = new HttpGet(serverURL + "/version");
+//            
httpGet.setConfig(RequestConfig.copy(RequestConfig.DEFAULT).setSocketTimeout(socketTimeout)
+//                    .setConnectTimeout(timeout).build());
+//            try (CloseableHttpResponse response = 
httpclient.execute(httpGet)) {
+//                if (response.getStatusLine().getStatusCode() == 
HttpStatus.SC_OK) {
+//                    final HttpEntity entity = response.getEntity();
+//                    // and ensure it is fully consumed
+//                    version = EntityUtils.toString(entity);
+//                    EntityUtils.consume(entity);
+//                }
+//            }
+//            return version;
+//        } catch (final Exception e) {
+//            LOG.log(Level.INFO, "Error getting etcd version from: " + 
serverURL, e);
+//        }
+//        return version;
+//    }
+//
+//    /**
+//     * Ask etcd for a single key, createValue pair. Hereby the response 
returned from
+//     * etcd:
+//     *
+//     * <pre>
+//     * {
+//     * "action": "current",
+//     * "value": {
+//     * "createdIndex": 2,
+//     * "key": "/message",
+//     * "modifiedIndex": 2,
+//     * "value": "Hello world"
+//     * }
+//     * }
+//     * </pre>
+//     *
+//     * is mapped to:
+//     *
+//     * <pre>
+//     *     key=value
+//     *     _key.source=[etcd]http://127.0.0.1:4001
+//     *     _key.createdIndex=12
+//     *     _key.modifiedIndex=34
+//     *     _key.ttl=300
+//     *     _key.expiration=...
+//     * </pre>
+//     *
+//     * @param key the requested key
+//     * @return the mapped result, including getMeta-entries.
+//     */
+//    public Map<String, String> get(String key) {
+//        final Map<String, String> result = new HashMap<>();
+//        try {
+//            final HttpGet httpGet = new HttpGet(serverURL + "/v2/keys/" + 
key);
+//            
httpGet.setConfig(RequestConfig.copy(RequestConfig.DEFAULT).setSocketTimeout(socketTimeout)
+//                    
.setConnectionRequestTimeout(timeout).setConnectTimeout(connectTimeout).build());
+//            try (CloseableHttpResponse response = 
httpclient.execute(httpGet)) {
+//                if (response.getStatusLine().getStatusCode() == 
HttpStatus.SC_OK) {
+//                    final HttpEntity entity = response.getEntity();
+//                    final JsonReader reader = readerFactory
+//                            .createReader(new 
StringReader(EntityUtils.toString(entity)));
+//                    final JsonObject o = reader.readObject();
+//                    final JsonObject node = o.getJsonObject("value");
+//                    if (node.containsKey("key")) {
+//                        result.put(key, node.getString("key"));
+//                        result.put("_" + key + ".source", "[etcd]" + 
serverURL);
+//                    }
+//                    if (node.containsKey("createdIndex")) {
+//                        result.put("_" + key + ".createdIndex", 
String.valueOf(node.getInt("createdIndex")));
+//                    }
+//                    if (node.containsKey("modifiedIndex")) {
+//                        result.put("_" + key + ".modifiedIndex", 
String.valueOf(node.getInt("modifiedIndex")));
+//                    }
+//                    if (node.containsKey("expiration")) {
+//                        result.put("_" + key + ".expiration", 
String.valueOf(node.getString("expiration")));
+//                    }
+//                    if (node.containsKey("ttl")) {
+//                        result.put("_" + key + ".ttl", 
String.valueOf(node.getInt("ttl")));
+//                    }
+//                    EntityUtils.consume(entity);
+//                } else {
+//                    result.put("_" + key + ".NOT_FOUND.target", "[etcd]" + 
serverURL);
+//                }
+//            }
+//        } catch (final Exception e) {
+//            LOG.log(Level.INFO, "Error reading key '" + key + "' from etcd: 
" + serverURL, e);
+//            result.put("_ERROR", "Error reading key '" + key + "' from etcd: 
" + serverURL + ": " + e.toString());
+//        }
+//        return result;
+//    }
+//
+//    /**
+//     * Creates/updates an entry in etcd without any ttl setCurrent.
+//     *
+//     * @param key   the property key, not null
+//     * @param value the createValue to be setCurrent
+//     * @return the result map as described above.
+//     * @see #set(String, String, Integer)
+//     */
+//    public Map<String, String> set(String key, String value) {
+//        return set(key, value, null);
+//    }
+//
+//    /**
+//     * Creates/updates an entry in etcd. The response as follows:
+//     *
+//     * <pre>
+//     *     {
+//     * "action": "setCurrent",
+//     * "getValue": {
+//     * "createdIndex": 3,
+//     * "key": "/message",
+//     * "modifiedIndex": 3,
+//     * "createValue": "Hello etcd"
+//     * },
+//     * "prevNode": {
+//     * "createdIndex": 2,
+//     * "key": "/message",
+//     * "createValue": "Hello world",
+//     * "modifiedIndex": 2
+//     * }
+//     * }
+//     * </pre>
+//     *
+//     * is mapped to:
+//     *
+//     * <pre>
+//     *     key=createValue
+//     *     _key.source=[etcd]http://127.0.0.1:4001
+//     *     _key.createdIndex=12
+//     *     _key.modifiedIndex=34
+//     *     _key.ttl=300
+//     *     _key.expiry=...
+//     *      // optional
+//     *     _key.prevNode.createdIndex=12
+//     *     _key.prevNode.modifiedIndex=34
+//     *     _key.prevNode.ttl=300
+//     *     _key.prevNode.expiration=...
+//     * </pre>
+//     *
+//     * @param key        the property key, not null
+//     * @param value      the createValue to be setCurrent
+//     * @param ttlSeconds the ttl in seconds (optional)
+//     * @return the result map as described above.
+//     */
+//    public Map<String, String> set(String key, String value, Integer 
ttlSeconds) {
+//        final Map<String, String> result = new HashMap<>();
+//        try {
+//            final HttpPut put = new HttpPut(serverURL + "/v2/keys/" + key);
+//            
put.setConfig(RequestConfig.copy(RequestConfig.DEFAULT).setSocketTimeout(socketTimeout)
+//                    
.setConnectionRequestTimeout(timeout).setConnectTimeout(connectTimeout).build());
+//            final List<NameValuePair> nvps = new ArrayList<>();
+//            nvps.add(new BasicNameValuePair("value", value));
+//            if (ttlSeconds != null) {
+//                nvps.add(new BasicNameValuePair("ttl", 
ttlSeconds.toString()));
+//            }
+//            put.setEntity(new UrlEncodedFormEntity(nvps));
+//            try (CloseableHttpResponse response = httpclient.execute(put)) {
+//                if (response.getStatusLine().getStatusCode() == 
HttpStatus.SC_CREATED
+//                        || response.getStatusLine().getStatusCode() == 
HttpStatus.SC_OK) {
+//                    final HttpEntity entity = response.getEntity();
+//                    final JsonReader reader = readerFactory
+//                            .createReader(new 
StringReader(EntityUtils.toString(entity)));
+//                    final JsonObject o = reader.readObject();
+//                    final JsonObject node = o.getJsonObject("value");
+//                    if (node.containsKey("createdIndex")) {
+//                        result.put("_" + key + ".createdIndex", 
String.valueOf(node.getInt("createdIndex")));
+//                    }
+//                    if (node.containsKey("modifiedIndex")) {
+//                        result.put("_" + key + ".modifiedIndex", 
String.valueOf(node.getInt("modifiedIndex")));
+//                    }
+//                    if (node.containsKey("expiration")) {
+//                        result.put("_" + key + ".expiration", 
String.valueOf(node.getString("expiration")));
+//                    }
+//                    if (node.containsKey("ttl")) {
+//                        result.put("_" + key + ".ttl", 
String.valueOf(node.getInt("ttl")));
+//                    }
+//                    result.put(key, node.getString("key"));
+//                    result.put("_" + key + ".source", "[etcd]" + serverURL);
+//                    parsePrevNode(key, result, node);
+//                    EntityUtils.consume(entity);
+//                }
+//            }
+//        } catch (final Exception e) {
+//            LOG.log(Level.INFO, "Error writing to etcd: " + serverURL, e);
+//            result.put("_ERROR", "Error writing '" + key + "' to etcd: " + 
serverURL + ": " + e.toString());
+//        }
+//        return result;
+//    }
+//
+//    /**
+//     * Deletes a given key. The response is as follows:
+//     *
+//     * <pre>
+//     *     _key.source=[etcd]http://127.0.0.1:4001
+//     *     _key.createdIndex=12
+//     *     _key.modifiedIndex=34
+//     *     _key.ttl=300
+//     *     _key.expiry=...
+//     *      // optional
+//     *     _key.prevNode.createdIndex=12
+//     *     _key.prevNode.modifiedIndex=34
+//     *     _key.prevNode.ttl=300
+//     *     _key.prevNode.expiration=...
+//     *     _key.prevNode.value=...
+//     * </pre>
+//     *
+//     * @param key the key to be deleted.
+//     * @return the response maps as described above.
+//     */
+//    public Map<String, String> delete(String key) {
+//        final Map<String, String> result = new HashMap<>();
+//        try {
+//            final HttpDelete delete = new HttpDelete(serverURL + "/v2/keys/" 
+ key);
+//            
delete.setConfig(RequestConfig.copy(RequestConfig.DEFAULT).setSocketTimeout(socketTimeout)
+//                    
.setConnectionRequestTimeout(timeout).setConnectTimeout(connectTimeout).build());
+//            try (CloseableHttpResponse response = 
httpclient.execute(delete)) {
+//                if (response.getStatusLine().getStatusCode() == 
HttpStatus.SC_OK) {
+//                    final HttpEntity entity = response.getEntity();
+//                    final JsonReader reader = readerFactory
+//                            .createReader(new 
StringReader(EntityUtils.toString(entity)));
+//                    final JsonObject o = reader.readObject();
+//                    final JsonObject node = o.getJsonObject("value");
+//                    if (node.containsKey("createdIndex")) {
+//                        result.put("_" + key + ".createdIndex", 
String.valueOf(node.getInt("createdIndex")));
+//                    }
+//                    if (node.containsKey("modifiedIndex")) {
+//                        result.put("_" + key + ".modifiedIndex", 
String.valueOf(node.getInt("modifiedIndex")));
+//                    }
+//                    if (node.containsKey("expiration")) {
+//                        result.put("_" + key + ".expiration", 
String.valueOf(node.getString("expiration")));
+//                    }
+//                    if (node.containsKey("ttl")) {
+//                        result.put("_" + key + ".ttl", 
String.valueOf(node.getInt("ttl")));
+//                    }
+//                    parsePrevNode(key, result, o);
+//                    EntityUtils.consume(entity);
+//                }
+//            }
+//        } catch (final Exception e) {
+//            LOG.log(Level.INFO, "Error deleting key '" + key + "' from etcd: 
" + serverURL, e);
+//            result.put("_ERROR", "Error deleting '" + key + "' from etcd: " 
+ serverURL + ": " + e.toString());
+//        }
+//        return result;
+//    }
+//
+//    private static void parsePrevNode(String key, Map<String, String> 
result, JsonObject o) {
+//        if (o.containsKey("prevNode")) {
+//            final JsonObject prevNode = o.getJsonObject("prevNode");
+//            if (prevNode.containsKey("createdIndex")) {
+//                result.put("_" + key + ".prevNode.createdIndex",
+//                        String.valueOf(prevNode.getInt("createdIndex")));
+//            }
+//            if (prevNode.containsKey("modifiedIndex")) {
+//                result.put("_" + key + ".prevNode.modifiedIndex",
+//                        String.valueOf(prevNode.getInt("modifiedIndex")));
+//            }
+//            if (prevNode.containsKey("expiration")) {
+//                result.put("_" + key + ".prevNode.expiration",
+//                        String.valueOf(prevNode.getString("expiration")));
+//            }
+//            if (prevNode.containsKey("ttl")) {
+//                result.put("_" + key + ".prevNode.ttl", 
String.valueOf(prevNode.getInt("ttl")));
+//            }
+//            result.put("_" + key + ".prevNode.value", 
prevNode.getString("value"));
+//        }
+//    }
+//
+//    /**
+//     * Get all properties for the given directory key recursively.
+//     *
+//     * @param directory the directory entry
+//     * @return the properties and its metadata
+//     * @see #getProperties(String, boolean)
+//     */
+//    public Map<String, String> getProperties(String directory) {
+//        return getProperties(directory, true);
+//    }
+//
+//    /**
+//     * Access all properties. The response of:
+//     *
+//     * <pre>
+//     * {
+//     * "action": "current",
+//     * "getValue": {
+//     * "key": "/",
+//     * "dir": true,
+//     * "getValues": [
+//     * {
+//     * "key": "/foo_dir",
+//     * "dir": true,
+//     * "modifiedIndex": 2,
+//     * "createdIndex": 2
+//     * },
+//     * {
+//     * "key": "/foo",
+//     * "createValue": "two",
+//     * "modifiedIndex": 1,
+//     * "createdIndex": 1
+//     * }
+//     * ]
+//     * }
+//     * }
+//     * </pre>
+//     *
+//     * is mapped to a regular Tamaya properties map as follows:
+//     *
+//     * <pre>
+//     *    key1=myvalue
+//     *     _key1.source=[etcd]http://127.0.0.1:4001
+//     *     _key1.createdIndex=12
+//     *     _key1.modifiedIndex=34
+//     *     _key1.ttl=300
+//     *     _key1.expiration=...
+//     *
+//     *      key2=myvaluexxx
+//     *     _key2.source=[etcd]http://127.0.0.1:4001
+//     *     _key2.createdIndex=12
+//     *
+//     *      key3=val3
+//     *     _key3.source=[etcd]http://127.0.0.1:4001
+//     *     _key3.createdIndex=12
+//     *     _key3.modifiedIndex=2
+//     * </pre>
+//     *
+//     * @param directory remote directory to query.
+//     * @param recursive allows to setCurrent if querying is performed 
recursively
+//     * @return all properties read from the remote server.
+//     */
+//    public Map<String, String> getProperties(String directory, boolean 
recursive) {
+//        final Map<String, String> result = new HashMap<>();
+//        try {
+//            final HttpGet get = new HttpGet(serverURL + "/v2/keys/" + 
directory + "?recursive=" + recursive);
+//            
get.setConfig(RequestConfig.copy(RequestConfig.DEFAULT).setSocketTimeout(socketTimeout)
+//                    
.setConnectionRequestTimeout(timeout).setConnectTimeout(connectTimeout).build());
+//            try (CloseableHttpResponse response = httpclient.execute(get)) {
+//
+//                if (response.getStatusLine().getStatusCode() == 
HttpStatus.SC_OK) {
+//                    final HttpEntity entity = response.getEntity();
+//                    final JsonReader reader = readerFactory.createReader(new 
StringReader(EntityUtils.toString(entity)));
+//                    final JsonObject o = reader.readObject();
+//                    final JsonObject node = o.getJsonObject("value");
+//                    if (node != null) {
+//                        addNodes(result, node);
+//                    }
+//                    EntityUtils.consume(entity);
+//                }
+//            }
+//        } catch (final Exception e) {
+//            LOG.log(Level.INFO, "Error reading properties for '" + directory 
+ "' from etcd: " + serverURL, e);
+//            result.put("_ERROR",
+//                    "Error reading properties for '" + directory + "' from 
etcd: " + serverURL + ": " + e.toString());
+//        }
+//        return result;
+//    }
+//
+//    /**
+//     * Recursively read out all key/values from this etcd JSON array.
+//     *
+//     * @param result map with key, values and metadata.
+//     * @param node   the getValue to parse.
+//     */
+//    private void addNodes(Map<String, String> result, JsonObject node) {
+//        if (!node.containsKey("dir") || 
"false".equals(node.get("dir").toString())) {
+//            final String key = node.getString("key").substring(1);
+//            result.put(key, node.getString("value"));
+//            if (node.containsKey("createdIndex")) {
+//                result.put("_" + key + ".createdIndex", 
String.valueOf(node.getInt("createdIndex")));
+//            }
+//            if (node.containsKey("modifiedIndex")) {
+//                result.put("_" + key + ".modifiedIndex", 
String.valueOf(node.getInt("modifiedIndex")));
+//            }
+//            if (node.containsKey("expiration")) {
+//                result.put("_" + key + ".expiration", 
String.valueOf(node.getString("expiration")));
+//            }
+//            if (node.containsKey("ttl")) {
+//                result.put("_" + key + ".ttl", 
String.valueOf(node.getInt("ttl")));
+//            }
+//            result.put("_" + key + ".source", "[etcd]" + serverURL);
+//        } else {
+//            final JsonArray nodes = node.getJsonArray("values");
+//            if (nodes != null) {
+//                for (int i = 0; i < nodes.size(); i++) {
+//                    addNodes(result, nodes.getJsonObject(i));
+//                }
+//            }
+//        }
+//    }
+//
+//    /**
+//     * Access the server root URL used by this accessor.
+//     *
+//     * @return the server root URL.
+//     */
+//    public String getUrl() {
+//        return serverURL;
+//    }
+//}
diff --git 
a/kubernetes/src/main/java/org/apache/tamaya/k8s/EtcdBackendConfig.java 
b/kubernetes/src/main/java/org/apache/tamaya/k8s/EtcdBackendConfig.java
new file mode 100644
index 0000000..0eeb925
--- /dev/null
+++ b/kubernetes/src/main/java/org/apache/tamaya/k8s/EtcdBackendConfig.java
@@ -0,0 +1,95 @@
+///*
+// * 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.etcd;
+//
+//import java.util.ArrayList;
+//import java.util.List;
+//import java.util.concurrent.TimeUnit;
+//import java.util.logging.Level;
+//import java.util.logging.Logger;
+//
+///**
+// * Singleton that reads the current etcd setup, especially the possible URLs 
to be used.
+// */
+//final class EtcdBackendConfig {
+//
+//     private static final Logger LOG = 
Logger.getLogger(EtcdBackendConfig.class.getName());
+//     private static final String TAMAYA_ETCD_SERVER_URLS = 
"tamaya.etcd.server";
+//     private static final String TAMAYA_ETCD_TIMEOUT = "tamaya.etcd.timeout";
+//    private static final String TAMAYA_ETCD_DIRECTORY = 
"tamaya.etcd.directory";
+//
+//
+//    private EtcdBackendConfig(){}
+//
+//    /**
+//     * Get the default etcd directory selector, default {@code ""}.
+//     * @return the default etcd directory selector, never null.
+//     */
+//    public static String getEtcdDirectory(){
+//        String val = System.getProperty(TAMAYA_ETCD_DIRECTORY);
+//        if(val == null){
+//            val = System.getenv(TAMAYA_ETCD_DIRECTORY);
+//        }
+//        if(val!=null){
+//            return val;
+//        }
+//        return "";
+//    }
+//
+//    /**
+//     * Get the etcd connection timeout from system/enfironment property 
{@code tamaya.etcd.timeout (=seconds)}
+//     * (default 2 seconds).
+//     * @return the etcd connection timeout.
+//     */
+//    public static long getEtcdTimeout(){
+//        String val = System.getProperty(TAMAYA_ETCD_TIMEOUT);
+//        if(val == null){
+//            val = System.getenv(TAMAYA_ETCD_TIMEOUT);
+//        }
+//        if(val!=null){
+//            return TimeUnit.MILLISECONDS.convert(Integer.parseInt(val), 
TimeUnit.SECONDS);
+//        }
+//        return 2000L;
+//    }
+//
+//    /**
+//     * Evaluate the etcd target servers fomr system/environment property 
{@code tamaya.etcd.server}.
+//     * @return the servers configured, or {@code http://127.0.0.1:4001} 
(default).
+//     */
+//    public static List<String> getServers(){
+//        String serverURLs = System.getProperty(TAMAYA_ETCD_SERVER_URLS);
+//        if(serverURLs==null){
+//            serverURLs = System.getenv(TAMAYA_ETCD_SERVER_URLS);
+//        }
+//        if(serverURLs==null){
+//            serverURLs = "http://127.0.0.1:4001";;
+//        }
+//        List<String> servers = new ArrayList<>();
+//        for(String url:serverURLs.split("\\,")) {
+//            try{
+//                servers.add(url.trim());
+//                LOG.info("Using etcd endoint: " + url);
+//            } catch(Exception e){
+//                LOG.log(Level.SEVERE, "Error initializing etcd accessor for 
URL: " + url, e);
+//            }
+//        }
+//        return servers;
+//    }
+//
+//}
diff --git 
a/kubernetes/src/main/java/org/apache/tamaya/k8s/EtcdPropertySource.java 
b/kubernetes/src/main/java/org/apache/tamaya/k8s/EtcdPropertySource.java
new file mode 100644
index 0000000..d4981ba
--- /dev/null
+++ b/kubernetes/src/main/java/org/apache/tamaya/k8s/EtcdPropertySource.java
@@ -0,0 +1,52 @@
+///*
+// * 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.etcd;
+//
+//import org.apache.tamaya.spi.PropertyValue;
+//
+//import java.util.*;
+//import java.util.logging.Logger;
+//
+///**
+// * Propertysource that is reading configuration from a configured etcd 
endpoint. Setting
+// * {@code etcd.prefix} as system property maps the etcd based configuration
+// * to this prefix namespace. Etcd servers are configured as {@code 
etcd.server.urls} system or environment property.
+// * Etcd can be disabled by setting {@code tamaya.etcdprops.disable} either 
as environment or system property.
+// */
+//public class EtcdPropertySource extends AbstractEtcdPropertySource{
+//
+//    private static final Logger LOG = 
Logger.getLogger(EtcdPropertySource.class.getName());
+//
+//    public EtcdPropertySource(List<String> server){
+//        this();
+//        setServer(server);
+//    }
+//
+//    public EtcdPropertySource(String... server){
+//        this();
+//        setServer(Arrays.asList(server));
+//    }
+//
+//    public EtcdPropertySource(){
+//        setDefaultOrdinal(1000);
+//        setDirectory(EtcdBackendConfig.getEtcdDirectory());
+//        setServer(EtcdBackendConfig.getServers());
+//    }
+//
+//}
diff --git a/kubernetes/src/main/java/org/apache/tamaya/k8s/K8SAccessor.java 
b/kubernetes/src/main/java/org/apache/tamaya/k8s/K8SAccessor.java
new file mode 100644
index 0000000..e84d5fa
--- /dev/null
+++ b/kubernetes/src/main/java/org/apache/tamaya/k8s/K8SAccessor.java
@@ -0,0 +1,44 @@
+/*
+ * 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.k8s;
+
+import io.kubernetes.client.ApiClient;
+import io.kubernetes.client.Configuration;
+import io.kubernetes.client.models.V1APIService;
+import io.kubernetes.client.models.V1ConfigMap;
+import io.kubernetes.client.proto.V1;
+import io.kubernetes.client.util.Config;
+
+import java.util.logging.Logger;
+
+
+/**
+ * Accessor for reading to or writing from an etcd endpoint.
+ */
+class K8SAccessor {
+
+    private static final Logger LOG = 
Logger.getLogger(K8SAccessor.class.getName());
+
+    public void test(){
+        ApiClient client = Config.defaultClient();
+        Configuration.setDefaultApiClient(client);
+        client.
+        V1ConfigMap configMap = new V1ConfigMap().    }
+
+}
diff --git 
a/kubernetes/src/test/java/org/apache/tamaya/k8s/EtcdAccessorTest.java 
b/kubernetes/src/test/java/org/apache/tamaya/k8s/EtcdAccessorTest.java
new file mode 100644
index 0000000..f7fdc3a
--- /dev/null
+++ b/kubernetes/src/test/java/org/apache/tamaya/k8s/EtcdAccessorTest.java
@@ -0,0 +1,116 @@
+///*
+// * 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.etcd;
+//
+//import org.junit.BeforeClass;
+//import org.junit.Test;
+//
+//import java.net.MalformedURLException;
+//import java.util.Map;
+//import java.util.UUID;
+//
+//import static org.junit.Assert.*;
+//
+///**
+// * Tests for the etcd backend integration. You must have setCurrent a system 
property so, theses tests are executed, e.g.
+// * {@code -Detcd.url=http://127.0.0.1:4001}.
+// */
+//public class EtcdAccessorTest {
+//
+//    private static EtcdAccessor accessor;
+//    static boolean execute = false;
+//
+//    @BeforeClass
+//    public static void setup() throws MalformedURLException {
+//        accessor = new EtcdAccessor("http://192.168.99.105:4001";);
+//        if(!accessor.getVersion().contains("etcd")){
+//            System.out.println("Disabling etcd tests, etcd not accessible 
at: " + System.getProperty("etcd.server.urls"));
+//            System.out.println("Configure etcd with 
-Detcd.server.urls=http://<IP>:<PORT>");
+//        }
+//        else{
+//            execute = true;
+//        }
+//    }
+//
+//    @Test
+//    public void testGetVersion() throws Exception {
+//        if(!execute)return;
+//        assertEquals(accessor.getVersion(), "etcd 0.4.9");
+//    }
+//
+//    @Test
+//    public void testGet() throws Exception {
+//        if(!execute)return;
+//        Map<String,String> result = accessor.get("test1");
+//        assertNotNull(result);
+//    }
+//
+//    @Test
+//    public void testSetNormal() throws Exception {
+//        if(!execute)return;
+//        String value = UUID.randomUUID().toString();
+//        Map<String,String> result = accessor.set("testSetNormal", value);
+//        assertNull(result.get("_testSetNormal.ttl"));
+//        assertEquals(value, 
accessor.get("testSetNormal").get("testSetNormal"));
+//    }
+//
+//    @Test
+//    public void testSetNormal2() throws Exception {
+//        if(!execute)return;
+//        String value = UUID.randomUUID().toString();
+//        Map<String,String> result = accessor.set("testSetNormal2", value, 
null);
+//        assertNull(result.get("_testSetNormal2.ttl"));
+//        assertEquals(value, 
accessor.get("testSetNormal2").get("testSetNormal2"));
+//    }
+//
+//    @Test
+//    public void testSetWithTTL() throws Exception {
+//        if(!execute)return;
+//        String value = UUID.randomUUID().toString();
+//        Map<String,String> result = accessor.set("testSetWithTTL", value, 1);
+//        assertNotNull(result.get("_testSetWithTTL.ttl"));
+//        assertEquals(value, 
accessor.get("testSetWithTTL").get("testSetWithTTL"));
+//        Thread.sleep(2000L);
+//        result = accessor.get("testSetWithTTL");
+//        assertNull(result.get("testSetWithTTL"));
+//    }
+//
+//    @Test
+//    public void testDelete() throws Exception {
+//        if(!execute)return;
+//        String value = UUID.randomUUID().toString();
+//        Map<String,String> result = accessor.set("testDelete", value, null);
+//        assertEquals(value, accessor.get("testDelete").get("testDelete"));
+//        assertNotNull(result.get("_testDelete.createdIndex"));
+//        result = accessor.delete("testDelete");
+//        assertEquals(value, result.get("_testDelete.prevNode.createValue"));
+//        assertNull(accessor.get("testDelete").get("testDelete"));
+//    }
+//
+//    @Test
+//    public void testGetProperties() throws Exception {
+//        if(!execute)return;
+//        String value = UUID.randomUUID().toString();
+//        accessor.set("testGetProperties1", value);
+//        Map<String,String> result = accessor.getProperties("");
+//        assertNotNull(result);
+//        assertEquals(value, result.get("testGetProperties1"));
+//        assertNotNull(result.get("_testGetProperties1.createdIndex"));
+//    }
+//}
\ No newline at end of file
diff --git 
a/kubernetes/src/test/java/org/apache/tamaya/k8s/EtcdPropertySourceTest.java 
b/kubernetes/src/test/java/org/apache/tamaya/k8s/EtcdPropertySourceTest.java
new file mode 100644
index 0000000..f7ee47a
--- /dev/null
+++ b/kubernetes/src/test/java/org/apache/tamaya/k8s/EtcdPropertySourceTest.java
@@ -0,0 +1,75 @@
+///*
+// * 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.etcd;
+//
+//import org.apache.tamaya.spi.PropertyValue;
+//import org.junit.BeforeClass;
+//import org.junit.Test;
+//
+//import java.util.Map;
+//
+//import static org.junit.Assert.*;
+//import static org.junit.Assert.assertEquals;
+//
+///**
+// * Created by atsticks on 07.01.16.
+// */
+//public class EtcdPropertySourceTest {
+//
+//    private final EtcdPropertySource propertySource = new 
EtcdPropertySource();
+//
+//    @BeforeClass
+//    public static void setup(){
+//        System.setProperty("etcd.server.urls", 
"http://8.8.8.8:4001,http://192.168.99.105:4001";);
+//    }
+//
+//    @Test
+//    public void testGetOrdinal() throws Exception {
+//        assertEquals(1000, propertySource.getOrdinal());
+//    }
+//
+//    @Test
+//    public void testGetDefaultOrdinal() throws Exception {
+//        assertEquals(1000, propertySource.getDefaultOrdinal());
+//    }
+//
+//    @Test
+//    public void testGetName() throws Exception {
+//        assertEquals("etcd", propertySource.getName());
+//    }
+//
+//    @Test
+//    public void testGet() throws Exception {
+//        Map<String,PropertyValue> props = propertySource.getProperties();
+//        for(Map.Entry<String,PropertyValue> en:props.entrySet()){
+//            assertNotNull("Key not found: " + en.getKey(), 
propertySource.get(en.getKey()));
+//        }
+//    }
+//
+//    @Test
+//    public void testGetProperties() throws Exception {
+//        Map<String,PropertyValue> props = propertySource.getProperties();
+//        assertNotNull(props);
+//    }
+//
+//    @Test
+//    public void testIsScannable() throws Exception {
+//        assertTrue(propertySource.isScannable());
+//    }
+//}
\ No newline at end of file

Reply via email to