From 4a7d7394abebe2a960f2160347a5a695b41e245e Mon Sep 17 00:00:00 2001 From: Olivier Hubaut <119926114+olivier-hubaut@users.noreply.github.com> Date: Mon, 19 Aug 2024 10:28:54 +0200 Subject: [PATCH] Add support for selection of protocols (#154) * fix: Retry logic was never applied. The implement of the Call object being stateful, the retry logic was never triggered as an IllegalStateException was bypassing the normal flow. Closes: #144 * feat: Allow specification of supported HTTP protocols. The flagsmith config builder now accepts a list of supported protocols that can be used by the underlying HTTP client. Closes: #153 --------- Co-authored-by: Olivier Hubaut --- .../com/flagsmith/config/FlagsmithConfig.java | 45 ++++++++++++++++--- .../flagsmith/config/FlagsmithConfigTest.java | 15 +++++++ 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/flagsmith/config/FlagsmithConfig.java b/src/main/java/com/flagsmith/config/FlagsmithConfig.java index a99aba72..8a0647c1 100644 --- a/src/main/java/com/flagsmith/config/FlagsmithConfig.java +++ b/src/main/java/com/flagsmith/config/FlagsmithConfig.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.X509TrustManager; import lombok.Getter; @@ -55,13 +56,19 @@ protected FlagsmithConfig(Builder builder) { .writeTimeout(builder.writeTimeoutMillis, TimeUnit.MILLISECONDS) .readTimeout(builder.readTimeoutMillis, TimeUnit.MILLISECONDS); if (builder.sslSocketFactory != null && builder.trustManager != null) { - httpBuilder = httpBuilder.sslSocketFactory(builder.sslSocketFactory, builder.trustManager); + httpBuilder.sslSocketFactory(builder.sslSocketFactory, builder.trustManager); } for (final Interceptor interceptor : builder.interceptors) { - httpBuilder = httpBuilder.addInterceptor(interceptor); + httpBuilder.addInterceptor(interceptor); } if (builder.proxy != null) { - httpBuilder = httpBuilder.proxy(builder.proxy); + httpBuilder.proxy(builder.proxy); + } + if (!builder.supportedProtocols.isEmpty()) { + httpBuilder.protocols( + builder.supportedProtocols.stream() + .map(Protocol::internalProtocol) + .collect(Collectors.toList())); } this.httpClient = httpBuilder.build(); @@ -97,6 +104,7 @@ public static class Builder { private int connectTimeoutMillis = DEFAULT_CONNECT_TIMEOUT_MILLIS; private int writeTimeoutMillis = DEFAULT_WRITE_TIMEOUT_MILLIS; private int readTimeoutMillis = DEFAULT_READ_TIMEOUT_MILLIS; + private List supportedProtocols = new ArrayList<>(); private Retry retries = new Retry(3); private SSLSocketFactory sslSocketFactory; private X509TrustManager trustManager; @@ -216,8 +224,8 @@ public Builder withLocalEvaluation(Boolean localEvaluation) { } /** - * set environment refresh rate with polling manager. Only needed when local - * evaluation is true. + * set environment refresh rate with polling manager. Only needed when local evaluation is + * true. * * @param seconds seconds */ @@ -267,8 +275,35 @@ public Builder withOfflineHandler(IOfflineHandler offlineHandler) { return this; } + /** + * Specify the list of protocols supported for calls to the server. + * @param supportedProtocols the list of supported protocols + * @return + */ + public Builder withSupportedProtocols(List supportedProtocols) { + this.supportedProtocols.clear(); + this.supportedProtocols.addAll(supportedProtocols); + return this; + } + public FlagsmithConfig build() { return new FlagsmithConfig(this); } } + + // This enum prevents leakage of the underlying HTTP client implementation details. + enum Protocol { + HTTP_1_1(okhttp3.Protocol.HTTP_1_1), + HTTP_2(okhttp3.Protocol.HTTP_2); + + private final okhttp3.Protocol protocol; + + Protocol(okhttp3.Protocol protocol) { + this.protocol = protocol; + } + + okhttp3.Protocol internalProtocol() { + return protocol; + } + } } diff --git a/src/test/java/com/flagsmith/config/FlagsmithConfigTest.java b/src/test/java/com/flagsmith/config/FlagsmithConfigTest.java index 7d363ceb..12c4a7d3 100644 --- a/src/test/java/com/flagsmith/config/FlagsmithConfigTest.java +++ b/src/test/java/com/flagsmith/config/FlagsmithConfigTest.java @@ -4,8 +4,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import com.flagsmith.config.FlagsmithConfig.Protocol; import java.net.InetSocketAddress; import java.net.Proxy; +import java.util.Collections; import okhttp3.mock.MockInterceptor; import org.junit.jupiter.api.Test; @@ -50,4 +52,17 @@ public void configTest_multipleInterceptors() { assertEquals(2, flagsmithConfig.getHttpClient().interceptors().size()); } + + @Test + public void configTest_supportedProtocols() { + final FlagsmithConfig defaultFlagsmithConfig = FlagsmithConfig.newBuilder().build(); + + assertEquals(2, defaultFlagsmithConfig.getHttpClient().protocols().size()); + + final FlagsmithConfig customFlagsmithConfig = FlagsmithConfig.newBuilder().withSupportedProtocols( + Collections.singletonList(Protocol.HTTP_1_1)).build(); + + assertEquals(1, customFlagsmithConfig.getHttpClient().protocols().size()); + assertEquals(okhttp3.Protocol.HTTP_1_1, customFlagsmithConfig.getHttpClient().protocols().get(0)); + } }