Removed null params and return types from Config API.

This commit is contained in:
Tomas Langer
2020-02-03 16:43:22 +01:00
committed by Tomas Langer
parent 551395fb62
commit 88f798c506
23 changed files with 293 additions and 208 deletions

View File

@@ -83,10 +83,9 @@ public class ClasspathConfigSource extends AbstractParsableConfigSource<Instant>
}
@Override
protected String mediaType() {
return Optional.ofNullable(super.mediaType())
.or(this::probeContentType)
.orElse(null);
protected Optional<String> mediaType() {
return super.mediaType()
.or(this::probeContentType);
}
private Optional<String> probeContentType() {
@@ -95,16 +94,22 @@ public class ClasspathConfigSource extends AbstractParsableConfigSource<Instant>
@Override
protected Optional<Instant> dataStamp() {
return Optional.ofNullable(ClasspathSourceHelper.resourceTimestamp(resource));
return Optional.of(ClasspathSourceHelper.resourceTimestamp(resource));
}
@Override
protected ConfigParser.Content<Instant> content() throws ConfigException {
return ClasspathSourceHelper.content(resource,
description(),
(inputStreamReader, instant) -> ConfigParser.Content.create(inputStreamReader,
mediaType(),
instant));
(inputStreamReader, instant) -> {
ConfigParser.Content.Builder<Instant> builder = ConfigParser.Content
.builder(inputStreamReader);
builder.stamp(instant);
mediaType().ifPresent(builder::mediaType);
return builder.build();
});
}
@Override

View File

@@ -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<Instant> {
(inputStreamReader, instant) -> {
return new Data<>(
Optional.of(OverrideData.create(inputStreamReader)),
instant);
Optional.of(instant));
});
}

View File

