Repository: helidon-io/helidon
Issue: Config: Refactor usage of exceptions in optional sources

When we start Helidon SE and have logging set to "FINE", config logs a number of exceptions that should not be thrown, related to optional config sources.
When a config source is optional, there should be no exception thrown, instead we should gracefully ignore it.

Reasons:

1. Log is polluted with useless information
2. Debugging using Exception breakpoints is more complicated, as it stops on "false" positives
 
## Environment Details
* Helidon Version: 1.0.0
* Helidon SE

----------

Log output:
```
Mar 06, 2019 7:22:19 PM io.helidon.config.spi.AbstractSource loadDataChangedSinceLastLoad
FINE: Source ClasspathConfig[meta-config.yaml]? has changed to Optional[1970-01-01T00:00:00Z] from Optional.empty.
Mar 06, 2019 7:22:19 PM io.helidon.config.internal.ClasspathConfigSource content
FINE: Error to get ClasspathConfig[meta-config.yaml]? using java.lang.ClassLoader@1043d64e8 CONTEXT ClassLoader.
Mar 06, 2019 7:22:19 PM io.helidon.config.spi.AbstractSource processMissingData
CONFIG: Cannot load data from optional source ClasspathConfig[meta-config.yaml]?. Will not be used to load from. ClasspathConfig[meta-config.yaml]? does not exist. Used ClassLoader: java.lang.ClassLoader@1043d64e8
Mar 06, 2019 7:22:19 PM io.helidon.config.spi.AbstractSource processMissingData
FINE: Load of 'ClasspathConfig[meta-config.yaml]?' source failed with an exception.
io.helidon.config.ConfigException: ClasspathConfig[meta-config.yaml]? does not exist. Used ClassLoader: java.lang.ClassLoader@1043d64e8
        at io.helidon.config.internal.ClasspathConfigSource.content(ClasspathConfigSource.java:115)
        at io.helidon.config.spi.AbstractParsableConfigSource.loadData(AbstractParsableConfigSource.java:58)
        at io.helidon.config.RetryPolicies$JustCallRetryPolicyHolder$1.execute(RetryPolicies.java:77)
        at io.helidon.config.spi.AbstractSource.loadDataChangedSinceLastLoad(AbstractSource.java:197)
        at io.helidon.config.spi.AbstractSource.load(AbstractSource.java:177)
        at io.helidon.config.UseFirstAvailableConfigSource.load(UseFirstAvailableConfigSource.java:58)
        at io.helidon.config.ProviderImpl.newConfig(ProviderImpl.java:103)
        at io.helidon.config.BuilderImpl.build(BuilderImpl.java:245)
        at io.helidon.config.ConfigSources.load(ConfigSources.java:345)
        at io.helidon.config.BuilderImpl.defaultConfigSource(BuilderImpl.java:348)
        at io.helidon.config.BuilderImpl.targetConfigSource(BuilderImpl.java:309)
        at io.helidon.config.BuilderImpl.buildProvider(BuilderImpl.java:278)
        at io.helidon.config.BuilderImpl.build(BuilderImpl.java:245)
        at io.helidon.config.Config.create(Config.java:358)
        at io.helidon.examples.graalvm.GraalVMNativeImageMain.main(GraalVMNativeImageMain.java:76)

Mar 06, 2019 7:22:19 PM io.helidon.config.spi.AbstractSource loadDataChangedSinceLastLoad
FINE: Source ClasspathConfig[meta-config.conf]? has changed to Optional[1970-01-01T00:00:00Z] from Optional.empty.
Mar 06, 2019 7:22:19 PM io.helidon.config.internal.ClasspathConfigSource content
FINE: Error to get ClasspathConfig[meta-config.conf]? using java.lang.ClassLoader@1043d64e8 CONTEXT ClassLoader.
Mar 06, 2019 7:22:19 PM io.helidon.config.spi.AbstractSource processMissingData
CONFIG: Cannot load data from optional source ClasspathConfig[meta-config.conf]?. Will not be used to load from. ClasspathConfig[meta-config.conf]? does not exist. Used ClassLoader: java.lang.ClassLoader@1043d64e8
Mar 06, 2019 7:22:19 PM io.helidon.config.spi.AbstractSource processMissingData
FINE: Load of 'ClasspathConfig[meta-config.conf]?' source failed with an exception.
io.helidon.config.ConfigException: ClasspathConfig[meta-config.conf]? does not exist. Used ClassLoader: java.lang.ClassLoader@1043d64e8
        at io.helidon.config.internal.ClasspathConfigSource.content(ClasspathConfigSource.java:115)
        at io.helidon.config.spi.AbstractParsableConfigSource.loadData(AbstractParsableConfigSource.java:58)
        at io.helidon.config.RetryPolicies$JustCallRetryPolicyHolder$1.execute(RetryPolicies.java:77)
        at io.helidon.config.spi.AbstractSource.loadDataChangedSinceLastLoad(AbstractSource.java:197)
        at io.helidon.config.spi.AbstractSource.load(AbstractSource.java:177)
        at io.helidon.config.UseFirstAvailableConfigSource.load(UseFirstAvailableConfigSource.java:58)
        at io.helidon.config.ProviderImpl.newConfig(ProviderImpl.java:103)
        at io.helidon.config.BuilderImpl.build(BuilderImpl.java:245)
        at io.helidon.config.ConfigSources.load(ConfigSources.java:345)
        at io.helidon.config.BuilderImpl.defaultConfigSource(BuilderImpl.java:348)
        at io.helidon.config.BuilderImpl.targetConfigSource(BuilderImpl.java:309)
        at io.helidon.config.BuilderImpl.buildProvider(BuilderImpl.java:278)
        at io.helidon.config.BuilderImpl.build(BuilderImpl.java:245)
        at io.helidon.config.Config.create(Config.java:358)
        at io.helidon.examples.graalvm.GraalVMNativeImageMain.main(GraalVMNativeImageMain.java:76)

Mar 06, 2019 7:22:19 PM io.helidon.config.spi.AbstractSource loadDataChangedSinceLastLoad
FINE: Source ClasspathConfig[meta-config.json]? has changed to Optional[1970-01-01T00:00:00Z] from Optional.empty.
Mar 06, 2019 7:22:19 PM io.helidon.config.internal.ClasspathConfigSource content
FINE: Error to get ClasspathConfig[meta-config.json]? using java.lang.ClassLoader@1043d64e8 CONTEXT ClassLoader.
Mar 06, 2019 7:22:19 PM io.helidon.config.spi.AbstractSource processMissingData
CONFIG: Cannot load data from optional source ClasspathConfig[meta-config.json]?. Will not be used to load from. ClasspathConfig[meta-config.json]? does not exist. Used ClassLoader: java.lang.ClassLoader@1043d64e8
Mar 06, 2019 7:22:19 PM io.helidon.config.spi.AbstractSource processMissingData
FINE: Load of 'ClasspathConfig[meta-config.json]?' source failed with an exception.
io.helidon.config.ConfigException: ClasspathConfig[meta-config.json]? does not exist. Used ClassLoader: java.lang.ClassLoader@1043d64e8
        at io.helidon.config.internal.ClasspathConfigSource.content(ClasspathConfigSource.java:115)
        at io.helidon.config.spi.AbstractParsableConfigSource.loadData(AbstractParsableConfigSource.java:58)
        at io.helidon.config.RetryPolicies$JustCallRetryPolicyHolder$1.execute(RetryPolicies.java:77)
        at io.helidon.config.spi.AbstractSource.loadDataChangedSinceLastLoad(AbstractSource.java:197)
        at io.helidon.config.spi.AbstractSource.load(AbstractSource.java:177)
        at io.helidon.config.UseFirstAvailableConfigSource.load(UseFirstAvailableConfigSource.java:58)
        at io.helidon.config.ProviderImpl.newConfig(ProviderImpl.java:103)
        at io.helidon.config.BuilderImpl.build(BuilderImpl.java:245)
        at io.helidon.config.ConfigSources.load(ConfigSources.java:345)
        at io.helidon.config.BuilderImpl.defaultConfigSource(BuilderImpl.java:348)
        at io.helidon.config.BuilderImpl.targetConfigSource(BuilderImpl.java:309)
        at io.helidon.config.BuilderImpl.buildProvider(BuilderImpl.java:278)
        at io.helidon.config.BuilderImpl.build(BuilderImpl.java:245)
        at io.helidon.config.Config.create(Config.java:358)
        at io.helidon.examples.graalvm.GraalVMNativeImageMain.main(GraalVMNativeImageMain.java:76)

Mar 06, 2019 7:22:19 PM io.helidon.config.spi.AbstractSource loadDataChangedSinceLastLoad
FINE: Source ClasspathConfig[meta-config.properties]? has changed to Optional[1970-01-01T00:00:00Z] from Optional.empty.
Mar 06, 2019 7:22:19 PM io.helidon.config.internal.ClasspathConfigSource content
FINE: Error to get ClasspathConfig[meta-config.properties]? using java.lang.ClassLoader@1043d64e8 CONTEXT ClassLoader.
Mar 06, 2019 7:22:19 PM io.helidon.config.spi.AbstractSource processMissingData
CONFIG: Cannot load data from optional source ClasspathConfig[meta-config.properties]?. Will not be used to load from. ClasspathConfig[meta-config.properties]? does not exist. Used ClassLoader: java.lang.ClassLoader@1043d64e8
Mar 06, 2019 7:22:19 PM io.helidon.config.spi.AbstractSource processMissingData
FINE: Load of 'ClasspathConfig[meta-config.properties]?' source failed with an exception.
io.helidon.config.ConfigException: ClasspathConfig[meta-config.properties]? does not exist. Used ClassLoader: java.lang.ClassLoader@1043d64e8
        at io.helidon.config.internal.ClasspathConfigSource.content(ClasspathConfigSource.java:115)
        at io.helidon.config.spi.AbstractParsableConfigSource.loadData(AbstractParsableConfigSource.java:58)
        at io.helidon.config.RetryPolicies$JustCallRetryPolicyHolder$1.execute(RetryPolicies.java:77)
        at io.helidon.config.spi.AbstractSource.loadDataChangedSinceLastLoad(AbstractSource.java:197)
        at io.helidon.config.spi.AbstractSource.load(AbstractSource.java:177)
        at io.helidon.config.UseFirstAvailableConfigSource.load(UseFirstAvailableConfigSource.java:58)
        at io.helidon.config.ProviderImpl.newConfig(ProviderImpl.java:103)
        at io.helidon.config.BuilderImpl.build(BuilderImpl.java:245)
        at io.helidon.config.ConfigSources.load(ConfigSources.java:345)
        at io.helidon.config.BuilderImpl.defaultConfigSource(BuilderImpl.java:348)
        at io.helidon.config.BuilderImpl.targetConfigSource(BuilderImpl.java:309)
        at io.helidon.config.BuilderImpl.buildProvider(BuilderImpl.java:278)
        at io.helidon.config.BuilderImpl.build(BuilderImpl.java:245)
        at io.helidon.config.Config.create(Config.java:358)
        at io.helidon.examples.graalvm.GraalVMNativeImageMain.main(GraalVMNativeImageMain.java:76)

```

