SPI Config API for Jersey (#4116)
Config SPI API for Jersey
Signed-off-by: Maxim Nesen <maxim.nesen@oracle.com>
diff --git a/bom/pom.xml b/bom/pom.xml
index e2b5ccb..a0bb9cd 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -150,6 +150,11 @@
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
+ <artifactId>jersey-mp-config</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-mvc</artifactId>
<version>${project.version}</version>
</dependency>
diff --git a/core-common/src/main/java/org/glassfish/jersey/CommonProperties.java b/core-common/src/main/java/org/glassfish/jersey/CommonProperties.java
index 3218d3b..654d9e7 100644
--- a/core-common/src/main/java/org/glassfish/jersey/CommonProperties.java
+++ b/core-common/src/main/java/org/glassfish/jersey/CommonProperties.java
@@ -217,6 +217,17 @@
public static final String OUTBOUND_CONTENT_LENGTH_BUFFER_SERVER = "jersey.config.server.contentLength.buffer";
/**
+ * Property which allows (if true) default System properties configuration provider.
+ *
+ * Effective if there are no any external properties providers
+ *
+ * Shall be set (if used) in system properties.
+ * @since 2.29
+ */
+
+ public static final String ALLOW_SYSTEM_PROPERTIES_PROVIDER = "jersey.config.allowSystemPropertiesProvider";
+
+ /**
* Prevent instantiation.
*/
private CommonProperties() {
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/config/ExternalPropertiesAutoDiscoverable.java b/core-common/src/main/java/org/glassfish/jersey/internal/config/ExternalPropertiesAutoDiscoverable.java
new file mode 100644
index 0000000..e7d0adc
--- /dev/null
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/config/ExternalPropertiesAutoDiscoverable.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.internal.config;
+
+import org.glassfish.jersey.internal.spi.AutoDiscoverable;
+
+import javax.annotation.Priority;
+import javax.ws.rs.ConstrainedTo;
+import javax.ws.rs.RuntimeType;
+import javax.ws.rs.core.FeatureContext;
+
+@ConstrainedTo(RuntimeType.CLIENT) //server is configured directly in ResourceConfig
+@Priority(AutoDiscoverable.DEFAULT_PRIORITY)
+public class ExternalPropertiesAutoDiscoverable implements AutoDiscoverable {
+ @Override
+ public void configure(FeatureContext context) {
+ if (!context.getConfiguration().isRegistered(ExternalPropertiesConfigurationFeature.class)) {
+ context.register(ExternalPropertiesConfigurationFeature.class);
+ }
+ }
+}
\ No newline at end of file
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/config/ExternalPropertiesConfigurationFactory.java b/core-common/src/main/java/org/glassfish/jersey/internal/config/ExternalPropertiesConfigurationFactory.java
new file mode 100644
index 0000000..35ca77a
--- /dev/null
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/config/ExternalPropertiesConfigurationFactory.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.internal.config;
+
+import org.glassfish.jersey.internal.ServiceFinder;
+import org.glassfish.jersey.spi.ExternalConfigurationModel;
+import org.glassfish.jersey.spi.ExternalConfigurationProvider;
+
+import javax.annotation.Priority;
+import javax.ws.rs.Priorities;
+import javax.ws.rs.core.Configurable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * Factory for external properties providers
+ * Offers methods to work with properties loaded from providers or
+ * just configure Jersey's Configurables with loaded properties from providers
+ */
+public class ExternalPropertiesConfigurationFactory {
+
+ private static final List<ExternalConfigurationProvider> EXTERNAL_CONFIGURATION_PROVIDERS =
+ getExternalConfigurations();
+
+
+ /**
+ * Map of merged properties from all found providers
+ *
+ * @return map of merged properties from all found/plugged providers
+ */
+ static Map<String, Object> readExternalPropertiesMap() {
+
+ final ExternalConfigurationProvider provider = mergeConfigs(EXTERNAL_CONFIGURATION_PROVIDERS);
+ return provider == null ? Collections.emptyMap() : provider.getProperties();
+ }
+
+
+ /**
+ * Input Configurable object shall be provided in order to be filled with all found properties
+ *
+ * @param config Input Configurable initialised object to be filled with properties
+ * @return true if configured false otherwise
+ */
+
+ public static boolean configure(Configurable config) {
+
+ if (config instanceof ExternalConfigurationModel) {
+ return false; //shall not configure itself
+ }
+
+ final Map<String, Object> properties = readExternalPropertiesMap();
+
+ properties.forEach((k, v) -> config.property(k, v));
+
+ return true;
+ }
+
+ /**
+ * Merged config model from all found configuration models
+ *
+ * @return merged Model object with all properties
+ */
+ static ExternalConfigurationModel getConfig() {
+ final ExternalConfigurationProvider provider = mergeConfigs(getExternalConfigurations());
+ return provider == null ? null : provider.getConfiguration();
+ }
+
+ /**
+ * List of all found models as they are found by Jersey
+ *
+ * @return list of models (or empty list)
+ */
+ private static List<ExternalConfigurationProvider> getExternalConfigurations() {
+ final List<ExternalConfigurationProvider> providers = new ArrayList<>();
+ final ServiceFinder<ExternalConfigurationProvider> finder =
+ ServiceFinder.find(ExternalConfigurationProvider.class);
+ if (finder.iterator().hasNext()) {
+ finder.forEach(providers::add);
+ } else {
+ providers.add(new SystemPropertiesConfigurationProvider());
+ }
+ return providers;
+ }
+
+ private static ExternalConfigurationProvider mergeConfigs(List<ExternalConfigurationProvider> configurations) {
+ final Set<ExternalConfigurationProvider> orderedConfigurations = orderConfigs(configurations);
+ final Iterator<ExternalConfigurationProvider> configurationIterator = orderedConfigurations.iterator();
+ if (!configurationIterator.hasNext()) {
+ return null;
+ }
+ final ExternalConfigurationProvider firstConfig = configurationIterator.next();
+ while (configurationIterator.hasNext()) {
+ final ExternalConfigurationProvider nextConfig = configurationIterator.next();
+ firstConfig.merge(nextConfig.getConfiguration());
+ }
+
+ return firstConfig;
+ }
+
+ private static Set<ExternalConfigurationProvider> orderConfigs(List<ExternalConfigurationProvider> configurations) {
+
+ final SortedSet<ExternalConfigurationProvider> sortedSet = new TreeSet<>(new ConfigComparator());
+ sortedSet.addAll(configurations);
+ return Collections.unmodifiableSortedSet(sortedSet);
+ }
+
+ private static class ConfigComparator implements Comparator<ExternalConfigurationProvider> {
+
+ @Override
+ public int compare(ExternalConfigurationProvider config1, ExternalConfigurationProvider config2) {
+
+ boolean config1PriorityPresent = config1.getClass().isAnnotationPresent(Priority.class);
+ boolean config2PriorityPresent = config2.getClass().isAnnotationPresent(Priority.class);
+
+ int priority1 = Priorities.USER;
+ int priority2 = Priorities.USER;
+
+ if (config1PriorityPresent) {
+ priority1 = config1.getClass().getAnnotation(Priority.class).value();
+ }
+ if (config2PriorityPresent) {
+ priority2 = config2.getClass().getAnnotation(Priority.class).value();
+ }
+
+ if (priority1 == priority2) {
+ return config1.getClass().getName().compareTo(config2.getClass().getName());
+ }
+ return Integer.compare(priority1, priority2);
+ }
+ }
+}
\ No newline at end of file
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/config/ExternalPropertiesConfigurationFeature.java b/core-common/src/main/java/org/glassfish/jersey/internal/config/ExternalPropertiesConfigurationFeature.java
new file mode 100644
index 0000000..acdab23
--- /dev/null
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/config/ExternalPropertiesConfigurationFeature.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.internal.config;
+
+import javax.ws.rs.core.Feature;
+import javax.ws.rs.core.FeatureContext;
+
+public class ExternalPropertiesConfigurationFeature implements Feature {
+
+ @Override
+ public boolean configure(FeatureContext configurableContext) {
+ return ExternalPropertiesConfigurationFactory.configure(configurableContext);
+ }
+
+}
\ No newline at end of file
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/config/SystemPropertiesConfigurationModel.java b/core-common/src/main/java/org/glassfish/jersey/internal/config/SystemPropertiesConfigurationModel.java
new file mode 100644
index 0000000..3c0fd7a
--- /dev/null
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/config/SystemPropertiesConfigurationModel.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.internal.config;
+
+import org.glassfish.jersey.CommonProperties;
+import org.glassfish.jersey.internal.LocalizationMessages;
+import org.glassfish.jersey.internal.util.PropertiesHelper;
+import org.glassfish.jersey.internal.util.ReflectionHelper;
+import org.glassfish.jersey.spi.ExternalConfigurationModel;
+
+import javax.ws.rs.RuntimeType;
+import javax.ws.rs.core.Feature;
+import java.lang.reflect.Field;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.logging.Logger;
+
+
+class SystemPropertiesConfigurationModel implements ExternalConfigurationModel<Void> {
+
+ private static final Logger log = Logger.getLogger(SystemPropertiesConfigurationModel.class.getName());
+
+
+ private static final Map<Class, Function> converters = new HashMap<>();
+ static {
+ converters.put(String.class, (Function<String, String>) s -> s);
+ converters.put(Integer.class, (Function<String, Integer>) s -> Integer.valueOf(s));
+ converters.put(Boolean.class, (Function<String, Boolean>) s -> s.equalsIgnoreCase("1")
+ ? true
+ : Boolean.parseBoolean(s));
+ }
+
+ private String getSystemProperty(String name) {
+ return AccessController.doPrivileged(PropertiesHelper.getSystemProperty(name));
+ }
+
+ @Override
+ public <T> T as(String name, Class<T> clazz) {
+ if (converters.get(clazz) == null) {
+ throw new IllegalArgumentException("Unsupported class type");
+ }
+ return (name != null && clazz != null && isProperty(name))
+ ? clazz.cast(converters.get(clazz).apply(getSystemProperty(name)))
+ : null;
+ }
+
+
+
+ @Override
+ public <T> Optional<T> getOptionalProperty(String name, Class<T> clazz) {
+ return Optional.of(as(name, clazz));
+ }
+
+ @Override
+ public ExternalConfigurationModel mergeProperties(Map<String, Object> inputProperties) {
+ return this;
+ }
+
+ @Override
+ public Void getConfig() {
+ return null;
+ }
+
+ @Override
+ public boolean isProperty(String name) {
+ return Optional.ofNullable(
+ AccessController.doPrivileged(
+ PropertiesHelper.getSystemProperty(name)
+ )
+ ).isPresent();
+ }
+
+ @Override
+ public RuntimeType getRuntimeType() {
+ return null;
+ }
+
+ @Override
+ public Map<String, Object> getProperties() {
+ final Map<String, Object> result = new HashMap<>();
+
+ final Boolean allowSystemPropertiesProvider = as(
+ CommonProperties.ALLOW_SYSTEM_PROPERTIES_PROVIDER, Boolean.class
+ );
+ if (!Boolean.TRUE.equals(allowSystemPropertiesProvider)) {
+ log.finer(LocalizationMessages.WARNING_PROPERTIES());
+ return result;
+ }
+
+ try {
+ AccessController.doPrivileged(PropertiesHelper.getSystemProperties())
+ .forEach((k, v) -> result.put(String.valueOf(k), v));
+ } catch (SecurityException se) {
+ log.warning(LocalizationMessages.SYSTEM_PROPERTIES_WARNING());
+ return getExpectedSystemProperties();
+ }
+ return result;
+ }
+
+ private Map<String, Object> getExpectedSystemProperties() {
+
+
+ final Map<String, Object> result = new HashMap<>();
+
+ mapFieldsToProperties(result, CommonProperties.class);
+
+
+
+ mapFieldsToProperties(result,
+ AccessController.doPrivileged(
+ ReflectionHelper.classForNamePA("org.glassfish.jersey.server.ServerProperties")
+ )
+ );
+
+ mapFieldsToProperties(result,
+ AccessController.doPrivileged(
+ ReflectionHelper.classForNamePA("org.glassfish.jersey.client.ClientProperties")
+ )
+ );
+
+
+ return result;
+ }
+
+ private <T> void mapFieldsToProperties(Map<String, Object> properties, Class<T> clazz) {
+ if (clazz == null) {
+ return;
+ }
+
+ final Field[] fields = AccessController.doPrivileged(
+ ReflectionHelper.getDeclaredFieldsPA(clazz)
+ );
+
+ for (final Field field : fields) {
+ if (field.getType().isAssignableFrom(String.class)) {
+ final String propertyValue = getPropertyNameByField(field);
+ properties.put(propertyValue, PropertiesHelper.getSystemProperty(propertyValue));
+ }
+ }
+ }
+
+ private String getPropertyNameByField(Field field) {
+ return AccessController.doPrivileged((PrivilegedAction<String>) () -> {
+ try {
+ return (String) field.get(null);
+ } catch (IllegalAccessException e) {
+ log.warning(e.getLocalizedMessage());
+ }
+ return null;
+ });
+ }
+
+ @Override
+ public Object getProperty(String name) {
+ return getSystemProperty(name);
+ }
+
+ @Override
+ public Collection<String> getPropertyNames() {
+ return PropertiesHelper.getSystemProperties().run().stringPropertyNames();
+ }
+
+ @Override
+ public boolean isEnabled(Feature feature) {
+ return false;
+ }
+
+ @Override
+ public boolean isEnabled(Class<? extends Feature> featureClass) {
+ return false;
+ }
+
+ @Override
+ public boolean isRegistered(Object component) {
+ return false;
+ }
+
+ @Override
+ public boolean isRegistered(Class<?> componentClass) {
+ return false;
+ }
+
+ @Override
+ public Map<Class<?>, Integer> getContracts(Class<?> componentClass) {
+ return null;
+ }
+
+ @Override
+ public Set<Class<?>> getClasses() {
+ return null;
+ }
+
+ @Override
+ public Set<Object> getInstances() {
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/config/SystemPropertiesConfigurationProvider.java b/core-common/src/main/java/org/glassfish/jersey/internal/config/SystemPropertiesConfigurationProvider.java
new file mode 100644
index 0000000..145f5f7
--- /dev/null
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/config/SystemPropertiesConfigurationProvider.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.internal.config;
+
+import org.glassfish.jersey.spi.ExternalConfigurationModel;
+import org.glassfish.jersey.spi.ExternalConfigurationProvider;
+
+import java.util.Map;
+
+class SystemPropertiesConfigurationProvider implements ExternalConfigurationProvider {
+
+ private final SystemPropertiesConfigurationModel model = new SystemPropertiesConfigurationModel();
+ @Override
+ public Map<String, Object> getProperties() {
+ return model.getProperties();
+ }
+
+ @Override
+ public ExternalConfigurationModel getConfiguration() {
+ return model;
+ }
+
+ @Override
+ public ExternalConfigurationModel merge(ExternalConfigurationModel input) {
+ return input == null ? model : model.mergeProperties(input.getProperties());
+ }
+
+}
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/config/package-info.java b/core-common/src/main/java/org/glassfish/jersey/internal/config/package-info.java
new file mode 100644
index 0000000..21206bd
--- /dev/null
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/config/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/**
+ * Configuration factory to handle external properties from different config SPI implementations
+ *
+ * @since 2.29
+ */
+package org.glassfish.jersey.internal.config;
\ No newline at end of file
diff --git a/core-common/src/main/java/org/glassfish/jersey/spi/ExternalConfigurationModel.java b/core-common/src/main/java/org/glassfish/jersey/spi/ExternalConfigurationModel.java
new file mode 100644
index 0000000..333cd35
--- /dev/null
+++ b/core-common/src/main/java/org/glassfish/jersey/spi/ExternalConfigurationModel.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.spi;
+
+import org.glassfish.jersey.ExtendedConfig;
+
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * Model of configuration for external properties. Requires certain utilities methods to be implemented
+ * @param <CONFIG> type of an external config
+ */
+public interface ExternalConfigurationModel<CONFIG> extends ExtendedConfig {
+
+ /**
+ * Get value of a property as a definite type
+ *
+ * property shall exist in order for this method to be used. Otherwise exception is thrown
+ *
+ * @param name property name
+ * @param clazz class type of an expected value
+ * @param <T> type of an expected value
+ * @return value of an expected type
+ */
+ <T> T as(String name, Class<T> clazz);
+
+ /**
+ * Get value of a property as a definite type
+ *
+ * property may not exist, an empty Optional object is returned in case of an empty property
+ *
+ * @param name property name
+ * @param clazz class type of an expected value
+ * @param <T> type of an expected value
+ * @return Optional object filled by a value of an expected type or by the NULL value (
+ */
+ <T> Optional<T> getOptionalProperty(String name, Class<T> clazz);
+
+ /**
+ * Merge properties from other (found) external configuration.
+ *
+ * @param inputProperties those properties will be merged into ours
+ * @return current instance of the model
+ */
+ ExternalConfigurationModel mergeProperties(Map<String, Object> inputProperties);
+
+ /**
+ * Obtain config object
+ *
+ * @return external config provider
+ */
+ CONFIG getConfig();
+}
diff --git a/core-common/src/main/java/org/glassfish/jersey/spi/ExternalConfigurationProvider.java b/core-common/src/main/java/org/glassfish/jersey/spi/ExternalConfigurationProvider.java
new file mode 100644
index 0000000..80e0784
--- /dev/null
+++ b/core-common/src/main/java/org/glassfish/jersey/spi/ExternalConfigurationProvider.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+
+package org.glassfish.jersey.spi;
+
+import java.util.Map;
+
+/**
+ * Provider interface for external (SPI) providers to provide
+ * their configuration properties implementations
+ *
+ * Priority of providers can be adjusted by Priority annotation
+ * or just alphabetically (if no Provider annotation is found)
+ */
+public interface ExternalConfigurationProvider {
+
+ /**
+ * Map of properties from the model (external config file)
+ *
+ * @return Map of properties loaded by a model from config file
+ */
+ Map<String, Object> getProperties();
+
+ /**
+ * obrain model object which has direct access to external configuration
+ *
+ * @return model of external properties
+ */
+ ExternalConfigurationModel getConfiguration();
+
+ /**
+ * Merge properties from other provider/model
+ *
+ * @param input those properties will be merged into ours
+ * @return current instance of provider
+ */
+ ExternalConfigurationModel merge(ExternalConfigurationModel input);
+}
diff --git a/core-common/src/main/resources/META-INF/services/org.glassfish.jersey.internal.spi.AutoDiscoverable b/core-common/src/main/resources/META-INF/services/org.glassfish.jersey.internal.spi.AutoDiscoverable
index 371b37b..abc1825 100644
--- a/core-common/src/main/resources/META-INF/services/org.glassfish.jersey.internal.spi.AutoDiscoverable
+++ b/core-common/src/main/resources/META-INF/services/org.glassfish.jersey.internal.spi.AutoDiscoverable
@@ -1 +1,2 @@
-org.glassfish.jersey.logging.LoggingFeatureAutoDiscoverable
\ No newline at end of file
+org.glassfish.jersey.logging.LoggingFeatureAutoDiscoverable
+org.glassfish.jersey.internal.config.ExternalPropertiesAutoDiscoverable
\ No newline at end of file
diff --git a/core-common/src/main/resources/org/glassfish/jersey/internal/localization.properties b/core-common/src/main/resources/org/glassfish/jersey/internal/localization.properties
index e7abfd8..6b56cf5 100644
--- a/core-common/src/main/resources/org/glassfish/jersey/internal/localization.properties
+++ b/core-common/src/main/resources/org/glassfish/jersey/internal/localization.properties
@@ -193,3 +193,5 @@
warning.provider.constrainedTo.wrong.package=A registered provider {0} constrained (via @ConstrainedTo) to {1} runtime implements interface {2} which is only usable in a {3} runtime context.
# {0} - List of arbitrary localized messages, e.g.: [FATAL] <localized_message>; source=<object>
warnings.detected=The following warnings have been detected: {0}
+warning.properties=System properties configuration provider not allowed
+system.properties.warning=Could not read system properties
diff --git a/core-common/src/test/java/org/glassfish/jersey/internal/config/ExternalPropertiesConfigurationFactoryTest.java b/core-common/src/test/java/org/glassfish/jersey/internal/config/ExternalPropertiesConfigurationFactoryTest.java
new file mode 100644
index 0000000..d0df568
--- /dev/null
+++ b/core-common/src/test/java/org/glassfish/jersey/internal/config/ExternalPropertiesConfigurationFactoryTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.internal.config;
+
+import org.glassfish.jersey.CommonProperties;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.glassfish.jersey.internal.config.ExternalPropertiesConfigurationFactory.getConfig;
+import static org.glassfish.jersey.internal.config.ExternalPropertiesConfigurationFactory.readExternalPropertiesMap;
+
+public class ExternalPropertiesConfigurationFactoryTest {
+
+ /**
+ * Predefine some properties to be read from config
+ */
+ @BeforeClass
+ public static void setUp() {
+ System.setProperty(CommonProperties.ALLOW_SYSTEM_PROPERTIES_PROVIDER, Boolean.TRUE.toString());
+
+ System.setProperty("jersey.config.server.provider.scanning.recursive", "PASSED");
+ System.setProperty(CommonProperties.JSON_PROCESSING_FEATURE_DISABLE, "1");
+ System.setProperty("jersey.config.client.readTimeout", "10");
+ }
+
+ @AfterClass
+ public static void tearDown() {
+ System.clearProperty("jersey.config.server.provider.scanning.recursive");
+ System.clearProperty(CommonProperties.JSON_PROCESSING_FEATURE_DISABLE);
+ System.clearProperty("jersey.config.client.readTimeout");
+ }
+
+ @Test
+ public void readSystemPropertiesTest() {
+ final Object result =
+ readExternalPropertiesMap().get("jersey.config.server.provider.scanning.recursive");
+ Assert.assertNull(result);
+ Assert.assertEquals(Boolean.TRUE,
+ getConfig().as(CommonProperties.JSON_PROCESSING_FEATURE_DISABLE, Boolean.class));
+ Assert.assertEquals(Boolean.FALSE,
+ getConfig().as("jersey.config.client.readTimeout", Boolean.class));
+ Assert.assertEquals(1,
+ getConfig().as(CommonProperties.JSON_PROCESSING_FEATURE_DISABLE, Integer.class));
+ Assert.assertEquals(10,
+ getConfig().as("jersey.config.client.readTimeout", Integer.class));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void unsupportedMapperTest() {
+ getConfig().as(CommonProperties.JSON_PROCESSING_FEATURE_DISABLE, Double.class);
+ }
+
+ @Test
+ public void mergePropertiesTest() {
+ final Map<String, Object> inputProperties = new HashMap<>();
+ inputProperties.put("jersey.config.server.provider.scanning.recursive", "MODIFIED");
+ inputProperties.put("org.jersey.microprofile.config.added", "ADDED");
+ getConfig().mergeProperties(inputProperties);
+ final Object result = readExternalPropertiesMap().get("jersey.config.server.provider.scanning.recursive");
+ Assert.assertNull(result);
+ Assert.assertNull(readExternalPropertiesMap().get("org.jersey.microprofile.config.added"));
+ }
+
+}
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/ResourceConfig.java b/core-server/src/main/java/org/glassfish/jersey/server/ResourceConfig.java
index 2560fd2..ecf884d 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/ResourceConfig.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/ResourceConfig.java
@@ -38,6 +38,7 @@
import javax.ws.rs.core.Feature;
import org.glassfish.jersey.internal.Errors;
+import org.glassfish.jersey.internal.config.ExternalPropertiesConfigurationFactory;
import org.glassfish.jersey.internal.inject.Binder;
import org.glassfish.jersey.internal.inject.InjectionManager;
import org.glassfish.jersey.internal.spi.AutoDiscoverable;
@@ -56,6 +57,7 @@
import org.glassfish.jersey.server.internal.scanning.PackageNamesScanner;
import org.glassfish.jersey.server.model.Resource;
+
/**
* The resource configuration for configuring a web application.
*
@@ -713,6 +715,7 @@
final State current = state;
if (!(current instanceof ImmutableState)) {
setupApplicationName();
+ ExternalPropertiesConfigurationFactory.configure(state);
state = new ImmutableState(current);
}
}
@@ -1297,4 +1300,5 @@
setApplicationName(appName);
}
}
+
}
diff --git a/ext/microprofile/config/pom.xml b/ext/microprofile/config/pom.xml
new file mode 100644
index 0000000..39d5029
--- /dev/null
+++ b/ext/microprofile/config/pom.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>project</artifactId>
+ <groupId>org.glassfish.jersey.ext</groupId>
+ <version>2.29-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>jersey-mp-config</artifactId>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.eclipse.microprofile.config</groupId>
+ <artifactId>microprofile-config-api</artifactId>
+ <version>${config.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>jakarta.ws.rs</groupId>
+ <artifactId>jakarta.ws.rs-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.glassfish.jersey.core</groupId>
+ <artifactId>jersey-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+ <artifactId>jersey-test-framework-provider-jetty</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.glassfish.jersey.inject</groupId>
+ <artifactId>jersey-hk2</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework</groupId>
+ <artifactId>jersey-test-framework-core</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+ <artifactId>jersey-test-framework-provider-jetty</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>io.helidon.microprofile.config</groupId>
+ <artifactId>helidon-microprofile-config</artifactId>
+ <version>${helidon.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+</project>
diff --git a/ext/microprofile/config/src/main/java/org/glassfish/jersey/microprofile/config/ConfigurationModel.java b/ext/microprofile/config/src/main/java/org/glassfish/jersey/microprofile/config/ConfigurationModel.java
new file mode 100644
index 0000000..8de143e
--- /dev/null
+++ b/ext/microprofile/config/src/main/java/org/glassfish/jersey/microprofile/config/ConfigurationModel.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.microprofile.config;
+
+import org.eclipse.microprofile.config.Config;
+import org.glassfish.jersey.spi.ExternalConfigurationModel;
+
+import javax.ws.rs.RuntimeType;
+import javax.ws.rs.core.Feature;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * Generic class which implements default properties provider's logic and wraps not used methods from ExtConfig
+ *
+ * @param <CONFIG> type of MP configuration impl
+ */
+public class ConfigurationModel<CONFIG extends Config>
+ implements ExternalConfigurationModel<CONFIG> {
+
+ private final Map<String, Object> properties;
+ private final CONFIG config;
+
+ public ConfigurationModel(CONFIG config) {
+ this.properties = new HashMap<>();
+ this.config = config;
+ }
+
+ @Override
+ public <T> T as(String name, Class<T> clazz) {
+ return config.getValue(name, clazz);
+ }
+
+ @Override
+ public <T> Optional<T> getOptionalProperty(String name, Class<T> clazz) {
+ return config.getOptionalValue(name, clazz);
+ }
+
+ @Override
+ public CONFIG getConfig() {
+ return config;
+ }
+
+ @Override
+ public boolean isProperty(String name) {
+ return properties.isEmpty() ? getValueFromConfig(name) != null : properties.containsKey(name);
+ }
+
+ /**
+ * Allows ancestors to work with native configuration providers
+ *
+ * @param name property name
+ * @return property's value if any
+ */
+ public Object getValueFromConfig(String name){
+ return getConfig().getValue(name, Object.class);
+ }
+
+ @Override
+ public RuntimeType getRuntimeType() {
+
+ return null;
+ }
+
+ @Override
+ public Map<String, Object> getProperties() {
+ if (properties.isEmpty()) {
+ config.getPropertyNames().forEach(c -> properties.put(c, config.getValue(c, String.class)));
+ }
+
+ return properties;
+ }
+
+ @Override
+ public Object getProperty(String name) {
+ return properties.isEmpty() ? getValueFromConfig(name) : properties.get(name);
+ }
+
+ @Override
+ public Collection<String> getPropertyNames() {
+ final Set<String> names = new HashSet<>(properties.keySet());
+ if (names.isEmpty()) {
+ config.getPropertyNames().forEach(names::add);
+ }
+ return names;
+ }
+
+ public ExternalConfigurationModel mergeProperties(Map<String, Object> inputProperties) {
+ if (inputProperties == null || inputProperties.isEmpty()) {
+ return this;
+ }
+ if (properties.isEmpty()) {
+ getProperties();
+ }
+ properties.putAll(inputProperties);
+
+ return this;
+
+ }
+
+ @Override
+ public boolean isEnabled(Feature feature) {
+ return false;
+ }
+
+ @Override
+ public boolean isEnabled(Class<? extends Feature> featureClass) {
+ return false;
+ }
+
+ @Override
+ public boolean isRegistered(Object component) {
+ return false;
+ }
+
+ @Override
+ public boolean isRegistered(Class<?> componentClass) {
+ return false;
+ }
+
+ @Override
+ public Map<Class<?>, Integer> getContracts(Class<?> componentClass) {
+ return null;
+ }
+
+ @Override
+ public Set<Class<?>> getClasses() {
+ return null;
+ }
+
+ @Override
+ public Set<Object> getInstances() {
+ return null;
+ }
+}
diff --git a/ext/microprofile/config/src/main/java/org/glassfish/jersey/microprofile/config/ConfigurationProvider.java b/ext/microprofile/config/src/main/java/org/glassfish/jersey/microprofile/config/ConfigurationProvider.java
new file mode 100644
index 0000000..df50eee
--- /dev/null
+++ b/ext/microprofile/config/src/main/java/org/glassfish/jersey/microprofile/config/ConfigurationProvider.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.microprofile.config;
+
+import org.eclipse.microprofile.config.Config;
+import org.eclipse.microprofile.config.ConfigProvider;
+import org.glassfish.jersey.spi.ExternalConfigurationModel;
+import org.glassfish.jersey.spi.ExternalConfigurationProvider;
+
+import java.util.Map;
+
+public class ConfigurationProvider implements ExternalConfigurationProvider {
+
+
+ private ConfigurationModel<Config> configModel;
+
+ public ConfigurationProvider() {
+
+ configModel = new ConfigurationModel(ConfigProvider.getConfig());
+ }
+
+ @Override
+ public Map<String, Object> getProperties() {
+ return configModel.getProperties();
+ }
+
+ @Override
+ public ExternalConfigurationModel getConfiguration() {
+ return configModel;
+ }
+
+ @Override
+ public ExternalConfigurationModel merge(ExternalConfigurationModel input) {
+ return input == null ? this.configModel : this.configModel.mergeProperties(input.getProperties());
+ }
+}
diff --git a/ext/microprofile/config/src/main/java/org/glassfish/jersey/microprofile/config/package-info.java b/ext/microprofile/config/src/main/java/org/glassfish/jersey/microprofile/config/package-info.java
new file mode 100644
index 0000000..da40c5a
--- /dev/null
+++ b/ext/microprofile/config/src/main/java/org/glassfish/jersey/microprofile/config/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/**
+ * Support for microprofile external configurations in Jersey
+ *
+ * Configuration properties for Jersey (client/server/common) could be passed from different sources
+ * using this implementation
+ *
+ * @since 2.29
+ */
+package org.glassfish.jersey.microprofile.config;
\ No newline at end of file
diff --git a/ext/microprofile/config/src/main/resources/META-INF/services/org.glassfish.jersey.spi.ExternalConfigurationProvider b/ext/microprofile/config/src/main/resources/META-INF/services/org.glassfish.jersey.spi.ExternalConfigurationProvider
new file mode 100644
index 0000000..e7aa15a
--- /dev/null
+++ b/ext/microprofile/config/src/main/resources/META-INF/services/org.glassfish.jersey.spi.ExternalConfigurationProvider
@@ -0,0 +1 @@
+org.glassfish.jersey.microprofile.config.ConfigurationProvider
\ No newline at end of file
diff --git a/ext/microprofile/config/src/test/java/org/glassfish/jersey/microprofile/config/ExternalPropertiesConfigurationFactoryTest.java b/ext/microprofile/config/src/test/java/org/glassfish/jersey/microprofile/config/ExternalPropertiesConfigurationFactoryTest.java
new file mode 100644
index 0000000..2c4e70b
--- /dev/null
+++ b/ext/microprofile/config/src/test/java/org/glassfish/jersey/microprofile/config/ExternalPropertiesConfigurationFactoryTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.microprofile.config;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.glassfish.jersey.test.jetty.JettyTestContainerFactory;
+import org.glassfish.jersey.test.spi.TestContainerException;
+import org.glassfish.jersey.test.spi.TestContainerFactory;
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.inject.Singleton;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+public class ExternalPropertiesConfigurationFactoryTest extends JerseyTest {
+
+ private static final ApplicationPropertiesConfig applicationPropertiesConfig = new ApplicationPropertiesConfig();
+
+ private static class ApplicationPropertiesConfig extends ResourceConfig {
+
+ public ApplicationPropertiesConfig() {
+ register(MyResource.class);
+ }
+ }
+
+ @Path("/")
+ @Singleton
+ public static class MyResource {
+
+
+ @GET
+ @Path("readProperty/{key}")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response readProperties(@PathParam("key") String key) {
+ return Response.ok(String.valueOf(applicationPropertiesConfig.getProperty(key))).build();
+ }
+
+ @GET
+ @Path("getPropertyValue/{key}")
+ @Produces(MediaType.WILDCARD)
+ public Boolean getPropertyValue(@PathParam("key") String key) {
+ final Object value = applicationPropertiesConfig.getProperty(key);
+ return value == null ? null : Boolean.valueOf(value.toString());
+ }
+
+ }
+
+
+ @Override
+ protected Application configure() {
+
+ return applicationPropertiesConfig;
+
+ }
+
+ @Override
+ protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
+ return new JettyTestContainerFactory();
+ }
+
+ @Test
+ public void readConfigTest() {
+
+ final Boolean responce = target("getPropertyValue/{key}")
+ .resolveTemplate("key", "jersey.config.disableMetainfServicesLookup").request().get(Boolean.class);
+ Assert.assertEquals(Boolean.TRUE, responce);
+ }
+
+ @Test
+ public void smallRyeConfigTest() {
+
+ final String responce = target("readProperty/{key}")
+ .resolveTemplate("key", "jersey.config.disableAutoDiscovery").request().get(String.class);
+ Assert.assertEquals("1", responce);
+ }
+
+ @Test
+ public void defaultHeaderValueTest() {
+ final String responce = target("readProperty/{key}")
+ .resolveTemplate("key", "jersey.config.disableJsonProcessing").request().get(String.class);
+ Assert.assertEquals("true", responce);
+ }
+}
\ No newline at end of file
diff --git a/ext/microprofile/config/src/test/resources/META-INF/microprofile-config.properties b/ext/microprofile/config/src/test/resources/META-INF/microprofile-config.properties
new file mode 100644
index 0000000..dbb4a93
--- /dev/null
+++ b/ext/microprofile/config/src/test/resources/META-INF/microprofile-config.properties
@@ -0,0 +1,3 @@
+jersey.config.disableJsonProcessing = true
+jersey.config.disableAutoDiscovery=1
+jersey.config.disableMetainfServicesLookup=true
\ No newline at end of file
diff --git a/ext/pom.xml b/ext/pom.xml
index 672d697..22245f1 100644
--- a/ext/pom.xml
+++ b/ext/pom.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright (c) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2011, 2019 Oracle and/or its affiliates. All rights reserved.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0, which is available at
@@ -44,6 +44,7 @@
<module>cdi</module>
<module>entity-filtering</module>
<module>metainf-services</module>
+ <module>microprofile/config</module>
<module>mvc</module>
<module>mvc-bean-validation</module>
<module>mvc-freemarker</module>
diff --git a/pom.xml b/pom.xml
index cfdf004..ba9780e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2048,6 +2048,8 @@
<weld3.version>3.0.0.Final</weld3.version>
<xerces.version>2.11.0</xerces.version>
<yasson.version>1.0.3</yasson.version>
+ <helidon.version>1.0.3</helidon.version>
+ <config.version>1.2.1</config.version>
<skip.e2e>false</skip.e2e>
</properties>
</project>
diff --git a/tests/integration/microprofile/config/helidon/pom.xml b/tests/integration/microprofile/config/helidon/pom.xml
new file mode 100644
index 0000000..84f0d84
--- /dev/null
+++ b/tests/integration/microprofile/config/helidon/pom.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>project</artifactId>
+ <groupId>org.glassfish.jersey.tests.integration</groupId>
+ <version>2.29-SNAPSHOT</version>
+ <relativePath>../../../pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>helidon-config-webapp</artifactId>
+ <packaging>war</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.glassfish.jersey.tests.integration</groupId>
+ <artifactId>config-webapp</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext</groupId>
+ <artifactId>jersey-mp-config</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.helidon.config</groupId>
+ <artifactId>helidon-config</artifactId>
+ <version>${helidon.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.helidon.microprofile.config</groupId>
+ <artifactId>helidon-microprofile-config</artifactId>
+ <version>${helidon.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework</groupId>
+ <artifactId>jersey-test-framework-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+ <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+ <artifactId>jersey-test-framework-provider-bundle</artifactId>
+ <type>pom</type>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>jetty-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
\ No newline at end of file
diff --git a/tests/integration/microprofile/config/helidon/src/main/java/webapp/WEB-INF/web.xml b/tests/integration/microprofile/config/helidon/src/main/java/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..b27c40e
--- /dev/null
+++ b/tests/integration/microprofile/config/helidon/src/main/java/webapp/WEB-INF/web.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
+ <servlet>
+ <servlet-name>helidonConfigApplicationServlet</servlet-name>
+ <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
+ <init-param>
+ <param-name>javax.ws.rs.Application</param-name>
+ <param-value>org.glassfish.jersey.tests.integration.config.MyApplication</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>helidonConfigApplicationServlet</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+</web-app>
\ No newline at end of file
diff --git a/tests/integration/microprofile/config/helidon/src/test/java/org/glassfish/jersey/tests/integration/config/HelidonConfigApplicationTest.java b/tests/integration/microprofile/config/helidon/src/test/java/org/glassfish/jersey/tests/integration/config/HelidonConfigApplicationTest.java
new file mode 100644
index 0000000..0543f63
--- /dev/null
+++ b/tests/integration/microprofile/config/helidon/src/test/java/org/glassfish/jersey/tests/integration/config/HelidonConfigApplicationTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.integration.config;
+
+
+import org.glassfish.jersey.test.JerseyTest;
+import org.glassfish.jersey.test.grizzly.GrizzlyTestContainerFactory;
+import org.glassfish.jersey.test.spi.TestContainerException;
+import org.glassfish.jersey.test.spi.TestContainerFactory;
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+
+public class HelidonConfigApplicationTest extends JerseyTest {
+
+ @Override
+ protected Application configure() {
+ return new MyApplication();
+ }
+
+ @Override
+ protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
+ return new GrizzlyTestContainerFactory();
+ }
+
+ @Test
+ public void testGetConfigProperty() {
+ final String response = target("/config/getProperty/{name}")
+ .resolveTemplate("name", "jersey.config.disableMetainfServicesLookup")
+ .request(MediaType.TEXT_PLAIN).get(String.class);
+ Assert.assertEquals("true", response);
+ }
+}
\ No newline at end of file
diff --git a/tests/integration/microprofile/config/webapp/pom.xml b/tests/integration/microprofile/config/webapp/pom.xml
new file mode 100644
index 0000000..116ef93
--- /dev/null
+++ b/tests/integration/microprofile/config/webapp/pom.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>project</artifactId>
+ <groupId>org.glassfish.jersey.tests.integration</groupId>
+ <version>2.29-SNAPSHOT</version>
+ <relativePath>../../../pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>config-webapp</artifactId>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.glassfish.jersey.core</groupId>
+ <artifactId>jersey-server</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.bundles</groupId>
+ <artifactId>jaxrs-ri</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>jetty-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
\ No newline at end of file
diff --git a/tests/integration/microprofile/config/webapp/src/main/java/org/glassfish/jersey/tests/integration/config/MyApplication.java b/tests/integration/microprofile/config/webapp/src/main/java/org/glassfish/jersey/tests/integration/config/MyApplication.java
new file mode 100644
index 0000000..1f12a24
--- /dev/null
+++ b/tests/integration/microprofile/config/webapp/src/main/java/org/glassfish/jersey/tests/integration/config/MyApplication.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.integration.config;
+
+import org.glassfish.jersey.server.ResourceConfig;
+
+import javax.ws.rs.ApplicationPath;
+
+@ApplicationPath("/")
+public class MyApplication
+ extends ResourceConfig {
+
+ public MyApplication() {
+ register(new MyResource(this));
+ }
+}
\ No newline at end of file
diff --git a/tests/integration/microprofile/config/webapp/src/main/java/org/glassfish/jersey/tests/integration/config/MyResource.java b/tests/integration/microprofile/config/webapp/src/main/java/org/glassfish/jersey/tests/integration/config/MyResource.java
new file mode 100644
index 0000000..eafefd5
--- /dev/null
+++ b/tests/integration/microprofile/config/webapp/src/main/java/org/glassfish/jersey/tests/integration/config/MyResource.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.integration.config;
+
+
+import org.glassfish.jersey.server.ResourceConfig;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.Response;
+
+@Path("config")
+public class MyResource {
+ private ResourceConfig config;
+
+ public MyResource(ResourceConfig config) {
+ this.config = config;
+ }
+
+ @GET
+ @Path("getProperty/{name}")
+ public Response getProperty(@PathParam("name") String name) {
+ return Response.ok(config.getProperty(name)).build();
+ }
+}
diff --git a/tests/integration/microprofile/config/webapp/src/main/resources/META-INF/microprofile-config.properties b/tests/integration/microprofile/config/webapp/src/main/resources/META-INF/microprofile-config.properties
new file mode 100644
index 0000000..dbb4a93
--- /dev/null
+++ b/tests/integration/microprofile/config/webapp/src/main/resources/META-INF/microprofile-config.properties
@@ -0,0 +1,3 @@
+jersey.config.disableJsonProcessing = true
+jersey.config.disableAutoDiscovery=1
+jersey.config.disableMetainfServicesLookup=true
\ No newline at end of file
diff --git a/tests/integration/pom.xml b/tests/integration/pom.xml
index 65371a7..2aa40ef 100644
--- a/tests/integration/pom.xml
+++ b/tests/integration/pom.xml
@@ -134,6 +134,8 @@
<!-- TODO: conflict in ASM version (too old) of jetty plugin -->
<!--<module>spring4</module>-->
<module>tracing-support</module>
+ <module>microprofile/config/helidon</module>
+ <module>microprofile/config/webapp</module>
</modules>
<profiles>