Skip to content

Commit b33b489

Browse files
authored
Add generic object type configuration support to Configurator (NationalSecurityAgency#1344)
1 parent 6ab6401 commit b33b489

7 files changed

Lines changed: 51 additions & 38 deletions

File tree

src/main/java/emissary/config/Configurator.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.util.List;
55
import java.util.Map;
66
import java.util.Set;
7+
import java.util.function.Function;
78

89
/**
910
* Interface for dealing with configured properties
@@ -174,7 +175,7 @@ public interface Configurator {
174175
long findLongEntry(String param, long dflt);
175176

176177
/**
177-
* Find config entry as an double
178+
* Find config entry as a double
178179
*
179180
* @param param name of config entry
180181
* @param dflt default value when none found
@@ -183,7 +184,7 @@ public interface Configurator {
183184
double findDoubleEntry(String param, double dflt);
184185

185186
/**
186-
* Find config entry as an boolean
187+
* Find config entry as a boolean
187188
*
188189
* @param param name of config entry
189190
* @param dflt default value when none found
@@ -193,14 +194,25 @@ public interface Configurator {
193194

194195

195196
/**
196-
* Find config entry as an boolean
197+
* Find config entry as a boolean
197198
*
198199
* @param param name of config entry
199200
* @param dflt default value when none found
200201
* @return boolean value or dflt when none found or not a boolean
201202
*/
202203
boolean findBooleanEntry(String param, String dflt);
203204

205+
/**
206+
* Find config entry as a generic Object
207+
*
208+
* @param param name of config entry
209+
* @param parser method to turn entry from String into the correct type
210+
* @param dflt default value when none found
211+
* @return object value or dflt when none found or not the right type
212+
* @param <T> the type of the return object
213+
*/
214+
<T> T findObjectEntry(String param, Function<String, T> parser, T dflt);
215+
204216
/**
205217
* Get the names of all entries for this config. This set is not backed by the configuration and any changes to it are
206218
* not relflected in the configuration.

src/main/java/emissary/config/ServiceConfigGuide.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.util.Map;
3434
import java.util.Properties;
3535
import java.util.Set;
36+
import java.util.function.Function;
3637

3738
/**
3839
* This class implements the Configurator interface for services within the Emissary framework.
@@ -1157,6 +1158,25 @@ public boolean findBooleanEntry(final String theParameter, final String dflt) {
11571158
return findBooleanEntry(theParameter, Boolean.parseBoolean(dflt));
11581159
}
11591160

1161+
/**
1162+
* Return the first entry matching the key parameter or the default if no match is found
1163+
*
1164+
* @param theParameter the key to match
1165+
* @param parser method to turn the matched value from a String into the correct type
1166+
* @param dflt the value to use when no matches are found
1167+
* @return the first matching value or the default when none found
1168+
* @param <T> the expected return type
1169+
*/
1170+
@Override
1171+
public <T> T findObjectEntry(String theParameter, Function<String, T> parser, T dflt) {
1172+
final List<String> matchingEntries = findEntries(theParameter);
1173+
if (!matchingEntries.isEmpty()) {
1174+
String el = matchingEntries.get(0);
1175+
return parser.apply(el);
1176+
}
1177+
return dflt;
1178+
}
1179+
11601180
/**
11611181
* Get the value of a parameter that is purported to be numeric
11621182
*

src/main/java/emissary/grpc/pool/ConnectionFactory.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ public ConnectionFactory(String host, int port, Configurator configG,
115115

116116
// Specifies how the client chooses between multiple backend addresses
117117
// e.g. "pick_first" uses the first address only, "round_robin" cycles through all of them for client-side balancing
118-
this.loadBalancingPolicy = LoadBalancingPolicy.getPolicyName(
119-
configG.findStringEntry(GRPC_LOAD_BALANCING_POLICY), LoadBalancingPolicy.ROUND_ROBIN);
118+
this.loadBalancingPolicy = configG.findObjectEntry(
119+
GRPC_LOAD_BALANCING_POLICY, LoadBalancingPolicy::valueOf, LoadBalancingPolicy.ROUND_ROBIN).formattedName();
120120

121121
// Max size (in bytes) for incoming messages and message metadata from the server
122122
this.maxInboundMessageByteSize = configG.findIntEntry(GRPC_MAX_INBOUND_MESSAGE_BYTE_SIZE, 4 << 20); // 4 MiB
@@ -142,8 +142,9 @@ public ConnectionFactory(String host, int port, Configurator configG,
142142
this.poolConfig.setMaxTotal(configG.findIntEntry(GRPC_POOL_MAX_SIZE, 8));
143143

144144
// Order for pool to borrow connections
145-
this.poolConfig.setLifo(PoolRetrievalOrdering.isLifo(
146-
configG.findStringEntry(GRPC_POOL_RETRIEVAL_ORDER), PoolRetrievalOrdering.LIFO));
145+
PoolRetrievalOrdering retrievalOrdering = configG.findObjectEntry(
146+
GRPC_POOL_RETRIEVAL_ORDER, PoolRetrievalOrdering::valueOf, PoolRetrievalOrdering.LIFO);
147+
this.poolConfig.setLifo(retrievalOrdering.equals(PoolRetrievalOrdering.LIFO));
147148

148149
// Whether to validate channels when borrowing from the pool
149150
this.poolConfig.setTestOnBorrow(configG.findBooleanEntry(GRPC_POOL_TEST_BEFORE_BORROW, true));

src/main/java/emissary/grpc/pool/LoadBalancingPolicy.java

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,7 @@
55
public enum LoadBalancingPolicy {
66
ROUND_ROBIN, PICK_FIRST;
77

8-
public static LoadBalancingPolicy getPolicy(String input, LoadBalancingPolicy defaultPolicy) {
9-
if (input == null) {
10-
return defaultPolicy;
11-
}
12-
return LoadBalancingPolicy.valueOf(input.toUpperCase(Locale.ROOT));
13-
}
14-
15-
public static String getPolicyName(String input, LoadBalancingPolicy defaultPolicy) {
16-
return LoadBalancingPolicy
17-
.getPolicy(input, defaultPolicy)
18-
.name()
19-
.toLowerCase(Locale.ROOT);
8+
public String formattedName() {
9+
return name().toLowerCase(Locale.ROOT);
2010
}
2111
}
Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,5 @@
11
package emissary.grpc.pool;
22

3-
import java.util.Locale;
4-
53
public enum PoolRetrievalOrdering {
64
LIFO, FIFO;
7-
8-
public static PoolRetrievalOrdering getOrder(String input, PoolRetrievalOrdering defaultOrdering) {
9-
if (input == null) {
10-
return defaultOrdering;
11-
}
12-
return PoolRetrievalOrdering.valueOf(input.toUpperCase(Locale.ROOT));
13-
}
14-
15-
public static boolean isLifo(String order, PoolRetrievalOrdering defaultOrdering) {
16-
return PoolRetrievalOrdering.getOrder(order, defaultOrdering) == LIFO;
17-
}
18-
19-
public static boolean isFifo(String order, PoolRetrievalOrdering defaultOrdering) {
20-
return PoolRetrievalOrdering.getOrder(order, defaultOrdering) == FIFO;
21-
}
225
}

src/test/java/emissary/config/ServiceConfigGuideTest.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,8 @@ void testEntryPrimitives() throws IOException {
310310
+ "BOOLEANQ = \"BOGUS\"\n" + "SZP = \"123\"\n" + "SZB = \"123b\"\n" + "SZK = \"123k\"\n" + "SZM = \"123m\"\n"
311311
+ "SZG = \"123g\"\n" + "SZT = \"123t\"\n" + "SZQ = \"red balloons\"\n" + "SZ1 = \"111\"\n" + "SZ2 = \"222\"\n"
312312
+ "SZ3 = \"333\"\n" + "SZ4 = \"444\"\n" + "SZ5 = \"555\"\n" + "SZ6 = \"666\"\n" + "SZ7 = \"777\"\n" + "SZ8 = \"888\"\n"
313-
+ "SZ9 = \"999\"\n" + "SZ0 = \"000\"\n" + "STRING = \"chars\"\n" + "LONG2 = 12345678901234").getBytes();
313+
+ "SZ9 = \"999\"\n" + "SZ0 = \"000\"\n" + "STRING = \"chars\"\n" + "LONG2 = 12345678901234\n"
314+
+ "OBJECTM = \"MATCH_VALUE\"\n").getBytes();
314315
final ByteArrayInputStream str = new ByteArrayInputStream(configData);
315316
final Configurator c = ConfigUtil.getConfigInfo(str);
316317
assertEquals(123, c.findIntEntry("INTEGER", 456), "Int entry with def");
@@ -352,6 +353,9 @@ void testEntryPrimitives() throws IOException {
352353
assertEquals(888L, c.findSizeEntry("SZ8", -1L), "Size digit check");
353354
assertEquals(999L, c.findSizeEntry("SZ9", -1L), "Size digit check");
354355
assertEquals(0L, c.findSizeEntry("SZ0", -1L), "Size digit check");
356+
357+
assertEquals(TestType.MATCH_VALUE, c.findObjectEntry("OBJECTM", TestType::valueOf, TestType.DEFAULT_VALUE));
358+
assertEquals(TestType.DEFAULT_VALUE, c.findObjectEntry("OBJECTD", TestType::valueOf, TestType.DEFAULT_VALUE));
355359
}
356360

357361
@Test
@@ -699,4 +703,7 @@ void testFindStringMatchMultiMapOrdered(boolean preserveCase) {
699703

700704
}
701705

706+
private enum TestType {
707+
DEFAULT_VALUE, MATCH_VALUE
708+
}
702709
}

src/test/java/emissary/grpc/pool/ConnectionFactoryTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ void testFifoPoolRetrievalOrderConfig() {
7070
@Test
7171
void testBadLoadBalancingConfig() {
7272
Configurator configT = getDefaultConfigs();
73-
configT.addEntry(ConnectionFactory.GRPC_LOAD_BALANCING_POLICY, "bad_scheduler");
73+
configT.addEntry(ConnectionFactory.GRPC_LOAD_BALANCING_POLICY, "BAD_SCHEDULER");
7474
IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
7575
() -> buildConnectionFactory(configT));
7676
assertEquals("No enum constant emissary.grpc.pool.LoadBalancingPolicy.BAD_SCHEDULER", e.getMessage());

0 commit comments

Comments
 (0)