Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #4516 #5758

Merged
merged 2 commits into from
Nov 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.quarkus.runtime.configuration;

import java.io.Serializable;
import java.util.Map;
import java.util.Set;

Expand All @@ -12,7 +13,8 @@
/**
* A base class for configuration sources which delegate to other configuration sources.
*/
public abstract class AbstractDelegatingConfigSource implements ConfigSource {
public abstract class AbstractDelegatingConfigSource implements ConfigSource, Serializable {
private static final long serialVersionUID = -6636734120743034580L;
protected final ConfigSource delegate;
private Map<String, String> propertiesMap;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.quarkus.runtime.configuration;

import java.io.Serializable;
import java.util.Collections;
import java.util.Map;

Expand All @@ -8,7 +9,9 @@
/**
* The base class for the config source that yields the 'raw' default values.
*/
public abstract class AbstractRawDefaultConfigSource implements ConfigSource {
public abstract class AbstractRawDefaultConfigSource implements ConfigSource, Serializable {
private static final long serialVersionUID = 2524612253582530249L;

protected AbstractRawDefaultConfigSource() {
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import static io.quarkus.runtime.configuration.ConverterSupport.DEFAULT_QUARKUS_CONVERTER_PRIORITY;

import java.io.Serializable;

import javax.annotation.Priority;

import org.eclipse.microprofile.config.spi.Converter;
Expand All @@ -12,7 +14,9 @@
* A converter which converts a CIDR address into an instance of {@link CidrAddress}.
*/
@Priority(DEFAULT_QUARKUS_CONVERTER_PRIORITY)
public class CidrAddressConverter implements Converter<CidrAddress> {
public class CidrAddressConverter implements Converter<CidrAddress>, Serializable {

private static final long serialVersionUID = 2023552088048952902L;

@Override
public CidrAddress convert(String value) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.quarkus.runtime.configuration;

import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import java.util.function.UnaryOperator;
Expand All @@ -11,6 +13,7 @@
* A configuration source which supports deployment profiles.
*/
public class DeploymentProfileConfigSource extends AbstractDelegatingConfigSource {
private static final long serialVersionUID = -8001338475089294128L;

private final String profilePrefix;

Expand All @@ -35,6 +38,26 @@ public DeploymentProfileConfigSource(final ConfigSource delegate, final String p
profilePrefix = "%" + profileName + ".";
}

Object writeReplace() throws ObjectStreamException {
return new Ser(delegate, profilePrefix);
}

static final class Ser implements Serializable {
private static final long serialVersionUID = -4618790131794331510L;

final ConfigSource d;
final String p;

Ser(final ConfigSource d, String p) {
this.d = d;
this.p = p;
}

Object readResolve() {
return new DeploymentProfileConfigSource(d, p);
}
}

public Set<String> getPropertyNames() {
Set<String> propertyNames = delegate.getPropertyNames();
//if a key is only present in a profile we still want the unprofiled key name to show up
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static io.quarkus.runtime.configuration.ConverterSupport.DEFAULT_QUARKUS_CONVERTER_PRIORITY;

import java.io.Serializable;
import java.time.Duration;
import java.time.format.DateTimeParseException;
import java.util.regex.Pattern;
Expand All @@ -14,7 +15,8 @@
* A converter for a {@link Duration} interface.
*/
@Priority(DEFAULT_QUARKUS_CONVERTER_PRIORITY)
public class DurationConverter implements Converter<Duration> {
public class DurationConverter implements Converter<Duration>, Serializable {
private static final long serialVersionUID = 7499347081928776532L;
private static final String PERIOD_OF_TIME = "PT";
private static final Pattern DIGITS = Pattern.compile("^[-+]?\\d+$");
private static final Pattern START_WITH_DIGITS = Pattern.compile("^[-+]?\\d+.*");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.quarkus.runtime.configuration;

import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.UnaryOperator;
Expand All @@ -13,6 +15,7 @@
*/
public class ExpandingConfigSource extends AbstractDelegatingConfigSource {

private static final long serialVersionUID = 1075000015425893741L;
private static final ThreadLocal<Boolean> NO_EXPAND = new ThreadLocal<>();

public static UnaryOperator<ConfigSource> wrapper(Cache cache) {
Expand Down Expand Up @@ -44,6 +47,24 @@ public String getValue(final String propertyName) {
return isExpanding() ? expand(delegateValue) : delegateValue;
}

Object writeReplace() throws ObjectStreamException {
return new Ser(delegate);
}

static final class Ser implements Serializable {
private static final long serialVersionUID = 3633535720479375279L;

final ConfigSource d;

Ser(final ConfigSource d) {
this.d = d;
}

Object readResolve() {
return new ExpandingConfigSource(d, new Cache());
}
}

String expand(final String value) {
return expandValue(value, cache);
}
Expand Down Expand Up @@ -83,7 +104,9 @@ public static String expandValue(String value, Cache cache) {
/**
* An expression cache to use with {@link ExpandingConfigSource}.
*/
public static final class Cache {
public static final class Cache implements Serializable {
private static final long serialVersionUID = 6111143168103886992L;

// this is a cache of compiled expressions, NOT a cache of expanded values
final ConcurrentHashMap<String, Expression> exprCache = new ConcurrentHashMap<>();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.quarkus.runtime.configuration;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
Expand All @@ -12,9 +13,10 @@
/**
* A converter for hyphenated enums.
*/
public final class HyphenateEnumConverter<E extends Enum<E>> implements Converter<E> {
public final class HyphenateEnumConverter<E extends Enum<E>> implements Converter<E>, Serializable {
private static final String HYPHEN = "-";
private static final Pattern PATTERN = Pattern.compile("([-_]+)");
private static final long serialVersionUID = 5675903245398498741L;

private final Class<E> enumType;
private final Map<String, E> values = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static io.quarkus.runtime.configuration.ConverterSupport.DEFAULT_QUARKUS_CONVERTER_PRIORITY;

import java.io.Serializable;
import java.net.InetAddress;
import java.net.UnknownHostException;

Expand All @@ -14,7 +15,9 @@
* A converter which produces values of type {@link InetAddress}.
*/
@Priority(DEFAULT_QUARKUS_CONVERTER_PRIORITY)
public class InetAddressConverter implements Converter<InetAddress> {
public class InetAddressConverter implements Converter<InetAddress>, Serializable {

private static final long serialVersionUID = 4539214213710330204L;

@Override
public InetAddress convert(String value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static io.quarkus.runtime.configuration.ConverterSupport.DEFAULT_QUARKUS_CONVERTER_PRIORITY;

import java.io.Serializable;
import java.net.InetAddress;
import java.net.InetSocketAddress;

Expand All @@ -16,7 +17,9 @@
* an unresolved instance is returned.
*/
@Priority(DEFAULT_QUARKUS_CONVERTER_PRIORITY)
public class InetSocketAddressConverter implements Converter<InetSocketAddress> {
public class InetSocketAddressConverter implements Converter<InetSocketAddress>, Serializable {

private static final long serialVersionUID = 1928336763333858343L;

@Override
public InetSocketAddress convert(String value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static io.quarkus.runtime.configuration.ConverterSupport.DEFAULT_QUARKUS_CONVERTER_PRIORITY;

import java.io.Serializable;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
Expand All @@ -16,10 +17,11 @@
* A converter to support data sizes.
*/
@Priority(DEFAULT_QUARKUS_CONVERTER_PRIORITY)
public class MemorySizeConverter implements Converter<MemorySize> {
public class MemorySizeConverter implements Converter<MemorySize>, Serializable {
private static final Pattern MEMORY_SIZE_PATTERN = Pattern.compile("^(\\d+)([BbKkMmGgTtPpEeZzYy]?)$");
static final BigInteger KILO_BYTES = BigInteger.valueOf(1024);
private static final Map<String, BigInteger> MEMORY_SIZE_MULTIPLIERS;
private static final long serialVersionUID = -1988485929047973068L;

static {
MEMORY_SIZE_MULTIPLIERS = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static io.quarkus.runtime.configuration.ConverterSupport.DEFAULT_QUARKUS_CONVERTER_PRIORITY;

import java.io.Serializable;
import java.nio.file.Path;
import java.nio.file.Paths;

Expand All @@ -13,7 +14,9 @@
* A converter for a {@link Path} interface.
*/
@Priority(DEFAULT_QUARKUS_CONVERTER_PRIORITY)
public class PathConverter implements Converter<Path> {
public class PathConverter implements Converter<Path>, Serializable {

private static final long serialVersionUID = 4452863383998867844L;

@Override
public Path convert(String value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static io.quarkus.runtime.configuration.ConverterSupport.DEFAULT_QUARKUS_CONVERTER_PRIORITY;

import java.io.Serializable;
import java.util.regex.Pattern;

import javax.annotation.Priority;
Expand All @@ -12,7 +13,9 @@
* A converter to support regular expressions.
*/
@Priority(DEFAULT_QUARKUS_CONVERTER_PRIORITY)
public class RegexConverter implements Converter<Pattern> {
public class RegexConverter implements Converter<Pattern>, Serializable {

private static final long serialVersionUID = -2627801624423530576L;

/**
* Construct a new instance.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static io.quarkus.runtime.configuration.ConverterSupport.DEFAULT_QUARKUS_CONVERTER_PRIORITY;

import java.io.Serializable;
import java.util.logging.Level;

import javax.annotation.Priority;
Expand All @@ -13,7 +14,9 @@
* A simple converter for logging levels.
*/
@Priority(DEFAULT_QUARKUS_CONVERTER_PRIORITY)
public final class LevelConverter implements Converter<Level> {
public final class LevelConverter implements Converter<Level>, Serializable {

private static final long serialVersionUID = 704275577610445233L;

public Level convert(final String value) {
if (value == null || value.isEmpty()) {
Expand Down
3 changes: 1 addition & 2 deletions tcks/microprofile-config/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@
<!-- TCK and spec dispute: https://github.com/eclipse/microprofile-config/pull/407 -->
<exclude>org.eclipse.microprofile.config.tck.EmptyValuesTest</exclude>
<!-- "testEnvironmentConfigSource" fails because of the above TCK/spec dispute -->
<!-- "testInjectedConfigSerializable" fails because not all ConfigSource, Converters, etc are serializable -->
<!-- We have a custom version of this TCK class that excludes "testEnvironmentConfigSource" and "testInjectedConfigSerializable", allowing other tests to run -->
<!-- We have a custom version of this TCK class that excludes "testEnvironmentConfigSource", allowing other tests to run -->
<exclude>org.eclipse.microprofile.config.tck.ConfigProviderTest</exclude>
</excludes>
</configuration>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
package io.quarkus.tck.config;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import javax.inject.Inject;

import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.tck.ConfigProviderTest;
import org.hamcrest.CoreMatchers;
import org.hamcrest.MatcherAssert;
import org.testng.Assert;
import org.testng.annotations.Test;

import io.quarkus.runtime.configuration.ExpandingConfigSource;

public class CustomConfigProviderTest extends ConfigProviderTest {

@Inject
private Config config;

@Test
public void testEnvironmentConfigSource() {
// this test fails when there is a expression-like thing in an env prop
Expand All @@ -17,8 +33,25 @@ public void testEnvironmentConfigSource() {
}
}

@Test(enabled = false)
@Test
public void testInjectedConfigSerializable() {
// Needed a custom ObjectInputStream.resolveClass() to use a ClassLoader with Quarkus generated classes in it
// Everything else is identical to the test class it overwrites
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try (ObjectOutputStream out = new ObjectOutputStream(byteArrayOutputStream)) {
out.writeObject(config);
} catch (IOException ex) {
Assert.fail("Injected config should be serializable, but could not serialize it", ex);
}
Object readObject = null;
try (ObjectInputStream in = new CustomObjectInputStream(
new ByteArrayInputStream(byteArrayOutputStream.toByteArray()))) {
readObject = in.readObject();
} catch (IOException | ClassNotFoundException ex) {
Assert.fail("Injected config should be serializable, but could not deserialize a previously serialized instance",
ex);
}
MatcherAssert.assertThat("Deserialized object", readObject, CoreMatchers.instanceOf(Config.class));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.quarkus.tck.config;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;

public class CustomObjectInputStream extends ObjectInputStream {

public CustomObjectInputStream(InputStream in) throws IOException {
super(in);
}

@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
String name = desc.getName();
try {
return Class.forName(name, false, Thread.currentThread().getContextClassLoader());
} catch (ClassNotFoundException ex) {
// Do nothing
}
// Fallback to parent implementation if we can't find the class
return super.resolveClass(desc);
}
}
Loading