Skip to content
Open
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
Expand Up @@ -92,6 +92,10 @@ public interface PartialServiceConfiguration {
@JsonAlias("proxy-configuration")
Optional<ProxyConfiguration> proxyConfiguration();

/** Reuse policy for connection pooling. If absent, uses client implementation default. */
@JsonAlias("pool-reuse-policy")
Optional<PoolReusePolicy> poolReusePolicy();
Comment on lines +95 to +97
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Connection pools are often managed by the underlying HTTP client implementation. It's not clear to me that all client implementations we will ever use will allow us to configure the connection pool in this way. Does the Apache client used by Dialogue support this? At they very least, I'd like to see functioning CJR and Dialogue PRs before merging this.


static PartialServiceConfiguration of(List<String> uris, Optional<SslConfiguration> sslConfig) {
return PartialServiceConfiguration.builder()
.uris(uris)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* (c) Copyright 2025 Palantir Technologies Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.palantir.conjure.java.api.config.service;

public enum PoolReusePolicy {

/** Re-use as few connections as possible, making it possible for connections to become idle and expire. */
LIFO,

/** Re-use all connections equally, preventing them from becoming idle and expiring. */
FIFO,
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ public interface ServiceConfiguration {

Optional<ProxyConfiguration> proxy();

Optional<PoolReusePolicy> poolReusePolicy();

static ImmutableServiceConfiguration.Builder builder() {
return new Builder();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ private ServiceConfiguration propagateDefaults(String serviceName, PartialServic
.enableHttp2(orElse(partial.enableHttp2(), services.defaultEnableHttp2()))
.fallbackToCommonNameVerification(orElse(
partial.fallbackToCommonNameVerification(), services.defaultFallbackToCommonNameVerification()))
.poolReusePolicy(orElse(partial.poolReusePolicy(), services.defaultPoolReusePolicy()))
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ public abstract class ServicesConfigBlock {
@JsonAlias("fallback-to-common-name-verification")
public abstract Optional<Boolean> defaultFallbackToCommonNameVerification();

/** Default global pool reuse policy. */
@JsonProperty("poolReusePolicy")
@JsonAlias("pool-reuse-policy")
public abstract Optional<PoolReusePolicy> defaultPoolReusePolicy();

public static ServicesConfigBlock empty() {
return ImmutableServicesConfigBlock.of();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ public void serDe() throws Exception {
+ "\"maxNumRetries\":5,\"backoffSlotSize\":\"1 day\","
+ "\"enableGcmCipherSuites\":null,\"enableHttp2\":null,\"fallbackToCommonNameVerification\":null,"
+ "\"proxyConfiguration\":{\"hostAndPort\":\"host:80\",\"credentials\":null,"
+ "\"type\":\"HTTP\"}}";
+ "\"type\":\"HTTP\"},\"poolReusePolicy\":null}";
String kebabCase = "{\"api-token\":\"bearerToken\",\"security\":"
+ "{\"trust-store-path\":\"truststore.jks\",\"trust-store-type\":\"JKS\",\"key-store-path\":null,"
+ "\"key-store-password\":null,\"key-store-type\":\"JKS\",\"key-store-key-alias\":null},"
+ "\"connect-timeout\":\"1 day\",\"read-timeout\":\"1 day\",\"write-timeout\":\"1 day\","
+ "\"max-num-retries\":5,\"backoff-slot-size\":\"1 day\","
+ "\"uris\":[\"uri1\"],\"proxy-configuration\":{\"host-and-port\":\"host:80\",\"credentials\":null},"
+ "\"enable-gcm-cipher-suites\":null,\"enable-http2\":null,"
+ "\"fallback-to-common-name-verification\":null}";
+ "\"fallback-to-common-name-verification\":null,\"pool-reuse-policy\":null}";

assertThat(mapper.writeValueAsString(serialized)).isEqualTo(camelCase);
assertThat(mapper.readValue(camelCase, PartialServiceConfiguration.class))
Expand All @@ -74,12 +74,12 @@ public void serDe_optional() throws Exception {
String camelCase = "{\"apiToken\":null,\"security\":null,\"uris\":[],\"connectTimeout\":null,"
+ "\"readTimeout\":null,\"writeTimeout\":null,\"maxNumRetries\":null,\"backoffSlotSize\":null,"
+ "\"enableGcmCipherSuites\":null,\"enableHttp2\":null,\"fallbackToCommonNameVerification\":null,"
+ "\"proxyConfiguration\":null}";
+ "\"proxyConfiguration\":null,\"poolReusePolicy\":null}";
String kebabCase = "{\"api-token\":null,\"security\":null,\"connect-timeout\":null,"
+ "\"read-timeout\":null,\"write-timeout\":null,\"max-num-retries\":null,\"backoff-slot-size\":null,"
+ "\"enable-gcm-cipher-suites\":null,\"enable-http2\":null,"
+ "\"fallback-to-common-name-verification\":null,"
+ "\"uris\":[],\"proxy-configuration\":null}";
+ "\"uris\":[],\"proxy-configuration\":null,\"pool-reuse-policy\":null}";

assertThat(ObjectMappers.newClientObjectMapper().writeValueAsString(serialized))
.isEqualTo(camelCase);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ public final class ServiceConfigurationFactoryTests {
private static final boolean enableGcm = false;
private static final boolean defaultFallbackToCn = true;
private static final boolean fallbackToCn = false;
private static final PoolReusePolicy poolReusePolicy = PoolReusePolicy.FIFO;
private static final PoolReusePolicy defaultPoolReusePolicy = PoolReusePolicy.LIFO;

private final ObjectMapper mapper = new ObjectMapper(new YAMLFactory())
.registerModule(new ShimJdk7Module())
Expand Down Expand Up @@ -136,12 +138,14 @@ public void testServiceSpecificConfigTrumpsDefaultConfig() {
.enableGcmCipherSuites(enableGcm)
.fallbackToCommonNameVerification(fallbackToCn)
.proxyConfiguration(proxy)
.poolReusePolicy(poolReusePolicy)
.build();
ServicesConfigBlock services = ServicesConfigBlock.builder()
.putAllServices(ImmutableMap.of("service1", partial))
.defaultSecurity(defaultSecurity)
.defaultApiToken(defaultApiToken)
.defaultProxyConfiguration(defaultProxyConfiguration)
.defaultPoolReusePolicy(defaultPoolReusePolicy)
.defaultConnectTimeout(defaultConnectTimeout)
.defaultReadTimeout(defaultReadTimeout)
.defaultWriteTimeout(defaultWriteTimeout)
Expand All @@ -163,6 +167,7 @@ public void testServiceSpecificConfigTrumpsDefaultConfig() {
.enableGcmCipherSuites(enableGcm)
.fallbackToCommonNameVerification(fallbackToCn)
.proxy(proxy)
.poolReusePolicy(poolReusePolicy)
.build();

assertThat(service).isEqualTo(expected);
Expand Down Expand Up @@ -198,18 +203,19 @@ public void serDe() throws Exception {
+ "{\"service\":{\"apiToken\":null,\"security\":null,\"uris\":[\"uri\"],\"connectTimeout\":null,"
+ "\"readTimeout\":null,\"writeTimeout\":null,\"maxNumRetries\":null,\"backoffSlotSize\":null,"
+ "\"enableGcmCipherSuites\":null,\"enableHttp2\":null,\"fallbackToCommonNameVerification\":null,"
+ "\"proxyConfiguration\":null}},\"proxyConfiguration\":"
+ "{\"hostAndPort\":\"host:80\",\"credentials\":null,\"type\":\"HTTP\"},\"connectTimeout\":\"1 day\","
+ "\"proxyConfiguration\":null,\"poolReusePolicy\":null}},\"proxyConfiguration\":{\"hostAndPort\":"
+ "\"host:80\",\"credentials\":null,\"type\":\"HTTP\"},\"connectTimeout\":\"1 day\","
+ "\"readTimeout\":\"1 day\",\"writeTimeout\":\"1 day\",\"backoffSlotSize\":\"1 day\","
+ "\"enableGcmCipherSuites\":null,\"enableHttp2\":null,\"fallbackToCommonNameVerification\":null}";
+ "\"enableGcmCipherSuites\":null,\"enableHttp2\":null,\"fallbackToCommonNameVerification\":null,"
+ "\"poolReusePolicy\":null}";
String kebabCase = "{\"api-token\":\"bearerToken\",\"security\":"
+ "{\"trust-store-path\":\"truststore.jks\",\"trust-store-type\":\"JKS\",\"key-store-path\":null,"
+ "\"key-store-password\":null,\"key-store-type\":\"JKS\",\"key-store-key-alias\":null},\"services\":"
+ "{\"service\":{\"apiToken\":null,\"security\":null,\"connect-timeout\":null,\"read-timeout\":null,"
+ "\"write-timeout\":null,\"max-num-retries\":null,\"backoffSlotSize\":null,\"uris\":[\"uri\"],"
+ "\"enable-gcm-cipher-suites\":null,\"enable-http2\":null,"
+ "\"fallback-to-common-name-verification\":null,"
+ "\"proxy-configuration\":null}},\"proxy-configuration\":"
+ "\"proxy-configuration\":null,\"pool-reuse-policy\":null}},\"proxy-configuration\":"
+ "{\"host-and-port\":\"host:80\",\"credentials\":null},\"connect-timeout\":\"1 day\","
+ "\"read-timeout\":\"1 day\",\"write-timeout\":\"1 day\",\"backoff-slot-size\":\"1 day\"}";

Expand All @@ -227,11 +233,11 @@ public void serDe_optional() throws Exception {
String serializedCamelCase = "{\"apiToken\":null,\"security\":null,\"services\":{},"
+ "\"proxyConfiguration\":null,\"connectTimeout\":null,\"readTimeout\":null,\"writeTimeout\":null,"
+ "\"backoffSlotSize\":null,\"enableGcmCipherSuites\":null,\"enableHttp2\":null,"
+ "\"fallbackToCommonNameVerification\":null}";
+ "\"fallbackToCommonNameVerification\":null,\"poolReusePolicy\":null}";
String serializedKebabCase = "{\"api-token\":null,\"security\":null,\"services\":{},"
+ "\"proxy-configuration\":null,\"connect-timeout\":null,\"read-timeout\":null,\"write-timeout\":null,"
+ "\"backoff-slot-size\":null,\"enable-gcm-cipher-suites\":null,\"enable-http2\":null,"
+ "\"fallback-to-common-name-verification\":null}";
+ "\"fallback-to-common-name-verification\":null,\"pool-reuse-policy\":null}";

assertThat(ObjectMappers.newClientObjectMapper().writeValueAsString(deserialized))
.isEqualTo(serializedCamelCase);
Expand Down