Skip to content
Merged
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 @@ -2,16 +2,15 @@

import com.google.common.annotations.VisibleForTesting;
import io.split.client.dtos.ImpressionCount;
import io.split.client.dtos.SplitHttpResponse;
import io.split.client.dtos.TestImpressions;
import io.split.client.utils.Utils;

import io.split.service.SplitHttpClient;
import io.split.telemetry.domain.enums.HTTPLatenciesEnum;
import io.split.telemetry.domain.enums.LastSynchronizationRecordsEnum;
import io.split.telemetry.domain.enums.ResourceEnum;
import io.split.telemetry.storage.TelemetryRuntimeProducer;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpStatus;
import org.slf4j.Logger;
Expand All @@ -22,6 +21,7 @@
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.google.common.base.Preconditions.checkNotNull;

Expand All @@ -36,13 +36,13 @@ public class HttpImpressionsSender implements ImpressionsSender {

private static final Logger _logger = LoggerFactory.getLogger(HttpImpressionsSender.class);

private final CloseableHttpClient _client;
private final SplitHttpClient _client;
private final URI _impressionBulkTarget;
private final URI _impressionCountTarget;
private final ImpressionsManager.Mode _mode;
private final TelemetryRuntimeProducer _telemetryRuntimeProducer;

public static HttpImpressionsSender create(CloseableHttpClient client, URI eventsRootEndpoint, ImpressionsManager.Mode mode,
public static HttpImpressionsSender create(SplitHttpClient client, URI eventsRootEndpoint, ImpressionsManager.Mode mode,
TelemetryRuntimeProducer telemetryRuntimeProducer) throws URISyntaxException {
return new HttpImpressionsSender(client,
Utils.appendPath(eventsRootEndpoint, BULK_ENDPOINT_PATH),
Expand All @@ -51,7 +51,7 @@ public static HttpImpressionsSender create(CloseableHttpClient client, URI event
telemetryRuntimeProducer);
}

private HttpImpressionsSender(CloseableHttpClient client, URI impressionBulkTarget, URI impressionCountTarget, ImpressionsManager.Mode mode,
private HttpImpressionsSender(SplitHttpClient client, URI impressionBulkTarget, URI impressionCountTarget, ImpressionsManager.Mode mode,
TelemetryRuntimeProducer telemetryRuntimeProducer) {
_client = client;
_mode = mode;
Expand All @@ -63,32 +63,26 @@ private HttpImpressionsSender(CloseableHttpClient client, URI impressionBulkTarg
@Override
public void postImpressionsBulk(List<TestImpressions> impressions) {

CloseableHttpResponse response = null;
SplitHttpResponse response = null;
long initTime = System.currentTimeMillis();
try {
HttpEntity entity = Utils.toJsonEntity(impressions);
Map<String, String> additionalHeader = new HashMap<>();
additionalHeader.put(IMPRESSIONS_MODE_HEADER, _mode.toString());
response = _client.post(_impressionBulkTarget, entity, additionalHeader);

HttpPost request = new HttpPost(_impressionBulkTarget);
request.addHeader(IMPRESSIONS_MODE_HEADER, _mode.toString());
request.setEntity(entity);

response = _client.execute(request);

int status = response.getCode();
int status = response.statusCode;

if (status < HttpStatus.SC_OK || status >= HttpStatus.SC_MULTIPLE_CHOICES) {
_telemetryRuntimeProducer.recordSyncError(ResourceEnum.IMPRESSION_SYNC, status);
_logger.warn(String.format("Response status was: %s. Reason: %s", status , response.getReasonPhrase()));
}
_telemetryRuntimeProducer.recordSuccessfulSync(LastSynchronizationRecordsEnum.IMPRESSIONS, System.currentTimeMillis());

} catch (Throwable t) {
_logger.warn("Exception when posting impressions" + impressions, t);
} finally {
_telemetryRuntimeProducer.recordSyncLatency(HTTPLatenciesEnum.IMPRESSIONS, System.currentTimeMillis() - initTime);
Utils.forceClose(response);
}

}

@Override
Expand All @@ -99,13 +93,14 @@ public void postCounters(HashMap<ImpressionCounter.Key, Integer> raw) {
return;
}

HttpPost request = new HttpPost(_impressionCountTarget);
request.setEntity(Utils.toJsonEntity(ImpressionCount.fromImpressionCounterData(raw)));
try (CloseableHttpResponse response = _client.execute(request)) {
int status = response.getCode();
try {
SplitHttpResponse response = _client.post(_impressionCountTarget,
Utils.toJsonEntity(ImpressionCount.fromImpressionCounterData(raw)),
null);

int status = response.statusCode;
if (status < HttpStatus.SC_OK || status >= HttpStatus.SC_MULTIPLE_CHOICES) {
_telemetryRuntimeProducer.recordSyncError(ResourceEnum.IMPRESSION_COUNT_SYNC, status);
_logger.warn(String.format("Response status was: %s. Reason: %s", status , response.getReasonPhrase()));
}
_telemetryRuntimeProducer.recordSyncLatency(HTTPLatenciesEnum.IMPRESSIONS_COUNT, System.currentTimeMillis() - initTime);
_telemetryRuntimeProducer.recordSuccessfulSync(LastSynchronizationRecordsEnum.IMPRESSIONS_COUNT, System.currentTimeMillis());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import io.split.TestHelper;
import io.split.client.RequestDecorator;
import io.split.client.dtos.ImpressionCount;
import io.split.client.dtos.KeyImpression;
import io.split.client.dtos.TestImpressions;
import io.split.service.SplitHttpClient;
import io.split.service.SplitHttpClientImpl;
import io.split.telemetry.storage.InMemoryTelemetryStorage;
import io.split.telemetry.storage.TelemetryStorage;
import org.apache.hc.client5.http.classic.methods.HttpPost;
Expand Down Expand Up @@ -42,31 +45,35 @@ public class HttpImpressionsSenderTest {
public void testDefaultURL() throws URISyntaxException {
URI rootTarget = URI.create("https://api.split.io");
CloseableHttpClient httpClient = HttpClients.custom().build();
HttpImpressionsSender fetcher = HttpImpressionsSender.create(httpClient, rootTarget, ImpressionsManager.Mode.DEBUG, TELEMETRY_STORAGE);
SplitHttpClient splitHtpClient = SplitHttpClientImpl.create(httpClient, new RequestDecorator(null));
HttpImpressionsSender fetcher = HttpImpressionsSender.create(splitHtpClient, rootTarget, ImpressionsManager.Mode.DEBUG, TELEMETRY_STORAGE);
Assert.assertThat(fetcher.getTarget().toString(), Matchers.is(Matchers.equalTo("https://api.split.io/api/testImpressions/bulk")));
}

@Test
public void testCustomURLNoPathNoBackslash() throws URISyntaxException {
URI rootTarget = URI.create("https://kubernetesturl.com");
CloseableHttpClient httpClient = HttpClients.custom().build();
HttpImpressionsSender fetcher = HttpImpressionsSender.create(httpClient, rootTarget, ImpressionsManager.Mode.DEBUG, TELEMETRY_STORAGE);
SplitHttpClient splitHtpClient = SplitHttpClientImpl.create(httpClient, new RequestDecorator(null));
HttpImpressionsSender fetcher = HttpImpressionsSender.create(splitHtpClient, rootTarget, ImpressionsManager.Mode.DEBUG, TELEMETRY_STORAGE);
Assert.assertThat(fetcher.getTarget().toString(), Matchers.is(Matchers.equalTo("https://kubernetesturl.com/api/testImpressions/bulk")));
}

@Test
public void testCustomURLAppendingPath() throws URISyntaxException {
URI rootTarget = URI.create("https://kubernetesturl.com/split/");
CloseableHttpClient httpClient = HttpClients.custom().build();
HttpImpressionsSender fetcher = HttpImpressionsSender.create(httpClient, rootTarget, ImpressionsManager.Mode.DEBUG, TELEMETRY_STORAGE);
SplitHttpClient splitHtpClient = SplitHttpClientImpl.create(httpClient, new RequestDecorator(null));
HttpImpressionsSender fetcher = HttpImpressionsSender.create(splitHtpClient, rootTarget, ImpressionsManager.Mode.DEBUG, TELEMETRY_STORAGE);
Assert.assertThat(fetcher.getTarget().toString(), Matchers.is(Matchers.equalTo("https://kubernetesturl.com/split/api/testImpressions/bulk")));
}

@Test
public void testCustomURLAppendingPathNoBackslash() throws URISyntaxException {
URI rootTarget = URI.create("https://kubernetesturl.com/split");
CloseableHttpClient httpClient = HttpClients.custom().build();
HttpImpressionsSender fetcher = HttpImpressionsSender.create(httpClient, rootTarget, ImpressionsManager.Mode.DEBUG, TELEMETRY_STORAGE);
SplitHttpClient splitHtpClient = SplitHttpClientImpl.create(httpClient, new RequestDecorator(null));
HttpImpressionsSender fetcher = HttpImpressionsSender.create(splitHtpClient, rootTarget, ImpressionsManager.Mode.DEBUG, TELEMETRY_STORAGE);
Assert.assertThat(fetcher.getTarget().toString(), Matchers.is(Matchers.equalTo("https://kubernetesturl.com/split/api/testImpressions/bulk")));
}

Expand All @@ -76,9 +83,10 @@ public void testImpressionCountsEndpointOptimized() throws URISyntaxException, I

// Setup response mock
CloseableHttpClient httpClient = TestHelper.mockHttpClient("", HttpStatus.SC_OK);
SplitHttpClient splitHtpClient = SplitHttpClientImpl.create(httpClient, new RequestDecorator(null));

// Send counters
HttpImpressionsSender sender = HttpImpressionsSender.create(httpClient, rootTarget, ImpressionsManager.Mode.OPTIMIZED, TELEMETRY_STORAGE);
HttpImpressionsSender sender = HttpImpressionsSender.create(splitHtpClient, rootTarget, ImpressionsManager.Mode.OPTIMIZED, TELEMETRY_STORAGE);
HashMap<ImpressionCounter.Key, Integer> toSend = new HashMap<>();
toSend.put(new ImpressionCounter.Key("test1", 0), 4);
toSend.put(new ImpressionCounter.Key("test2", 0), 5);
Expand Down Expand Up @@ -106,9 +114,10 @@ public void testImpressionCountsEndpointDebug() throws URISyntaxException, IOExc

// Setup response mock
CloseableHttpClient httpClient = TestHelper.mockHttpClient("", HttpStatus.SC_OK);
SplitHttpClient splitHtpClient = SplitHttpClientImpl.create(httpClient, new RequestDecorator(null));

// Send counters
HttpImpressionsSender sender = HttpImpressionsSender.create(httpClient, rootTarget, ImpressionsManager.Mode.DEBUG, TELEMETRY_STORAGE);
HttpImpressionsSender sender = HttpImpressionsSender.create(splitHtpClient, rootTarget, ImpressionsManager.Mode.DEBUG, TELEMETRY_STORAGE);
HashMap<ImpressionCounter.Key, Integer> toSend = new HashMap<>();
toSend.put(new ImpressionCounter.Key("test1", 0), 4);
toSend.put(new ImpressionCounter.Key("test2", 0), 5);
Expand All @@ -124,8 +133,9 @@ public void testImpressionBulksEndpoint() throws URISyntaxException, IOException

// Setup response mock
CloseableHttpClient httpClient = TestHelper.mockHttpClient("", HttpStatus.SC_OK);
SplitHttpClient splitHtpClient = SplitHttpClientImpl.create(httpClient, new RequestDecorator(null));

HttpImpressionsSender sender = HttpImpressionsSender.create(httpClient, rootTarget, ImpressionsManager.Mode.OPTIMIZED, TELEMETRY_STORAGE);
HttpImpressionsSender sender = HttpImpressionsSender.create(splitHtpClient, rootTarget, ImpressionsManager.Mode.OPTIMIZED, TELEMETRY_STORAGE);

// Send impressions
List<TestImpressions> toSend = Arrays.asList(new TestImpressions("t1", Arrays.asList(
Expand Down Expand Up @@ -155,8 +165,9 @@ public void testImpressionBulksEndpoint() throws URISyntaxException, IOException

// Do the same flow for imrpessionsMode = debug
CloseableHttpClient httpClientDebugMode = TestHelper.mockHttpClient("", HttpStatus.SC_OK);
SplitHttpClient splitHtpClient2 = SplitHttpClientImpl.create(httpClientDebugMode, new RequestDecorator(null));

sender = HttpImpressionsSender.create(httpClientDebugMode, rootTarget, ImpressionsManager.Mode.DEBUG, TELEMETRY_STORAGE);
sender = HttpImpressionsSender.create(splitHtpClient2, rootTarget, ImpressionsManager.Mode.DEBUG, TELEMETRY_STORAGE);
sender.postImpressionsBulk(toSend);
captor = ArgumentCaptor.forClass(HttpUriRequest.class);
verify(httpClientDebugMode).execute(captor.capture());
Expand Down