@@ -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> T content(String resource,
String description,
BiFunction<InputStreamReader, Optional<Instant>, T> processor) throws ConfigException {
BiFunction<InputStreamReader, Instant, T> 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<Instant> 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",

View File

@@ -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 <T> dual type to mark parameter both readable and auto closeable
* @return a config source
*/
public static ConfigSource create(Readable readable, String mediaType) {
public static <T extends Readable & AutoCloseable> 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();
}

View File

@@ -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<byte[]> {
}
@Override
protected String mediaType() {
return Optional.ofNullable(super.mediaType())
.or(this::probeContentType)
.orElse(null);
protected Optional<String> mediaType() {
return super.mediaType()
.or(this::probeContentType);
}
private Optional<String> probeContentType() {
@@ -108,12 +106,14 @@ public class FileConfigSource extends AbstractParsableConfigSource<byte[]> {
@Override
protected Content<byte[]> content() throws ConfigException {
Optional<byte[]> 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<byte[]> builder = Content.builder(new StringReader(FileSourceHelper.safeReadContent(filePath)));
dataStamp().ifPresent(builder::stamp);
mediaType().ifPresent(builder::mediaType);
return builder.build();
}
/**

View File

@@ -114,22 +114,27 @@ public class UrlConfigSource extends AbstractParsableConfigSource<Instant> {
}
private ConfigParser.Content<Instant> 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<Instant> builder = ConfigParser.Content.builder(reader);
builder.stamp(Instant.now());
mediaType()
.or(this::probeContentType)
.ifPresent(builder::mediaType);
return builder.build();
}
private ConfigParser.Content<Instant> httpContent(HttpURLConnection connection) throws IOException, URISyntaxException {
connection.setRequestMethod(GET_METHOD);
final String mediaType = mediaType(connection.getContentType());
final Optional<Instant> timestamp;
Optional<String> 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<Instant> {
Reader reader = new InputStreamReader(connection.getInputStream(),
ConfigUtils.getContentCharset(connection.getContentEncoding()));
return ConfigParser.Content.create(reader, mediaType, timestamp);
ConfigParser.Content.Builder<Instant> 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<String> 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<String> mediaType(String responseMediaType) throws URISyntaxException {
return mediaType()
.or(() -> Optional.ofNullable(responseMediaType))
.or(() -> {
Optional<String> 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<String> probeContentType() {
return MediaTypes.detectType(url);
}
@Override

View File

@@ -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<S> extends AbstractMpSource<S> implem
private ConfigNode processValue(Optional<S> datastamp, Config.Key key, ValueNode valueNode) {
AtomicReference<ConfigNode> 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();
}

View File

@@ -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<S> extends AbstractConfigSource<S> {
private final String mediaType;
private final ConfigParser parser;
private final Optional<String> mediaType;
private final Optional<ConfigParser> 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<S> extends AbstractConfigSour
*
* @return source associated media type or {@code null} if unknown.
*/
protected String mediaType() {
protected Optional<String> 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<ConfigParser> parser() {
return parser;
}
@@ -94,12 +95,12 @@ public abstract class AbstractParsableConfigSource<S> extends AbstractConfigSour
* @throws ConfigParserException in case of problem to parse configuration from the source
*/
private ObjectNode parse(ConfigContext context, ConfigParser.Content<S> 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<S> extends AbstractConfigSour
*
* @return media type property.
*/
protected String mediaType() {
return mediaType;
protected Optional<String> mediaType() {
return Optional.ofNullable(mediaType);
}
/**
@@ -201,10 +202,9 @@ public abstract class AbstractParsableConfigSource<S> extends AbstractConfigSour
*
* @return parser property.
*/
protected ConfigParser parser() {
return parser;
protected Optional<ConfigParser> parser() {
return Optional.ofNullable(parser);
}
}
}

View File

@@ -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<String> mediaType();
/**
* Returns a {@link Readable} that is use to read configuration content from.
@@ -114,48 +115,109 @@ public interface ConfigParser {
*/
<T extends Readable & AutoCloseable> T asReadable();
/**
* Create a fluent API builder for content.
*
* @param readable readable to base this content builder on
* @param <S> type of the stamp to use
* @param <T> dual type of readable and autocloseable parameter
* @return a new fluent API builder for content
*/
static <S, T extends Readable & AutoCloseable> Builder<S> 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 <S> a type of data stamp
* @param <T> dual type of readable and autocloseable parameter
* @return a config content
*/
static <S> Content<S> create(Readable readable, String mediaType, Optional<S> stamp) {
return new Content<S>() {
@Override
public void close() throws ConfigException {
if (readable instanceof AutoCloseable) {
static <S, T extends Readable & AutoCloseable> Content<S> 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<S> builder = builder(readable);
return builder
.mediaType(mediaType)
.stamp(stamp)
.build();
}
/**
* Fluent API builder for {@link io.helidon.config.spi.ConfigParser.Content}.
*
* @param <S> type of the stamp of the built content
*/
class Builder<S> implements io.helidon.common.Builder<Content<S>> {
private final AutoCloseable readable;
private String mediaType;
private S stamp;
private <T extends Readable & AutoCloseable> Builder(T readable) {
this.readable = readable;
}
@Override
public Content<S> build() {
final Optional<String> mediaType = Optional.ofNullable(this.mediaType);
final Optional<S> stamp = Optional.ofNullable(this.stamp);
return new Content<>() {
@Override
public Optional<String> mediaType() {
return mediaType;
}
@SuppressWarnings("unchecked")
@Override
public <T extends Readable & AutoCloseable> 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 extends Readable & AutoCloseable> T asReadable() {
return (T) readable;
}
@Override
public Optional<S> stamp() {
return stamp;
}
};
}
@Override
public String mediaType() {
return mediaType;
}
@Override
public Optional<S> stamp() {
return stamp;
}
};
/**
* Content media type.
* @param mediaType type of the content
*/
public Builder<S> mediaType(String mediaType) {
this.mediaType = mediaType;
return this;
}
/**
* Content stamp.
*
* @param stamp stamp of the content
*/
public Builder<S> stamp(S stamp) {
this.stamp = stamp;
return this;
}
}
}
}

View File

@@ -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<Instant> 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<Instant> 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) {

View File

@@ -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) {

View File

@@ -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<ConfigParser.Content<Instant>> 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<ConfigParser.Content<Instant>> 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<ConfigParser.Content<Instant>> 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<ConfigParser.Content<Instant>> 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();

View File

@@ -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) {

View File

@@ -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()));
}
}

View File

@@ -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"));

View File

@@ -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<String> mediaType() {
return Optional.of(MEDIA_TYPE_TEXT_JAVA_PROPERTIES);
}
@Override

View File

@@ -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<Instant> 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<Instant> 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<Instant> 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<Instant> 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<Instant> 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<Instant> 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<Instant> 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<ConfigParser.Content<Instant>> contentReference = new AtomicReference<>();
// set content
Optional<Instant> 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<ConfigParser.Content<Instant>> contentReference = new AtomicReference<>();
// set content
Optional<Instant> 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<ConfigParser.Content> contentReference = new AtomicReference<>();
// set content
Optional<Instant> 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<Instant> mockContent() {
ConfigParser.Content<Instant> 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;
}

View File

@@ -60,10 +60,9 @@ public class EtcdConfigSource extends AbstractParsableConfigSource<Long> {
}
@Override
protected String mediaType() {
return Optional.ofNullable(super.mediaType())
.or(this::probeContentType)
.orElse(null);
protected Optional<String> mediaType() {
return super.mediaType()
.or(this::probeContentType);
}
private Optional<String> probeContentType() {
@@ -86,18 +85,25 @@ public class EtcdConfigSource extends AbstractParsableConfigSource<Long> {
@Override
protected ConfigParser.Content<Long> 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<Long> builder = ConfigParser.Content.builder(new StringReader(content));
mediaType().ifPresent(builder::mediaType);
dataStamp().ifPresent(builder::stamp);
return builder.build();
}
EtcdEndpoint etcdEndpoint() {

View File

@@ -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;

View File

@@ -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<Long>() {
@Override
public String mediaType() {
return MEDIA_TYPE_APPLICATION_HOCON;
public Optional<String> mediaType() {
return Optional.of(MEDIA_TYPE_APPLICATION_HOCON);
}
@Override

View File

@@ -229,10 +229,9 @@ public class GitConfigSource extends AbstractParsableConfigSource<byte[]> {
}
@Override
protected String mediaType() {
return Optional.ofNullable(super.mediaType())
.or(this::probeContentType)
.orElse(null);
protected Optional<String> mediaType() {
return super.mediaType()
.or(this::probeContentType);
}
private Optional<String> probeContentType() {
@@ -255,14 +254,20 @@ public class GitConfigSource extends AbstractParsableConfigSource<byte[]> {
@Override
protected ConfigParser.Content<byte[]> 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<byte[]> stamp = dataStamp();
return ConfigParser.Content.create(new StringReader(FileSourceHelper.safeReadContent(targetPath)),
mediaType(),
stamp);
String fileContent = FileSourceHelper.safeReadContent(targetPath);
LOGGER.finest(fileContent);
ConfigParser.Content.Builder<byte[]> builder = ConfigParser.Content.builder(new StringReader(fileContent));
mediaType().ifPresent(builder::mediaType);
dataStamp().ifPresent(builder::stamp);
return builder.build();
}
GitConfigSourceBuilder.GitEndpoint gitEndpoint() {

View File

@@ -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<String> mediaType() {
return Optional.of(HoconConfigParser.MEDIA_TYPE_APPLICATION_HOCON);
}
@Override

View File

@@ -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<String> mediaType() {
return Optional.of(YamlConfigParser.MEDIA_TYPE_APPLICATION_YAML);
}
@Override