diff --git a/CHANGES.txt b/CHANGES.txt index 5018ca452..5a060d81e 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,6 @@ +4.10.1 (Nov 9, 2023) +- Fixed handler for response http headers. + 4.10.0 (Nov 2, 2023) - Added support for Flag Sets on the SDK, which enables grouping feature flags and interacting with the group rather than individually (more details in our documentation): - Added new variations of the get treatment methods to support evaluating flags in given flag set/s. diff --git a/client/pom.xml b/client/pom.xml index 26483d47b..131bfe230 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -5,7 +5,7 @@ io.split.client java-client-parent - 4.10.0 + 4.10.1 java-client jar diff --git a/client/src/main/java/io/split/client/HttpSegmentChangeFetcher.java b/client/src/main/java/io/split/client/HttpSegmentChangeFetcher.java index ef676de6e..84bf09509 100644 --- a/client/src/main/java/io/split/client/HttpSegmentChangeFetcher.java +++ b/client/src/main/java/io/split/client/HttpSegmentChangeFetcher.java @@ -14,7 +14,6 @@ import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; import org.apache.hc.core5.http.HttpStatus; -import org.apache.hc.core5.http.Header; import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.core5.net.URIBuilder; import org.slf4j.Logger; @@ -23,8 +22,6 @@ import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.stream.Collectors; import static com.google.common.base.Preconditions.checkNotNull; @@ -40,9 +37,6 @@ public final class HttpSegmentChangeFetcher implements SegmentChangeFetcher { private static final String CACHE_CONTROL_HEADER_NAME = "Cache-Control"; private static final String CACHE_CONTROL_HEADER_VALUE = "no-cache"; - private static final String HEADER_FASTLY_DEBUG_NAME = "Fastly-Debug"; - private static final String HEADER_FASTLY_DEBUG_VALUE = "1"; - private final CloseableHttpClient _client; private final URI _target; private final TelemetryRuntimeProducer _telemetryRuntimeProducer; @@ -81,15 +75,8 @@ public SegmentChange fetch(String segmentName, long since, FetchOptions options) request.setHeader(CACHE_CONTROL_HEADER_NAME, CACHE_CONTROL_HEADER_VALUE); } - if (options.fastlyDebugHeaderEnabled()) { - request.addHeader(HEADER_FASTLY_DEBUG_NAME, HEADER_FASTLY_DEBUG_VALUE); - } - response = _client.execute(request); - options.handleResponseHeaders(Arrays.stream(response.getHeaders()) - .collect(Collectors.toMap(Header::getName, Header::getValue))); - int statusCode = response.getCode(); if (_log.isDebugEnabled()) { diff --git a/client/src/main/java/io/split/client/HttpSplitChangeFetcher.java b/client/src/main/java/io/split/client/HttpSplitChangeFetcher.java index e4bd7c3d4..65d37d144 100644 --- a/client/src/main/java/io/split/client/HttpSplitChangeFetcher.java +++ b/client/src/main/java/io/split/client/HttpSplitChangeFetcher.java @@ -14,7 +14,6 @@ import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; import org.apache.hc.core5.http.HttpStatus; -import org.apache.hc.core5.http.Header; import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.core5.net.URIBuilder; import org.slf4j.Logger; @@ -23,8 +22,6 @@ import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.stream.Collectors; import static com.google.common.base.Preconditions.checkNotNull; @@ -41,9 +38,6 @@ public final class HttpSplitChangeFetcher implements SplitChangeFetcher { private static final String HEADER_CACHE_CONTROL_NAME = "Cache-Control"; private static final String HEADER_CACHE_CONTROL_VALUE = "no-cache"; - private static final String HEADER_FASTLY_DEBUG_NAME = "Fastly-Debug"; - private static final String HEADER_FASTLY_DEBUG_VALUE = "1"; - private final CloseableHttpClient _client; private final URI _target; private final TelemetryRuntimeProducer _telemetryRuntimeProducer; @@ -87,13 +81,7 @@ public SplitChange fetch(long since, FetchOptions options) { request.setHeader(HEADER_CACHE_CONTROL_NAME, HEADER_CACHE_CONTROL_VALUE); } - if (options.fastlyDebugHeaderEnabled()) { - request.addHeader(HEADER_FASTLY_DEBUG_NAME, HEADER_FASTLY_DEBUG_VALUE); - } - response = _client.execute(request); - options.handleResponseHeaders(Arrays.stream(response.getHeaders()) - .collect(Collectors.toMap(Header::getName, Header::getValue))); int statusCode = response.getCode(); diff --git a/client/src/main/java/io/split/client/SplitClientConfig.java b/client/src/main/java/io/split/client/SplitClientConfig.java index de6ea4ecf..11e2ec2bc 100644 --- a/client/src/main/java/io/split/client/SplitClientConfig.java +++ b/client/src/main/java/io/split/client/SplitClientConfig.java @@ -73,7 +73,6 @@ public class SplitClientConfig { private final int _uniqueKeysRefreshRateInMemory; private final int _uniqueKeysRefreshRateRedis; private static int _filterUniqueKeysRefreshRate; - private final boolean _cdnDebugLogging; private final OperationMode _operationMode; private long _validateAfterInactivityInMillis; private final long _startingSyncCallBackoffBaseMs; @@ -135,7 +134,6 @@ private SplitClientConfig(String endpoint, int onDemandFetchRetryDelayMs, int onDemandFetchMaxRetries, int failedAttemptsBeforeLogging, - boolean cdnDebugLogging, OperationMode operationMode, long validateAfterInactivityInMillis, long startingSyncCallBackoffBaseMs, @@ -190,7 +188,6 @@ private SplitClientConfig(String endpoint, _onDemandFetchRetryDelayMs = onDemandFetchRetryDelayMs; _onDemandFetchMaxRetries = onDemandFetchMaxRetries; _failedAttemptsBeforeLogging = failedAttemptsBeforeLogging; - _cdnDebugLogging = cdnDebugLogging; _operationMode = operationMode; _storageMode = storageMode; _validateAfterInactivityInMillis = validateAfterInactivityInMillis; @@ -367,8 +364,6 @@ public int get_telemetryRefreshRate() { public int failedAttemptsBeforeLogging() {return _failedAttemptsBeforeLogging;} - public boolean cdnDebugLogging() { return _cdnDebugLogging; } - public OperationMode operationMode() { return _operationMode;} public long validateAfterInactivityInMillis() { @@ -445,7 +440,6 @@ public static final class Builder { private int _onDemandFetchRetryDelayMs = 50; private final int _onDemandFetchMaxRetries = 10; private final int _failedAttemptsBeforeLogging = 10; - private final boolean _cdnDebugLogging = true; private OperationMode _operationMode = OperationMode.STANDALONE; private long _validateAfterInactivityInMillis = 1000; private static final long STARTING_SYNC_CALL_BACKOFF_BASE_MS = 1000; //backoff base starting at 1 seconds @@ -1086,7 +1080,6 @@ public SplitClientConfig build() { _onDemandFetchRetryDelayMs, _onDemandFetchMaxRetries, _failedAttemptsBeforeLogging, - _cdnDebugLogging, _operationMode, _validateAfterInactivityInMillis, STARTING_SYNC_CALL_BACKOFF_BASE_MS, diff --git a/client/src/main/java/io/split/engine/common/FetchOptions.java b/client/src/main/java/io/split/engine/common/FetchOptions.java index f98e13ce8..926137135 100644 --- a/client/src/main/java/io/split/engine/common/FetchOptions.java +++ b/client/src/main/java/io/split/engine/common/FetchOptions.java @@ -1,8 +1,6 @@ package io.split.engine.common; -import java.util.Map; import java.util.Objects; -import java.util.function.Function; public class FetchOptions { @@ -15,8 +13,6 @@ public Builder() {} public Builder(FetchOptions opts) { _targetCN = opts._targetCN; _cacheControlHeaders = opts._cacheControlHeaders; - _fastlyDebugHeader = opts._fastlyDebugHeader; - _responseHeadersCallback = opts._responseHeadersCallback; _flagSetsFilter = opts._flagSetsFilter; } @@ -25,16 +21,6 @@ public Builder cacheControlHeaders(boolean on) { return this; } - public Builder fastlyDebugHeader(boolean on) { - _fastlyDebugHeader = on; - return this; - } - - public Builder responseHeadersCallback(Function, Void> callback) { - _responseHeadersCallback = callback; - return this; - } - public Builder targetChangeNumber(long targetCN) { _targetCN = targetCN; return this; @@ -46,13 +32,11 @@ public Builder flagSetsFilter(String flagSetsFilter) { } public FetchOptions build() { - return new FetchOptions(_cacheControlHeaders, _targetCN, _responseHeadersCallback, _fastlyDebugHeader, _flagSetsFilter); + return new FetchOptions(_cacheControlHeaders, _targetCN, _flagSetsFilter); } private long _targetCN = DEFAULT_TARGET_CHANGENUMBER; private boolean _cacheControlHeaders = false; - private boolean _fastlyDebugHeader = false; - private Function, Void> _responseHeadersCallback = null; private String _flagSetsFilter = ""; } @@ -60,10 +44,6 @@ public boolean cacheControlHeadersEnabled() { return _cacheControlHeaders; } - public boolean fastlyDebugHeaderEnabled() { - return _fastlyDebugHeader; - } - public long targetCN() { return _targetCN; } public boolean hasCustomCN() { return _targetCN != DEFAULT_TARGET_CHANGENUMBER; } @@ -72,22 +52,11 @@ public String flagSetsFilter() { return _flagSetsFilter; } - public void handleResponseHeaders(Map headers) { - if (Objects.isNull(_responseHeadersCallback) || Objects.isNull(headers)) { - return; - } - _responseHeadersCallback.apply(headers); - } - private FetchOptions(boolean cacheControlHeaders, long targetCN, - Function, Void> responseHeadersCallback, - boolean fastlyDebugHeader, String flagSetsFilter) { _cacheControlHeaders = cacheControlHeaders; _targetCN = targetCN; - _responseHeadersCallback = responseHeadersCallback; - _fastlyDebugHeader = fastlyDebugHeader; _flagSetsFilter = flagSetsFilter; } @@ -100,21 +69,17 @@ public boolean equals(Object obj) { FetchOptions other = (FetchOptions) obj; return Objects.equals(_cacheControlHeaders, other._cacheControlHeaders) - && Objects.equals(_fastlyDebugHeader, other._fastlyDebugHeader) - && Objects.equals(_responseHeadersCallback, other._responseHeadersCallback) && Objects.equals(_targetCN, other._targetCN) && Objects.equals(_flagSetsFilter, other._flagSetsFilter); } @Override public int hashCode() { - return com.google.common.base.Objects.hashCode(_cacheControlHeaders, _fastlyDebugHeader, _responseHeadersCallback, + return com.google.common.base.Objects.hashCode(_cacheControlHeaders, _targetCN, _flagSetsFilter); } private final boolean _cacheControlHeaders; - private final boolean _fastlyDebugHeader; private final long _targetCN; - private final Function, Void> _responseHeadersCallback; private final String _flagSetsFilter; } \ No newline at end of file diff --git a/client/src/main/java/io/split/engine/common/SyncManagerImp.java b/client/src/main/java/io/split/engine/common/SyncManagerImp.java index 295396ee9..dcebbc100 100644 --- a/client/src/main/java/io/split/engine/common/SyncManagerImp.java +++ b/client/src/main/java/io/split/engine/common/SyncManagerImp.java @@ -98,7 +98,6 @@ public static SyncManagerImp build(SplitTasks splitTasks, config.streamingRetryDelay(), config.streamingFetchMaxRetries(), config.failedAttemptsBeforeLogging(), - config.cdnDebugLogging(), config.getSetsFilter()); PushManager pushManager = PushManagerImp.build(synchronizer, diff --git a/client/src/main/java/io/split/engine/common/SynchronizerImp.java b/client/src/main/java/io/split/engine/common/SynchronizerImp.java index 38863db28..81f26ccd4 100644 --- a/client/src/main/java/io/split/engine/common/SynchronizerImp.java +++ b/client/src/main/java/io/split/engine/common/SynchronizerImp.java @@ -3,7 +3,6 @@ import io.split.client.events.EventsTask; import io.split.client.impressions.ImpressionsManager; import io.split.client.impressions.UniqueKeysTracker; -import io.split.client.utils.Json; import io.split.engine.experiments.FetchResult; import io.split.engine.experiments.SplitFetcher; import io.split.engine.experiments.SplitSynchronizationTask; @@ -17,8 +16,6 @@ import org.slf4j.LoggerFactory; import java.util.HashSet; -import java.util.List; -import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; @@ -45,7 +42,6 @@ public class SynchronizerImp implements Synchronizer { private final int _onDemandFetchRetryDelayMs; private final int _onDemandFetchMaxRetries; private final int _failedAttemptsBeforeLogging; - private final boolean _cdnResponseHeadersLogging; private final String _sets; public SynchronizerImp(SplitTasks splitTasks, @@ -55,7 +51,6 @@ public SynchronizerImp(SplitTasks splitTasks, int onDemandFetchRetryDelayMs, int onDemandFetchMaxRetries, int failedAttemptsBeforeLogging, - boolean cdnResponseHeadersLogging, HashSet sets) { _splitSynchronizationTask = checkNotNull(splitTasks.getSplitSynchronizationTask()); _splitFetcher = checkNotNull(splitFetcher); @@ -63,7 +58,6 @@ public SynchronizerImp(SplitTasks splitTasks, _splitCacheProducer = checkNotNull(splitCacheProducer); this.segmentCacheProducer = checkNotNull(segmentCacheProducer); _onDemandFetchRetryDelayMs = checkNotNull(onDemandFetchRetryDelayMs); - _cdnResponseHeadersLogging = cdnResponseHeadersLogging; _onDemandFetchMaxRetries = onDemandFetchMaxRetries; _failedAttemptsBeforeLogging = failedAttemptsBeforeLogging; _impressionManager = splitTasks.getImpressionManager(); @@ -135,12 +129,6 @@ private SyncResult attemptSplitsSync(long targetChangeNumber, } } - private void logCdnHeaders(String prefix, int maxRetries, int remainingAttempts, List> headers) { - if (maxRetries - remainingAttempts > _failedAttemptsBeforeLogging) { - _log.info(String.format("%s: CDN Debug headers: %s", prefix, Json.toJson(headers))); - } - } - @Override public void refreshSplits(Long targetChangeNumber) { @@ -151,8 +139,6 @@ public void refreshSplits(Long targetChangeNumber) { FastlyHeadersCaptor captor = new FastlyHeadersCaptor(); FetchOptions opts = new FetchOptions.Builder() .cacheControlHeaders(true) - .fastlyDebugHeader(_cdnResponseHeadersLogging) - .responseHeadersCallback(_cdnResponseHeadersLogging ? captor::handle : null) .flagSetsFilter(_sets) .build(); @@ -162,9 +148,7 @@ public void refreshSplits(Long targetChangeNumber) { int attempts = _onDemandFetchMaxRetries - regularResult.remainingAttempts(); if (regularResult.success()) { _log.debug(String.format("Refresh completed in %s attempts.", attempts)); - if (_cdnResponseHeadersLogging) { - logCdnHeaders("[splits]", _onDemandFetchMaxRetries , regularResult.remainingAttempts(), captor.get()); - } + regularResult._fetchResult.getSegments().stream() .forEach(segmentName -> forceRefreshSegment(segmentName)); return; @@ -184,11 +168,6 @@ public void refreshSplits(Long targetChangeNumber) { } else { _log.debug(String.format("No changes fetched after %s attempts with CDN bypassed.", withoutCDNAttempts)); } - - if (_cdnResponseHeadersLogging) { - logCdnHeaders("[splits]", _onDemandFetchMaxRetries + ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES, - withCDNBypassed.remainingAttempts(), captor.get()); - } } @Override @@ -238,8 +217,6 @@ public void refreshSegment(String segmentName, Long targetChangeNumber) { FastlyHeadersCaptor captor = new FastlyHeadersCaptor(); FetchOptions opts = new FetchOptions.Builder() .cacheControlHeaders(true) - .fastlyDebugHeader(_cdnResponseHeadersLogging) - .responseHeadersCallback(_cdnResponseHeadersLogging ? captor::handle : null) .build(); SyncResult regularResult = attemptSegmentSync(segmentName, targetChangeNumber, opts, @@ -248,9 +225,7 @@ public void refreshSegment(String segmentName, Long targetChangeNumber) { int attempts = _onDemandFetchMaxRetries - regularResult.remainingAttempts(); if (regularResult.success()) { _log.debug(String.format("Segment %s refresh completed in %s attempts.", segmentName, attempts)); - if (_cdnResponseHeadersLogging) { - logCdnHeaders(String.format("[segment/%s]", segmentName), _onDemandFetchMaxRetries , regularResult.remainingAttempts(), captor.get()); - } + return; } @@ -266,11 +241,6 @@ public void refreshSegment(String segmentName, Long targetChangeNumber) { } else { _log.debug(String.format("No changes fetched for segment %s after %s attempts with CDN bypassed.", segmentName, withoutCDNAttempts)); } - - if (_cdnResponseHeadersLogging) { - logCdnHeaders(String.format("[segment/%s]", segmentName), _onDemandFetchMaxRetries + ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES, - withCDNBypassed.remainingAttempts(), captor.get()); - } } @Override diff --git a/client/src/test/java/io/split/TestHelper.java b/client/src/test/java/io/split/TestHelper.java index 39b973c78..449a692f6 100644 --- a/client/src/test/java/io/split/TestHelper.java +++ b/client/src/test/java/io/split/TestHelper.java @@ -5,6 +5,8 @@ import org.apache.hc.core5.http.ClassicHttpResponse; import org.apache.hc.core5.http.Header; import org.apache.hc.core5.http.HttpEntity; +import org.apache.hc.core5.http.HttpHeaders; +import org.apache.hc.core5.http.message.BasicHeader; import org.mockito.Mockito; import java.io.IOException; @@ -19,7 +21,10 @@ public static CloseableHttpClient mockHttpClient(String jsonName, int httpStatus ClassicHttpResponse httpResponseMock = Mockito.mock(ClassicHttpResponse.class); Mockito.when(httpResponseMock.getEntity()).thenReturn(entityMock); Mockito.when(httpResponseMock.getCode()).thenReturn(httpStatus); - Mockito.when(httpResponseMock.getHeaders()).thenReturn(new Header[0]); + Header[] headers = new Header[2]; + headers[0] = new BasicHeader(HttpHeaders.VIA, "HTTP/1.1 m_proxy_rio1"); + headers[1] = new BasicHeader(HttpHeaders.VIA, "HTTP/1.1 s_proxy_rio1"); + Mockito.when(httpResponseMock.getHeaders()).thenReturn(headers); CloseableHttpClient httpClientMock = Mockito.mock(CloseableHttpClient.class); Mockito.when(httpClientMock.execute(Mockito.anyObject())).thenReturn(classicResponseToCloseableMock(httpResponseMock)); diff --git a/client/src/test/java/io/split/engine/common/FetcherOptionsTest.java b/client/src/test/java/io/split/engine/common/FetcherOptionsTest.java index f19728f72..19a1d45ec 100644 --- a/client/src/test/java/io/split/engine/common/FetcherOptionsTest.java +++ b/client/src/test/java/io/split/engine/common/FetcherOptionsTest.java @@ -2,50 +2,20 @@ import org.junit.Test; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Function; - import static org.junit.Assert.assertEquals; public class FetcherOptionsTest { @Test public void optionsPropagatedOk() { - final boolean[] called = {false}; - Function, Void> func = new Function, Void>() { - @Override - public Void apply(Map unused) { - called[0] = true; - return null; - } - }; - FetchOptions options = new FetchOptions.Builder() .cacheControlHeaders(true) - .fastlyDebugHeader(true) - .responseHeadersCallback(func) .targetChangeNumber(123) .flagSetsFilter("set1,set2") .build(); assertEquals(options.cacheControlHeadersEnabled(), true); - assertEquals(options.fastlyDebugHeaderEnabled(), true); assertEquals(options.targetCN(), 123); - options.handleResponseHeaders(new HashMap<>()); - assertEquals(called[0], true); assertEquals("set1,set2", options.flagSetsFilter()); } - - @Test - public void nullHandlerDoesNotExplode() { - - FetchOptions options = new FetchOptions.Builder() - .cacheControlHeaders(true) - .fastlyDebugHeader(true) - .responseHeadersCallback(null) - .build(); - - options.handleResponseHeaders(new HashMap<>()); - } } diff --git a/client/src/test/java/io/split/engine/common/SynchronizerTest.java b/client/src/test/java/io/split/engine/common/SynchronizerTest.java index 7fc69b590..b51ff8a8e 100644 --- a/client/src/test/java/io/split/engine/common/SynchronizerTest.java +++ b/client/src/test/java/io/split/engine/common/SynchronizerTest.java @@ -65,7 +65,7 @@ public void beforeMethod() { _splitTasks = SplitTasks.build(_refreshableSplitFetcherTask, _segmentFetcher, _impressionsManager, _eventsTask, _telemetrySyncTask, _uniqueKeysTracker); - _synchronizer = new SynchronizerImp(_splitTasks, _splitFetcher, _splitCacheProducer, _segmentCacheProducer, 50, 10, 5, false, new HashSet<>()); + _synchronizer = new SynchronizerImp(_splitTasks, _splitFetcher, _splitCacheProducer, _segmentCacheProducer, 50, 10, 5, new HashSet<>()); } @Test @@ -161,7 +161,6 @@ public void testCDNBypassIsRequestedAfterNFailures() { 50, 3, 1, - true, new HashSet<>()); ArgumentCaptor optionsCaptor = ArgumentCaptor.forClass(FetchOptions.class); @@ -194,7 +193,6 @@ public void testCDNBypassRequestLimitAndBackoff() throws NoSuchFieldException, I 50, 3, 1, - true, new HashSet<>()); ArgumentCaptor optionsCaptor = ArgumentCaptor.forClass(FetchOptions.class); @@ -250,7 +248,6 @@ public void testCDNBypassRequestLimitAndForSegmentsBackoff() throws NoSuchFieldE 50, 3, 1, - true, new HashSet<>()); SegmentFetcher fetcher = Mockito.mock(SegmentFetcher.class); @@ -309,7 +306,6 @@ public void testDataRecording(){ 50, 3, 1, - true, new HashSet<>()); imp.startPeriodicDataRecording(); diff --git a/pluggable-storage/pom.xml b/pluggable-storage/pom.xml index 9cbda4011..693016b51 100644 --- a/pluggable-storage/pom.xml +++ b/pluggable-storage/pom.xml @@ -6,7 +6,7 @@ java-client-parent io.split.client - 4.10.0 + 4.10.1 2.1.0 diff --git a/pom.xml b/pom.xml index 244405858..d3d441c0e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 io.split.client java-client-parent - 4.10.0 + 4.10.1 diff --git a/redis-wrapper/pom.xml b/redis-wrapper/pom.xml index f84f88362..fb354ff47 100644 --- a/redis-wrapper/pom.xml +++ b/redis-wrapper/pom.xml @@ -6,7 +6,7 @@ java-client-parent io.split.client - 4.10.0 + 4.10.1 redis-wrapper 3.1.0 diff --git a/testing/pom.xml b/testing/pom.xml index 683bd2172..704c77320 100644 --- a/testing/pom.xml +++ b/testing/pom.xml @@ -5,7 +5,7 @@ io.split.client java-client-parent - 4.10.0 + 4.10.1 java-client-testing jar