From 88f798c506af371a6827e3ddd184cfe4f83f46ac Mon Sep 17 00:00:00 2001 From: Tomas Langer Date: Mon, 3 Feb 2020 16:43:22 +0100 Subject: [PATCH] Removed null params and return types from Config API. --- .../helidon/config/ClasspathConfigSource.java | 21 ++-- .../config/ClasspathOverrideSource.java | 4 +- .../helidon/config/ClasspathSourceHelper.java | 7 +- .../java/io/helidon/config/ConfigSources.java | 9 +- .../io/helidon/config/FileConfigSource.java | 20 ++-- .../io/helidon/config/UrlConfigSource.java | 53 +++++---- .../config/spi/AbstractConfigSource.java | 7 +- .../spi/AbstractParsableConfigSource.java | 32 ++--- .../io/helidon/config/spi/ConfigParser.java | 112 ++++++++++++++---- .../config/BuilderImplParsersTest.java | 15 +-- .../config/ClasspathConfigSourceTest.java | 12 +- .../config/CompositeConfigSourceTest.java | 14 +-- .../helidon/config/FileConfigSourceTest.java | 12 +- .../config/UrlConfigSourceServerMockTest.java | 11 +- .../helidon/config/UrlConfigSourceTest.java | 18 +-- .../internal/PropertiesConfigParserTest.java | 7 +- .../spi/AbstractParsableConfigSourceTest.java | 80 ++++++------- .../helidon/config/etcd/EtcdConfigSource.java | 18 ++- config/etcd/src/main/java/module-info.java | 2 +- .../config/etcd/EtcdConfigSourceTest.java | 6 +- .../helidon/config/git/GitConfigSource.java | 27 +++-- .../config/hocon/HoconConfigParserTest.java | 7 +- .../config/yaml/YamlConfigParserTest.java | 7 +- 23 files changed, 293 insertions(+), 208 deletions(-) diff --git a/config/config/src/main/java/io/helidon/config/ClasspathConfigSource.java b/config/config/src/main/java/io/helidon/config/ClasspathConfigSource.java index 7b98bf41b..8241536bd 100644 --- a/config/config/src/main/java/io/helidon/config/ClasspathConfigSource.java +++ b/config/config/src/main/java/io/helidon/config/ClasspathConfigSource.java @@ -83,10 +83,9 @@ public class ClasspathConfigSource extends AbstractParsableConfigSource } @Override - protected String mediaType() { - return Optional.ofNullable(super.mediaType()) - .or(this::probeContentType) - .orElse(null); + protected Optional mediaType() { + return super.mediaType() + .or(this::probeContentType); } private Optional probeContentType() { @@ -95,16 +94,22 @@ public class ClasspathConfigSource extends AbstractParsableConfigSource @Override protected Optional dataStamp() { - return Optional.ofNullable(ClasspathSourceHelper.resourceTimestamp(resource)); + return Optional.of(ClasspathSourceHelper.resourceTimestamp(resource)); } @Override protected ConfigParser.Content content() throws ConfigException { return ClasspathSourceHelper.content(resource, description(), - (inputStreamReader, instant) -> ConfigParser.Content.create(inputStreamReader, - mediaType(), - instant)); + (inputStreamReader, instant) -> { + ConfigParser.Content.Builder builder = ConfigParser.Content + .builder(inputStreamReader); + + builder.stamp(instant); + mediaType().ifPresent(builder::mediaType); + + return builder.build(); + }); } @Override diff --git a/config/config/src/main/java/io/helidon/config/ClasspathOverrideSource.java b/config/config/src/main/java/io/helidon/config/ClasspathOverrideSource.java index 4df790f70..d4068201d 100644 --- a/config/config/src/main/java/io/helidon/config/ClasspathOverrideSource.java +++ b/config/config/src/main/java/io/helidon/config/ClasspathOverrideSource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,7 +58,7 @@ public class ClasspathOverrideSource extends AbstractOverrideSource { (inputStreamReader, instant) -> { return new Data<>( Optional.of(OverrideData.create(inputStreamReader)), - instant); + Optional.of(instant)); }); } diff --git a/config/config/src/main/java/io/helidon/config/ClasspathSourceHelper.java b/config/config/src/main/java/io/helidon/config/ClasspathSourceHelper.java index a89745f1b..5c3235dae 100644 --- a/config/config/src/main/java/io/helidon/config/ClasspathSourceHelper.java +++ b/config/config/src/main/java/io/helidon/config/ClasspathSourceHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.time.Instant; -import java.util.Optional; import java.util.function.BiFunction; import java.util.logging.Level; import java.util.logging.Logger; @@ -92,7 +91,7 @@ class ClasspathSourceHelper { static T content(String resource, String description, - BiFunction, T> processor) throws ConfigException { + BiFunction processor) throws ConfigException { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); InputStream inputStream = classLoader.getResourceAsStream(resource); @@ -102,7 +101,7 @@ class ClasspathSourceHelper { String.format("Error to get %s using %s CONTEXT ClassLoader.", description, classLoader)); throw new ConfigException(description + " does not exist. Used ClassLoader: " + classLoader); } - Optional resourceTimestamp = Optional.ofNullable(resourceTimestamp(resource)); + Instant resourceTimestamp = resourceTimestamp(resource); try { LOGGER.log(Level.FINE, String.format("Getting content from '%s'. Last modified at %s. Used ClassLoader: %s", diff --git a/config/config/src/main/java/io/helidon/config/ConfigSources.java b/config/config/src/main/java/io/helidon/config/ConfigSources.java index abba7725f..25bda122c 100644 --- a/config/config/src/main/java/io/helidon/config/ConfigSources.java +++ b/config/config/src/main/java/io/helidon/config/ConfigSources.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -120,14 +120,15 @@ public final class ConfigSources { * * @param readable a {@code Readable} providing the configuration content * @param mediaType a configuration media type + * @param dual type to mark parameter both readable and auto closeable * @return a config source */ - public static ConfigSource create(Readable readable, String mediaType) { + public static ConfigSource create(T readable, String mediaType) { return InMemoryConfigSource.builder() .mediaType(mediaType) .changesExecutor(Runnable::run) .changesMaxBuffer(1) - .content("Readable", ConfigParser.Content.create(readable, mediaType, Optional.of(Instant.now()))) + .content("Readable", ConfigParser.Content.create(readable, mediaType, Instant.now())) .build(); } @@ -146,7 +147,7 @@ public final class ConfigSources { .mediaType(mediaType) .changesExecutor(Runnable::run) .changesMaxBuffer(1) - .content("String", ConfigParser.Content.create(new StringReader(content), mediaType, Optional.of(Instant.now()))) + .content("String", ConfigParser.Content.create(new StringReader(content), mediaType, Instant.now())) .build(); } diff --git a/config/config/src/main/java/io/helidon/config/FileConfigSource.java b/config/config/src/main/java/io/helidon/config/FileConfigSource.java index 03bc78d13..3fd87ad05 100644 --- a/config/config/src/main/java/io/helidon/config/FileConfigSource.java +++ b/config/config/src/main/java/io/helidon/config/FileConfigSource.java @@ -19,7 +19,6 @@ package io.helidon.config; import java.io.StringReader; import java.nio.file.Path; import java.util.Optional; -import java.util.logging.Level; import java.util.logging.Logger; import io.helidon.common.media.type.MediaTypes; @@ -91,10 +90,9 @@ public class FileConfigSource extends AbstractParsableConfigSource { } @Override - protected String mediaType() { - return Optional.ofNullable(super.mediaType()) - .or(this::probeContentType) - .orElse(null); + protected Optional mediaType() { + return super.mediaType() + .or(this::probeContentType); } private Optional probeContentType() { @@ -108,12 +106,14 @@ public class FileConfigSource extends AbstractParsableConfigSource { @Override protected Content content() throws ConfigException { - Optional stamp = dataStamp(); - LOGGER.log(Level.FINE, String.format("Getting content from '%s'", filePath)); + LOGGER.fine(() -> String.format("Getting content from '%s'", filePath)); - return Content.create(new StringReader(FileSourceHelper.safeReadContent(filePath)), - mediaType(), - stamp); + Content.Builder builder = Content.builder(new StringReader(FileSourceHelper.safeReadContent(filePath))); + + dataStamp().ifPresent(builder::stamp); + mediaType().ifPresent(builder::mediaType); + + return builder.build(); } /** diff --git a/config/config/src/main/java/io/helidon/config/UrlConfigSource.java b/config/config/src/main/java/io/helidon/config/UrlConfigSource.java index eb00f638c..391d890c0 100644 --- a/config/config/src/main/java/io/helidon/config/UrlConfigSource.java +++ b/config/config/src/main/java/io/helidon/config/UrlConfigSource.java @@ -114,22 +114,27 @@ public class UrlConfigSource extends AbstractParsableConfigSource { } private ConfigParser.Content genericContent(URLConnection urlConnection) throws IOException, URISyntaxException { - final String mediaType = mediaType(null); Reader reader = new InputStreamReader(urlConnection.getInputStream(), StandardCharsets.UTF_8); - return ConfigParser.Content.create(reader, mediaType, Optional.of(Instant.now())); + ConfigParser.Content.Builder builder = ConfigParser.Content.builder(reader); + builder.stamp(Instant.now()); + mediaType() + .or(this::probeContentType) + .ifPresent(builder::mediaType); + + return builder.build(); } private ConfigParser.Content httpContent(HttpURLConnection connection) throws IOException, URISyntaxException { connection.setRequestMethod(GET_METHOD); - final String mediaType = mediaType(connection.getContentType()); - final Optional timestamp; + Optional mediaType = mediaType(connection.getContentType()); + final Instant timestamp; if (connection.getLastModified() != 0) { - timestamp = Optional.of(Instant.ofEpochMilli(connection.getLastModified())); + timestamp = Instant.ofEpochMilli(connection.getLastModified()); } else { - timestamp = Optional.of(Instant.now()); + timestamp = Instant.now(); LOGGER.fine("Missing GET '" + url + "' response header 'Last-Modified'. Used current time '" + timestamp + "' as a content timestamp."); } @@ -137,31 +142,33 @@ public class UrlConfigSource extends AbstractParsableConfigSource { Reader reader = new InputStreamReader(connection.getInputStream(), ConfigUtils.getContentCharset(connection.getContentEncoding())); - return ConfigParser.Content.create(reader, mediaType, timestamp); + ConfigParser.Content.Builder builder = ConfigParser.Content.builder(reader); + + builder.stamp(timestamp); + mediaType.ifPresent(builder::mediaType); + + return builder.build(); } @Override - protected String mediaType() { - //do not call ConfigHelper.guessMediaType here - it is done in content() method + protected Optional mediaType() { return super.mediaType(); } - private String mediaType(String responseMediaType) throws URISyntaxException { - String mediaType = mediaType(); - if (mediaType == null) { - mediaType = responseMediaType; - if (mediaType == null) { - mediaType = probeContentType(); - if (LOGGER.isLoggable(Level.FINE)) { - LOGGER.fine("HTTP response does not contain content-type, used guessed one: " + mediaType + "."); - } - } - } - return mediaType; + private Optional mediaType(String responseMediaType) throws URISyntaxException { + return mediaType() + .or(() -> Optional.ofNullable(responseMediaType)) + .or(() -> { + Optional mediaType = probeContentType(); + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("HTTP response does not contain content-type, used guessed one: " + mediaType + "."); + } + return mediaType; + }); } - private String probeContentType() { - return MediaTypes.detectType(url).orElse(null); + private Optional probeContentType() { + return MediaTypes.detectType(url); } @Override diff --git a/config/config/src/main/java/io/helidon/config/spi/AbstractConfigSource.java b/config/config/src/main/java/io/helidon/config/spi/AbstractConfigSource.java index 8fcfd89eb..b60260360 100644 --- a/config/config/src/main/java/io/helidon/config/spi/AbstractConfigSource.java +++ b/config/config/src/main/java/io/helidon/config/spi/AbstractConfigSource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -121,8 +121,9 @@ public abstract class AbstractConfigSource extends AbstractMpSource implem private ConfigNode processValue(Optional datastamp, Config.Key key, ValueNode valueNode) { AtomicReference result = new AtomicReference<>(valueNode); findParserForKey(key) - .ifPresent(parser -> result.set(parser.parse( - Content.create(new StringReader(valueNode.get()), null, datastamp)))); + .ifPresent(parser -> result.set(parser.parse(Content.builder(new StringReader(valueNode.get())) + .stamp(datastamp) + .build()))); return result.get(); } diff --git a/config/config/src/main/java/io/helidon/config/spi/AbstractParsableConfigSource.java b/config/config/src/main/java/io/helidon/config/spi/AbstractParsableConfigSource.java index b29e7a85b..0302d9807 100644 --- a/config/config/src/main/java/io/helidon/config/spi/AbstractParsableConfigSource.java +++ b/config/config/src/main/java/io/helidon/config/spi/AbstractParsableConfigSource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,17 +37,18 @@ import io.helidon.config.spi.ConfigNode.ObjectNode; */ public abstract class AbstractParsableConfigSource extends AbstractConfigSource { - private final String mediaType; - private final ConfigParser parser; + private final Optional mediaType; + private final Optional parser; /** * Initializes config source from builder. * * @param builder builder to be initialized from */ - protected AbstractParsableConfigSource(AbstractParsableConfigSource.Builder builder) { + protected AbstractParsableConfigSource(AbstractParsableConfigSource.Builder builder) { super(builder); + // using Optional as field types, as we already get them as optional mediaType = builder.mediaType(); parser = builder.parser(); } @@ -64,16 +65,16 @@ public abstract class AbstractParsableConfigSource extends AbstractConfigSour * * @return source associated media type or {@code null} if unknown. */ - protected String mediaType() { + protected Optional mediaType() { return mediaType; } /** - * Returns source associated parser or {@code null} if unknown. + * Returns source associated parser or {@code empty} if unknown. * - * @return source associated parser or {@code null} if unknown. + * @return source associated parser or {@code empty} if unknown. */ - protected ConfigParser parser() { + protected Optional parser() { return parser; } @@ -94,12 +95,12 @@ public abstract class AbstractParsableConfigSource extends AbstractConfigSour * @throws ConfigParserException in case of problem to parse configuration from the source */ private ObjectNode parse(ConfigContext context, ConfigParser.Content content) throws ConfigParserException { - return Optional.ofNullable(parser()) - .or(() -> context.findParser(Optional.ofNullable(content.mediaType()) + return parser() + .or(() -> context.findParser(content.mediaType() .orElseThrow(() -> new ConfigException("Unknown media type.")))) .map(parser -> parser.parse(content)) .orElseThrow(() -> new ConfigException("Cannot find suitable parser for '" - + content.mediaType() + "' media type.")); + + content.mediaType().orElse(null) + "' media type.")); } /** @@ -192,8 +193,8 @@ public abstract class AbstractParsableConfigSource extends AbstractConfigSour * * @return media type property. */ - protected String mediaType() { - return mediaType; + protected Optional mediaType() { + return Optional.ofNullable(mediaType); } /** @@ -201,10 +202,9 @@ public abstract class AbstractParsableConfigSource extends AbstractConfigSour * * @return parser property. */ - protected ConfigParser parser() { - return parser; + protected Optional parser() { + return Optional.ofNullable(parser); } } - } diff --git a/config/config/src/main/java/io/helidon/config/spi/ConfigParser.java b/config/config/src/main/java/io/helidon/config/spi/ConfigParser.java index fda1a158b..1e2723625 100644 --- a/config/config/src/main/java/io/helidon/config/spi/ConfigParser.java +++ b/config/config/src/main/java/io/helidon/config/spi/ConfigParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package io.helidon.config.spi; import java.nio.file.Path; import java.time.Instant; +import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -102,9 +103,9 @@ public interface ConfigParser { /** * Returns configuration content media type. * - * @return content media type + * @return content media type if known, {@code empty} otherwise */ - String mediaType(); + Optional mediaType(); /** * Returns a {@link Readable} that is use to read configuration content from. @@ -114,48 +115,109 @@ public interface ConfigParser { */ T asReadable(); + /** + * Create a fluent API builder for content. + * + * @param readable readable to base this content builder on + * @param type of the stamp to use + * @param dual type of readable and autocloseable parameter + * @return a new fluent API builder for content + */ + static Builder builder(T readable) { + Objects.requireNonNull(readable, "Readable must not be null when creating content"); + return new Builder<>(readable); + } + /** * Creates {@link Content} from given {@link Readable readable content} and * with specified {@code mediaType} of configuration format. * * @param readable a readable providing configuration. - * If it implements {@link AutoCloseable} it is automatically closed whenever parsed. * @param mediaType a configuration mediaType * @param stamp content stamp * @param a type of data stamp + * @param dual type of readable and autocloseable parameter * @return a config content */ - static Content create(Readable readable, String mediaType, Optional stamp) { - return new Content() { - @Override - public void close() throws ConfigException { - if (readable instanceof AutoCloseable) { + static Content create(T readable, String mediaType, S stamp) { + Objects.requireNonNull(mediaType, "Media type must not be null when creating content using Content.create()"); + Objects.requireNonNull(stamp, "Stamp must not be null when creating content using Content.create()"); + + Builder builder = builder(readable); + + return builder + .mediaType(mediaType) + .stamp(stamp) + .build(); + } + + /** + * Fluent API builder for {@link io.helidon.config.spi.ConfigParser.Content}. + * + * @param type of the stamp of the built content + */ + class Builder implements io.helidon.common.Builder> { + private final AutoCloseable readable; + private String mediaType; + private S stamp; + + private Builder(T readable) { + this.readable = readable; + } + + @Override + public Content build() { + final Optional mediaType = Optional.ofNullable(this.mediaType); + final Optional stamp = Optional.ofNullable(this.stamp); + + return new Content<>() { + @Override + public Optional mediaType() { + return mediaType; + } + + @SuppressWarnings("unchecked") + @Override + public T asReadable() { + return (T) readable; + } + + @Override + public void close() throws ConfigException { try { - ((AutoCloseable) readable).close(); + readable.close(); } catch (ConfigException ex) { throw ex; } catch (Exception ex) { throw new ConfigException("Error while closing readable [" + readable + "].", ex); } } - } - @Override - public T asReadable() { - return (T) readable; - } + @Override + public Optional stamp() { + return stamp; + } + }; + } - @Override - public String mediaType() { - return mediaType; - } - - @Override - public Optional stamp() { - return stamp; - } - }; + /** + * Content media type. + * @param mediaType type of the content + */ + public Builder mediaType(String mediaType) { + this.mediaType = mediaType; + return this; + } + /** + * Content stamp. + * + * @param stamp stamp of the content + */ + public Builder stamp(S stamp) { + this.stamp = stamp; + return this; + } } } } diff --git a/config/config/src/test/java/io/helidon/config/BuilderImplParsersTest.java b/config/config/src/test/java/io/helidon/config/BuilderImplParsersTest.java index 8b717575b..2ab215c77 100644 --- a/config/config/src/test/java/io/helidon/config/BuilderImplParsersTest.java +++ b/config/config/src/test/java/io/helidon/config/BuilderImplParsersTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package io.helidon.config; +import java.time.Instant; import java.util.List; import java.util.Optional; import java.util.Set; @@ -74,8 +75,8 @@ public class BuilderImplParsersTest { @Test public void testContextFindParserNotAvailable() { - ConfigParser.Content content = mock(ConfigParser.Content.class); - when(content.mediaType()).thenReturn(TEST_MEDIA_TYPE); + ConfigParser.Content content = mock(ConfigParser.Content.class); + when(content.mediaType()).thenReturn(Optional.of(TEST_MEDIA_TYPE)); BuilderImpl.ConfigContextImpl context = new BuilderImpl.ConfigContextImpl(List.of( mockParser("application/hocon", "application/json"), @@ -83,13 +84,13 @@ public class BuilderImplParsersTest { mockParser("application/x-yaml") )); - assertThat(context.findParser(content.mediaType()), is(Optional.empty())); + assertThat(context.findParser(content.mediaType().get()), is(Optional.empty())); } @Test public void testContextFindParserFindFirst() { - ConfigParser.Content content = mock(ConfigParser.Content.class); - when(content.mediaType()).thenReturn(TEST_MEDIA_TYPE); + ConfigParser.Content content = mock(ConfigParser.Content.class); + when(content.mediaType()).thenReturn(Optional.of(TEST_MEDIA_TYPE)); ConfigParser firstParser = mockParser(TEST_MEDIA_TYPE); @@ -100,7 +101,7 @@ public class BuilderImplParsersTest { mockParser("application/x-yaml") )); - assertThat(context.findParser(content.mediaType()).get(), is(firstParser)); + assertThat(context.findParser(content.mediaType().get()).get(), is(firstParser)); } private ConfigParser mockParser(String... supportedMediaTypes) { diff --git a/config/config/src/test/java/io/helidon/config/ClasspathConfigSourceTest.java b/config/config/src/test/java/io/helidon/config/ClasspathConfigSourceTest.java index 3db4140d9..bbf66e9fd 100644 --- a/config/config/src/test/java/io/helidon/config/ClasspathConfigSourceTest.java +++ b/config/config/src/test/java/io/helidon/config/ClasspathConfigSourceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +32,6 @@ import io.helidon.config.spi.ConfigParserException; import io.helidon.config.spi.ConfigSource; import io.helidon.config.spi.PollingStrategy; -import org.hamcrest.core.Is; import org.junit.jupiter.api.Test; import static org.hamcrest.CoreMatchers.notNullValue; @@ -40,7 +39,6 @@ import static org.hamcrest.CoreMatchers.startsWith; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.nullValue; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.fail; import static org.mockito.Mockito.mock; @@ -75,7 +73,7 @@ public class ClasspathConfigSourceTest { .changesMaxBuffer(1) .build(); - assertThat(configSource.mediaType(), is(TEST_MEDIA_TYPE)); + assertThat(configSource.mediaType(), is(Optional.of(TEST_MEDIA_TYPE))); } @Test @@ -86,7 +84,7 @@ public class ClasspathConfigSourceTest { .changesMaxBuffer(1) .build(); - assertThat(configSource.mediaType(), Is.is("text/x-java-properties")); + assertThat(configSource.mediaType(), is(Optional.of("text/x-java-properties"))); } @Test @@ -97,7 +95,7 @@ public class ClasspathConfigSourceTest { .changesMaxBuffer(1) .build(); - assertThat(configSource.mediaType(), is(nullValue())); + assertThat(configSource.mediaType(), is(Optional.empty())); } @Test @@ -133,7 +131,7 @@ public class ClasspathConfigSourceTest { @Override public ObjectNode parse(Content content) throws ConfigParserException { assertThat(content, notNullValue()); - assertThat(content.mediaType(), is("application/hocon")); + assertThat(content.mediaType(), is(Optional.of("application/hocon"))); try { assertThat((char) ConfigHelper.createReader(content.asReadable()).read(), is('#')); } catch (IOException e) { diff --git a/config/config/src/test/java/io/helidon/config/CompositeConfigSourceTest.java b/config/config/src/test/java/io/helidon/config/CompositeConfigSourceTest.java index d05313c8b..9dd215a17 100644 --- a/config/config/src/test/java/io/helidon/config/CompositeConfigSourceTest.java +++ b/config/config/src/test/java/io/helidon/config/CompositeConfigSourceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -132,7 +132,7 @@ public class CompositeConfigSourceTest { AtomicReference> contentReferenceAAA = new AtomicReference<>(); contentReferenceAAA.set(ConfigParser.Content.create(new StringReader("ooo=1\nrrr=5"), PropertiesConfigParser.MEDIA_TYPE_TEXT_JAVA_PROPERTIES, - Optional.of(Instant.now()))); + Instant.now())); TestingParsableConfigSource configSourceAAA = TestingParsableConfigSource.builder() .content(contentReferenceAAA::get) .parser(ConfigParsers.properties()) @@ -142,7 +142,7 @@ public class CompositeConfigSourceTest { AtomicReference> contentReferenceBBB = new AtomicReference<>(); contentReferenceBBB.set(ConfigParser.Content.create(new StringReader("ooo=2\nppp=9"), PropertiesConfigParser.MEDIA_TYPE_TEXT_JAVA_PROPERTIES, - Optional.of(Instant.now()))); + Instant.now())); TestingParsableConfigSource configSourceBBB = TestingParsableConfigSource.builder() .content(contentReferenceBBB::get) .parser(ConfigParsers.properties()) @@ -253,7 +253,7 @@ public class CompositeConfigSourceTest { AtomicReference> contentReferenceAAA = new AtomicReference<>(); contentReferenceAAA.set(ConfigParser.Content.create(new StringReader("ooo=1\nrrr=5"), PropertiesConfigParser.MEDIA_TYPE_TEXT_JAVA_PROPERTIES, - Optional.of(Instant.now()))); + Instant.now())); TestingParsableConfigSource configSourceAAA = TestingParsableConfigSource.builder() .content(contentReferenceAAA::get) .parser(ConfigParsers.properties()) @@ -263,7 +263,7 @@ public class CompositeConfigSourceTest { AtomicReference> contentReferenceBBB = new AtomicReference<>(); contentReferenceBBB.set(ConfigParser.Content.create(new StringReader("ooo=2\nppp=9"), PropertiesConfigParser.MEDIA_TYPE_TEXT_JAVA_PROPERTIES, - Optional.of(Instant.now()))); + Instant.now())); TestingParsableConfigSource configSourceBBB = TestingParsableConfigSource.builder() .content(contentReferenceBBB::get) .parser(ConfigParsers.properties()) @@ -295,7 +295,7 @@ public class CompositeConfigSourceTest { TimeUnit.MILLISECONDS.sleep(TEST_DELAY_MS); contentReferenceBBB.set(ConfigParser.Content.create(new StringReader("ooo=22\nppp=9"), PropertiesConfigParser.MEDIA_TYPE_TEXT_JAVA_PROPERTIES, - Optional.of(Instant.now()))); + Instant.now())); // NO ticks event -> NO change yet assertThat(lastObjectNode, is(configSource.lastObjectNode().get())); @@ -465,7 +465,7 @@ public class CompositeConfigSourceTest { .content(ConfigParser.Content .create(new StringReader("ooo=1\nrrr=5"), PropertiesConfigParser.MEDIA_TYPE_TEXT_JAVA_PROPERTIES, - Optional.of(Instant.now()))) + Instant.now())) .parser(ConfigParsers.properties()) .build()) .build(); diff --git a/config/config/src/test/java/io/helidon/config/FileConfigSourceTest.java b/config/config/src/test/java/io/helidon/config/FileConfigSourceTest.java index c5b3f7897..c954a7c7f 100644 --- a/config/config/src/test/java/io/helidon/config/FileConfigSourceTest.java +++ b/config/config/src/test/java/io/helidon/config/FileConfigSourceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,7 +37,6 @@ import io.helidon.config.spi.ConfigSource; import io.helidon.config.spi.PollingStrategy; import io.helidon.config.test.infra.TemporaryFolderExt; -import org.hamcrest.core.Is; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -47,7 +46,6 @@ import static org.hamcrest.CoreMatchers.startsWith; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.core.Is.is; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.fail; @@ -88,7 +86,7 @@ public class FileConfigSourceTest { .changesMaxBuffer(1) .build(); - assertThat(configSource.mediaType(), is(TEST_MEDIA_TYPE)); + assertThat(configSource.mediaType(), is(Optional.of(TEST_MEDIA_TYPE))); } @Test @@ -99,7 +97,7 @@ public class FileConfigSourceTest { .changesMaxBuffer(1) .build(); - assertThat(configSource.mediaType(), Is.is("text/x-java-properties")); + assertThat(configSource.mediaType(), is(Optional.of("text/x-java-properties"))); } @Test @@ -110,7 +108,7 @@ public class FileConfigSourceTest { .changesMaxBuffer(1) .build(); - assertThat(configSource.mediaType(), is(nullValue())); + assertThat(configSource.mediaType(), is(Optional.empty())); } @Test @@ -145,7 +143,7 @@ public class FileConfigSourceTest { @Override public ObjectNode parse(Content content) throws ConfigParserException { assertThat(content, notNullValue()); - assertThat(content.mediaType(), is("application/hocon")); + assertThat(content.mediaType(), is(Optional.of("application/hocon"))); try { assertThat((char) ConfigHelper.createReader(content.asReadable()).read(), is('#')); } catch (IOException e) { diff --git a/config/config/src/test/java/io/helidon/config/UrlConfigSourceServerMockTest.java b/config/config/src/test/java/io/helidon/config/UrlConfigSourceServerMockTest.java index 60221a987..c02809a48 100644 --- a/config/config/src/test/java/io/helidon/config/UrlConfigSourceServerMockTest.java +++ b/config/config/src/test/java/io/helidon/config/UrlConfigSourceServerMockTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,6 @@ import static io.helidon.config.internal.PropertiesConfigParser.MEDIA_TYPE_TEXT_ import static org.glassfish.grizzly.http.Method.HEAD; import static org.glassfish.grizzly.http.util.HttpStatus.OK_200; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.core.Is.is; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -216,7 +215,7 @@ public class UrlConfigSourceServerMockTest { ConfigParser.Content content = configSource.content(); - assertThat(content.mediaType(), is(TEST_MEDIA_TYPE)); + assertThat(content.mediaType(), is(Optional.of(TEST_MEDIA_TYPE))); assertThat(ConfigHelperTest.readerToString(content.asReadable()), is(TEST_CONFIG)); verifyHttp(server).once( @@ -241,7 +240,7 @@ public class UrlConfigSourceServerMockTest { ConfigParser.Content content = configSource.content(); - assertThat(content.mediaType(), is(MEDIA_TYPE_TEXT_JAVA_PROPERTIES)); + assertThat(content.mediaType(), is(Optional.of(MEDIA_TYPE_TEXT_JAVA_PROPERTIES))); assertThat(ConfigHelperTest.readerToString(content.asReadable()), is(TEST_CONFIG)); verifyHttp(server).once( @@ -266,7 +265,7 @@ public class UrlConfigSourceServerMockTest { ConfigParser.Content content = configSource.content(); - assertThat(content.mediaType(), is(TEST_MEDIA_TYPE)); + assertThat(content.mediaType(), is(Optional.of(TEST_MEDIA_TYPE))); assertThat(ConfigHelperTest.readerToString(content.asReadable()), is(TEST_CONFIG)); verifyHttp(server).once( @@ -288,7 +287,7 @@ public class UrlConfigSourceServerMockTest { .url(new URL(String.format("http://127.0.0.1:%d/application.unknown", server.getPort()))) .build(); - assertThat(configSource.content().mediaType(), is(nullValue())); + assertThat(configSource.content().mediaType(), is(Optional.empty())); } } diff --git a/config/config/src/test/java/io/helidon/config/UrlConfigSourceTest.java b/config/config/src/test/java/io/helidon/config/UrlConfigSourceTest.java index d6614f4dc..ea714b198 100644 --- a/config/config/src/test/java/io/helidon/config/UrlConfigSourceTest.java +++ b/config/config/src/test/java/io/helidon/config/UrlConfigSourceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ package io.helidon.config; import java.net.MalformedURLException; import java.net.URL; import java.time.Duration; +import java.util.Optional; import java.util.concurrent.Flow; import io.helidon.config.UrlConfigSource.UrlBuilder; @@ -32,7 +33,6 @@ import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.startsWith; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.core.Is.is; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.mock; @@ -70,7 +70,7 @@ public class UrlConfigSourceTest { .changesMaxBuffer(1) .build(); - assertThat(configSource.mediaType(), is(TEST_MEDIA_TYPE)); + assertThat(configSource.mediaType(), is(Optional.of(TEST_MEDIA_TYPE))); } @Test @@ -82,7 +82,7 @@ public class UrlConfigSourceTest { .changesMaxBuffer(1) .build(); - assertThat(configSource.mediaType(), is(nullValue())); + assertThat(configSource.mediaType(), is(Optional.empty())); } @Test @@ -94,7 +94,7 @@ public class UrlConfigSourceTest { .changesMaxBuffer(1) .build(); - assertThat(configSource.mediaType(), is(nullValue())); + assertThat(configSource.mediaType(), is(Optional.empty())); } @Test @@ -106,8 +106,8 @@ public class UrlConfigSourceTest { .build(); ConfigException ex = assertThrows(ConfigException.class, () -> { - configSource.init(mock(ConfigContext.class)); - configSource.load(); + configSource.init(mock(ConfigContext.class)); + configSource.load(); }); assertThat(ex.getCause(), instanceOf(ConfigException.class)); assertThat(ex.getMessage(), startsWith("Cannot load data from mandatory source")); @@ -127,8 +127,8 @@ public class UrlConfigSourceTest { .build(); ConfigException ex = assertThrows(ConfigException.class, () -> { - configSource.init(mock(ConfigContext.class)); - configSource.load(); + configSource.init(mock(ConfigContext.class)); + configSource.load(); }); assertThat(ex.getCause(), instanceOf(ConfigException.class)); assertThat(ex.getMessage(), startsWith("Cannot load data from mandatory source")); diff --git a/config/config/src/test/java/io/helidon/config/internal/PropertiesConfigParserTest.java b/config/config/src/test/java/io/helidon/config/internal/PropertiesConfigParserTest.java index 0502f0474..d7d3446f1 100644 --- a/config/config/src/test/java/io/helidon/config/internal/PropertiesConfigParserTest.java +++ b/config/config/src/test/java/io/helidon/config/internal/PropertiesConfigParserTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package io.helidon.config.internal; import java.io.Reader; import java.io.StringReader; +import java.util.Optional; import io.helidon.config.spi.ConfigNode; import io.helidon.config.spi.ConfigParser; @@ -67,8 +68,8 @@ public class PropertiesConfigParserTest { @FunctionalInterface private interface StringContent extends ConfigParser.Content { @Override - default String mediaType() { - return MEDIA_TYPE_TEXT_JAVA_PROPERTIES; + default Optional mediaType() { + return Optional.of(MEDIA_TYPE_TEXT_JAVA_PROPERTIES); } @Override diff --git a/config/config/src/test/java/io/helidon/config/spi/AbstractParsableConfigSourceTest.java b/config/config/src/test/java/io/helidon/config/spi/AbstractParsableConfigSourceTest.java index fb0a16873..700f14bb5 100644 --- a/config/config/src/test/java/io/helidon/config/spi/AbstractParsableConfigSourceTest.java +++ b/config/config/src/test/java/io/helidon/config/spi/AbstractParsableConfigSourceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -68,8 +68,8 @@ public class AbstractParsableConfigSourceTest { TestingParsableConfigSource source = TestingParsableConfigSource.builder().build(); assertThat(source.isMandatory(), is(true)); - assertThat(source.mediaType(), is(nullValue())); - assertThat(source.parser(), is(nullValue())); + assertThat(source.mediaType(), is(Optional.empty())); + assertThat(source.parser(), is(Optional.empty())); } @Test @@ -79,9 +79,9 @@ public class AbstractParsableConfigSourceTest { .build(); assertThat(source.isMandatory(), is(true)); - assertThat(source.mediaType(), is(nullValue())); - assertThat(source.parser(), is(nullValue())); - assertThat(source.content().mediaType(), is(TEST_MEDIA_TYPE)); + assertThat(source.mediaType(), is(Optional.empty())); + assertThat(source.parser(), is(Optional.empty())); + assertThat(source.content().mediaType(), is(Optional.of(TEST_MEDIA_TYPE))); assertThat(readerToString(source.content().asReadable()), is(TEST_CONFIG)); } @@ -91,9 +91,9 @@ public class AbstractParsableConfigSourceTest { .create(new StringReader(TEST_CONFIG), TEST_MEDIA_TYPE); assertThat(source.isMandatory(), is(true)); - assertThat(source.mediaType(), is(TEST_MEDIA_TYPE)); - assertThat(source.parser(), is(nullValue())); - assertThat(source.content().mediaType(), is(TEST_MEDIA_TYPE)); + assertThat(source.mediaType(), is(Optional.of(TEST_MEDIA_TYPE))); + assertThat(source.parser(), is(Optional.empty())); + assertThat(source.content().mediaType(), is(Optional.of(TEST_MEDIA_TYPE))); assertThat(readerToString(source.content().asReadable()), is(TEST_CONFIG)); } @@ -107,16 +107,16 @@ public class AbstractParsableConfigSourceTest { .build(); assertThat(source.isMandatory(), is(false)); - assertThat(source.mediaType(), is(TEST_MEDIA_TYPE)); - assertThat(source.parser(), is(parser)); + assertThat(source.mediaType(), is(Optional.of(TEST_MEDIA_TYPE))); + assertThat(source.parser(), is(Optional.of(parser))); } @Test public void testMandatoryParserSetContentExistsParserRegistered() { - ConfigParser.Content content = mockContent(); + ConfigParser.Content content = mockContent(); ConfigParser registeredParser = mockParser("registered"); ConfigContext context = mock(ConfigContext.class); - when(context.findParser(content.mediaType())).thenReturn(Optional.of(registeredParser)); + when(context.findParser(content.mediaType().get())).thenReturn(Optional.of(registeredParser)); ConfigParser setParser = mockParser("set"); @@ -131,10 +131,10 @@ public class AbstractParsableConfigSourceTest { @Test public void testMandatoryParserSetContentNotExistsParserRegistered() { - ConfigParser.Content content = mockContent(); + ConfigParser.Content content = mockContent(); ConfigParser registeredParser = mockParser("registered"); ConfigContext context = mock(ConfigContext.class); - when(context.findParser(content.mediaType())).thenReturn(Optional.of(registeredParser)); + when(context.findParser(content.mediaType().get())).thenReturn(Optional.of(registeredParser)); ConfigParser setParser = mockParser("set"); @@ -155,10 +155,10 @@ public class AbstractParsableConfigSourceTest { @Test public void testMandatoryParserNotSetContentExistsParserRegistered() { - ConfigParser.Content content = mockContent(); + ConfigParser.Content content = mockContent(); ConfigParser registeredParser = mockParser("registered"); ConfigContext context = mock(ConfigContext.class); - when(context.findParser(content.mediaType())).thenReturn(Optional.of(registeredParser)); + when(context.findParser(content.mediaType().get())).thenReturn(Optional.of(registeredParser)); TestingParsableConfigSource source = TestingParsableConfigSource.builder() .content(content) @@ -170,9 +170,9 @@ public class AbstractParsableConfigSourceTest { @Test public void testMandatoryParserNotSetContentExistsParserNotRegistered() { - ConfigParser.Content content = mockContent(); + ConfigParser.Content content = mockContent(); ConfigContext context = mock(ConfigContext.class); - when(context.findParser(content.mediaType())).thenReturn(Optional.empty()); + when(context.findParser(content.mediaType().get())).thenReturn(Optional.empty()); TestingParsableConfigSource source = TestingParsableConfigSource.builder() .content(content) @@ -192,9 +192,9 @@ public class AbstractParsableConfigSourceTest { @Test public void testOptionalParserNotSetContentExistsParserNotRegistered() { - ConfigParser.Content content = mockContent(); + ConfigParser.Content content = mockContent(); ConfigContext context = mock(ConfigContext.class); - when(context.findParser(content.mediaType())).thenReturn(Optional.empty()); + when(context.findParser(content.mediaType().get())).thenReturn(Optional.empty()); TestingParsableConfigSource source = TestingParsableConfigSource.builder() .content(content) @@ -207,9 +207,9 @@ public class AbstractParsableConfigSourceTest { @Test public void testOptionalParserSetContentNotExistsParserNotRegistered() { - ConfigParser.Content content = mockContent(); + ConfigParser.Content content = mockContent(); ConfigContext context = mock(ConfigContext.class); - when(context.findParser(content.mediaType())).thenReturn(Optional.empty()); + when(context.findParser(content.mediaType().get())).thenReturn(Optional.empty()); ConfigParser setParser = mockParser("set"); @@ -309,7 +309,7 @@ public class AbstractParsableConfigSourceTest { // change content TimeUnit.MILLISECONDS.sleep(TEST_DELAY_MS); // Make sure timestamp changes. - Optional contentTimestamp = Optional.of(Instant.now()); + Instant contentTimestamp = Instant.now(); contentReference.set(ConfigParser.Content.create(new StringReader("aaa=bbb"), PropertiesConfigParser.MEDIA_TYPE_TEXT_JAVA_PROPERTIES, contentTimestamp)); @@ -323,14 +323,14 @@ public class AbstractParsableConfigSourceTest { // objectNode assertThat(configSource.lastData().get().data().get().get("aaa"), valueNode("bbb")); // content timestamp - assertThat(configSource.lastData().get().stamp(), is(contentTimestamp)); + assertThat(configSource.lastData().get().stamp().get(), is(contentTimestamp)); } @Test public void testChangesFromContentToSameContent() throws InterruptedException { AtomicReference> contentReference = new AtomicReference<>(); // set content - Optional contentTimestamp = Optional.of(Instant.now()); + Instant contentTimestamp = Instant.now(); contentReference.set(ConfigParser.Content.create(new StringReader("aaa=bbb"), PropertiesConfigParser.MEDIA_TYPE_TEXT_JAVA_PROPERTIES, contentTimestamp)); @@ -351,7 +351,7 @@ public class AbstractParsableConfigSourceTest { // objectNode assertThat(configSource.lastData().get().data().get().get("aaa"), valueNode("bbb")); // content timestamp - assertThat(configSource.lastData().get().stamp(), is(contentTimestamp)); + assertThat(configSource.lastData().get().stamp().get(), is(contentTimestamp)); // listen on changes TestingConfigSourceChangeSubscriber subscriber = new TestingConfigSourceChangeSubscriber(); @@ -360,7 +360,7 @@ public class AbstractParsableConfigSourceTest { // reset content TimeUnit.MILLISECONDS.sleep(TEST_DELAY_MS); // Make sure timestamp changes. - contentTimestamp = Optional.of(Instant.now()); + contentTimestamp = Instant.now(); contentReference.set(ConfigParser.Content.create(new StringReader("aaa=bbb"), PropertiesConfigParser.MEDIA_TYPE_TEXT_JAVA_PROPERTIES, contentTimestamp)); @@ -374,14 +374,14 @@ public class AbstractParsableConfigSourceTest { // objectNode still null assertThat(configSource.lastData().get().data().get(), is(lastObjectNode)); // timestamp has not changed - assertThat(configSource.lastData().get().stamp(), is(contentTimestamp)); + assertThat(configSource.lastData().get().stamp().get(), is(contentTimestamp)); } @Test public void testChangesFromContentToNoContent() throws InterruptedException { AtomicReference> contentReference = new AtomicReference<>(); // set content - Optional contentTimestamp = Optional.of(Instant.now()); + Instant contentTimestamp = Instant.now(); contentReference.set(ConfigParser.Content.create(new StringReader("aaa=bbb"), PropertiesConfigParser.MEDIA_TYPE_TEXT_JAVA_PROPERTIES, contentTimestamp)); @@ -401,7 +401,7 @@ public class AbstractParsableConfigSourceTest { // objectNode assertThat(configSource.lastData().get().data().get().get("aaa"), valueNode("bbb")); // content timestamp - assertThat(configSource.lastData().get().stamp(), is(contentTimestamp)); + assertThat(configSource.lastData().get().stamp().get(), is(contentTimestamp)); // listen on changes TestingConfigSourceChangeSubscriber subscriber = new TestingConfigSourceChangeSubscriber(); @@ -426,7 +426,7 @@ public class AbstractParsableConfigSourceTest { public void testChangesFromContentToDifferentOne() throws InterruptedException { AtomicReference contentReference = new AtomicReference<>(); // set content - Optional contentTimestamp = Optional.of(Instant.now()); + Instant contentTimestamp = Instant.now(); contentReference.set(ConfigParser.Content.create(new StringReader("aaa=bbb"), PropertiesConfigParser.MEDIA_TYPE_TEXT_JAVA_PROPERTIES, contentTimestamp)); @@ -447,7 +447,7 @@ public class AbstractParsableConfigSourceTest { // objectNode assertThat(configSource.lastData().get().data().get().get("aaa"), valueNode("bbb")); // content timestamp - assertThat(configSource.lastData().get().stamp(), is(contentTimestamp)); + assertThat(configSource.lastData().get().stamp().get(), is(contentTimestamp)); // listen on changes TestingConfigSourceChangeSubscriber subscriber = new TestingConfigSourceChangeSubscriber(); @@ -456,7 +456,7 @@ public class AbstractParsableConfigSourceTest { // reset content TimeUnit.MILLISECONDS.sleep(TEST_DELAY_MS); // Make sure timestamp changes. - contentTimestamp = Optional.of(Instant.now()); + contentTimestamp = Instant.now(); contentReference.set(ConfigParser.Content.create(new StringReader("aaa=ccc"), PropertiesConfigParser.MEDIA_TYPE_TEXT_JAVA_PROPERTIES, contentTimestamp)); @@ -470,7 +470,7 @@ public class AbstractParsableConfigSourceTest { // objectNode assertThat(configSource.lastData().get().data().get().get("aaa"), valueNode("ccc")); // content timestamp - assertThat(configSource.lastData().get().stamp(), is(contentTimestamp)); + assertThat(configSource.lastData().get().stamp().get(), is(contentTimestamp)); } @Test @@ -533,7 +533,7 @@ public class AbstractParsableConfigSourceTest { .config(Config.create(ConfigSources.create(Map.of("media-type", "application/x-yaml")))); //media-type - assertThat(builder.mediaType(), is("application/x-yaml")); + assertThat(builder.mediaType(), is(Optional.of("application/x-yaml"))); } @Test @@ -541,14 +541,14 @@ public class AbstractParsableConfigSourceTest { TestingParsableConfigSource.TestingBuilder builder = TestingParsableConfigSource.builder().config((Config.empty())); //media-type - assertThat(builder.mediaType(), is(nullValue())); + assertThat(builder.mediaType(), is(Optional.empty())); } - private ConfigParser.Content mockContent() { - ConfigParser.Content content = mock(ConfigParser.Content.class); + private ConfigParser.Content mockContent() { + ConfigParser.Content content = mock(ConfigParser.Content.class); Readable readable = new StringReader(TEST_CONFIG); when(content.asReadable()).thenReturn(readable); - when(content.mediaType()).thenReturn(TEST_MEDIA_TYPE); + when(content.mediaType()).thenReturn(Optional.of(TEST_MEDIA_TYPE)); when(content.stamp()).thenReturn(Optional.of(Instant.EPOCH)); return content; } diff --git a/config/etcd/src/main/java/io/helidon/config/etcd/EtcdConfigSource.java b/config/etcd/src/main/java/io/helidon/config/etcd/EtcdConfigSource.java index ec91e3f0c..86dfabfd1 100644 --- a/config/etcd/src/main/java/io/helidon/config/etcd/EtcdConfigSource.java +++ b/config/etcd/src/main/java/io/helidon/config/etcd/EtcdConfigSource.java @@ -60,10 +60,9 @@ public class EtcdConfigSource extends AbstractParsableConfigSource { } @Override - protected String mediaType() { - return Optional.ofNullable(super.mediaType()) - .or(this::probeContentType) - .orElse(null); + protected Optional mediaType() { + return super.mediaType() + .or(this::probeContentType); } private Optional probeContentType() { @@ -86,18 +85,25 @@ public class EtcdConfigSource extends AbstractParsableConfigSource { @Override protected ConfigParser.Content content() throws ConfigException { - String content = null; + String content; try { content = etcdClient().get(endpoint.key()); } catch (EtcdClientException e) { LOGGER.log(Level.FINEST, "Get operation threw an exception.", e); + throw new ConfigException(String.format("Could not get data for key '%s'", endpoint.key()), e); } // a KV pair does not exist if (content == null) { throw new ConfigException(String.format("Key '%s' does not contain any value", endpoint.key())); } - return ConfigParser.Content.create(new StringReader(content), mediaType(), dataStamp()); + + ConfigParser.Content.Builder builder = ConfigParser.Content.builder(new StringReader(content)); + + mediaType().ifPresent(builder::mediaType); + dataStamp().ifPresent(builder::stamp); + + return builder.build(); } EtcdEndpoint etcdEndpoint() { diff --git a/config/etcd/src/main/java/module-info.java b/config/etcd/src/main/java/module-info.java index 8f04bd29f..21abc9d9e 100644 --- a/config/etcd/src/main/java/module-info.java +++ b/config/etcd/src/main/java/module-info.java @@ -22,13 +22,13 @@ module io.helidon.config.etcd { requires java.logging; requires transitive io.helidon.config; requires etcd4j; - requires io.grpc; requires grpc.protobuf; requires grpc.stub; requires com.google.protobuf; requires com.google.common; requires io.helidon.common; requires io.helidon.common.media.type; + requires grpc.api; exports io.helidon.config.etcd; diff --git a/config/etcd/src/test/java/io/helidon/config/etcd/EtcdConfigSourceTest.java b/config/etcd/src/test/java/io/helidon/config/etcd/EtcdConfigSourceTest.java index 882d0e1ac..7e6b263fd 100644 --- a/config/etcd/src/test/java/io/helidon/config/etcd/EtcdConfigSourceTest.java +++ b/config/etcd/src/test/java/io/helidon/config/etcd/EtcdConfigSourceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -114,8 +114,8 @@ public class EtcdConfigSourceTest { when(mockedConfigSource.etcdClient()).thenReturn(etcdClient); when(mockedConfigSource.content()).thenReturn(new ConfigParser.Content() { @Override - public String mediaType() { - return MEDIA_TYPE_APPLICATION_HOCON; + public Optional mediaType() { + return Optional.of(MEDIA_TYPE_APPLICATION_HOCON); } @Override diff --git a/config/git/src/main/java/io/helidon/config/git/GitConfigSource.java b/config/git/src/main/java/io/helidon/config/git/GitConfigSource.java index f1735557f..535e63430 100644 --- a/config/git/src/main/java/io/helidon/config/git/GitConfigSource.java +++ b/config/git/src/main/java/io/helidon/config/git/GitConfigSource.java @@ -229,10 +229,9 @@ public class GitConfigSource extends AbstractParsableConfigSource { } @Override - protected String mediaType() { - return Optional.ofNullable(super.mediaType()) - .or(this::probeContentType) - .orElse(null); + protected Optional mediaType() { + return super.mediaType() + .or(this::probeContentType); } private Optional probeContentType() { @@ -255,14 +254,20 @@ public class GitConfigSource extends AbstractParsableConfigSource { @Override protected ConfigParser.Content content() throws ConfigException { - Instant lastModifiedTime = lastModifiedTime(targetPath); - LOGGER.log(Level.FINE, String.format("Getting content from '%s'. Last stamp is %s.", targetPath, lastModifiedTime)); + if (LOGGER.isLoggable(Level.FINE)) { + Instant lastModifiedTime = lastModifiedTime(targetPath); + LOGGER.log(Level.FINE, String.format("Getting content from '%s'. Last stamp is %s.", targetPath, lastModifiedTime)); + } - LOGGER.finest(FileSourceHelper.safeReadContent(targetPath)); - Optional stamp = dataStamp(); - return ConfigParser.Content.create(new StringReader(FileSourceHelper.safeReadContent(targetPath)), - mediaType(), - stamp); + String fileContent = FileSourceHelper.safeReadContent(targetPath); + LOGGER.finest(fileContent); + + ConfigParser.Content.Builder builder = ConfigParser.Content.builder(new StringReader(fileContent)); + + mediaType().ifPresent(builder::mediaType); + dataStamp().ifPresent(builder::stamp); + + return builder.build(); } GitConfigSourceBuilder.GitEndpoint gitEndpoint() { diff --git a/config/hocon/src/test/java/io/helidon/config/hocon/HoconConfigParserTest.java b/config/hocon/src/test/java/io/helidon/config/hocon/HoconConfigParserTest.java index 815b84e33..3588b04b2 100644 --- a/config/hocon/src/test/java/io/helidon/config/hocon/HoconConfigParserTest.java +++ b/config/hocon/src/test/java/io/helidon/config/hocon/HoconConfigParserTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -282,8 +283,8 @@ public class HoconConfigParserTest { @FunctionalInterface private interface StringContent extends Content { @Override - default String mediaType() { - return HoconConfigParser.MEDIA_TYPE_APPLICATION_HOCON; + default Optional mediaType() { + return Optional.of(HoconConfigParser.MEDIA_TYPE_APPLICATION_HOCON); } @Override diff --git a/config/yaml/src/test/java/io/helidon/config/yaml/YamlConfigParserTest.java b/config/yaml/src/test/java/io/helidon/config/yaml/YamlConfigParserTest.java index 24ae70961..91cfbb2bb 100644 --- a/config/yaml/src/test/java/io/helidon/config/yaml/YamlConfigParserTest.java +++ b/config/yaml/src/test/java/io/helidon/config/yaml/YamlConfigParserTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ package io.helidon.config.yaml; import java.io.Reader; import java.io.StringReader; import java.util.List; +import java.util.Optional; import io.helidon.config.spi.ConfigNode; import io.helidon.config.spi.ConfigParser; @@ -107,8 +108,8 @@ public class YamlConfigParserTest { @FunctionalInterface private interface StringContent extends ConfigParser.Content { @Override - default String mediaType() { - return YamlConfigParser.MEDIA_TYPE_APPLICATION_YAML; + default Optional mediaType() { + return Optional.of(YamlConfigParser.MEDIA_TYPE_APPLICATION_YAML); } @Override