Skip to content

Commit 2299c0b

Browse files
jansupolsenivam
authored andcommitted
Allow for passing in additional property files to configure additional configs
Signed-off-by: jansupol <jan.supol@oracle.com>
1 parent 9dbc693 commit 2299c0b

File tree

9 files changed

+255
-105
lines changed

9 files changed

+255
-105
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0, which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the
10+
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11+
* version 2 with the GNU Classpath Exception, which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
*/
16+
17+
package org.glassfish.jersey.internal.config;
18+
19+
import org.glassfish.jersey.spi.ExternalConfigurationModel;
20+
import org.glassfish.jersey.spi.ExternalConfigurationProvider;
21+
22+
import java.util.Map;
23+
24+
public class ExternalConfigurationProviderImpl implements ExternalConfigurationProvider {
25+
26+
protected final ExternalConfigurationModel<?> model;
27+
28+
protected ExternalConfigurationProviderImpl(ExternalConfigurationModel<?> model) {
29+
this.model = model;
30+
}
31+
32+
@Override
33+
public Map<String, Object> getProperties() {
34+
return model.getProperties();
35+
}
36+
37+
@Override
38+
public ExternalConfigurationModel getConfiguration() {
39+
return model;
40+
}
41+
42+
@Override
43+
public ExternalConfigurationModel merge(ExternalConfigurationModel input) {
44+
return input == null ? model : model.mergeProperties(input.getProperties());
45+
}
46+
}

core-common/src/main/java/org/glassfish/jersey/internal/config/ExternalPropertiesConfigurationFactory.java

+28-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2022 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -32,6 +32,7 @@
3232
import java.util.Set;
3333
import java.util.SortedSet;
3434
import java.util.TreeSet;
35+
import java.util.function.BiConsumer;
3536

3637
/**
3738
* Factory for external properties providers
@@ -50,12 +51,20 @@ public class ExternalPropertiesConfigurationFactory {
5051
* @return map of merged properties from all found/plugged providers
5152
*/
5253
static Map<String, Object> readExternalPropertiesMap() {
54+
return readExternalPropertiesMap(EXTERNAL_CONFIGURATION_PROVIDERS);
55+
}
5356

54-
final ExternalConfigurationProvider provider = mergeConfigs(EXTERNAL_CONFIGURATION_PROVIDERS);
57+
/**
58+
* Map of merged properties from all given providers
59+
*
60+
* @param externalConfigProviders list of providers to use
61+
* @return map of merged properties from {@code externalConfigProviders} providers
62+
*/
63+
private static Map<String, Object> readExternalPropertiesMap(List<ExternalConfigurationProvider> externalConfigProviders) {
64+
final ExternalConfigurationProvider provider = mergeConfigs(externalConfigProviders);
5565
return provider == null ? Collections.emptyMap() : provider.getProperties();
5666
}
5767

58-
5968
/**
6069
* Input Configurable object shall be provided in order to be filled with all found properties
6170
*
@@ -64,14 +73,28 @@ static Map<String, Object> readExternalPropertiesMap() {
6473
*/
6574

6675
public static boolean configure(Configurable config) {
76+
return configure((k, v) -> config.property(k, v), EXTERNAL_CONFIGURATION_PROVIDERS);
77+
}
6778

79+
/**
80+
* Key Value pairs gathered by {@link ExternalConfigurationProvider}s are applied to a given {@code config}. The
81+
* {@code config} can be for instance {@code (k,v) -> configurable.property(k,v)} of a
82+
* {@link Configurable#property(String, Object) Configurable structure}, or {@code (k,v) -> properties.put(k,v)} of a
83+
* {@link java.util.Properties#put(Object, Object) Properties structure}.
84+
*
85+
* @param config
86+
* @param externalConfigurationProviders the providers to grab the properties from it.
87+
* @return true if configured false otherwise.
88+
*/
89+
public static boolean configure(BiConsumer<String, Object> config,
90+
List<ExternalConfigurationProvider> externalConfigurationProviders) {
6891
if (config instanceof ExternalConfigurationModel) {
6992
return false; //shall not configure itself
7093
}
7194

72-
final Map<String, Object> properties = readExternalPropertiesMap();
95+
final Map<String, Object> properties = readExternalPropertiesMap(externalConfigurationProviders);
7396

74-
properties.forEach((k, v) -> config.property(k, v));
97+
properties.forEach((k, v) -> config.accept(k, v));
7598

7699
return true;
77100
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) 2019, 2022 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0, which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the
10+
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11+
* version 2 with the GNU Classpath Exception, which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
*/
16+
17+
package org.glassfish.jersey.internal.config;
18+
19+
import java.util.Arrays;
20+
import java.util.List;
21+
22+
class JerseySystemPropertiesConfigurationModel extends SystemPropertiesConfigurationModel {
23+
24+
static final List<String> PROPERTY_CLASSES = Arrays.asList(
25+
"org.glassfish.jersey.CommonProperties",
26+
"org.glassfish.jersey.ExternalProperties",
27+
"org.glassfish.jersey.server.ServerProperties",
28+
"org.glassfish.jersey.client.ClientProperties",
29+
"org.glassfish.jersey.servlet.ServletProperties",
30+
"org.glassfish.jersey.message.MessageProperties",
31+
"org.glassfish.jersey.apache.connector.ApacheClientProperties",
32+
"org.glassfish.jersey.helidon.connector.HelidonClientProperties",
33+
"org.glassfish.jersey.jdk.connector.JdkConnectorProperties",
34+
"org.glassfish.jersey.jetty.connector.JettyClientProperties",
35+
"org.glassfish.jersey.netty.connector.NettyClientProperties",
36+
"org.glassfish.jersey.media.multipart.MultiPartProperties",
37+
"org.glassfish.jersey.server.oauth1.OAuth1ServerProperties");
38+
39+
JerseySystemPropertiesConfigurationModel() {
40+
super(PROPERTY_CLASSES);
41+
}
42+
}

