diff --git a/client/pom.xml b/client/pom.xml index 6d5bab624..5c13cc447 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -172,6 +172,11 @@ tracker ${project.version} + + io.split.client + impressions + ${project.version} + io.split.client targeting-engine diff --git a/client/src/main/java/io/split/client/SplitFactoryImpl.java b/client/src/main/java/io/split/client/SplitFactoryImpl.java index 05f21d856..41a4364fd 100644 --- a/client/src/main/java/io/split/client/SplitFactoryImpl.java +++ b/client/src/main/java/io/split/client/SplitFactoryImpl.java @@ -17,8 +17,12 @@ import io.split.client.impressions.ImpressionListener; import io.split.client.impressions.ImpressionObserver; import io.split.client.impressions.ImpressionsManager; +import io.split.client.impressions.ImpressionsManagerConfig; import io.split.client.impressions.ImpressionsManagerImpl; +import io.split.client.impressions.ImpressionsTelemetryRecorder; import io.split.client.impressions.ImpressionsSender; +import io.split.client.impressions.TelemetryRuntimeImpressionsRecorder; +import io.split.client.impressions.TelemetryUniqueKeysSender; import io.split.client.impressions.ImpressionsStorage; import io.split.client.impressions.ImpressionsStorageConsumer; import io.split.client.impressions.ImpressionsStorageProducer; @@ -752,11 +756,12 @@ private ImpressionsManagerImpl buildImpressionsManager(SplitClientConfig config, : null; ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(listener != null, _uniqueKeysTracker, counter); + ImpressionsTelemetryRecorder telemetryRecorder = new TelemetryRuntimeImpressionsRecorder(_telemetryStorageProducer); switch (config.impressionsMode()) { case OPTIMIZED: ImpressionObserver impressionObserver = new ImpressionObserver(config.getLastSeenCacheSize()); processImpressionStrategy = new ProcessImpressionOptimized(listener != null, impressionObserver, - counter, _telemetryStorageProducer); + counter, telemetryRecorder); break; case DEBUG: impressionObserver = new ImpressionObserver(config.getLastSeenCacheSize()); @@ -766,7 +771,13 @@ private ImpressionsManagerImpl buildImpressionsManager(SplitClientConfig config, processImpressionStrategy = processImpressionNone; break; } - return ImpressionsManagerImpl.instance(config, _telemetryStorageProducer, impressionsStorageConsumer, + ImpressionsManagerConfig impressionsManagerConfig = ImpressionsManagerConfig.builder() + .mode(config.impressionsMode()) + .impressionsRefreshRateSeconds(config.impressionsRefreshRate()) + .threadFactory(config.getThreadFactory()) + .debugEnabled(config.debugEnabled()) + .build(); + return ImpressionsManagerImpl.instance(impressionsManagerConfig, telemetryRecorder, impressionsStorageConsumer, impressionsStorageProducer, _impressionsSender, processImpressionNone, processImpressionStrategy, counter, listener); } @@ -809,7 +820,7 @@ private UniqueKeysTracker createUniqueKeysTracker(SplitClientConfig config) { int uniqueKeysRefreshRate = config.operationMode().equals(OperationMode.STANDALONE) ? config.uniqueKeysRefreshRateInMemory() : config.uniqueKeysRefreshRateRedis(); - return new UniqueKeysTrackerImp(_telemetrySynchronizer, uniqueKeysRefreshRate, + return new UniqueKeysTrackerImp(new TelemetryUniqueKeysSender(_telemetrySynchronizer), uniqueKeysRefreshRate, config.filterUniqueKeysRefreshRate(), config.getThreadFactory()); } diff --git a/client/src/main/java/io/split/client/impressions/TelemetryRuntimeImpressionsRecorder.java b/client/src/main/java/io/split/client/impressions/TelemetryRuntimeImpressionsRecorder.java new file mode 100644 index 000000000..02b287018 --- /dev/null +++ b/client/src/main/java/io/split/client/impressions/TelemetryRuntimeImpressionsRecorder.java @@ -0,0 +1,23 @@ +package io.split.client.impressions; + +import io.split.telemetry.domain.enums.ImpressionsDataTypeEnum; +import io.split.telemetry.storage.TelemetryRuntimeProducer; + +public class TelemetryRuntimeImpressionsRecorder implements ImpressionsTelemetryRecorder { + + private final TelemetryRuntimeProducer _telemetryRuntimeProducer; + + public TelemetryRuntimeImpressionsRecorder(TelemetryRuntimeProducer telemetryRuntimeProducer) { + _telemetryRuntimeProducer = telemetryRuntimeProducer; + } + + @Override + public void recordImpressionsDropped(long count) { + _telemetryRuntimeProducer.recordImpressionStats(ImpressionsDataTypeEnum.IMPRESSIONS_DROPPED, count); + } + + @Override + public void recordImpressionsQueued(long count) { + _telemetryRuntimeProducer.recordImpressionStats(ImpressionsDataTypeEnum.IMPRESSIONS_QUEUED, count); + } +} diff --git a/client/src/main/java/io/split/client/impressions/TelemetryUniqueKeysSender.java b/client/src/main/java/io/split/client/impressions/TelemetryUniqueKeysSender.java new file mode 100644 index 000000000..faae8792d --- /dev/null +++ b/client/src/main/java/io/split/client/impressions/TelemetryUniqueKeysSender.java @@ -0,0 +1,18 @@ +package io.split.client.impressions; + +import io.split.client.dtos.UniqueKeys; +import io.split.telemetry.synchronizer.TelemetrySynchronizer; + +public class TelemetryUniqueKeysSender implements UniqueKeysSender { + + private final TelemetrySynchronizer _telemetrySynchronizer; + + public TelemetryUniqueKeysSender(TelemetrySynchronizer telemetrySynchronizer) { + _telemetrySynchronizer = telemetrySynchronizer; + } + + @Override + public void send(UniqueKeys uniqueKeys) { + _telemetrySynchronizer.synchronizeUniqueKeys(uniqueKeys); + } +} diff --git a/impressions/pom.xml b/impressions/pom.xml new file mode 100644 index 000000000..79215437e --- /dev/null +++ b/impressions/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + + io.split.client + java-client-parent + 4.18.3 + + + impressions + jar + Impressions + Impression tracking core: dedup strategies, bloom-filter unique-key tracking, counter aggregation + + + + com.google.code.gson + gson + 2.13.1 + + + org.slf4j + slf4j-api + 1.7.36 + + + com.google.guava + guava + 32.0.1-jre + + + junit + junit + test + + + org.hamcrest + hamcrest-all + 1.3 + test + + + org.mockito + mockito-core + 1.10.19 + test + + + org.powermock + powermock-module-junit4 + 1.7.4 + test + + + org.powermock + powermock-api-mockito + 1.7.4 + test + + + diff --git a/client/src/main/java/io/split/client/dtos/DecoratedImpression.java b/impressions/src/main/java/io/split/client/dtos/DecoratedImpression.java similarity index 100% rename from client/src/main/java/io/split/client/dtos/DecoratedImpression.java rename to impressions/src/main/java/io/split/client/dtos/DecoratedImpression.java diff --git a/client/src/main/java/io/split/client/dtos/ImpressionCount.java b/impressions/src/main/java/io/split/client/dtos/ImpressionCount.java similarity index 100% rename from client/src/main/java/io/split/client/dtos/ImpressionCount.java rename to impressions/src/main/java/io/split/client/dtos/ImpressionCount.java diff --git a/client/src/main/java/io/split/client/dtos/KeyImpression.java b/impressions/src/main/java/io/split/client/dtos/KeyImpression.java similarity index 100% rename from client/src/main/java/io/split/client/dtos/KeyImpression.java rename to impressions/src/main/java/io/split/client/dtos/KeyImpression.java diff --git a/client/src/main/java/io/split/client/dtos/TestImpressions.java b/impressions/src/main/java/io/split/client/dtos/TestImpressions.java similarity index 100% rename from client/src/main/java/io/split/client/dtos/TestImpressions.java rename to impressions/src/main/java/io/split/client/dtos/TestImpressions.java diff --git a/client/src/main/java/io/split/client/dtos/UniqueKeys.java b/impressions/src/main/java/io/split/client/dtos/UniqueKeys.java similarity index 100% rename from client/src/main/java/io/split/client/dtos/UniqueKeys.java rename to impressions/src/main/java/io/split/client/dtos/UniqueKeys.java diff --git a/client/src/main/java/io/split/client/impressions/AsynchronousImpressionListener.java b/impressions/src/main/java/io/split/client/impressions/AsynchronousImpressionListener.java similarity index 85% rename from client/src/main/java/io/split/client/impressions/AsynchronousImpressionListener.java rename to impressions/src/main/java/io/split/client/impressions/AsynchronousImpressionListener.java index 66f1d17d4..9e247c7b3 100644 --- a/client/src/main/java/io/split/client/impressions/AsynchronousImpressionListener.java +++ b/impressions/src/main/java/io/split/client/impressions/AsynchronousImpressionListener.java @@ -1,6 +1,5 @@ package io.split.client.impressions; -import com.google.common.util.concurrent.ThreadFactoryBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -9,6 +8,7 @@ import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; /** * A wrapper around an ImpressionListener provided by the customer. The purpose @@ -25,10 +25,12 @@ public class AsynchronousImpressionListener implements ImpressionListener { private final ExecutorService _executor; public static AsynchronousImpressionListener build(ImpressionListener delegate, int capacity) { - ThreadFactory threadFactory = new ThreadFactoryBuilder() - .setDaemon(true) - .setNameFormat("impression-listener-wrapper-%d") - .build(); + AtomicInteger counter = new AtomicInteger(0); + ThreadFactory threadFactory = r -> { + Thread t = new Thread(r, "impression-listener-wrapper-" + counter.getAndIncrement()); + t.setDaemon(true); + return t; + }; ExecutorService executor = new ThreadPoolExecutor(2, 2, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(capacity), threadFactory); diff --git a/client/src/main/java/io/split/client/impressions/Impression.java b/impressions/src/main/java/io/split/client/impressions/Impression.java similarity index 100% rename from client/src/main/java/io/split/client/impressions/Impression.java rename to impressions/src/main/java/io/split/client/impressions/Impression.java diff --git a/client/src/main/java/io/split/client/impressions/ImpressionCounter.java b/impressions/src/main/java/io/split/client/impressions/ImpressionCounter.java similarity index 94% rename from client/src/main/java/io/split/client/impressions/ImpressionCounter.java rename to impressions/src/main/java/io/split/client/impressions/ImpressionCounter.java index 381177a89..02ff29ac7 100644 --- a/client/src/main/java/io/split/client/impressions/ImpressionCounter.java +++ b/impressions/src/main/java/io/split/client/impressions/ImpressionCounter.java @@ -5,8 +5,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; -import static com.google.common.base.Preconditions.checkNotNull; - public class ImpressionCounter { public static class Key { @@ -14,7 +12,7 @@ public static class Key { private final long _timeFrame; public Key(String featureFlagName, long timeframe) { - _featureName = checkNotNull(featureFlagName); + _featureName = Objects.requireNonNull(featureFlagName); _timeFrame = timeframe; } diff --git a/client/src/main/java/io/split/client/impressions/ImpressionHasher.java b/impressions/src/main/java/io/split/client/impressions/ImpressionHasher.java similarity index 100% rename from client/src/main/java/io/split/client/impressions/ImpressionHasher.java rename to impressions/src/main/java/io/split/client/impressions/ImpressionHasher.java diff --git a/client/src/main/java/io/split/client/impressions/ImpressionListener.java b/impressions/src/main/java/io/split/client/impressions/ImpressionListener.java similarity index 100% rename from client/src/main/java/io/split/client/impressions/ImpressionListener.java rename to impressions/src/main/java/io/split/client/impressions/ImpressionListener.java diff --git a/client/src/main/java/io/split/client/impressions/ImpressionObserver.java b/impressions/src/main/java/io/split/client/impressions/ImpressionObserver.java similarity index 100% rename from client/src/main/java/io/split/client/impressions/ImpressionObserver.java rename to impressions/src/main/java/io/split/client/impressions/ImpressionObserver.java diff --git a/client/src/main/java/io/split/client/impressions/ImpressionUtils.java b/impressions/src/main/java/io/split/client/impressions/ImpressionUtils.java similarity index 100% rename from client/src/main/java/io/split/client/impressions/ImpressionUtils.java rename to impressions/src/main/java/io/split/client/impressions/ImpressionUtils.java diff --git a/client/src/main/java/io/split/client/impressions/ImpressionsManager.java b/impressions/src/main/java/io/split/client/impressions/ImpressionsManager.java similarity index 100% rename from client/src/main/java/io/split/client/impressions/ImpressionsManager.java rename to impressions/src/main/java/io/split/client/impressions/ImpressionsManager.java diff --git a/impressions/src/main/java/io/split/client/impressions/ImpressionsManagerConfig.java b/impressions/src/main/java/io/split/client/impressions/ImpressionsManagerConfig.java new file mode 100644 index 000000000..d3b9e1b9b --- /dev/null +++ b/impressions/src/main/java/io/split/client/impressions/ImpressionsManagerConfig.java @@ -0,0 +1,39 @@ +package io.split.client.impressions; + +import java.util.concurrent.ThreadFactory; + +public final class ImpressionsManagerConfig { + + private final ImpressionsManager.Mode _mode; + private final int _impressionsRefreshRateSeconds; + private final ThreadFactory _threadFactory; + private final boolean _debugEnabled; + + private ImpressionsManagerConfig(Builder builder) { + _mode = builder._mode; + _impressionsRefreshRateSeconds = builder._impressionsRefreshRateSeconds; + _threadFactory = builder._threadFactory; + _debugEnabled = builder._debugEnabled; + } + + public ImpressionsManager.Mode mode() { return _mode; } + public int impressionsRefreshRateSeconds() { return _impressionsRefreshRateSeconds; } + public ThreadFactory threadFactory() { return _threadFactory; } + public boolean debugEnabled() { return _debugEnabled; } + + public static Builder builder() { return new Builder(); } + + public static final class Builder { + private ImpressionsManager.Mode _mode = ImpressionsManager.Mode.OPTIMIZED; + private int _impressionsRefreshRateSeconds = 60; + private ThreadFactory _threadFactory = null; + private boolean _debugEnabled = false; + + public Builder mode(ImpressionsManager.Mode mode) { _mode = mode; return this; } + public Builder impressionsRefreshRateSeconds(int rate) { _impressionsRefreshRateSeconds = rate; return this; } + public Builder threadFactory(ThreadFactory tf) { _threadFactory = tf; return this; } + public Builder debugEnabled(boolean debug) { _debugEnabled = debug; return this; } + + public ImpressionsManagerConfig build() { return new ImpressionsManagerConfig(this); } + } +} diff --git a/client/src/main/java/io/split/client/impressions/ImpressionsManagerImpl.java b/impressions/src/main/java/io/split/client/impressions/ImpressionsManagerImpl.java similarity index 51% rename from client/src/main/java/io/split/client/impressions/ImpressionsManagerImpl.java rename to impressions/src/main/java/io/split/client/impressions/ImpressionsManagerImpl.java index 3b784abaf..f9f7d7343 100644 --- a/client/src/main/java/io/split/client/impressions/ImpressionsManagerImpl.java +++ b/impressions/src/main/java/io/split/client/impressions/ImpressionsManagerImpl.java @@ -1,33 +1,24 @@ package io.split.client.impressions; -import com.google.common.annotations.VisibleForTesting; -import io.split.client.SplitClientConfig; import io.split.client.dtos.DecoratedImpression; import io.split.client.dtos.KeyImpression; import io.split.client.dtos.TestImpressions; import io.split.client.impressions.strategy.ProcessImpressionNone; import io.split.client.impressions.strategy.ProcessImpressionStrategy; -import io.split.client.utils.SplitExecutorFactory; -import io.split.telemetry.domain.enums.ImpressionsDataTypeEnum; -import io.split.telemetry.storage.TelemetryRuntimeProducer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Closeable; -import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.stream.Stream; -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * Created by patricioe on 6/17/16. - */ public class ImpressionsManagerImpl implements ImpressionsManager, Closeable { private static final Logger _log = LoggerFactory.getLogger(ImpressionsManagerImpl.class); @@ -35,89 +26,89 @@ public class ImpressionsManagerImpl implements ImpressionsManager, Closeable { private static final long BULK_INITIAL_DELAY_SECONDS = 10L; private static final long COUNT_INITIAL_DELAY_SECONDS = 100L; private static final long COUNT_REFRESH_RATE_SECONDS = 30 * 60; - private final SplitClientConfig _config; + + private final ImpressionsManagerConfig _config; private final ImpressionsStorageProducer _impressionsStorageProducer; private final ImpressionsStorageConsumer _impressionsStorageConsumer; private final ScheduledExecutorService _scheduler; private final ImpressionsSender _impressionsSender; private final ImpressionListener _listener; private final ImpressionsManager.Mode _impressionsMode; - private TelemetryRuntimeProducer _telemetryRuntimeProducer; + private final ImpressionsTelemetryRecorder _telemetryRecorder; private ImpressionCounter _counter; private ProcessImpressionStrategy _processImpressionStrategy; private ProcessImpressionNone _processImpressionNone; - private final int _impressionsRefreshRate; - - public static ImpressionsManagerImpl instance(SplitClientConfig config, - TelemetryRuntimeProducer telemetryRuntimeProducer, - ImpressionsStorageConsumer impressionsStorageConsumer, - ImpressionsStorageProducer impressionsStorageProducer, - ImpressionsSender impressionsSender, - ProcessImpressionNone processImpressionNone, - ProcessImpressionStrategy processImpressionStrategy, - ImpressionCounter counter, - ImpressionListener listener) throws URISyntaxException { - return new ImpressionsManagerImpl(config, impressionsSender, telemetryRuntimeProducer, impressionsStorageConsumer, + public static ImpressionsManagerImpl instance(ImpressionsManagerConfig config, + ImpressionsTelemetryRecorder telemetryRecorder, + ImpressionsStorageConsumer impressionsStorageConsumer, + ImpressionsStorageProducer impressionsStorageProducer, + ImpressionsSender impressionsSender, + ProcessImpressionNone processImpressionNone, + ProcessImpressionStrategy processImpressionStrategy, + ImpressionCounter counter, + ImpressionListener listener) { + return new ImpressionsManagerImpl(config, impressionsSender, telemetryRecorder, impressionsStorageConsumer, impressionsStorageProducer, processImpressionNone, processImpressionStrategy, counter, listener); } - public static ImpressionsManagerImpl instanceForTest(SplitClientConfig config, - ImpressionsSender impressionsSender, - TelemetryRuntimeProducer telemetryRuntimeProducer, - ImpressionsStorageConsumer impressionsStorageConsumer, - ImpressionsStorageProducer impressionsStorageProducer, - ProcessImpressionNone processImpressionNone, - ProcessImpressionStrategy processImpressionStrategy, - ImpressionCounter counter, - ImpressionListener listener) { - return new ImpressionsManagerImpl(config, impressionsSender, telemetryRuntimeProducer, impressionsStorageConsumer, + public static ImpressionsManagerImpl instanceForTest(ImpressionsManagerConfig config, + ImpressionsSender impressionsSender, + ImpressionsTelemetryRecorder telemetryRecorder, + ImpressionsStorageConsumer impressionsStorageConsumer, + ImpressionsStorageProducer impressionsStorageProducer, + ProcessImpressionNone processImpressionNone, + ProcessImpressionStrategy processImpressionStrategy, + ImpressionCounter counter, + ImpressionListener listener) { + return new ImpressionsManagerImpl(config, impressionsSender, telemetryRecorder, impressionsStorageConsumer, impressionsStorageProducer, processImpressionNone, processImpressionStrategy, counter, listener); } - private ImpressionsManagerImpl(SplitClientConfig config, - ImpressionsSender impressionsSender, - TelemetryRuntimeProducer telemetryRuntimeProducer, - ImpressionsStorageConsumer impressionsStorageConsumer, - ImpressionsStorageProducer impressionsStorageProducer, - ProcessImpressionNone processImpressionNone, - ProcessImpressionStrategy processImpressionStrategy, - ImpressionCounter impressionCounter, - ImpressionListener impressionListener) { - - - _config = checkNotNull(config); - _impressionsMode = checkNotNull(config.impressionsMode()); - _impressionsStorageConsumer = checkNotNull(impressionsStorageConsumer); - _impressionsStorageProducer = checkNotNull(impressionsStorageProducer); - _telemetryRuntimeProducer = checkNotNull(telemetryRuntimeProducer); - _processImpressionNone = checkNotNull(processImpressionNone); - _processImpressionStrategy = checkNotNull(processImpressionStrategy); + private ImpressionsManagerImpl(ImpressionsManagerConfig config, + ImpressionsSender impressionsSender, + ImpressionsTelemetryRecorder telemetryRecorder, + ImpressionsStorageConsumer impressionsStorageConsumer, + ImpressionsStorageProducer impressionsStorageProducer, + ProcessImpressionNone processImpressionNone, + ProcessImpressionStrategy processImpressionStrategy, + ImpressionCounter impressionCounter, + ImpressionListener impressionListener) { + _config = Objects.requireNonNull(config); + _impressionsMode = Objects.requireNonNull(config.mode()); + _impressionsStorageConsumer = Objects.requireNonNull(impressionsStorageConsumer); + _impressionsStorageProducer = Objects.requireNonNull(impressionsStorageProducer); + _telemetryRecorder = Objects.requireNonNull(telemetryRecorder); + _processImpressionNone = Objects.requireNonNull(processImpressionNone); + _processImpressionStrategy = Objects.requireNonNull(processImpressionStrategy); _impressionsSender = impressionsSender; _counter = impressionCounter; - _scheduler = SplitExecutorFactory.buildScheduledExecutorService(config.getThreadFactory(), "Split-ImpressionsManager-%d", 2); + ThreadFactory tf = config.threadFactory(); + _scheduler = tf != null + ? Executors.newScheduledThreadPool(2, tf) + : Executors.newScheduledThreadPool(2); _listener = impressionListener; - - _impressionsRefreshRate = config.impressionsRefreshRate(); } @Override - public void start(){ - switch (_impressionsMode){ + public void start() { + switch (_impressionsMode) { case OPTIMIZED: - _scheduler.scheduleAtFixedRate(this::sendImpressionCounters, COUNT_INITIAL_DELAY_SECONDS, COUNT_REFRESH_RATE_SECONDS, - TimeUnit.SECONDS); - _scheduler.scheduleAtFixedRate(this::sendImpressions, BULK_INITIAL_DELAY_SECONDS, _impressionsRefreshRate, TimeUnit.SECONDS); + _scheduler.scheduleAtFixedRate(this::sendImpressionCounters, COUNT_INITIAL_DELAY_SECONDS, + COUNT_REFRESH_RATE_SECONDS, TimeUnit.SECONDS); + _scheduler.scheduleAtFixedRate(this::sendImpressions, BULK_INITIAL_DELAY_SECONDS, + _config.impressionsRefreshRateSeconds(), TimeUnit.SECONDS); break; case DEBUG: - _scheduler.scheduleAtFixedRate(this::sendImpressions, BULK_INITIAL_DELAY_SECONDS, _impressionsRefreshRate, TimeUnit.SECONDS); - _scheduler.scheduleAtFixedRate(this::sendImpressionCounters, COUNT_INITIAL_DELAY_SECONDS, COUNT_REFRESH_RATE_SECONDS, - TimeUnit.SECONDS); + _scheduler.scheduleAtFixedRate(this::sendImpressions, BULK_INITIAL_DELAY_SECONDS, + _config.impressionsRefreshRateSeconds(), TimeUnit.SECONDS); + _scheduler.scheduleAtFixedRate(this::sendImpressionCounters, COUNT_INITIAL_DELAY_SECONDS, + COUNT_REFRESH_RATE_SECONDS, TimeUnit.SECONDS); break; case NONE: - _scheduler.scheduleAtFixedRate(this::sendImpressionCounters, COUNT_INITIAL_DELAY_SECONDS, COUNT_REFRESH_RATE_SECONDS, - TimeUnit.SECONDS); + _scheduler.scheduleAtFixedRate(this::sendImpressionCounters, COUNT_INITIAL_DELAY_SECONDS, + COUNT_REFRESH_RATE_SECONDS, TimeUnit.SECONDS); break; } } @@ -142,17 +133,19 @@ public void track(List decoratedImpressions) { if (!Objects.isNull(impressionsResult.getImpressionsToQueue())) { impressionsForLogs.addAll(impressionsResult.getImpressionsToQueue()); } - if (!Objects.isNull(impressionsResult.getImpressionsToListener())) + if (!Objects.isNull(impressionsResult.getImpressionsToListener())) { impressionsToListener.addAll(impressionsResult.getImpressionsToListener()); + } } int totalImpressions = impressionsForLogs.size(); - long queued = _impressionsStorageProducer.put(impressionsForLogs.stream().map(KeyImpression::fromImpression).collect(Collectors.toList())); + long queued = _impressionsStorageProducer.put( + impressionsForLogs.stream().map(KeyImpression::fromImpression).collect(Collectors.toList())); if (queued < totalImpressions) { - _telemetryRuntimeProducer.recordImpressionStats(ImpressionsDataTypeEnum.IMPRESSIONS_DROPPED, totalImpressions-queued); + _telemetryRecorder.recordImpressionsDropped(totalImpressions - queued); } - _telemetryRuntimeProducer.recordImpressionStats(ImpressionsDataTypeEnum.IMPRESSIONS_QUEUED, queued); + _telemetryRecorder.recordImpressionsQueued(queued); - if (_listener!=null){ + if (_listener != null) { impressionsToListener.forEach(imp -> _listener.log(imp)); } } @@ -160,22 +153,20 @@ public void track(List decoratedImpressions) { @Override public void close() { try { - if(_listener!= null){ + if (_listener != null) { _listener.close(); _log.info("Successful shutdown of ImpressionListener"); } _scheduler.shutdown(); sendImpressions(); - if(_counter != null) { + if (_counter != null) { sendImpressionCounters(); } } catch (Exception e) { _log.warn("Unable to close ImpressionsManager properly", e); } - } - @VisibleForTesting /* package private */ void sendImpressions() { if (_impressionsStorageConsumer.isFull()) { _log.warn("Split SDK impressions queue is full. Impressions may have been dropped. Consider increasing capacity."); @@ -184,7 +175,7 @@ public void close() { long start = System.currentTimeMillis(); List impressions = _impressionsStorageConsumer.pop(); if (impressions.isEmpty()) { - return; // Nothing to send + return; } _impressionsSender.postImpressionsBulk(TestImpressions.fromKeyImpressions(impressions)); @@ -194,15 +185,13 @@ public void close() { } } - @VisibleForTesting - /* package private */ void sendImpressionCounters() { + /* package private */ void sendImpressionCounters() { if (!_counter.isEmpty()) { _impressionsSender.postCounters(_counter.popAll()); } } - @VisibleForTesting /* package private */ ImpressionCounter getCounter() { return _counter; } -} \ No newline at end of file +} diff --git a/client/src/main/java/io/split/client/impressions/ImpressionsResult.java b/impressions/src/main/java/io/split/client/impressions/ImpressionsResult.java similarity index 100% rename from client/src/main/java/io/split/client/impressions/ImpressionsResult.java rename to impressions/src/main/java/io/split/client/impressions/ImpressionsResult.java diff --git a/client/src/main/java/io/split/client/impressions/ImpressionsSender.java b/impressions/src/main/java/io/split/client/impressions/ImpressionsSender.java similarity index 100% rename from client/src/main/java/io/split/client/impressions/ImpressionsSender.java rename to impressions/src/main/java/io/split/client/impressions/ImpressionsSender.java diff --git a/client/src/main/java/io/split/client/impressions/ImpressionsStorage.java b/impressions/src/main/java/io/split/client/impressions/ImpressionsStorage.java similarity index 100% rename from client/src/main/java/io/split/client/impressions/ImpressionsStorage.java rename to impressions/src/main/java/io/split/client/impressions/ImpressionsStorage.java diff --git a/client/src/main/java/io/split/client/impressions/ImpressionsStorageConsumer.java b/impressions/src/main/java/io/split/client/impressions/ImpressionsStorageConsumer.java similarity index 100% rename from client/src/main/java/io/split/client/impressions/ImpressionsStorageConsumer.java rename to impressions/src/main/java/io/split/client/impressions/ImpressionsStorageConsumer.java diff --git a/client/src/main/java/io/split/client/impressions/ImpressionsStorageProducer.java b/impressions/src/main/java/io/split/client/impressions/ImpressionsStorageProducer.java similarity index 100% rename from client/src/main/java/io/split/client/impressions/ImpressionsStorageProducer.java rename to impressions/src/main/java/io/split/client/impressions/ImpressionsStorageProducer.java diff --git a/impressions/src/main/java/io/split/client/impressions/ImpressionsTelemetryRecorder.java b/impressions/src/main/java/io/split/client/impressions/ImpressionsTelemetryRecorder.java new file mode 100644 index 000000000..12603e8f9 --- /dev/null +++ b/impressions/src/main/java/io/split/client/impressions/ImpressionsTelemetryRecorder.java @@ -0,0 +1,6 @@ +package io.split.client.impressions; + +public interface ImpressionsTelemetryRecorder { + void recordImpressionsDropped(long count); + void recordImpressionsQueued(long count); +} diff --git a/client/src/main/java/io/split/client/impressions/InMemoryImpressionsStorage.java b/impressions/src/main/java/io/split/client/impressions/InMemoryImpressionsStorage.java similarity index 100% rename from client/src/main/java/io/split/client/impressions/InMemoryImpressionsStorage.java rename to impressions/src/main/java/io/split/client/impressions/InMemoryImpressionsStorage.java diff --git a/impressions/src/main/java/io/split/client/impressions/NoopImpressionsTelemetryRecorder.java b/impressions/src/main/java/io/split/client/impressions/NoopImpressionsTelemetryRecorder.java new file mode 100644 index 000000000..8f6da987b --- /dev/null +++ b/impressions/src/main/java/io/split/client/impressions/NoopImpressionsTelemetryRecorder.java @@ -0,0 +1,9 @@ +package io.split.client.impressions; + +public class NoopImpressionsTelemetryRecorder implements ImpressionsTelemetryRecorder { + @Override + public void recordImpressionsDropped(long count) {} + + @Override + public void recordImpressionsQueued(long count) {} +} diff --git a/impressions/src/main/java/io/split/client/impressions/UniqueKeysSender.java b/impressions/src/main/java/io/split/client/impressions/UniqueKeysSender.java new file mode 100644 index 000000000..a580669fc --- /dev/null +++ b/impressions/src/main/java/io/split/client/impressions/UniqueKeysSender.java @@ -0,0 +1,7 @@ +package io.split.client.impressions; + +import io.split.client.dtos.UniqueKeys; + +public interface UniqueKeysSender { + void send(UniqueKeys uniqueKeys); +} diff --git a/client/src/main/java/io/split/client/impressions/UniqueKeysTracker.java b/impressions/src/main/java/io/split/client/impressions/UniqueKeysTracker.java similarity index 100% rename from client/src/main/java/io/split/client/impressions/UniqueKeysTracker.java rename to impressions/src/main/java/io/split/client/impressions/UniqueKeysTracker.java diff --git a/client/src/main/java/io/split/client/impressions/UniqueKeysTrackerImp.java b/impressions/src/main/java/io/split/client/impressions/UniqueKeysTrackerImp.java similarity index 83% rename from client/src/main/java/io/split/client/impressions/UniqueKeysTrackerImp.java rename to impressions/src/main/java/io/split/client/impressions/UniqueKeysTrackerImp.java index c0034b6b2..61a98f6d5 100644 --- a/client/src/main/java/io/split/client/impressions/UniqueKeysTrackerImp.java +++ b/impressions/src/main/java/io/split/client/impressions/UniqueKeysTrackerImp.java @@ -1,13 +1,10 @@ package io.split.client.impressions; -import com.google.common.collect.Lists; import io.split.client.dtos.UniqueKeys; import io.split.client.impressions.filters.BloomFilterImp; import io.split.client.impressions.filters.Filter; import io.split.client.impressions.filters.FilterAdapter; import io.split.client.impressions.filters.FilterAdapterImpl; -import io.split.client.utils.SplitExecutorFactory; -import io.split.telemetry.synchronizer.TelemetrySynchronizer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,38 +15,43 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -public class UniqueKeysTrackerImp implements UniqueKeysTracker{ +public class UniqueKeysTrackerImp implements UniqueKeysTracker { private static final Logger _log = LoggerFactory.getLogger(UniqueKeysTrackerImp.class); private static final double MARGIN_ERROR = 0.01; private static final int MAX_UNIQUE_KEYS_POST_SIZE = 5000; private static final int MAX_AMOUNT_OF_KEYS = 10000000; private final AtomicInteger trackerKeysSize = new AtomicInteger(0); private FilterAdapter filterAdapter; - private final TelemetrySynchronizer _telemetrySynchronizer; + private final UniqueKeysSender _uniqueKeysSender; private final ScheduledExecutorService _uniqueKeysSyncScheduledExecutorService; private final ScheduledExecutorService _cleanFilterScheduledExecutorService; - private final ConcurrentHashMap> uniqueKeysTracker; + private final ConcurrentHashMap> uniqueKeysTracker; private final int _uniqueKeysRefreshRate; private final int _filterRefreshRate; private final AtomicBoolean sendGuard = new AtomicBoolean(false); private static final Logger _logger = LoggerFactory.getLogger(UniqueKeysTrackerImp.class); - public UniqueKeysTrackerImp(TelemetrySynchronizer telemetrySynchronizer, int uniqueKeysRefreshRate, int filterRefreshRate, + public UniqueKeysTrackerImp(UniqueKeysSender uniqueKeysSender, int uniqueKeysRefreshRate, int filterRefreshRate, ThreadFactory threadFactory) { Filter bloomFilter = new BloomFilterImp(MAX_AMOUNT_OF_KEYS, MARGIN_ERROR); this.filterAdapter = new FilterAdapterImpl(bloomFilter); uniqueKeysTracker = new ConcurrentHashMap<>(); - _telemetrySynchronizer = telemetrySynchronizer; + _uniqueKeysSender = uniqueKeysSender; _uniqueKeysRefreshRate = uniqueKeysRefreshRate; _filterRefreshRate = filterRefreshRate; - _uniqueKeysSyncScheduledExecutorService = SplitExecutorFactory.buildSingleThreadScheduledExecutor(threadFactory,"UniqueKeys-sync-%d"); - _cleanFilterScheduledExecutorService = SplitExecutorFactory.buildSingleThreadScheduledExecutor(threadFactory,"Filter-%d"); + _uniqueKeysSyncScheduledExecutorService = threadFactory != null + ? Executors.newSingleThreadScheduledExecutor(threadFactory) + : Executors.newSingleThreadScheduledExecutor(); + _cleanFilterScheduledExecutorService = threadFactory != null + ? Executors.newSingleThreadScheduledExecutor(threadFactory) + : Executors.newSingleThreadScheduledExecutor(); } @Override @@ -66,7 +68,7 @@ public boolean track(String featureFlagName, String key) { return keysByFeature; }); _logger.debug("The feature flag " + featureFlagName + " and key " + key + " was added"); - if (trackerKeysSize.intValue() >= MAX_UNIQUE_KEYS_POST_SIZE){ + if (trackerKeysSize.intValue() >= MAX_UNIQUE_KEYS_POST_SIZE) { _logger.warn("The UniqueKeysTracker size reached the maximum limit"); try { sendUniqueKeys(); @@ -105,8 +107,8 @@ public void stop() { _cleanFilterScheduledExecutorService.shutdown(); } - public HashMap> popAll(){ - HashMap> toReturn = new HashMap<>(); + public HashMap> popAll() { + HashMap> toReturn = new HashMap<>(); for (String key : uniqueKeysTracker.keySet()) { HashSet value = uniqueKeysTracker.remove(key); toReturn.put(key, value); @@ -115,7 +117,7 @@ public HashMap> popAll(){ return toReturn; } - private void sendUniqueKeys(){ + private void sendUniqueKeys() { if (!sendGuard.compareAndSet(false, true)) { _log.debug("SendUniqueKeys already running"); return; @@ -136,7 +138,7 @@ private void sendUniqueKeys(){ uniqueKeysFromPopAll = capChunksToMaxSize(uniqueKeysFromPopAll); for (List chunk : getChunks(uniqueKeysFromPopAll)) { - _telemetrySynchronizer.synchronizeUniqueKeys(new UniqueKeys(chunk)); + _uniqueKeysSender.send(new UniqueKeys(chunk)); } } finally { sendGuard.set(false); @@ -147,7 +149,7 @@ private List capChunksToMaxSize(List List finalChunk = new ArrayList<>(); for (UniqueKeys.UniqueKey uniqueKey : uniqueKeys) { if (uniqueKey.keysDto.size() > MAX_UNIQUE_KEYS_POST_SIZE) { - for(List subChunk : Lists.partition(uniqueKey.keysDto, MAX_UNIQUE_KEYS_POST_SIZE)) { + for (List subChunk : partition(uniqueKey.keysDto, MAX_UNIQUE_KEYS_POST_SIZE)) { finalChunk.add(new UniqueKeys.UniqueKey(uniqueKey.featureName, subChunk)); } continue; @@ -157,6 +159,14 @@ private List capChunksToMaxSize(List return finalChunk; } + private static List> partition(List list, int size) { + List> result = new ArrayList<>(); + for (int i = 0; i < list.size(); i += size) { + result.add(list.subList(i, Math.min(i + size, list.size()))); + } + return result; + } + private List> getChunks(List uniqueKeys) { List> chunks = new ArrayList<>(); List intermediateChunk = new ArrayList<>(); @@ -180,13 +190,12 @@ private int getChunkSize(List uniqueKeysChunk) { } return totalSize; } - - private interface ExecuteUniqueKeysAction{ + + private interface ExecuteUniqueKeysAction { void execute(); } private class ExecuteCleanFilter implements ExecuteUniqueKeysAction { - @Override public void execute() { filterAdapter.clear(); @@ -194,7 +203,6 @@ public void execute() { } private class ExecuteSendUniqueKeys implements ExecuteUniqueKeysAction { - @Override public void execute() { sendUniqueKeys(); diff --git a/client/src/main/java/io/split/client/impressions/filters/BloomFilterImp.java b/impressions/src/main/java/io/split/client/impressions/filters/BloomFilterImp.java similarity index 100% rename from client/src/main/java/io/split/client/impressions/filters/BloomFilterImp.java rename to impressions/src/main/java/io/split/client/impressions/filters/BloomFilterImp.java diff --git a/client/src/main/java/io/split/client/impressions/filters/Filter.java b/impressions/src/main/java/io/split/client/impressions/filters/Filter.java similarity index 100% rename from client/src/main/java/io/split/client/impressions/filters/Filter.java rename to impressions/src/main/java/io/split/client/impressions/filters/Filter.java diff --git a/client/src/main/java/io/split/client/impressions/filters/FilterAdapter.java b/impressions/src/main/java/io/split/client/impressions/filters/FilterAdapter.java similarity index 100% rename from client/src/main/java/io/split/client/impressions/filters/FilterAdapter.java rename to impressions/src/main/java/io/split/client/impressions/filters/FilterAdapter.java diff --git a/client/src/main/java/io/split/client/impressions/filters/FilterAdapterImpl.java b/impressions/src/main/java/io/split/client/impressions/filters/FilterAdapterImpl.java similarity index 100% rename from client/src/main/java/io/split/client/impressions/filters/FilterAdapterImpl.java rename to impressions/src/main/java/io/split/client/impressions/filters/FilterAdapterImpl.java diff --git a/client/src/main/java/io/split/client/impressions/strategy/ProcessImpressionDebug.java b/impressions/src/main/java/io/split/client/impressions/strategy/ProcessImpressionDebug.java similarity index 100% rename from client/src/main/java/io/split/client/impressions/strategy/ProcessImpressionDebug.java rename to impressions/src/main/java/io/split/client/impressions/strategy/ProcessImpressionDebug.java diff --git a/client/src/main/java/io/split/client/impressions/strategy/ProcessImpressionNone.java b/impressions/src/main/java/io/split/client/impressions/strategy/ProcessImpressionNone.java similarity index 100% rename from client/src/main/java/io/split/client/impressions/strategy/ProcessImpressionNone.java rename to impressions/src/main/java/io/split/client/impressions/strategy/ProcessImpressionNone.java diff --git a/client/src/main/java/io/split/client/impressions/strategy/ProcessImpressionOptimized.java b/impressions/src/main/java/io/split/client/impressions/strategy/ProcessImpressionOptimized.java similarity index 70% rename from client/src/main/java/io/split/client/impressions/strategy/ProcessImpressionOptimized.java rename to impressions/src/main/java/io/split/client/impressions/strategy/ProcessImpressionOptimized.java index 65fd9ab49..99c6fc551 100644 --- a/client/src/main/java/io/split/client/impressions/strategy/ProcessImpressionOptimized.java +++ b/impressions/src/main/java/io/split/client/impressions/strategy/ProcessImpressionOptimized.java @@ -1,28 +1,27 @@ package io.split.client.impressions.strategy; import io.split.client.impressions.Impression; +import io.split.client.impressions.ImpressionCounter; import io.split.client.impressions.ImpressionObserver; -import io.split.client.impressions.ImpressionUtils; import io.split.client.impressions.ImpressionsResult; -import io.split.client.impressions.ImpressionCounter; -import io.split.telemetry.domain.enums.ImpressionsDataTypeEnum; -import io.split.telemetry.storage.TelemetryRuntimeProducer; +import io.split.client.impressions.ImpressionsTelemetryRecorder; +import io.split.client.impressions.ImpressionUtils; import java.util.ArrayList; import java.util.List; import java.util.Objects; -public class ProcessImpressionOptimized implements ProcessImpressionStrategy{ +public class ProcessImpressionOptimized implements ProcessImpressionStrategy { private final ImpressionObserver _impressionObserver; private final ImpressionCounter _impressionCounter; - private final TelemetryRuntimeProducer _telemetryRuntimeProducer; + private final ImpressionsTelemetryRecorder _telemetryRecorder; private final boolean _listenerEnabled; - - public ProcessImpressionOptimized(boolean listenerEnabled, ImpressionObserver impressionObserver, ImpressionCounter impressionCounter, - TelemetryRuntimeProducer telemetryRuntimeProducer) { - _telemetryRuntimeProducer = telemetryRuntimeProducer; + public ProcessImpressionOptimized(boolean listenerEnabled, ImpressionObserver impressionObserver, + ImpressionCounter impressionCounter, + ImpressionsTelemetryRecorder telemetryRecorder) { + _telemetryRecorder = telemetryRecorder; _listenerEnabled = listenerEnabled; _impressionObserver = impressionObserver; _impressionCounter = impressionCounter; @@ -31,7 +30,7 @@ public ProcessImpressionOptimized(boolean listenerEnabled, ImpressionObserver im @Override public ImpressionsResult process(List impressions) { List impressionsToQueue = new ArrayList<>(); - for(Impression impression : impressions) { + for (Impression impression : impressions) { if (impression.properties() == null) { impression = impression.withPreviousTime(_impressionObserver.testAndSet(impression)); if (!Objects.isNull(impression.pt()) && impression.pt() != 0) { @@ -43,10 +42,9 @@ public ImpressionsResult process(List impressions) { } impressionsToQueue.add(impression); } - List impressionForListener = this._listenerEnabled ? impressions : null; + List impressionForListener = this._listenerEnabled ? impressions : null; - _telemetryRuntimeProducer.recordImpressionStats(ImpressionsDataTypeEnum.IMPRESSIONS_DEDUPED, impressions.size()- - (long)impressionsToQueue.size()); + _telemetryRecorder.recordImpressionsDropped(impressions.size() - (long) impressionsToQueue.size()); return new ImpressionsResult(impressionsToQueue, impressionForListener); } diff --git a/client/src/main/java/io/split/client/impressions/strategy/ProcessImpressionStrategy.java b/impressions/src/main/java/io/split/client/impressions/strategy/ProcessImpressionStrategy.java similarity index 100% rename from client/src/main/java/io/split/client/impressions/strategy/ProcessImpressionStrategy.java rename to impressions/src/main/java/io/split/client/impressions/strategy/ProcessImpressionStrategy.java diff --git a/impressions/src/main/java/io/split/rules/bucketing/MurmurHash3.java b/impressions/src/main/java/io/split/rules/bucketing/MurmurHash3.java new file mode 100644 index 000000000..da0376d8e --- /dev/null +++ b/impressions/src/main/java/io/split/rules/bucketing/MurmurHash3.java @@ -0,0 +1,302 @@ +package io.split.rules.bucketing; + +/** + * The MurmurHash3 algorithm was created by Austin Appleby and placed in the public domain. + * This java port was authored by Yonik Seeley and also placed into the public domain. + * The author hereby disclaims copyright to this source code. + *

+ * This produces exactly the same hash values as the final C++ + * version of MurmurHash3 and is thus suitable for producing the same hash values across + * platforms. + *

+ * The 32 bit x86 version of this hash should be the fastest variant for relatively short keys like ids. + * murmurhash3_x64_128 is a good choice for longer strings or if you need more than 32 bits of hash. + *

+ * Note - The x86 and x64 versions do _not_ produce the same results, as the + * algorithms are optimized for their respective platforms. + *

+ * See http://github.com/yonik/java_util for future updates to this file. + */ +public final class MurmurHash3 { + + /** + * 128 bits of state + */ + public static final class LongPair { + public long val1; + public long val2; + } + + public static final int fmix32(int h) { + h ^= h >>> 16; + h *= 0x85ebca6b; + h ^= h >>> 13; + h *= 0xc2b2ae35; + h ^= h >>> 16; + return h; + } + + public static final long fmix64(long k) { + k ^= k >>> 33; + k *= 0xff51afd7ed558ccdL; + k ^= k >>> 33; + k *= 0xc4ceb9fe1a85ec53L; + k ^= k >>> 33; + return k; + } + + /** + * Gets a long from a byte buffer in little endian byte order. + */ + public static final long getLongLittleEndian(byte[] buf, int offset) { + return ((long) buf[offset + 7] << 56) // no mask needed + | ((buf[offset + 6] & 0xffL) << 48) + | ((buf[offset + 5] & 0xffL) << 40) + | ((buf[offset + 4] & 0xffL) << 32) + | ((buf[offset + 3] & 0xffL) << 24) + | ((buf[offset + 2] & 0xffL) << 16) + | ((buf[offset + 1] & 0xffL) << 8) + | ((buf[offset] & 0xffL)); // no shift needed + } + + + /** + * Returns the MurmurHash3_x86_32 hash of the UTF-8 bytes of the String without actually encoding + * the string to a temporary buffer. This is more than 2x faster than hashing the result + * of String.getBytes(). + */ + public static long murmurhash3_x86_32(CharSequence data, int offset, int len, int seed) { + + final int c1 = 0xcc9e2d51; + final int c2 = 0x1b873593; + + int h1 = seed; + + int pos = offset; + int end = offset + len; + int k1 = 0; + int k2 = 0; + int shift = 0; + int bits = 0; + int nBytes = 0; // length in UTF8 bytes + + + while (pos < end) { + int code = data.charAt(pos++); + if (code < 0x80) { + k2 = code; + bits = 8; + + } else if (code < 0x800) { + k2 = (0xC0 | (code >> 6)) + | ((0x80 | (code & 0x3F)) << 8); + bits = 16; + } else if (code < 0xD800 || code > 0xDFFF || pos >= end) { + // we check for pos>=end to encode an unpaired surrogate as 3 bytes. + k2 = (0xE0 | (code >> 12)) + | ((0x80 | ((code >> 6) & 0x3F)) << 8) + | ((0x80 | (code & 0x3F)) << 16); + bits = 24; + } else { + // surrogate pair + // int utf32 = pos < end ? (int) data.charAt(pos++) : 0; + int utf32 = (int) data.charAt(pos++); + utf32 = ((code - 0xD7C0) << 10) + (utf32 & 0x3FF); + k2 = (0xff & (0xF0 | (utf32 >> 18))) + | ((0x80 | ((utf32 >> 12) & 0x3F))) << 8 + | ((0x80 | ((utf32 >> 6) & 0x3F))) << 16 + | (0x80 | (utf32 & 0x3F)) << 24; + bits = 32; + } + + + k1 |= k2 << shift; + + // int used_bits = 32 - shift; // how many bits of k2 were used in k1. + // int unused_bits = bits - used_bits; // (bits-(32-shift)) == bits+shift-32 == bits-newshift + + shift += bits; + if (shift >= 32) { + // mix after we have a complete word + + k1 *= c1; + k1 = (k1 << 15) | (k1 >>> 17); // ROTL32(k1,15); + k1 *= c2; + + h1 ^= k1; + h1 = (h1 << 13) | (h1 >>> 19); // ROTL32(h1,13); + h1 = h1 * 5 + 0xe6546b64; + + shift -= 32; + // unfortunately, java won't let you shift 32 bits off, so we need to check for 0 + if (shift != 0) { + k1 = k2 >>> (bits - shift); // bits used == bits - newshift + } else { + k1 = 0; + } + nBytes += 4; + } + + } // inner + + // handle tail + if (shift > 0) { + nBytes += shift >> 3; + k1 *= c1; + k1 = (k1 << 15) | (k1 >>> 17); // ROTL32(k1,15); + k1 *= c2; + h1 ^= k1; + } + + // finalization + h1 ^= nBytes; + + // fmix(h1); + h1 ^= h1 >>> 16; + h1 *= 0x85ebca6b; + h1 ^= h1 >>> 13; + h1 *= 0xc2b2ae35; + h1 ^= h1 >>> 16; + + return h1 & 0xFFFFFFFFL; + } + + // The following set of methods and constants are borrowed from: + // `This method is borrowed from `org.apache.commons.codec.digest.MurmurHash3` + + // Constants for 128-bit variant + private static final long C1 = 0x87c37b91114253d5L; + private static final long C2 = 0x4cf5ad432745937fL; + private static final int R1 = 31; + private static final int R2 = 27; + private static final int R3 = 33; + private static final int M = 5; + private static final int N1 = 0x52dce729; + private static final int N2 = 0x38495ab5; + + /** + * Gets the little-endian long from 8 bytes starting at the specified index. + * + * @param data The data + * @param index The index + * @return The little-endian long + */ + private static long getLittleEndianLong(final byte[] data, final int index) { + return (((long) data[index ] & 0xff) ) | + (((long) data[index + 1] & 0xff) << 8) | + (((long) data[index + 2] & 0xff) << 16) | + (((long) data[index + 3] & 0xff) << 24) | + (((long) data[index + 4] & 0xff) << 32) | + (((long) data[index + 5] & 0xff) << 40) | + (((long) data[index + 6] & 0xff) << 48) | + (((long) data[index + 7] & 0xff) << 56); + } + + public static long[] hash128x64(final byte[] data) { + return hash128x64(data, 0, data.length, 0); + } + + /** + * Generates 128-bit hash from the byte array with the given offset, length and seed. + * + *

This is an implementation of the 128-bit hash function {@code MurmurHash3_x64_128} + * from from Austin Applyby's original MurmurHash3 {@code c++} code in SMHasher.

+ * + * @param data The input byte array + * @param offset The first element of array + * @param length The length of array + * @param seed The initial seed value + * @return The 128-bit hash (2 longs) + */ + public static long[] hash128x64(final byte[] data, final int offset, final int length, final long seed) { + long h1 = seed; + long h2 = seed; + final int nblocks = length >> 4; + + // body + for (int i = 0; i < nblocks; i++) { + final int index = offset + (i << 4); + long k1 = getLittleEndianLong(data, index); + long k2 = getLittleEndianLong(data, index + 8); + + // mix functions for k1 + k1 *= C1; + k1 = Long.rotateLeft(k1, R1); + k1 *= C2; + h1 ^= k1; + h1 = Long.rotateLeft(h1, R2); + h1 += h2; + h1 = h1 * M + N1; + + // mix functions for k2 + k2 *= C2; + k2 = Long.rotateLeft(k2, R3); + k2 *= C1; + h2 ^= k2; + h2 = Long.rotateLeft(h2, R1); + h2 += h1; + h2 = h2 * M + N2; + } + + // tail + long k1 = 0; + long k2 = 0; + final int index = offset + (nblocks << 4); + switch (offset + length - index) { + case 15: + k2 ^= ((long) data[index + 14] & 0xff) << 48; + case 14: + k2 ^= ((long) data[index + 13] & 0xff) << 40; + case 13: + k2 ^= ((long) data[index + 12] & 0xff) << 32; + case 12: + k2 ^= ((long) data[index + 11] & 0xff) << 24; + case 11: + k2 ^= ((long) data[index + 10] & 0xff) << 16; + case 10: + k2 ^= ((long) data[index + 9] & 0xff) << 8; + case 9: + k2 ^= data[index + 8] & 0xff; + k2 *= C2; + k2 = Long.rotateLeft(k2, R3); + k2 *= C1; + h2 ^= k2; + + case 8: + k1 ^= ((long) data[index + 7] & 0xff) << 56; + case 7: + k1 ^= ((long) data[index + 6] & 0xff) << 48; + case 6: + k1 ^= ((long) data[index + 5] & 0xff) << 40; + case 5: + k1 ^= ((long) data[index + 4] & 0xff) << 32; + case 4: + k1 ^= ((long) data[index + 3] & 0xff) << 24; + case 3: + k1 ^= ((long) data[index + 2] & 0xff) << 16; + case 2: + k1 ^= ((long) data[index + 1] & 0xff) << 8; + case 1: + k1 ^= data[index] & 0xff; + k1 *= C1; + k1 = Long.rotateLeft(k1, R1); + k1 *= C2; + h1 ^= k1; + } + + // finalization + h1 ^= length; + h2 ^= length; + + h1 += h2; + h2 += h1; + + h1 = fmix64(h1); + h2 = fmix64(h2); + + h1 += h2; + h2 += h1; + + return new long[] { h1, h2 }; + } +} \ No newline at end of file diff --git a/client/src/test/java/io/split/client/dtos/ImpressionCountTest.java b/impressions/src/test/java/io/split/client/dtos/ImpressionCountTest.java similarity index 100% rename from client/src/test/java/io/split/client/dtos/ImpressionCountTest.java rename to impressions/src/test/java/io/split/client/dtos/ImpressionCountTest.java diff --git a/client/src/test/java/io/split/client/dtos/KeyImpressionTest.java b/impressions/src/test/java/io/split/client/dtos/KeyImpressionTest.java similarity index 100% rename from client/src/test/java/io/split/client/dtos/KeyImpressionTest.java rename to impressions/src/test/java/io/split/client/dtos/KeyImpressionTest.java diff --git a/client/src/test/java/io/split/client/dtos/TestImpressionsTest.java b/impressions/src/test/java/io/split/client/dtos/TestImpressionsTest.java similarity index 100% rename from client/src/test/java/io/split/client/dtos/TestImpressionsTest.java rename to impressions/src/test/java/io/split/client/dtos/TestImpressionsTest.java diff --git a/client/src/test/java/io/split/client/dtos/UniqueKeysTest.java b/impressions/src/test/java/io/split/client/dtos/UniqueKeysTest.java similarity index 100% rename from client/src/test/java/io/split/client/dtos/UniqueKeysTest.java rename to impressions/src/test/java/io/split/client/dtos/UniqueKeysTest.java diff --git a/client/src/test/java/io/split/client/impressions/BloomFilterImpTest.java b/impressions/src/test/java/io/split/client/impressions/BloomFilterImpTest.java similarity index 100% rename from client/src/test/java/io/split/client/impressions/BloomFilterImpTest.java rename to impressions/src/test/java/io/split/client/impressions/BloomFilterImpTest.java diff --git a/client/src/test/java/io/split/client/impressions/FilterAdapterImplTest.java b/impressions/src/test/java/io/split/client/impressions/FilterAdapterImplTest.java similarity index 100% rename from client/src/test/java/io/split/client/impressions/FilterAdapterImplTest.java rename to impressions/src/test/java/io/split/client/impressions/FilterAdapterImplTest.java diff --git a/client/src/test/java/io/split/client/impressions/ImpressionCounterTest.java b/impressions/src/test/java/io/split/client/impressions/ImpressionCounterTest.java similarity index 100% rename from client/src/test/java/io/split/client/impressions/ImpressionCounterTest.java rename to impressions/src/test/java/io/split/client/impressions/ImpressionCounterTest.java diff --git a/client/src/test/java/io/split/client/impressions/ImpressionHasherTest.java b/impressions/src/test/java/io/split/client/impressions/ImpressionHasherTest.java similarity index 100% rename from client/src/test/java/io/split/client/impressions/ImpressionHasherTest.java rename to impressions/src/test/java/io/split/client/impressions/ImpressionHasherTest.java diff --git a/client/src/test/java/io/split/client/impressions/ImpressionObserverTest.java b/impressions/src/test/java/io/split/client/impressions/ImpressionObserverTest.java similarity index 99% rename from client/src/test/java/io/split/client/impressions/ImpressionObserverTest.java rename to impressions/src/test/java/io/split/client/impressions/ImpressionObserverTest.java index 57fc258aa..50eb338a3 100644 --- a/client/src/test/java/io/split/client/impressions/ImpressionObserverTest.java +++ b/impressions/src/test/java/io/split/client/impressions/ImpressionObserverTest.java @@ -23,7 +23,7 @@ public class ImpressionObserverTest { - private static final Logger _log = LoggerFactory.getLogger(ImpressionsManagerImpl.class); + private static final Logger _log = LoggerFactory.getLogger(ImpressionObserverTest.class); // We allow the cache implementation to have a 0.01% drift in size when elements change, given that it's internal // structure/references might vary, and the ObjectSizeCalculator is not 100% accurate diff --git a/client/src/test/java/io/split/client/impressions/ImpressionTestUtils.java b/impressions/src/test/java/io/split/client/impressions/ImpressionTestUtils.java similarity index 100% rename from client/src/test/java/io/split/client/impressions/ImpressionTestUtils.java rename to impressions/src/test/java/io/split/client/impressions/ImpressionTestUtils.java diff --git a/client/src/test/java/io/split/client/impressions/ImpressionsManagerImplTest.java b/impressions/src/test/java/io/split/client/impressions/ImpressionsManagerImplTest.java similarity index 80% rename from client/src/test/java/io/split/client/impressions/ImpressionsManagerImplTest.java rename to impressions/src/test/java/io/split/client/impressions/ImpressionsManagerImplTest.java index 6dbf5061f..29a358d5d 100644 --- a/client/src/test/java/io/split/client/impressions/ImpressionsManagerImplTest.java +++ b/impressions/src/test/java/io/split/client/impressions/ImpressionsManagerImplTest.java @@ -1,6 +1,5 @@ package io.split.client.impressions; -import io.split.client.SplitClientConfig; import io.split.client.dtos.DecoratedImpression; import io.split.client.dtos.KeyImpression; import io.split.client.dtos.TestImpressions; @@ -9,14 +8,9 @@ import io.split.client.impressions.strategy.ProcessImpressionDebug; import io.split.client.impressions.strategy.ProcessImpressionNone; import io.split.client.impressions.strategy.ProcessImpressionOptimized; +import io.split.client.impressions.ImpressionsManagerConfig; +import io.split.client.impressions.ImpressionsTelemetryRecorder; import io.split.client.impressions.strategy.ProcessImpressionStrategy; -import io.split.storages.enums.OperationMode; -import io.split.telemetry.domain.enums.ImpressionsDataTypeEnum; -import io.split.telemetry.storage.InMemoryTelemetryStorage; -import io.split.telemetry.storage.TelemetryStorage; -import io.split.telemetry.storage.TelemetryStorageProducer; -import io.split.telemetry.synchronizer.TelemetryInMemorySubmitter; -import io.split.telemetry.synchronizer.TelemetrySynchronizer; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -25,7 +19,6 @@ import org.mockito.Captor; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; -import pluggable.CustomStorageWrapper; import java.net.URISyntaxException; import java.util.*; @@ -43,11 +36,11 @@ */ @RunWith(MockitoJUnitRunner.class) public class ImpressionsManagerImplTest { - private static TelemetryStorage TELEMETRY_STORAGE = Mockito.mock(InMemoryTelemetryStorage.class); + private static ImpressionsTelemetryRecorder TELEMETRY_RECORDER = Mockito.mock(ImpressionsTelemetryRecorder.class); @Before public void setUp() { - TELEMETRY_STORAGE = Mockito.mock(InMemoryTelemetryStorage.class); + TELEMETRY_RECORDER = Mockito.mock(ImpressionsTelemetryRecorder.class); } @Captor @@ -64,12 +57,10 @@ public void setUp() { @Test public void works() throws URISyntaxException { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(4) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.DEBUG) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.DEBUG) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(4); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); ImpressionCounter impressionCounter = Mockito.mock(ImpressionCounter.class); @@ -78,7 +69,7 @@ public void works() throws URISyntaxException { ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionDebug(false, impressionObserver); ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(false, null, null); - ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); + ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); treatmentLog.start(); KeyImpression ki1 = keyImpression("test1", "adil", "on", 1L, null, null); @@ -103,24 +94,21 @@ public void works() throws URISyntaxException { @Test public void testImpressionListenerOptimize() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.OPTIMIZED) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.OPTIMIZED) .build(); ImpressionsStorage storage = Mockito.mock(InMemoryImpressionsStorage.class); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); ImpressionCounter impressionCounter = new ImpressionCounter(); ImpressionObserver impressionObserver = new ImpressionObserver(200); - TelemetryStorageProducer telemetryStorageProducer = new InMemoryTelemetryStorage(); - - ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionOptimized(true, impressionObserver, impressionCounter, telemetryStorageProducer); + + ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionOptimized(true, impressionObserver, impressionCounter, TELEMETRY_RECORDER); ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(false, null, null); ImpressionListener impressionListener = Mockito.mock(AsynchronousImpressionListener.class); - ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, impressionListener); + ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, impressionListener); treatmentLog.start(); KeyImpression ki1 = keyImpression("test1", "adil", "on", 1L, 1L, null); @@ -146,10 +134,8 @@ public void testImpressionListenerOptimize() { @Test public void testImpressionListenerDebug() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(6) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.DEBUG) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.DEBUG) .build(); ImpressionsStorage storage = Mockito.mock(InMemoryImpressionsStorage.class); @@ -162,7 +148,7 @@ public void testImpressionListenerDebug() { ImpressionListener impressionListener = Mockito.mock(AsynchronousImpressionListener.class); - ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, impressionListener); + ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, impressionListener); treatmentLog.start(); KeyImpression ki1 = keyImpression("test1", "adil", "on", 1L, 1L, null); @@ -188,17 +174,15 @@ public void testImpressionListenerDebug() { @Test public void testImpressionListenerNone() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.NONE) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.NONE) .build(); ImpressionsStorage storage = Mockito.mock(InMemoryImpressionsStorage.class); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); - TelemetrySynchronizer telemetrySynchronizer = Mockito.mock(TelemetryInMemorySubmitter.class); + UniqueKeysSender uniqueKeysSender = Mockito.mock(UniqueKeysSender.class); ImpressionCounter impressionCounter = new ImpressionCounter(); - UniqueKeysTracker uniqueKeysTracker = new UniqueKeysTrackerImp(telemetrySynchronizer, 1000, 1000, null); + UniqueKeysTracker uniqueKeysTracker = new UniqueKeysTrackerImp(uniqueKeysSender, 1000, 1000, null); uniqueKeysTracker.start(); ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionNone(true, uniqueKeysTracker, impressionCounter); @@ -206,7 +190,7 @@ public void testImpressionListenerNone() { ImpressionListener impressionListener = Mockito.mock(AsynchronousImpressionListener.class); - ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, impressionListener); + ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, impressionListener); treatmentLog.start(); KeyImpression ki1 = keyImpression("test1", "adil", "on", 1L, 1L, null); @@ -233,12 +217,10 @@ public void testImpressionListenerNone() { @Test public void worksButDropsImpressions() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(3) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.DEBUG) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.DEBUG) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(3); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); ImpressionCounter impressionCounter = Mockito.mock(ImpressionCounter.class); @@ -247,7 +229,7 @@ public void worksButDropsImpressions() { ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionDebug(false, impressionObserver); ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(false, null, null); - ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); + ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); treatmentLog.start(); // These 4 unique test name will cause 4 entries but we are caping at the first 3. @@ -269,18 +251,16 @@ public void worksButDropsImpressions() { List captured = impressionsCaptor.getValue(); Assert.assertEquals(3, captured.size()); - verify(TELEMETRY_STORAGE, times(1)).recordImpressionStats(ImpressionsDataTypeEnum.IMPRESSIONS_DROPPED, 1); + verify(TELEMETRY_RECORDER, times(1)).recordImpressionsDropped(1); } @Test public void works4ImpressionsInOneTest() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.DEBUG) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.DEBUG) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(10); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); ImpressionCounter impressionCounter = Mockito.mock(ImpressionCounter.class); @@ -289,7 +269,7 @@ public void works4ImpressionsInOneTest() { ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionDebug(false, impressionObserver); ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(false, null, null); - ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); + ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); treatmentLog.start(); // These 4 unique test name will cause 4 entries but we are caping at the first 3. @@ -313,18 +293,16 @@ public void works4ImpressionsInOneTest() { Assert.assertEquals(1, captured.size()); Assert.assertEquals(4, captured.get(0).keyImpressions.size()); Assert.assertEquals(ki1, captured.get(0).keyImpressions.get(0)); - verify(TELEMETRY_STORAGE, times(4)).recordImpressionStats(ImpressionsDataTypeEnum.IMPRESSIONS_QUEUED, 1); + verify(TELEMETRY_RECORDER, times(4)).recordImpressionsQueued(1); } @Test public void worksNoImpressions() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.DEBUG) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.DEBUG) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(10); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); ImpressionCounter impressionCounter = Mockito.mock(ImpressionCounter.class); @@ -333,7 +311,7 @@ public void worksNoImpressions() { ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionDebug(false, impressionObserver); ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(false, null, null); - ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); + ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); // There are no impressions to post. @@ -345,12 +323,10 @@ public void worksNoImpressions() { @Test public void alreadySeenImpressionsAreMarked() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.DEBUG) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.DEBUG) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(10); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); ImpressionCounter impressionCounter = Mockito.mock(ImpressionCounter.class); @@ -358,7 +334,7 @@ public void alreadySeenImpressionsAreMarked() { ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionDebug(false, impressionObserver); ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(false, null, null); - ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); + ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); treatmentLog.start(); // These 4 unique test name will cause 4 entries but we are caping at the first 3. @@ -402,22 +378,19 @@ public void alreadySeenImpressionsAreMarked() { @Test public void testImpressionsStandaloneModeOptimizedMode() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.OPTIMIZED) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.OPTIMIZED) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(10); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); ImpressionCounter impressionCounter = new ImpressionCounter(); ImpressionObserver impressionObserver = new ImpressionObserver(200); - TelemetryStorageProducer telemetryStorageProducer = new InMemoryTelemetryStorage(); - - ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionOptimized(false, impressionObserver, impressionCounter, telemetryStorageProducer); + + ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionOptimized(false, impressionObserver, impressionCounter, TELEMETRY_RECORDER); ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(false, null, null); - ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); + ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); treatmentLog.start(); // These 4 unique test name will cause 4 entries but we are caping at the first 3. @@ -459,12 +432,10 @@ public void testImpressionsStandaloneModeOptimizedMode() { @Test public void testImpressionsStandaloneModeDebugMode() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.DEBUG) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.DEBUG) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(10); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); ImpressionCounter impressionCounter = Mockito.mock(ImpressionCounter.class); @@ -472,7 +443,7 @@ public void testImpressionsStandaloneModeDebugMode() { ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionDebug(false, impressionObserver); ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(false, null, null); - ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); + ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); treatmentLog.start(); // These 4 unique test name will cause 4 entries but we are caping at the first 3. @@ -508,23 +479,21 @@ public void testImpressionsStandaloneModeDebugMode() { @Test public void testImpressionsStandaloneModeNoneMode() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.NONE) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.NONE) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(10); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); - TelemetrySynchronizer telemetrySynchronizer = Mockito.mock(TelemetryInMemorySubmitter.class); + UniqueKeysSender uniqueKeysSender = Mockito.mock(UniqueKeysSender.class); ImpressionCounter impressionCounter = new ImpressionCounter(); - UniqueKeysTracker uniqueKeysTracker = new UniqueKeysTrackerImp(telemetrySynchronizer, 1000, 1000, null); + UniqueKeysTracker uniqueKeysTracker = new UniqueKeysTrackerImp(uniqueKeysSender, 1000, 1000, null); uniqueKeysTracker.start(); ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionNone(false, uniqueKeysTracker, impressionCounter); ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(false, null, null); - ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); + ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); treatmentLog.start(); // These 4 unique test name will cause 4 entries but we are caping at the first 3. @@ -540,7 +509,7 @@ public void testImpressionsStandaloneModeNoneMode() { treatmentLog.close(); uniqueKeysTracker.stop(); - verify(telemetrySynchronizer).synchronizeUniqueKeys(uniqueKeysCaptor.capture()); + verify(uniqueKeysSender).send(uniqueKeysCaptor.capture()); List uniqueKeysList = uniqueKeysCaptor.getAllValues(); UniqueKeys uniqueKeys = uniqueKeysList.get(0); @@ -565,23 +534,18 @@ public void testImpressionsStandaloneModeNoneMode() { @Test public void testImpressionsConsumerModeOptimizedMode() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.OPTIMIZED) - .operationMode(OperationMode.CONSUMER) - .customStorageWrapper(Mockito.mock(CustomStorageWrapper.class)) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.OPTIMIZED) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(10); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); ImpressionCounter impressionCounter = new ImpressionCounter(); ImpressionObserver impressionObserver = new ImpressionObserver(200); - TelemetryStorageProducer telemetryStorageProducer = new InMemoryTelemetryStorage(); - - ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionOptimized(false, impressionObserver, impressionCounter, telemetryStorageProducer); + + ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionOptimized(false, impressionObserver, impressionCounter, TELEMETRY_RECORDER); ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(false, null, null); - ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); + ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); treatmentLog.start(); // These 4 unique test name will cause 4 entries but we are caping at the first 3. @@ -623,24 +587,20 @@ public void testImpressionsConsumerModeOptimizedMode() { @Test public void testImpressionsConsumerModeNoneMode() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.NONE) - .operationMode(OperationMode.CONSUMER) - .customStorageWrapper(Mockito.mock(CustomStorageWrapper.class)) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.NONE) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(10); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); - TelemetrySynchronizer telemetrySynchronizer = Mockito.mock(TelemetryInMemorySubmitter.class); + UniqueKeysSender uniqueKeysSender = Mockito.mock(UniqueKeysSender.class); ImpressionCounter impressionCounter = new ImpressionCounter(); - UniqueKeysTracker uniqueKeysTracker = new UniqueKeysTrackerImp(telemetrySynchronizer, 1000, 1000, null); + UniqueKeysTracker uniqueKeysTracker = new UniqueKeysTrackerImp(uniqueKeysSender, 1000, 1000, null); uniqueKeysTracker.start(); ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionNone(false, uniqueKeysTracker, impressionCounter); ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(false, null, null); - ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); + ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); treatmentLog.start(); // These 4 unique test name will cause 4 entries but we are caping at the first 3. @@ -656,7 +616,7 @@ public void testImpressionsConsumerModeNoneMode() { uniqueKeysTracker.stop(); treatmentLog.close(); - verify(telemetrySynchronizer).synchronizeUniqueKeys(uniqueKeysCaptor.capture()); + verify(uniqueKeysSender).send(uniqueKeysCaptor.capture()); List uniqueKeysList = uniqueKeysCaptor.getAllValues(); UniqueKeys uniqueKeys = uniqueKeysList.get(0); @@ -681,14 +641,10 @@ public void testImpressionsConsumerModeNoneMode() { @Test public void testImpressionsConsumerModeDebugMode() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.DEBUG) - .operationMode(OperationMode.CONSUMER) - .customStorageWrapper(Mockito.mock(CustomStorageWrapper.class)) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.DEBUG) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(10); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); ImpressionCounter impressionCounter = Mockito.mock(ImpressionCounter.class); @@ -696,7 +652,7 @@ public void testImpressionsConsumerModeDebugMode() { ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionDebug(false, impressionObserver); ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(false, null, null); - ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); + ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); treatmentLog.start(); // These 4 unique test name will cause 4 entries but we are caping at the first 3. @@ -732,142 +688,119 @@ public void testImpressionsConsumerModeDebugMode() { @Test public void testCounterStandaloneModeOptimizedMode() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.OPTIMIZED) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.OPTIMIZED) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(10); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); ImpressionCounter impressionCounter = Mockito.mock(ImpressionCounter.class); ImpressionObserver impressionObserver = new ImpressionObserver(200); - TelemetryStorageProducer telemetryStorageProducer = new InMemoryTelemetryStorage(); - - ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionOptimized(false, impressionObserver, impressionCounter, telemetryStorageProducer); + + ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionOptimized(false, impressionObserver, impressionCounter, TELEMETRY_RECORDER); ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(false, null, null); - ImpressionsManagerImpl manager = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); + ImpressionsManagerImpl manager = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); manager.start(); Assert.assertNotNull(manager.getCounter()); } @Test public void testCounterStandaloneModeDebugMode() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.DEBUG) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.DEBUG) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(10); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); ImpressionObserver impressionObserver = new ImpressionObserver(200); ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionDebug(false, impressionObserver); ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(false, null, null); - ImpressionsManagerImpl manager = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, null, null); + ImpressionsManagerImpl manager = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, null, null); manager.start(); Assert.assertNull(manager.getCounter()); } @Test public void testCounterStandaloneModeNoneMode() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.NONE) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.NONE) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(10); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); ProcessImpressionStrategy processImpressionStrategy = Mockito.mock(ProcessImpressionNone.class); ImpressionCounter impressionCounter = Mockito.mock(ImpressionCounter.class); - ImpressionsManagerImpl manager = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, Mockito.mock(ProcessImpressionNone.class), processImpressionStrategy, impressionCounter, null); + ImpressionsManagerImpl manager = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, Mockito.mock(ProcessImpressionNone.class), processImpressionStrategy, impressionCounter, null); manager.start(); Assert.assertNotNull(manager.getCounter()); } @Test public void testCounterConsumerModeOptimizedMode() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.OPTIMIZED) - .operationMode(OperationMode.CONSUMER) - .customStorageWrapper(Mockito.mock(CustomStorageWrapper.class)) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.OPTIMIZED) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(10); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); ProcessImpressionStrategy processImpressionStrategy = Mockito.mock(ProcessImpressionOptimized.class); ImpressionCounter impressionCounter = Mockito.mock(ImpressionCounter.class); - ImpressionsManagerImpl manager = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, Mockito.mock(ProcessImpressionNone.class), processImpressionStrategy, impressionCounter, null); + ImpressionsManagerImpl manager = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, Mockito.mock(ProcessImpressionNone.class), processImpressionStrategy, impressionCounter, null); manager.start(); Assert.assertNotNull(manager.getCounter()); } @Test public void testCounterConsumerModeDebugMode() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.DEBUG) - .operationMode(OperationMode.CONSUMER) - .customStorageWrapper(Mockito.mock(CustomStorageWrapper.class)) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.DEBUG) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(10); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); ProcessImpressionStrategy processImpressionStrategy = Mockito.mock(ProcessImpressionDebug.class); - ImpressionsManagerImpl manager = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, Mockito.mock(ProcessImpressionNone.class), processImpressionStrategy, null, null); + ImpressionsManagerImpl manager = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, Mockito.mock(ProcessImpressionNone.class), processImpressionStrategy, null, null); manager.start(); Assert.assertNull(manager.getCounter()); } @Test public void testCounterConsumerModeNoneMode() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.NONE) - .operationMode(OperationMode.CONSUMER) - .customStorageWrapper(Mockito.mock(CustomStorageWrapper.class)) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.NONE) .build(); - - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(10); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); ProcessImpressionStrategy processImpressionStrategy = Mockito.mock(ProcessImpressionNone.class); ImpressionCounter impressionCounter = Mockito.mock(ImpressionCounter.class); - ImpressionsManagerImpl manager = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, Mockito.mock(ProcessImpressionNone.class), processImpressionStrategy, impressionCounter, null); + ImpressionsManagerImpl manager = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, Mockito.mock(ProcessImpressionNone.class), processImpressionStrategy, impressionCounter, null); manager.start(); Assert.assertNotNull(manager.getCounter()); } @Test public void testImpressionToggleStandaloneOptimizedMode() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.OPTIMIZED) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.OPTIMIZED) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(10); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); ImpressionCounter impressionCounter = new ImpressionCounter(); ImpressionObserver impressionObserver = new ImpressionObserver(200); - TelemetryStorageProducer telemetryStorageProducer = new InMemoryTelemetryStorage(); - TelemetrySynchronizer telemetrySynchronizer = Mockito.mock(TelemetryInMemorySubmitter.class); - UniqueKeysTracker uniqueKeysTracker = new UniqueKeysTrackerImp(telemetrySynchronizer, 1000, 1000, null); + UniqueKeysSender uniqueKeysSender1 = Mockito.mock(UniqueKeysSender.class); + UniqueKeysTracker uniqueKeysTracker = new UniqueKeysTrackerImp(uniqueKeysSender1, 1000, 1000, null); uniqueKeysTracker.start(); - ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionOptimized(false, impressionObserver, impressionCounter, telemetryStorageProducer); + ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionOptimized(false, impressionObserver, impressionCounter, TELEMETRY_RECORDER); ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(false, uniqueKeysTracker, impressionCounter); - ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); + ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); treatmentLog.start(); // These 4 unique test name will cause 4 entries but we are caping at the first 3. @@ -916,23 +849,21 @@ public void testImpressionToggleStandaloneOptimizedMode() { @Test public void testImpressionToggleStandaloneModeDebugMode() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.DEBUG) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.DEBUG) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(10); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); ImpressionCounter impressionCounter = Mockito.mock(ImpressionCounter.class); ImpressionObserver impressionObserver = new ImpressionObserver(200); ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionDebug(false, impressionObserver); - TelemetrySynchronizer telemetrySynchronizer = Mockito.mock(TelemetryInMemorySubmitter.class); - UniqueKeysTracker uniqueKeysTracker = new UniqueKeysTrackerImp(telemetrySynchronizer, 1000, 1000, null); + UniqueKeysSender uniqueKeysSender2 = Mockito.mock(UniqueKeysSender.class); + UniqueKeysTracker uniqueKeysTracker = new UniqueKeysTrackerImp(uniqueKeysSender2, 1000, 1000, null); uniqueKeysTracker.start(); ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(false, uniqueKeysTracker, impressionCounter); - ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); + ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); treatmentLog.start(); // These 4 unique test name will cause 4 entries but we are caping at the first 3. @@ -971,23 +902,21 @@ public void testImpressionToggleStandaloneModeDebugMode() { @Test public void testImpressionToggleStandaloneModeNoneMode() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.NONE) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.NONE) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(10); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); - TelemetrySynchronizer telemetrySynchronizer = Mockito.mock(TelemetryInMemorySubmitter.class); + UniqueKeysSender uniqueKeysSender = Mockito.mock(UniqueKeysSender.class); ImpressionCounter impressionCounter = new ImpressionCounter(); - UniqueKeysTracker uniqueKeysTracker = new UniqueKeysTrackerImp(telemetrySynchronizer, 1000, 1000, null); + UniqueKeysTracker uniqueKeysTracker = new UniqueKeysTrackerImp(uniqueKeysSender, 1000, 1000, null); uniqueKeysTracker.start(); ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionNone(false, uniqueKeysTracker, impressionCounter); ProcessImpressionNone processImpressionNone = (ProcessImpressionNone) processImpressionStrategy; - ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); + ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); treatmentLog.start(); // These 4 unique test name will cause 4 entries but we are caping at the first 3. @@ -1026,23 +955,18 @@ public void testImpressionToggleStandaloneModeNoneMode() { @Test public void testImpressionsPropertiesOptimizedMode() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.OPTIMIZED) - .operationMode(OperationMode.CONSUMER) - .customStorageWrapper(Mockito.mock(CustomStorageWrapper.class)) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.OPTIMIZED) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(10); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); ImpressionCounter impressionCounter = new ImpressionCounter(); ImpressionObserver impressionObserver = new ImpressionObserver(200); - TelemetryStorageProducer telemetryStorageProducer = new InMemoryTelemetryStorage(); - - ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionOptimized(false, impressionObserver, impressionCounter, telemetryStorageProducer); + + ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionOptimized(false, impressionObserver, impressionCounter, TELEMETRY_RECORDER); ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(false, null, null); - ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); + ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); treatmentLog.start(); // These 4 unique test name will cause 4 entries but we are caping at the first 3. @@ -1085,14 +1009,10 @@ public void testImpressionsPropertiesOptimizedMode() { @Test public void testImpressionsPropertiesDebugMode() { - SplitClientConfig config = SplitClientConfig.builder() - .impressionsQueueSize(10) - .endpoint("nowhere.com", "nowhere.com") - .impressionsMode(ImpressionsManager.Mode.DEBUG) - .operationMode(OperationMode.CONSUMER) - .customStorageWrapper(Mockito.mock(CustomStorageWrapper.class)) + ImpressionsManagerConfig config = ImpressionsManagerConfig.builder() + .mode(ImpressionsManager.Mode.DEBUG) .build(); - ImpressionsStorage storage = new InMemoryImpressionsStorage(config.impressionsQueueSize()); + ImpressionsStorage storage = new InMemoryImpressionsStorage(10); ImpressionsSender senderMock = Mockito.mock(ImpressionsSender.class); ImpressionCounter impressionCounter = Mockito.mock(ImpressionCounter.class); @@ -1100,7 +1020,7 @@ public void testImpressionsPropertiesDebugMode() { ProcessImpressionStrategy processImpressionStrategy = new ProcessImpressionDebug(false, impressionObserver); ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(false, null, null); - ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_STORAGE, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); + ImpressionsManagerImpl treatmentLog = ImpressionsManagerImpl.instanceForTest(config, senderMock, TELEMETRY_RECORDER, storage, storage, processImpressionNone, processImpressionStrategy, impressionCounter, null); treatmentLog.start(); // These 4 unique test name will cause 4 entries but we are caping at the first 3. diff --git a/client/src/test/java/io/split/client/impressions/InMemoryImpressionsStorageTest.java b/impressions/src/test/java/io/split/client/impressions/InMemoryImpressionsStorageTest.java similarity index 100% rename from client/src/test/java/io/split/client/impressions/InMemoryImpressionsStorageTest.java rename to impressions/src/test/java/io/split/client/impressions/InMemoryImpressionsStorageTest.java diff --git a/client/src/test/java/io/split/client/impressions/UniqueKeysTrackerImpTest.java b/impressions/src/test/java/io/split/client/impressions/UniqueKeysTrackerImpTest.java similarity index 83% rename from client/src/test/java/io/split/client/impressions/UniqueKeysTrackerImpTest.java rename to impressions/src/test/java/io/split/client/impressions/UniqueKeysTrackerImpTest.java index e758369eb..e769390fc 100644 --- a/client/src/test/java/io/split/client/impressions/UniqueKeysTrackerImpTest.java +++ b/impressions/src/test/java/io/split/client/impressions/UniqueKeysTrackerImpTest.java @@ -1,8 +1,6 @@ package io.split.client.impressions; import io.split.client.dtos.UniqueKeys; -import io.split.telemetry.synchronizer.TelemetryInMemorySubmitter; -import io.split.telemetry.synchronizer.TelemetrySynchronizer; import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; @@ -10,19 +8,19 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.ArrayList; import java.util.concurrent.atomic.AtomicInteger; public class UniqueKeysTrackerImpTest { - private static TelemetrySynchronizer _telemetrySynchronizer = Mockito.mock(TelemetryInMemorySubmitter.class); + private static UniqueKeysSender _uniqueKeysSender = Mockito.mock(UniqueKeysSender.class); @Test public void addSomeElements(){ - UniqueKeysTrackerImp uniqueKeysTrackerImp = new UniqueKeysTrackerImp(_telemetrySynchronizer, 10000, 10000, null); + UniqueKeysTrackerImp uniqueKeysTrackerImp = new UniqueKeysTrackerImp(_uniqueKeysSender, 10000, 10000, null); Assert.assertTrue(uniqueKeysTrackerImp.track("feature1","key1")); Assert.assertTrue(uniqueKeysTrackerImp.track("feature1","key2")); Assert.assertTrue(uniqueKeysTrackerImp.track("feature1","key3")); @@ -46,7 +44,7 @@ public void addSomeElements(){ @Test public void addTheSameElements(){ - UniqueKeysTrackerImp uniqueKeysTrackerImp = new UniqueKeysTrackerImp(_telemetrySynchronizer, 10000, 10000, null); + UniqueKeysTrackerImp uniqueKeysTrackerImp = new UniqueKeysTrackerImp(_uniqueKeysSender, 10000, 10000, null); Assert.assertTrue(uniqueKeysTrackerImp.track("feature1","key1")); Assert.assertTrue(uniqueKeysTrackerImp.track("feature1","key2")); Assert.assertTrue(uniqueKeysTrackerImp.track("feature1","key3")); @@ -67,7 +65,7 @@ public void addTheSameElements(){ @Test public void popAllUniqueKeys(){ - UniqueKeysTrackerImp uniqueKeysTrackerImp = new UniqueKeysTrackerImp(_telemetrySynchronizer, 10000, 10000, null); + UniqueKeysTrackerImp uniqueKeysTrackerImp = new UniqueKeysTrackerImp(_uniqueKeysSender, 10000, 10000, null); Assert.assertTrue(uniqueKeysTrackerImp.track("feature1","key1")); Assert.assertTrue(uniqueKeysTrackerImp.track("feature1","key2")); Assert.assertTrue(uniqueKeysTrackerImp.track("feature2","key3")); @@ -80,23 +78,23 @@ public void popAllUniqueKeys(){ @Test public void testSynchronization() throws Exception { - TelemetrySynchronizer telemetrySynchronizer = Mockito.mock(TelemetryInMemorySubmitter.class); - UniqueKeysTrackerImp uniqueKeysTrackerImp = new UniqueKeysTrackerImp(telemetrySynchronizer, 1, 3, null); + UniqueKeysSender sender = Mockito.mock(UniqueKeysSender.class); + UniqueKeysTrackerImp uniqueKeysTrackerImp = new UniqueKeysTrackerImp(sender, 1, 3, null); uniqueKeysTrackerImp.start(); Assert.assertTrue(uniqueKeysTrackerImp.track("feature1","key1")); Assert.assertTrue(uniqueKeysTrackerImp.track("feature1","key2")); Assert.assertTrue(uniqueKeysTrackerImp.track("feature2","key3")); Thread.sleep(2900); - Mockito.verify(telemetrySynchronizer, Mockito.times(1)).synchronizeUniqueKeys(Mockito.anyObject()); + Mockito.verify(sender, Mockito.times(1)).send(Mockito.anyObject()); Thread.sleep(2900); - Mockito.verify(telemetrySynchronizer, Mockito.times(1)).synchronizeUniqueKeys(Mockito.anyObject()); + Mockito.verify(sender, Mockito.times(1)).send(Mockito.anyObject()); } @Test public void testStopSynchronization() throws Exception { - TelemetrySynchronizer telemetrySynchronizer = Mockito.mock(TelemetryInMemorySubmitter.class); - UniqueKeysTrackerImp uniqueKeysTrackerImp = new UniqueKeysTrackerImp(telemetrySynchronizer, 1, 2, null); + UniqueKeysSender sender = Mockito.mock(UniqueKeysSender.class); + UniqueKeysTrackerImp uniqueKeysTrackerImp = new UniqueKeysTrackerImp(sender, 1, 2, null); uniqueKeysTrackerImp.start(); Assert.assertFalse(uniqueKeysTrackerImp.getSendGuard().get()); Assert.assertTrue(uniqueKeysTrackerImp.track("feature1","key1")); @@ -104,14 +102,14 @@ public void testStopSynchronization() throws Exception { Assert.assertTrue(uniqueKeysTrackerImp.track("feature2","key3")); Thread.sleep(2100); - Mockito.verify(telemetrySynchronizer, Mockito.times(1)).synchronizeUniqueKeys(Mockito.anyObject()); + Mockito.verify(sender, Mockito.times(1)).send(Mockito.anyObject()); uniqueKeysTrackerImp.stop(); - Mockito.verify(telemetrySynchronizer, Mockito.times(1)).synchronizeUniqueKeys(Mockito.anyObject()); + Mockito.verify(sender, Mockito.times(1)).send(Mockito.anyObject()); } @Test public void testUniqueKeysChunks() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { - UniqueKeysTrackerImp uniqueKeysTrackerImp = new UniqueKeysTrackerImp(_telemetrySynchronizer, 10000, 10000, null); + UniqueKeysTrackerImp uniqueKeysTrackerImp = new UniqueKeysTrackerImp(_uniqueKeysSender, 10000, 10000, null); HashMap> uniqueKeysHashMap = new HashMap<>(); HashSet feature1 = new HashSet<>(); HashSet feature2 = new HashSet<>(); @@ -162,17 +160,17 @@ public void testUniqueKeysChunks() throws NoSuchMethodException, InvocationTarge @Test public void testTrackReachMaxKeys() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException { - TelemetrySynchronizer telemetrySynchronizer = Mockito.mock(TelemetryInMemorySubmitter.class); - UniqueKeysTrackerImp uniqueKeysTrackerImp = new UniqueKeysTrackerImp(telemetrySynchronizer, 10000, 10000, null); + UniqueKeysSender sender = Mockito.mock(UniqueKeysSender.class); + UniqueKeysTrackerImp uniqueKeysTrackerImp = new UniqueKeysTrackerImp(sender, 10000, 10000, null); for (int i=1; i<6000; i++) { Assert.assertTrue(uniqueKeysTrackerImp.track("feature1", "key" + i)); Assert.assertTrue(uniqueKeysTrackerImp.track("feature2", "key" + i)); } - Mockito.verify(telemetrySynchronizer, Mockito.times(2)).synchronizeUniqueKeys(Mockito.anyObject()); + Mockito.verify(sender, Mockito.times(2)).send(Mockito.anyObject()); Field getTrackerSize = uniqueKeysTrackerImp.getClass().getDeclaredField("trackerKeysSize"); getTrackerSize.setAccessible(true); AtomicInteger trackerSize = (AtomicInteger) getTrackerSize.get(uniqueKeysTrackerImp); Assert.assertTrue(trackerSize.intValue() == 1998); } -} \ No newline at end of file +} diff --git a/client/src/test/java/io/split/client/impressions/strategy/ProcessImpressionDebugTest.java b/impressions/src/test/java/io/split/client/impressions/strategy/ProcessImpressionDebugTest.java similarity index 82% rename from client/src/test/java/io/split/client/impressions/strategy/ProcessImpressionDebugTest.java rename to impressions/src/test/java/io/split/client/impressions/strategy/ProcessImpressionDebugTest.java index 68be97c58..e464745ce 100644 --- a/client/src/test/java/io/split/client/impressions/strategy/ProcessImpressionDebugTest.java +++ b/impressions/src/test/java/io/split/client/impressions/strategy/ProcessImpressionDebugTest.java @@ -6,11 +6,8 @@ import io.split.client.impressions.Impression; import io.split.client.impressions.ImpressionObserver; import io.split.client.impressions.ImpressionsResult; -import io.split.telemetry.storage.InMemoryTelemetryStorage; -import io.split.telemetry.storage.TelemetryStorage; import org.junit.Assert; import org.junit.Test; -import org.mockito.Mockito; import java.util.ArrayList; import java.util.List; @@ -18,10 +15,9 @@ public class ProcessImpressionDebugTest { private static final long LAST_SEEN_CACHE_SIZE = 500000; - private static TelemetryStorage TELEMETRY_STORAGE = Mockito.mock(InMemoryTelemetryStorage.class); @Test - public void processImpressionsWithListener(){ + public void processImpressionsWithListener() { boolean listenerEnable = true; ImpressionObserver impressionObserver = new ImpressionObserver(LAST_SEEN_CACHE_SIZE); ProcessImpressionDebug processImpressionDebug = new ProcessImpressionDebug(listenerEnable, impressionObserver); @@ -40,12 +36,12 @@ public void processImpressionsWithListener(){ long pt3 = impressionsResult1.getImpressionsToQueue().get(2).pt(); Assert.assertEquals(1, pt3); - Assert.assertEquals(3,impressionsResult1.getImpressionsToQueue().size()); - Assert.assertEquals(3,impressionsResult1.getImpressionsToListener().size()); + Assert.assertEquals(3, impressionsResult1.getImpressionsToQueue().size()); + Assert.assertEquals(3, impressionsResult1.getImpressionsToListener().size()); } @Test - public void processImpressionsWithoutListener(){ + public void processImpressionsWithoutListener() { boolean listenerEnable = false; ImpressionObserver impressionObserver = new ImpressionObserver(LAST_SEEN_CACHE_SIZE); ProcessImpressionDebug processImpressionDebug = new ProcessImpressionDebug(listenerEnable, impressionObserver); @@ -64,7 +60,7 @@ public void processImpressionsWithoutListener(){ long pt3 = impressionsResult1.getImpressionsToQueue().get(2).pt(); Assert.assertEquals(1, pt3); - Assert.assertEquals(3,impressionsResult1.getImpressionsToQueue().size()); + Assert.assertEquals(3, impressionsResult1.getImpressionsToQueue().size()); Assert.assertNull(impressionsResult1.getImpressionsToListener()); } -} \ No newline at end of file +} diff --git a/client/src/test/java/io/split/client/impressions/strategy/ProcessImpressionNoneTest.java b/impressions/src/test/java/io/split/client/impressions/strategy/ProcessImpressionNoneTest.java similarity index 74% rename from client/src/test/java/io/split/client/impressions/strategy/ProcessImpressionNoneTest.java rename to impressions/src/test/java/io/split/client/impressions/strategy/ProcessImpressionNoneTest.java index 1debedd1e..51f8ede91 100644 --- a/client/src/test/java/io/split/client/impressions/strategy/ProcessImpressionNoneTest.java +++ b/impressions/src/test/java/io/split/client/impressions/strategy/ProcessImpressionNoneTest.java @@ -2,31 +2,28 @@ import io.split.client.dtos.KeyImpression; import io.split.client.impressions.Impression; +import io.split.client.impressions.ImpressionCounter; import io.split.client.impressions.ImpressionsResult; +import io.split.client.impressions.UniqueKeysSender; import io.split.client.impressions.UniqueKeysTrackerImp; -import io.split.client.impressions.ImpressionCounter; -import io.split.telemetry.storage.InMemoryTelemetryStorage; -import io.split.telemetry.storage.TelemetryStorage; -import io.split.telemetry.synchronizer.TelemetryInMemorySubmitter; -import io.split.telemetry.synchronizer.TelemetrySynchronizer; import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import static io.split.client.impressions.ImpressionTestUtils.keyImpression; public class ProcessImpressionNoneTest { - private static TelemetryStorage TELEMETRY_STORAGE = Mockito.mock(InMemoryTelemetryStorage.class); - @Test - public void processImpressionsWithListener(){ + public void processImpressionsWithListener() { boolean listenerEnable = true; ImpressionCounter counter = new ImpressionCounter(); - TelemetrySynchronizer telemetrySynchronizer = Mockito.mock(TelemetryInMemorySubmitter.class); - UniqueKeysTrackerImp uniqueKeysTracker = new UniqueKeysTrackerImp(telemetrySynchronizer, 10000, 10000, null); + UniqueKeysSender sender = Mockito.mock(UniqueKeysSender.class); + UniqueKeysTrackerImp uniqueKeysTracker = new UniqueKeysTrackerImp(sender, 10000, 10000, null); ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(listenerEnable, uniqueKeysTracker, counter); KeyImpression ki1 = keyImpression("test1", "adil", "on", 1L, null, null); @@ -39,8 +36,8 @@ public void processImpressionsWithListener(){ impressions.add(new Impression(ki3.keyName, null, ki3.feature, ki3.treatment, ki3.time, null, 1L, null, null)); ImpressionsResult impressionsResult1 = processImpressionNone.process(impressions); - Assert.assertEquals(0,impressionsResult1.getImpressionsToQueue().size()); - Assert.assertEquals(3,impressionsResult1.getImpressionsToListener().size()); + Assert.assertEquals(0, impressionsResult1.getImpressionsToQueue().size()); + Assert.assertEquals(3, impressionsResult1.getImpressionsToListener().size()); Assert.assertEquals(2, uniqueKeysTracker.popAll().size()); HashMap counters = counter.popAll(); @@ -48,11 +45,11 @@ public void processImpressionsWithListener(){ } @Test - public void processImpressionsWithoutListener(){ + public void processImpressionsWithoutListener() { boolean listenerEnable = false; ImpressionCounter counter = new ImpressionCounter(); - TelemetrySynchronizer telemetrySynchronizer = Mockito.mock(TelemetryInMemorySubmitter.class); - UniqueKeysTrackerImp uniqueKeysTracker = new UniqueKeysTrackerImp(telemetrySynchronizer, 10000, 10000, null); + UniqueKeysSender sender = Mockito.mock(UniqueKeysSender.class); + UniqueKeysTrackerImp uniqueKeysTracker = new UniqueKeysTrackerImp(sender, 10000, 10000, null); ProcessImpressionNone processImpressionNone = new ProcessImpressionNone(listenerEnable, uniqueKeysTracker, counter); KeyImpression ki1 = keyImpression("test1", "adil", "on", 1L, null, null); @@ -65,9 +62,9 @@ public void processImpressionsWithoutListener(){ impressions.add(new Impression(ki3.keyName, null, ki3.feature, ki3.treatment, ki3.time, null, 1L, null, null)); ImpressionsResult impressionsResult1 = processImpressionNone.process(impressions); - Assert.assertEquals(0,impressionsResult1.getImpressionsToQueue().size()); + Assert.assertEquals(0, impressionsResult1.getImpressionsToQueue().size()); Assert.assertNull(impressionsResult1.getImpressionsToListener()); Assert.assertEquals(2, uniqueKeysTracker.popAll().size()); Assert.assertEquals(2, counter.popAll().size()); } -} \ No newline at end of file +} diff --git a/client/src/test/java/io/split/client/impressions/strategy/ProcessImpressionOptimizedTest.java b/impressions/src/test/java/io/split/client/impressions/strategy/ProcessImpressionOptimizedTest.java similarity index 77% rename from client/src/test/java/io/split/client/impressions/strategy/ProcessImpressionOptimizedTest.java rename to impressions/src/test/java/io/split/client/impressions/strategy/ProcessImpressionOptimizedTest.java index f7cecebe5..e7ec04baf 100644 --- a/client/src/test/java/io/split/client/impressions/strategy/ProcessImpressionOptimizedTest.java +++ b/impressions/src/test/java/io/split/client/impressions/strategy/ProcessImpressionOptimizedTest.java @@ -3,16 +3,14 @@ import static io.split.client.impressions.ImpressionTestUtils.keyImpression; import io.split.client.dtos.KeyImpression; - import io.split.client.impressions.Impression; +import io.split.client.impressions.ImpressionCounter; import io.split.client.impressions.ImpressionObserver; import io.split.client.impressions.ImpressionsResult; -import io.split.client.impressions.ImpressionCounter; -import io.split.telemetry.storage.InMemoryTelemetryStorage; -import io.split.telemetry.storage.TelemetryStorage; +import io.split.client.impressions.ImpressionsTelemetryRecorder; +import io.split.client.impressions.NoopImpressionsTelemetryRecorder; import org.junit.Assert; import org.junit.Test; -import org.mockito.Mockito; import java.util.ArrayList; import java.util.List; @@ -20,14 +18,15 @@ public class ProcessImpressionOptimizedTest { private static final long LAST_SEEN_CACHE_SIZE = 500000; - private static TelemetryStorage TELEMETRY_STORAGE = Mockito.mock(InMemoryTelemetryStorage.class); + private static final ImpressionsTelemetryRecorder NOOP_RECORDER = new NoopImpressionsTelemetryRecorder(); @Test - public void processImpressionsWithListener(){ + public void processImpressionsWithListener() { boolean listenerEnable = true; ImpressionObserver impressionObserver = new ImpressionObserver(LAST_SEEN_CACHE_SIZE); ImpressionCounter counter = new ImpressionCounter(); - ProcessImpressionOptimized processImpressionOptimized = new ProcessImpressionOptimized(listenerEnable, impressionObserver, counter, TELEMETRY_STORAGE); + ProcessImpressionOptimized processImpressionOptimized = new ProcessImpressionOptimized(listenerEnable, + impressionObserver, counter, NOOP_RECORDER); KeyImpression ki1 = keyImpression("test1", "adil", "on", 1L, null, null); KeyImpression ki2 = keyImpression("test2", "adil", "on", 1L, null, null); @@ -40,17 +39,18 @@ public void processImpressionsWithListener(){ ImpressionsResult impressionsResult1 = processImpressionOptimized.process(impressions); - Assert.assertEquals(2,impressionsResult1.getImpressionsToQueue().size()); - Assert.assertEquals(3,impressionsResult1.getImpressionsToListener().size()); + Assert.assertEquals(2, impressionsResult1.getImpressionsToQueue().size()); + Assert.assertEquals(3, impressionsResult1.getImpressionsToListener().size()); Assert.assertEquals(1, counter.popAll().size()); } @Test - public void processImpressionsWithoutListener(){ + public void processImpressionsWithoutListener() { boolean listenerEnable = false; ImpressionObserver impressionObserver = new ImpressionObserver(LAST_SEEN_CACHE_SIZE); ImpressionCounter counter = new ImpressionCounter(); - ProcessImpressionOptimized processImpressionOptimized = new ProcessImpressionOptimized(listenerEnable, impressionObserver, counter, TELEMETRY_STORAGE); + ProcessImpressionOptimized processImpressionOptimized = new ProcessImpressionOptimized(listenerEnable, + impressionObserver, counter, NOOP_RECORDER); KeyImpression ki1 = keyImpression("test1", "adil", "on", 1L, null, null); KeyImpression ki2 = keyImpression("test2", "adil", "on", 1L, null, null); @@ -62,8 +62,8 @@ public void processImpressionsWithoutListener(){ impressions.add(new Impression(ki3.keyName, null, ki3.feature, ki3.treatment, ki3.time, null, 1L, null, null)); ImpressionsResult impressionsResult1 = processImpressionOptimized.process(impressions); - Assert.assertEquals(2,impressionsResult1.getImpressionsToQueue().size()); + Assert.assertEquals(2, impressionsResult1.getImpressionsToQueue().size()); Assert.assertNull(impressionsResult1.getImpressionsToListener()); Assert.assertEquals(1, counter.popAll().size()); } -} \ No newline at end of file +} diff --git a/pom.xml b/pom.xml index c17dd8e6d..5409bf6f2 100644 --- a/pom.xml +++ b/pom.xml @@ -72,6 +72,7 @@ testing okhttp-modules tracker + impressions client