getConfigSources();
diff --git a/api/src/main/java/org/eclipse/microprofile/config/ConfigProvider.java b/api/src/main/java/org/eclipse/microprofile/config/ConfigProvider.java
index eafe903d..83c4ad14 100644
--- a/api/src/main/java/org/eclipse/microprofile/config/ConfigProvider.java
+++ b/api/src/main/java/org/eclipse/microprofile/config/ConfigProvider.java
@@ -20,8 +20,6 @@
package org.eclipse.microprofile.config;
import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
-import org.eclipse.microprofile.config.spi.ConfigSource;
-import org.eclipse.microprofile.config.spi.Converter;
/**
*
@@ -41,14 +39,14 @@
*
*
*
- * A 'Configuration' consists of the information collected from the registered {@link ConfigSource ConfigSources}.
- * These {@link ConfigSource ConfigSources} get sorted according to
- * their ordinal defined via {@link ConfigSource#getOrdinal()}.
- * That way it is possible to overwrite configuration with lower importance from outside.
+ * A 'Configuration' consists of the information collected from the registered {@link org.eclipse.microprofile.config.spi.ConfigSource ConfigSources}.
+ * These {@link org.eclipse.microprofile.config.spi.ConfigSource ConfigSources} get sorted according to
+ * their ordinal defined via {@link org.eclipse.microprofile.config.spi.ConfigSource#getOrdinal()}.
+ * That way it is possible to overwrite configuration by providing in a ConfigSource with higher importance from outside.
*
*
*
- * It is also possible to register custom {@link ConfigSource ConfigSources} to flexibly
+ * It is also possible to register custom {@link org.eclipse.microprofile.config.spi.ConfigSource ConfigSources} to flexibly
* extend the configuration mechanism. An example would be to pick up
* configuration values from a database table.
*
@@ -61,6 +59,8 @@
* "myproject.some.remote.service.port", Integer.class);
*
*
+ * For more advanced use cases like e.g. registering a manually created {@link Config} please see
+ * {@link ConfigProviderResolver#registerConfig(Config, ClassLoader)} and {@link ConfigProviderResolver#getBuilder()}.
*
* @author Mark Struberg
* @author Romain Manni-Bucau
@@ -73,7 +73,7 @@ private ConfigProvider() {
}
/**
- * Provide a {@link Config} based on all {@link ConfigSource ConfigSources} of the
+ * Provide a {@link Config} based on all {@link org.eclipse.microprofile.config.spi.ConfigSource ConfigSources} of the
* current Thread Context ClassLoader (TCCL)
* The {@link Config} will be stored for future retrieval.
*
@@ -85,7 +85,7 @@ public static Config getConfig() {
}
/**
- * Provide a {@link Config} based on all {@link ConfigSource ConfigSources} of the
+ * Provide a {@link Config} based on all {@link org.eclipse.microprofile.config.spi.ConfigSource ConfigSources} of the
* specified ClassLoader
*
*
@@ -96,93 +96,4 @@ public static Config getConfig(ClassLoader cl) {
return INSTANCE.getConfig(cl);
}
- /**
- * Create a fresh {@link ConfigBuilder} instance. This ConfigBuilder will
- * initially contain no {@link ConfigSource} but with default {@link Converter Converters} and auto discovered
- * {@link ConfigSource configsources} and {@link Converter converters}.
- * Other undiscovered {@link ConfigSource} and {@link Converter Converters} will have to be added manually.
- *
- * The ConfigProvider will not manage the Config instance internally
- */
- public static ConfigBuilder getBuilder() {
- return INSTANCE.getBuilder();
- }
-
- /**
- * Register a given {@link Config} within the Application (or Module) identified by the given ClassLoader.
- * If the ClassLoader is {@code null} then the current Application will be used.
- *
- * @param config
- * which should get registered
- * @param classLoader
- * which identifies the Application or Module the given Config should get associated with.
- *
- * @throws IllegalStateException
- * if there is already a Config registered within the Application.
- * A user could explicitly use {@link #releaseConfig(Config)} for this case.
- */
- public static void setConfig(Config config, ClassLoader classLoader) {
- INSTANCE.setConfig(config, classLoader);
- }
-
- /**
- * A {@link Config} normally gets released if the Application it is associated with gets destroyed.
- * Invoke this method if you like to destroy the Config prematurely.
- *
- * If the given Config is associated within an Application then it will be unregistered.
- */
- public static void releaseConfig(Config config) {
- INSTANCE.releaseConfig(config);
- }
-
- /**
- * Builder for manually creating an instance of a {@code Config}.
- *
- * @see ConfigProvider#getBuilder()
- */
- public interface ConfigBuilder {
- /**
- * Add the default config sources appearing on the builder's classpath
- * including:
- *
- * - System properties
- * - Environment properties
- * - /META-INF/microprofile-config.properties
- *
- *
- * @return the ConfigBuilder with the default config sources
- */
- ConfigBuilder addDefaultSources();
-
- /**
- * Return the ConfigBuilder for a given classloader
- *
- * @param loader
- * @return the ConfigureBuilder for the given classloader
- */
- ConfigBuilder forClassLoader(ClassLoader loader);
-
- /**
- * Add the specified {@link ConfigSource}.
- *
- * @param sources
- * @return the ConfigBuilder with the configured sources
- */
- ConfigBuilder withSources(ConfigSource... sources);
-
- /**
- * Add the specified {@link Converter}
- *
- * @param converters
- * @return the ConfigBuilder with the added converters
- */
- ConfigBuilder withConverters(Converter>... converters);
-
- /**
- * Build the {@link Config} object.
- *
- * @return the Config object
- */
- Config build();
- }
}
diff --git a/api/src/main/java/org/eclipse/microprofile/config/inject/ConfigProperty.java b/api/src/main/java/org/eclipse/microprofile/config/inject/ConfigProperty.java
new file mode 100644
index 00000000..b8c32eae
--- /dev/null
+++ b/api/src/main/java/org/eclipse/microprofile/config/inject/ConfigProperty.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2016-2017 Payara Services Ltd. and others
+ *
+ * Licensed 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.eclipse.microprofile.config.inject;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import javax.enterprise.util.Nonbinding;
+import javax.inject.Qualifier;
+
+/**
+ * Binds the injection point with a configured value.
+ * Should annotate injection points of type {@code TYPE} or {@code ConfigValue},
+ * where {@code TYPE} can be {@code String} and all types which have appropriate converters.
+ *
+ * Example:
+ *
+ *
+ * {@literal @Inject}
+ * {@literal @ConfigProperty("my.long.property")}
+ * Long injectedLongValue;
+ * // injects value of my.long.property property
+ *
+ * {@literal @Inject}
+ * {@literal @ConfigProperty("my.long.property")}
+ * {@literal ConfigValue} longConfigValue;
+ * // injects a ConfigValue for the value of my.long.property property to resolve the property dynamically
+ *
+ *
+ * @author Ondrej Mihalyi
+ */
+@Qualifier
+@Retention(RUNTIME)
+@Target({METHOD, FIELD, PARAMETER, TYPE})
+public @interface ConfigProperty {
+ /**
+ * The kay of the config property used to look up the configuration value.
+ * If it is not specified, it will be derived automatically as {@code .},
+ * where {@code injection_point_name} is either a field name or a property name in case of field/property injection,
+ * {@code class_name} is the simple name of the class being injected to.
+ * If one of the {@code class_name} or {@code injection_point_name} cannot be determined, the value has to be provided.
+ *
+ * @return Name (key) of the config property to inject
+ */
+ @Nonbinding
+ String value() default "";
+}
diff --git a/api/src/main/java/org/eclipse/microprofile/config/spi/ConfigBuilder.java b/api/src/main/java/org/eclipse/microprofile/config/spi/ConfigBuilder.java
new file mode 100644
index 00000000..979d8d8b
--- /dev/null
+++ b/api/src/main/java/org/eclipse/microprofile/config/spi/ConfigBuilder.java
@@ -0,0 +1,76 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2016-2017 Mark Struberg and others
+ *
+ * Licensed 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.eclipse.microprofile.config.spi;
+
+import org.eclipse.microprofile.config.Config;
+
+/**
+ * Builder for manually creating an instance of a {@code Config}.
+ *
+ * @see ConfigProviderResolver#getBuilder()
+ *
+ * @author Mark Struberg
+ * @author Romain Manni-Bucau
+ * @author Emily Jiang
+
+ */
+public interface ConfigBuilder {
+ /**
+ * Add the default config sources appearing on the builder's classpath
+ * including:
+ *
+ * - System properties
+ * - Environment properties
+ * - /META-INF/microprofile-config.properties
+ *
+ *
+ * @return the ConfigBuilder with the default config sources
+ */
+ ConfigBuilder addDefaultSources();
+
+ /**
+ * Return the ConfigBuilder for a given classloader
+ *
+ * @param loader
+ * @return the ConfigureBuilder for the given classloader
+ */
+ ConfigBuilder forClassLoader(ClassLoader loader);
+
+ /**
+ * Add the specified {@link ConfigSource}.
+ *
+ * @param sources
+ * @return the ConfigBuilder with the configured sources
+ */
+ ConfigBuilder withSources(ConfigSource... sources);
+
+ /**
+ * Add the specified {@link Converter}
+ *
+ * @param converters
+ * @return the ConfigBuilder with the added converters
+ */
+ ConfigBuilder withConverters(Converter>... converters);
+
+ /**
+ * Build the {@link Config} object.
+ *
+ * @return the Config object
+ */
+ Config build();
+}
diff --git a/api/src/main/java/org/eclipse/microprofile/config/spi/ConfigProviderResolver.java b/api/src/main/java/org/eclipse/microprofile/config/spi/ConfigProviderResolver.java
index 05ddf5ff..4df7fe63 100644
--- a/api/src/main/java/org/eclipse/microprofile/config/spi/ConfigProviderResolver.java
+++ b/api/src/main/java/org/eclipse/microprofile/config/spi/ConfigProviderResolver.java
@@ -23,7 +23,6 @@
import java.util.ServiceLoader;
import org.eclipse.microprofile.config.Config;
-import org.eclipse.microprofile.config.ConfigProvider.ConfigBuilder;
/**
* This class is not intended to be used by end-users but for
@@ -53,17 +52,35 @@ protected ConfigProviderResolver() {
public abstract Config getConfig(ClassLoader loader);
/**
- * @see org.eclipse.microprofile.config.ConfigProvider#getBuilder()
+ * Create a fresh {@link ConfigBuilder} instance. This ConfigBuilder will
+ * initially contain no {@link ConfigSource} but with default {@link Converter Converters} and auto discovered
+ * {@link ConfigSource configsources} and {@link Converter converters}.
+ * Other undiscovered {@link ConfigSource} and {@link Converter Converters} will have to be added manually.
+ *
+ * The ConfigProvider will not manage the Config instance internally
*/
public abstract ConfigBuilder getBuilder();
/**
- * @see org.eclipse.microprofile.config.ConfigProvider#setConfig(Config, ClassLoader)
+ * Register a given {@link Config} within the Application (or Module) identified by the given ClassLoader.
+ * If the ClassLoader is {@code null} then the current Application will be used.
+ *
+ * @param config
+ * which should get registered
+ * @param classLoader
+ * which identifies the Application or Module the given Config should get associated with.
+ *
+ * @throws IllegalStateException
+ * if there is already a Config registered within the Application.
+ * A user could explicitly use {@link #releaseConfig(Config)} for this case.
*/
- public abstract void setConfig(Config config, ClassLoader classLoader);
+ public abstract void registerConfig(Config config, ClassLoader classLoader);
/**
- * @see org.eclipse.microprofile.config.ConfigProvider#releaseConfig(Config)
+ * A {@link Config} normally gets released if the Application it is associated with gets destroyed.
+ * Invoke this method if you like to destroy the Config prematurely.
+ *
+ * If the given Config is associated within an Application then it will be unregistered.
*/
public abstract void releaseConfig(Config config);
@@ -101,6 +118,7 @@ public ClassLoader run() {
return instance;
}
+
private static ConfigProviderResolver loadSpi(ClassLoader cl) {
if (cl == null) {
return null;
diff --git a/pom.xml b/pom.xml
index b8407c93..b84804a2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -15,6 +15,7 @@
1.8
2.17
+ ^_?[a-z][a-zA-Z0-9]*$
@@ -33,12 +34,37 @@
spec
+
+
+
+ javax.enterprise
+ cdi-api
+ 1.2
+
+
+ org.jboss.arquillian
+ arquillian-bom
+ 1.1.12.Final
+ import
+ pom
+
+
+
+
+
org.apache.maven.plugins
maven-checkstyle-plugin
${checkstyle.version}
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
verify-style
@@ -71,7 +97,7 @@
-
+
diff --git a/tck/pom.xml b/tck/pom.xml
index 285624a8..a9f74d63 100644
--- a/tck/pom.xml
+++ b/tck/pom.xml
@@ -13,12 +13,23 @@
microprofile-config-tck
1.0-SNAPSHOT
-
+
+ ^_?[a-z][a-zA-Z0-9_]*$
+
+
- org.eclipse.microprofile.config.api
- microprofile-config-api
+ org.eclipse.microprofile.apis
+ microprofile-config_1.0_api
1.0-SNAPSHOT
+ provided
+
+
+
+ javax.enterprise
+ cdi-api
+ 1.2
+ provided
@@ -27,6 +38,38 @@
6.9.9
compile
-
+
+
+ junit
+ junit
+ 4.12
+ compile
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
-
\ No newline at end of file
+
+ org.hamcrest
+ hamcrest-all
+ 1.3
+ compile
+
+
+
+ org.jboss.arquillian.junit
+ arquillian-junit-container
+ compile
+
+
+
+ org.jboss.shrinkwrap
+ shrinkwrap-api
+ compile
+
+
+
+
diff --git a/tck/running_the_tck.asciidoc b/tck/running_the_tck.asciidoc
new file mode 100644
index 00000000..a9de27c9
--- /dev/null
+++ b/tck/running_the_tck.asciidoc
@@ -0,0 +1,80 @@
+//
+// Copyright (c) 2016-2017 Mark Struberg and others
+//
+// Licensed 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.
+//
+
+= Running the Microprofile Config TCK
+
+Any Microprofile 1.1 and higher release must pass this test suite.
+The TCK uses `testng`
+
+To enable the tests in your project you need to add the following dependency to your build:
+
+[source, xml]
+----
+
+ org.eclipse.microprofile.apis
+ microprofile-config_1.0_api
+ 1.0-SNAPSHOT
+
+
+
+ org.eclipse.microprofile.config.tck
+ microprofile-config-tck
+ 1.0-SNAPSHOT
+ test
+
+
+ org.testng
+ testng
+ 6.9.9
+ test
+
+----
+
+You also need to specify which tests you want to run, e.g. create a file `tck-suite.xml` in your project which contains the following content:
+[source, xml]
+----
+
+
+
+
+
+
+
+
+
+
+
+
+----
+
+If you use Apache Maven then the tests are run via the `maven-surefire-plugin`
+[source, xml]
+----
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.19.1
+
+
+ tck-suite.xml
+
+
+
+
+
+----
\ No newline at end of file
diff --git a/tck/src/main/java/org/eclipse/microprofile/config/tck/CDIPlainInjectionTest.java b/tck/src/main/java/org/eclipse/microprofile/config/tck/CDIPlainInjectionTest.java
new file mode 100644
index 00000000..14ecda4b
--- /dev/null
+++ b/tck/src/main/java/org/eclipse/microprofile/config/tck/CDIPlainInjectionTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2016-2017 Payara Services Ltd. and others
+ *
+ * Licensed 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.eclipse.microprofile.config.tck;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.inject.Instance;
+import javax.inject.Inject;
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+import static org.eclipse.microprofile.config.tck.matchers.AdditionalMatchers.floatCloseTo;
+import static org.eclipse.microprofile.config.tck.testsupport.TestSetup.ensure_property_defined;
+import static org.eclipse.microprofile.config.tck.testsupport.TestSetup.ensure_property_undefined;
+import static org.eclipse.microprofile.config.tck.testsupport.TestSetup.get_bean_of_type;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.closeTo;
+import static org.hamcrest.Matchers.nullValue;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import static org.junit.Assert.assertThat;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test cases for CDI-based API that test retrieving values from the configuration.
+ * The tests depend only on CDI 1.2.
+ * @author Ondrej Mihalyi
+ */
+@RunWith(Arquillian.class)
+public class CDIPlainInjectionTest {
+
+ @Deployment
+ public static Archive deployment() {
+ return ShrinkWrap.create(WebArchive.class)
+ .addClasses(CDIPlainInjectionTest.class, SimpleValuesBean.class, DynamicValuesBean.class)
+ .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
+ }
+
+@Test
+ public void can_inject_simple_values_when_defined() {
+ ensure_all_property_values_are_defined();
+
+ SimpleValuesBean bean = get_bean_of_type(SimpleValuesBean.class);
+
+ assertThat(bean.stringProperty, is(equalTo("text")));
+ assertThat(bean.boolProperty, is(true));
+ assertThat(bean.intProperty, is(equalTo(5)));
+ assertThat(bean.longProperty, is(equalTo(10L)));
+ assertThat(bean.floatProperty, is(floatCloseTo(10.5f, 0.1f)));
+ assertThat(bean.doubleProperty, is(closeTo(11.5, 0.1)));
+ }
+
+ @Test
+ public void can_inject_dynamic_values_via_CDI_provider() {
+ clear_all_property_values();
+
+ DynamicValuesBean bean = get_bean_of_type(DynamicValuesBean.class);
+
+ assertThat(bean.getIntProperty(), is(nullValue()));
+
+ ensure_all_property_values_are_defined();
+
+ assertThat(bean.getIntProperty(), is(equalTo(5)));
+ }
+
+ private void ensure_all_property_values_are_defined() {
+ ensure_property_defined("my.string.property", "text");
+ ensure_property_defined("my.boolean.property", "true");
+ ensure_property_defined("my.int.property", "5");
+ ensure_property_defined("my.long.property", "10");
+ ensure_property_defined("my.float.property", "10.5");
+ ensure_property_defined("my.double.property", "11.5");
+ }
+
+ private void clear_all_property_values() {
+ ensure_property_undefined("my.string.property");
+ ensure_property_undefined("my.boolean.property");
+ ensure_property_undefined("my.int.property");
+ ensure_property_undefined("my.long.property");
+ ensure_property_undefined("my.float.property");
+ ensure_property_undefined("my.double.property");
+ }
+
+ @Dependent
+ public static class SimpleValuesBean {
+
+ @Inject
+ @ConfigProperty("my.string.property")
+ private String stringProperty;
+
+ @Inject
+ @ConfigProperty("my.boolean.property")
+ private Boolean boolProperty;
+
+ @Inject
+ @ConfigProperty("my.int.property")
+ private Integer intProperty;
+
+ @Inject
+ @ConfigProperty("my.long.property")
+ private Long longProperty;
+
+ @Inject
+ @ConfigProperty("my.float.property")
+ private Float floatProperty;
+
+ @Inject
+ @ConfigProperty("my.double.property")
+ private Double doubleProperty;
+
+ }
+
+ @Dependent
+ public static class DynamicValuesBean {
+
+ @Inject
+ @ConfigProperty("my.int.property")
+ private Instance intPropertyProvider;
+
+ public Integer getIntProperty() {
+ if (intPropertyProvider.isUnsatisfied()) {
+ return null;
+ }
+ else {
+ return intPropertyProvider.get();
+ }
+ }
+
+ }
+}
diff --git a/tck/src/main/java/org/eclipse/microprofile/config/tck/ConfigProviderTest.java b/tck/src/main/java/org/eclipse/microprofile/config/tck/ConfigProviderTest.java
index 3962de76..251a3196 100644
--- a/tck/src/main/java/org/eclipse/microprofile/config/tck/ConfigProviderTest.java
+++ b/tck/src/main/java/org/eclipse/microprofile/config/tck/ConfigProviderTest.java
@@ -22,6 +22,7 @@
import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;
+import org.eclipse.microprofile.config.spi.ConfigSource;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -72,4 +73,25 @@ public void testNonExistingConfigKey() {
Assert.assertNull(config.getString("tck.config.test.keydoesnotexist").get());
}
+ @Test
+ public void testEmptyConfigTreatedAsNotExisting() {
+ Config config = ConfigProvider.getConfig();
+ Assert.assertFalse(config.getString("tck.config.test.javaconfig.emptyvalue").isPresent());
+ }
+
+ @Test
+ public void testGetConfigSources() {
+ Config config = ConfigProvider.getConfig();
+ Iterable configSources = config.getConfigSources();
+ Assert.assertNotNull(configSources);
+
+ // check descending sorting
+ int prevOrdinal = Integer.MAX_VALUE;
+ for (ConfigSource configSource : configSources) {
+ Assert.assertTrue(configSource.getOrdinal() <= prevOrdinal);
+ prevOrdinal = configSource.getOrdinal();
+ }
+
+ }
+
}
diff --git a/tck/src/main/java/org/eclipse/microprofile/config/tck/matchers/AdditionalMatchers.java b/tck/src/main/java/org/eclipse/microprofile/config/tck/matchers/AdditionalMatchers.java
new file mode 100644
index 00000000..978d8d01
--- /dev/null
+++ b/tck/src/main/java/org/eclipse/microprofile/config/tck/matchers/AdditionalMatchers.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016-2017 Ondrej Mihalyi, Payara Services Ltd. and others
+ *
+ * Licensed 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.eclipse.microprofile.config.tck.matchers;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import static org.hamcrest.Matchers.closeTo;
+
+/**
+ *
+ * @author Ondrej Mihalyi
+ */
+public final class AdditionalMatchers {
+
+ private AdditionalMatchers() {
+ // utility class
+ }
+
+ public static Matcher floatCloseTo(float value, float range) {
+ return new BaseMatcher() {
+
+ private Matcher doubleMatcher = null;
+
+ @Override
+ public boolean matches(Object item) {
+ if (item instanceof Float) {
+ return (doubleMatcher = closeTo(value, range)).matches(((Float)item).doubleValue());
+ }
+ else {
+ return (doubleMatcher = closeTo(value, range)).matches(item);
+ }
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ doubleMatcher.describeTo(description);
+ }
+ };
+ }
+
+
+}
diff --git a/tck/src/main/java/org/eclipse/microprofile/config/tck/testsupport/TestSetup.java b/tck/src/main/java/org/eclipse/microprofile/config/tck/testsupport/TestSetup.java
new file mode 100644
index 00000000..0ada3a1e
--- /dev/null
+++ b/tck/src/main/java/org/eclipse/microprofile/config/tck/testsupport/TestSetup.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016-2017 Payara Services Ltd. and others
+ *
+ * Licensed 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.eclipse.microprofile.config.tck.testsupport;
+
+import java.time.ZonedDateTime;
+import java.util.Date;
+import javax.enterprise.inject.spi.CDI;
+
+/**
+ * Utility class for common functionality used in test scenarios.
+ * @author Ondrej Mihalyi
+ */
+public final class TestSetup {
+
+ private TestSetup() {
+ // utility class
+ }
+
+ public static Date toDate(String isoDateTime) {
+ return Date.from(ZonedDateTime.parse(isoDateTime).toInstant());
+ }
+
+ public static void ensure_property_defined(String key, String value) {
+ // setting configuration via system properties
+ System.setProperty(key, value);
+ }
+
+ public static void ensure_property_undefined(String key) {
+ // clearing configuration in system properties if previously set
+ System.getProperties().remove(key);
+ }
+
+ public static T get_bean_of_type(Class beanClass) {
+ return CDI.current().select(beanClass).get();
+ }
+
+}
diff --git a/tck/src/main/resources/META-INF/microprofile-config.properties b/tck/src/main/resources/META-INF/microprofile-config.properties
index 5315cccb..0f172ccb 100644
--- a/tck/src/main/resources/META-INF/microprofile-config.properties
+++ b/tck/src/main/resources/META-INF/microprofile-config.properties
@@ -65,6 +65,8 @@ tck.config.test.javaconfig.configvalue.long=1234567890123456
tck.config.test.javaconfig.configvalue.float=12.34
tck.config.test.javaconfig.configvalue.double=12.34567890123456
+# empty values treated as not existing
+tck.config.test.javaconfig.emptyvalue=
# withVariable
tck.config.test.javaconfig.configvalue.variable = the perfect value
diff --git a/tck/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource b/tck/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource
index 56e2050a..7acae1d6 100644
--- a/tck/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource
+++ b/tck/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource
@@ -15,4 +15,4 @@
# under the License.
#
-org.eclipse.microprofile.config.tck.configsources.CustomDbConfigSource
\ No newline at end of file
+org.eclipse.microprofile.config.tck.configsources.CustomDbConfigSource
diff --git a/tck/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSourceProvider b/tck/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSourceProvider
deleted file mode 100644
index 6938d921..00000000
--- a/tck/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSourceProvider
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (c) 2016-2017 Mark Struberg and others
-#
-# Licensed 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.eclipse.microprofile.config.tck.configsources.CustomConfigSourceProvider
\ No newline at end of file