Skip to content

Commit 8ec27d5

Browse files
chriswkCopilot
andauthored
feat: Added gzip content handling for features requests (#329)
* feat: Added gzip content handling for features requests fixes #328 * Update src/main/java/io/getunleash/repository/HttpFeatureFetcher.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix(nit): Removed unnecessary comments --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 0b17c96 commit 8ec27d5

File tree

3 files changed

+55
-36
lines changed

3 files changed

+55
-36
lines changed

pom.xml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,20 +115,20 @@
115115
<dependency>
116116
<groupId>org.assertj</groupId>
117117
<artifactId>assertj-core</artifactId>
118-
<version>3.26.3</version>
118+
<version>3.27.6</version>
119119
<scope>test</scope>
120120
</dependency>
121121

122122
<dependency>
123123
<groupId>org.mockito</groupId>
124124
<artifactId>mockito-core</artifactId>
125-
<version>4.8.1</version>
125+
<version>5.20.0</version>
126126
<scope>test</scope>
127127
</dependency>
128128
<dependency>
129129
<groupId>com.github.tomakehurst</groupId>
130130
<artifactId>wiremock-jre8</artifactId>
131-
<version>2.35.2</version>
131+
<version>3.0.1</version>
132132
<scope>test</scope>
133133
</dependency>
134134
<dependency>
@@ -177,6 +177,13 @@
177177
<groupId>org.apache.maven.plugins</groupId>
178178
<artifactId>maven-dependency-plugin</artifactId>
179179
<version>3.8.1</version>
180+
<executions>
181+
<execution>
182+
<goals>
183+
<goal>properties</goal>
184+
</goals>
185+
</execution>
186+
</executions>
180187
</plugin>
181188
<plugin>
182189
<groupId>org.apache.maven.plugins</groupId>
@@ -219,7 +226,7 @@
219226
<plugin>
220227
<groupId>org.jacoco</groupId>
221228
<artifactId>jacoco-maven-plugin</artifactId>
222-
<version>0.8.12</version>
229+
<version>0.8.13</version>
223230
<executions>
224231
<execution>
225232
<id>prepare-agent</id>
@@ -410,6 +417,9 @@
410417
<groupId>org.apache.maven.plugins</groupId>
411418
<artifactId>maven-surefire-plugin</artifactId>
412419
<version>3.5.2</version>
420+
<configuration>
421+
<argLine>@{argLine} -javaagent:${org.mockito:mockito-core:jar}</argLine>
422+
</configuration>
413423
</plugin>
414424
</plugins>
415425
</reporting>

src/main/java/io/getunleash/repository/HttpFeatureFetcher.java

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,13 @@
55
import io.getunleash.UnleashException;
66
import io.getunleash.event.ClientFeaturesResponse;
77
import io.getunleash.util.UnleashConfig;
8-
import java.io.BufferedReader;
9-
import java.io.IOException;
10-
import java.io.InputStream;
11-
import java.io.InputStreamReader;
8+
import java.io.*;
129
import java.net.HttpURLConnection;
1310
import java.net.URL;
1411
import java.nio.charset.StandardCharsets;
1512
import java.util.Optional;
1613
import java.util.stream.Collectors;
14+
import java.util.zip.GZIPInputStream;
1715
import org.slf4j.Logger;
1816
import org.slf4j.LoggerFactory;
1917

@@ -59,15 +57,30 @@ private ClientFeaturesResponse getFeatureResponse(
5957

6058
if (responseCode < 300) {
6159
etag = Optional.ofNullable(request.getHeaderField("ETag"));
62-
63-
try (BufferedReader reader =
64-
new BufferedReader(
65-
new InputStreamReader(
66-
(InputStream) request.getContent(), StandardCharsets.UTF_8))) {
67-
68-
String clientFeatures = reader.lines().collect(Collectors.joining("\n"));
69-
70-
return ClientFeaturesResponse.updated(clientFeatures);
60+
String contentEncoding = request.getHeaderField("Content-Encoding");
61+
if ("gzip".equalsIgnoreCase(contentEncoding)) {
62+
try (GZIPInputStream stream = new GZIPInputStream(request.getInputStream())) {
63+
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
64+
byte[] buffer = new byte[1024];
65+
int len;
66+
while ((len = stream.read(buffer)) != -1) {
67+
outputStream.write(buffer, 0, len);
68+
}
69+
String clientFeatures = outputStream.toString(StandardCharsets.UTF_8);
70+
return ClientFeaturesResponse.updated(clientFeatures);
71+
}
72+
}
73+
} else {
74+
try (BufferedReader reader =
75+
new BufferedReader(
76+
new InputStreamReader(
77+
(InputStream) request.getContent(),
78+
StandardCharsets.UTF_8))) {
79+
80+
String clientFeatures = reader.lines().collect(Collectors.joining("\n"));
81+
82+
return ClientFeaturesResponse.updated(clientFeatures);
83+
}
7184
}
7285
} else if (followRedirect
7386
&& (responseCode == HttpURLConnection.HTTP_MOVED_TEMP
@@ -114,6 +127,7 @@ private HttpURLConnection openConnection(URL url) throws IOException {
114127
connection.setReadTimeout((int) this.config.getFetchTogglesReadTimeout().toMillis());
115128
connection.setRequestProperty("Accept", "application/json");
116129
connection.setRequestProperty("Content-Type", "application/json");
130+
connection.setRequestProperty("Accept-Encoding", "gzip,deflate");
117131
UnleashConfig.setRequestProperties(connection, this.config);
118132

119133
etag.ifPresent(val -> connection.setRequestProperty("If-None-Match", val));

src/test/java/io/getunleash/HotReloadSchedulerReuseTest.java

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,23 @@
11
package io.getunleash;
22

3-
import io.getunleash.util.UnleashConfig;
4-
import org.junit.jupiter.api.*;
3+
import static org.assertj.core.api.Assertions.assertThat;
54

5+
import io.getunleash.util.UnleashConfig;
66
import java.lang.reflect.Field;
77
import java.util.concurrent.ScheduledThreadPoolExecutor;
8-
9-
import static org.assertj.core.api.Assertions.assertThat;
8+
import org.junit.jupiter.api.*;
109

1110
class HotReloadSchedulerReuseTest {
1211

13-
1412
private UnleashConfig baseConfig() {
1513
return UnleashConfig.builder()
16-
.appName("hot-reload-test-app")
17-
.instanceId("A")
18-
.unleashAPI("http://localhost") // never hit
19-
.synchronousFetchOnInitialisation(false)
20-
.fetchTogglesInterval(100)
21-
.sendMetricsInterval(100)
22-
.build();
14+
.appName("hot-reload-test-app")
15+
.instanceId("A")
16+
.unleashAPI("http://localhost") // never hit
17+
.synchronousFetchOnInitialisation(false)
18+
.fetchTogglesInterval(100)
19+
.sendMetricsInterval(100)
20+
.build();
2321
}
2422

2523
private ScheduledThreadPoolExecutor currentGlobalExecutor() throws Exception {
@@ -37,9 +35,7 @@ private ScheduledThreadPoolExecutor currentGlobalExecutor() throws Exception {
3735
@Test
3836
void secondClientDoesNotReuseSchedulerExecutor() throws Exception {
3937
// 1) Create first client; let it schedule background tasks
40-
DefaultUnleash first = new DefaultUnleash(
41-
baseConfig()
42-
);
38+
DefaultUnleash first = new DefaultUnleash(baseConfig());
4339

4440
// Let it initialize/schedule
4541
Thread.sleep(150);
@@ -57,11 +53,10 @@ void secondClientDoesNotReuseSchedulerExecutor() throws Exception {
5753
assertThat(execAfterShutdown).isNull();
5854

5955
// 3) "Reloaded app": create a second client in the same JVM (statics still around)
60-
DefaultUnleash second = new DefaultUnleash(
61-
baseConfig()
62-
);
56+
DefaultUnleash second = new DefaultUnleash(baseConfig());
6357

64-
// 4) Assert that the second client creates a fresh executor (not reusing the terminated one)
58+
// 4) Assert that the second client creates a fresh executor (not reusing the terminated
59+
// one)
6560
ScheduledThreadPoolExecutor execUsedBySecond = currentGlobalExecutor();
6661
assertThat(execUsedBySecond).isNotNull();
6762
assertThat(execUsedBySecond.isShutdown()).isFalse(); // it's a new one

0 commit comments

Comments
 (0)