core-common/src/main/java/org/glassfish/jersey/internal/config/SystemPropertiesConfigurationModel.java

+56-46
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2022 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -27,6 +27,7 @@
2727
import java.util.Map;
2828
import java.util.Optional;
2929
import java.util.Set;
30+
import java.util.concurrent.atomic.AtomicBoolean;
3031
import java.util.function.Function;
3132
import java.util.logging.Logger;
3233

@@ -39,57 +40,58 @@
3940
import org.glassfish.jersey.internal.util.ReflectionHelper;
4041
import org.glassfish.jersey.spi.ExternalConfigurationModel;
4142

43+
/**
44+
* The External Configuration Model that supports {@code System} properties. The properties are listed in a property class
45+
* in a form of {@code public static final String} property name. The {@code String} value of the property name is searched
46+
* among the {@code System} properties. The property scan is performed only when
47+
* {@link CommonProperties#ALLOW_SYSTEM_PROPERTIES_PROVIDER} is set to {@code true}.
48+
*/
49+
public class SystemPropertiesConfigurationModel implements ExternalConfigurationModel<Void> {
4250

43-
class SystemPropertiesConfigurationModel implements ExternalConfigurationModel<Void> {
44-
45-
private static final Logger log = Logger.getLogger(SystemPropertiesConfigurationModel.class.getName());
46-
static final List<String> PROPERTY_CLASSES = Arrays.asList(
47-
"org.glassfish.jersey.ExternalProperties",
48-
"org.glassfish.jersey.server.ServerProperties",
49-
"org.glassfish.jersey.client.ClientProperties",
50-
"org.glassfish.jersey.servlet.ServletProperties",
51-
"org.glassfish.jersey.message.MessageProperties",
52-
"org.glassfish.jersey.apache.connector.ApacheClientProperties",
53-
"org.glassfish.jersey.helidon.connector.HelidonClientProperties",
54-
"org.glassfish.jersey.jdk.connector.JdkConnectorProperties",
55-
"org.glassfish.jersey.jetty.connector.JettyClientProperties",
56-
"org.glassfish.jersey.netty.connector.NettyClientProperties",
57-
"org.glassfish.jersey.media.multipart.MultiPartProperties",
58-
"org.glassfish.jersey.server.oauth1.OAuth1ServerProperties");
59-
51+
private static final Logger LOGGER = Logger.getLogger(SystemPropertiesConfigurationModel.class.getName());
6052

6153
private static final Map<Class, Function> converters = new HashMap<>();
54+
private final Map<String, Object> properties = new HashMap<>();
55+
private final AtomicBoolean gotProperties = new AtomicBoolean(false);
56+
private final List<String> propertyClassNames;
6257
static {
6358
converters.put(String.class, (Function<String, String>) s -> s);
6459
converters.put(Integer.class, (Function<String, Integer>) s -> Integer.valueOf(s));
60+
converters.put(Long.class, (Function<String, Long>) s -> Long.parseLong(s));
6561
converters.put(Boolean.class, (Function<String, Boolean>) s -> s.equalsIgnoreCase("1")
6662
? true
6763
: Boolean.parseBoolean(s));
6864
}
6965

70-
private String getSystemProperty(String name) {
71-
return AccessController.doPrivileged(PropertiesHelper.getSystemProperty(name));
66+
/**
67+
* Create new {@link ExternalConfigurationModel} for properties defined by classes in {@code propertyClassNames} list.
68+
* @param propertyClassNames List of property defining class names.
69+
*/
70+
public SystemPropertiesConfigurationModel(List<String> propertyClassNames) {
71+
this.propertyClassNames = propertyClassNames;
72+
}
73+
74+
protected List<String> getPropertyClassNames() {
75+
return propertyClassNames;
7276
}
7377

7478
@Override
7579
public <T> T as(String name, Class<T> clazz) {
7680
if (converters.get(clazz) == null) {
7781
throw new IllegalArgumentException("Unsupported class type");
7882
}
79-
return (name != null && clazz != null && isProperty(name))
83+
return (name != null && clazz != null && hasProperty(name))
8084
? clazz.cast(converters.get(clazz).apply(getSystemProperty(name)))
8185
: null;
8286
}
83-
84-
85-
8687
@Override
8788
public <T> Optional<T> getOptionalProperty(String name, Class<T> clazz) {
8889
return Optional.of(as(name, clazz));
8990
}
9091

9192
@Override
9293
public ExternalConfigurationModel mergeProperties(Map<String, Object> inputProperties) {
94+
inputProperties.forEach((k, v) -> properties.put(k, v));
9395
return this;
9496
}
9597

@@ -100,11 +102,11 @@ public Void getConfig() {
100102

101103
@Override
102104
public boolean isProperty(String name) {
103-
return Optional.ofNullable(
104-
AccessController.doPrivileged(
105-
PropertiesHelper.getSystemProperty(name)
106-
)
107-
).isPresent();
105+
String property = getSystemProperty(name);
106+
return property != null && (
107+
"0".equals(property) || "1".equals(property)
108+
|| "true".equalsIgnoreCase(property) || "false".equalsIgnoreCase(property)
109+
);
108110
}
109111

110112
@Override
@@ -114,30 +116,29 @@ public RuntimeType getRuntimeType() {
114116

115117
@Override
116118
public Map<String, Object> getProperties() {
117-
final Map<String, Object> result = new HashMap<>();
118-
119119
final Boolean allowSystemPropertiesProvider = as(
120120
CommonProperties.ALLOW_SYSTEM_PROPERTIES_PROVIDER, Boolean.class
121121
);
122122
if (!Boolean.TRUE.equals(allowSystemPropertiesProvider)) {
123-
log.finer(LocalizationMessages.WARNING_PROPERTIES());
124-
return result;
123+
LOGGER.finer(LocalizationMessages.WARNING_PROPERTIES());
124+
return properties;
125125
}
126126

127-
try {
128-
AccessController.doPrivileged(PropertiesHelper.getSystemProperties())
129-
.forEach((k, v) -> result.put(String.valueOf(k), v));
130-
} catch (SecurityException se) {
131-
log.warning(LocalizationMessages.SYSTEM_PROPERTIES_WARNING());
132-
return getExpectedSystemProperties();
127+
if (gotProperties.compareAndSet(false, true)) {
128+
try {
129+
AccessController.doPrivileged(PropertiesHelper.getSystemProperties())
130+
.forEach((k, v) -> properties.put(String.valueOf(k), v));
131+
} catch (SecurityException se) {
132+
LOGGER.warning(LocalizationMessages.SYSTEM_PROPERTIES_WARNING());
133+
return getExpectedSystemProperties();
134+
}
133135
}
134-
return result;
136+
return properties;
135137
}
136138

137139
private Map<String, Object> getExpectedSystemProperties() {
138140
final Map<String, Object> result = new HashMap<>();
139-
mapFieldsToProperties(result, CommonProperties.class);
140-
for (String propertyClass : PROPERTY_CLASSES) {
141+
for (String propertyClass : getPropertyClassNames()) {
141142
mapFieldsToProperties(result,
142143
AccessController.doPrivileged(
143144
ReflectionHelper.classForNamePA(propertyClass)
@@ -148,7 +149,7 @@ private Map<String, Object> getExpectedSystemProperties() {
148149
return result;
149150
}
150151

151-
private <T> void mapFieldsToProperties(Map<String, Object> properties, Class<T> clazz) {
152+
private static <T> void mapFieldsToProperties(Map<String, Object> properties, Class<T> clazz) {
152153
if (clazz == null) {
153154
return;
154155
}
@@ -170,25 +171,29 @@ private <T> void mapFieldsToProperties(Map<String, Object> properties, Class<T>
170171
}
171172
}
172173

173-
private String getPropertyNameByField(Field field) {
174+
private static String getPropertyNameByField(Field field) {
174175
return AccessController.doPrivileged((PrivilegedAction<String>) () -> {
175176
try {
176177
return (String) field.get(null);
177178
} catch (IllegalAccessException e) {
178-
log.warning(e.getLocalizedMessage());
179+
LOGGER.warning(e.getLocalizedMessage());
179180
}
180181
return null;
181182
});
182183
}
183184

185+
private static String getSystemProperty(String name) {
186+
return AccessController.doPrivileged(PropertiesHelper.getSystemProperty(name));
187+
}
188+
184189
@Override
185190
public Object getProperty(String name) {
186191
return getSystemProperty(name);
187192
}
188193

189194
@Override
190195
public Collection<String> getPropertyNames() {
191-
return PropertiesHelper.getSystemProperties().run().stringPropertyNames();
196+
return AccessController.doPrivileged(PropertiesHelper.getSystemProperties()).stringPropertyNames();
192197
}
193198

194199
@Override
@@ -225,4 +230,9 @@ public Set<Class<?>> getClasses() {
225230
public Set<Object> getInstances() {
226231
return null;
227232
}
233+
234+
// Jersey 2.x
235+
private boolean hasProperty(String name) {
236+
return getProperty(name) != null;
237+
}
228238
}

0 commit comments

Comments
 (0)