Changed files:
config/config/src/main/java/io/helidon/config/BuilderImpl.java

diff --git a/config/config/src/main/java/io/helidon/config/BuilderImpl.java b/config/config/src/main/java/io/helidon/config/BuilderImpl.java
index 33e7761d4d..a2f8b7762f 100644
--- a/config/config/src/main/java/io/helidon/config/BuilderImpl.java
+++ b/config/config/src/main/java/io/helidon/config/BuilderImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
 package io.helidon.config;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -54,6 +55,7 @@ import static io.helidon.config.ConfigSources.classpath;
 class BuilderImpl implements Config.Builder {
 
     static final Executor DEFAULT_CHANGES_EXECUTOR = Executors.newCachedThreadPool(new ConfigThreadFactory("config"));
+    private static final List<String> DEFAULT_FILE_EXTENSIONS = Arrays.asList("yaml", "conf", "json", "properties");
 
     private List<ConfigSource> sources;
     private final MapperProviders mapperProviders;
@@ -342,21 +344,36 @@ class BuilderImpl implements Config.Builder {
     // utils
     //
 
-    static ConfigSource defaultConfigSource() {
-        return ConfigSources.create(
-                new UseFirstAvailableConfigSource(
-                        ConfigSources.load(
-                                new UseFirstAvailableConfigSource(
-                                        classpath("meta-config.yaml").optional().build(),
-                                        classpath("meta-config.conf").optional().build(),
-                                        classpath("meta-config.json").optional().build(),
-                                        classpath("meta-config.properties").optional().build()
-                                )).build(),
-                        classpath("application.yaml").optional().build(),
-                        classpath("application.conf").optional().build(),
-                        classpath("application.json").optional().build(),
-                        classpath("application.properties").optional().build()
-                )).build();
+    private static ConfigSource defaultConfigSource() {
+        final List<ConfigSource> sources = new ArrayList<>();
+        final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+        final List<ConfigSource> meta = defaultConfigSources(classLoader, "meta-config");
+        if (!meta.isEmpty()) {
+            sources.add(ConfigSources.load(toDefaultConfigSource(meta)).build());
+        }
+        sources.addAll(defaultConfigSources(classLoader, "application"));
+        return ConfigSources.create(toDefaultConfigSource(sources)).build();
+    }
+
+    private static List<ConfigSource> defaultConfigSources(final ClassLoader classLoader, final String baseResourceName) {
+        final List<ConfigSource> sources = new ArrayList<>();
+        for (final String extension : DEFAULT_FILE_EXTENSIONS) {
+            final String resource = baseResourceName + "." + extension;
+            if (classLoader.getResource(resource) != null) {
+                sources.add(classpath(resource).optional().build());
+            }
+        }
+        return sources;
+    }
+
+    private static ConfigSource toDefaultConfigSource(final List<ConfigSource> sources) {
+        if (sources.isEmpty()) {
+            return ConfigSources.empty();
+        } else if (sources.size() == 1) {
+            return sources.get(0);
+        } else {
+            return new UseFirstAvailableConfigSource(sources);
+        }
     }
 
     static List<ConfigParser> buildParsers(boolean servicesEnabled, List<ConfigParser> userDefinedParsers) {