All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.split.client.SplitFactoryImpl Maven / Gradle / Ivy

package io.split.client;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import io.split.client.dtos.Metadata;
import io.split.client.events.EventsSender;
import io.split.client.events.EventsStorage;
import io.split.client.events.EventsTask;
import io.split.client.events.InMemoryEventsStorage;
import io.split.client.impressions.AsynchronousImpressionListener;
import io.split.client.impressions.HttpImpressionsSender;
import io.split.client.impressions.ImpressionCounter;
import io.split.client.impressions.ImpressionListener;
import io.split.client.impressions.ImpressionObserver;
import io.split.client.impressions.ImpressionsManager;
import io.split.client.impressions.ImpressionsManagerImpl;
import io.split.client.impressions.ImpressionsSender;
import io.split.client.impressions.ImpressionsStorage;
import io.split.client.impressions.ImpressionsStorageConsumer;
import io.split.client.impressions.ImpressionsStorageProducer;
import io.split.client.impressions.InMemoryImpressionsStorage;
import io.split.client.impressions.PluggableImpressionSender;
import io.split.client.impressions.UniqueKeysTracker;
import io.split.client.impressions.UniqueKeysTrackerImp;
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.strategy.ProcessImpressionStrategy;
import io.split.client.interceptors.AuthorizationInterceptorFilter;
import io.split.client.interceptors.ClientKeyInterceptorFilter;
import io.split.client.interceptors.GzipDecoderResponseInterceptor;
import io.split.client.interceptors.GzipEncoderRequestInterceptor;
import io.split.client.interceptors.SdkMetadataInterceptorFilter;
import io.split.client.utils.SDKMetadata;
import io.split.engine.SDKReadinessGates;
import io.split.engine.common.SplitAPI;
import io.split.engine.common.SplitTasks;
import io.split.engine.common.SyncManager;
import io.split.engine.common.SyncManagerImp;
import io.split.engine.evaluator.Evaluator;
import io.split.engine.evaluator.EvaluatorImp;
import io.split.engine.experiments.SplitChangeFetcher;
import io.split.engine.experiments.SplitFetcher;
import io.split.engine.experiments.SplitFetcherImp;
import io.split.engine.experiments.SplitParser;
import io.split.engine.experiments.SplitSynchronizationTask;
import io.split.engine.segments.SegmentChangeFetcher;
import io.split.engine.segments.SegmentSynchronizationTaskImp;
import io.split.integrations.IntegrationsConfig;
import io.split.storages.SegmentCache;
import io.split.storages.SegmentCacheConsumer;
import io.split.storages.SegmentCacheProducer;
import io.split.storages.SplitCache;
import io.split.storages.SplitCacheConsumer;
import io.split.storages.SplitCacheProducer;
import io.split.storages.enums.OperationMode;
import io.split.storages.memory.InMemoryCacheImp;
import io.split.storages.memory.SegmentCacheInMemoryImpl;
import io.split.storages.pluggable.adapters.UserCustomEventAdapterProducer;
import io.split.storages.pluggable.adapters.UserCustomImpressionAdapterConsumer;
import io.split.storages.pluggable.adapters.UserCustomImpressionAdapterProducer;
import io.split.storages.pluggable.adapters.UserCustomSegmentAdapterConsumer;
import io.split.storages.pluggable.adapters.UserCustomSplitAdapterConsumer;
import io.split.storages.pluggable.adapters.UserCustomTelemetryAdapterProducer;
import io.split.storages.pluggable.domain.UserStorageWrapper;
import io.split.storages.pluggable.synchronizer.TelemetryConsumerSubmitter;
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.TelemetrySyncTask;
import io.split.telemetry.synchronizer.TelemetrySynchronizer;
import org.apache.hc.client5.http.auth.AuthScope;
import org.apache.hc.client5.http.auth.Credentials;
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.cookie.StandardCookieSpec;
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.impl.routing.DefaultProxyRoutePlanner;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder;
import org.apache.hc.core5.http.io.SocketConfig;
import org.apache.hc.core5.http.ssl.TLS;
import org.apache.hc.core5.ssl.SSLContexts;
import org.apache.hc.core5.util.TimeValue;
import org.apache.hc.core5.util.Timeout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pluggable.CustomStorageWrapper;

import java.io.IOException;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

public class SplitFactoryImpl implements SplitFactory {
    private static final Logger _log = LoggerFactory.getLogger(SplitFactory.class);
    private final static long SSE_CONNECT_TIMEOUT = 30000;
    private final static long SSE_SOCKET_TIMEOUT = 70000;

    private static Random RANDOM = new Random();

    private final SDKReadinessGates _gates;
    private final ImpressionsManagerImpl _impressionsManager;
    private final Evaluator _evaluator;
    private final String _apiToken;

    // Client and Manager
    private final SplitClient _client;
    private final SplitManager _manager;

    //Cache
    private final SplitCacheConsumer _splitCache;
    private final SegmentCacheConsumer _segmentCache;

    private boolean isTerminated = false;
    private final ApiKeyCounter _apiKeyCounter;
    private final TelemetryStorageProducer _telemetryStorageProducer;
    private final TelemetrySynchronizer _telemetrySynchronizer;
    private final long _startTime;
    private final SDKMetadata _sdkMetadata;
    private final OperationMode _operationMode;

    //Depending on mode are not mandatory
    private final TelemetrySyncTask _telemetrySyncTask;
    private final SegmentSynchronizationTaskImp _segmentSynchronizationTaskImp;
    private final SplitFetcher _splitFetcher;
    private final SplitSynchronizationTask _splitSynchronizationTask;
    private final EventsTask _eventsTask;
    private final SyncManager _syncManager;
    private final CloseableHttpClient _httpclient;
    private final UserStorageWrapper _userStorageWrapper;
    private final ImpressionsSender _impressionsSender;
    private final URI _rootTarget;
    private final URI _eventsRootTarget;
    private final UniqueKeysTracker _uniqueKeysTracker;


    //Constructor for standalone mode
    public SplitFactoryImpl(String apiToken, SplitClientConfig config) throws URISyntaxException {
        _userStorageWrapper = null;
        _operationMode = config.operationMode();
        _startTime = System.currentTimeMillis();
        _apiToken = apiToken;
        _apiKeyCounter = ApiKeyCounter.getApiKeyCounterInstance();
        _apiKeyCounter.add(apiToken);
        _sdkMetadata = createSdkMetadata(config.ipAddressEnabled(), SplitClientConfig.splitSdkVersion);

        TelemetryStorage telemetryStorage = new InMemoryTelemetryStorage();
        _telemetryStorageProducer = telemetryStorage;

        if (config.blockUntilReady() == -1) {
            //BlockUntilReady not been set
            _log.warn("no setBlockUntilReadyTimeout parameter has been set - incorrect control treatments could be logged” " +
                    "if no ready config has been set when building factory");
        }

        // SDKReadinessGates
        _gates = new SDKReadinessGates();

        // HttpClient
        _httpclient = buildHttpClient(apiToken, config, _sdkMetadata);

        // Roots
        _rootTarget = URI.create(config.endpoint());
        _eventsRootTarget = URI.create(config.eventsEndpoint());

        // Cache Initialisations
        SegmentCache segmentCache = new SegmentCacheInMemoryImpl();
        SplitCache splitCache = new InMemoryCacheImp();
        ImpressionsStorage impressionsStorage = new InMemoryImpressionsStorage(config.impressionsQueueSize());
        _splitCache = splitCache;
        _segmentCache = segmentCache;
        _telemetrySynchronizer = new TelemetryInMemorySubmitter(_httpclient, URI.create(config.telemetryURL()), telemetryStorage, splitCache, segmentCache, telemetryStorage, _startTime);

        // Segments
        _segmentSynchronizationTaskImp = buildSegments(config, segmentCache, splitCache);

        // SplitFetcher
        _splitFetcher = buildSplitFetcher(splitCache, splitCache);

        // SplitSynchronizationTask
        _splitSynchronizationTask = new SplitSynchronizationTask(_splitFetcher,
                splitCache,
                config.featuresRefreshRate());

        //ImpressionSender
        _impressionsSender = HttpImpressionsSender.create(_httpclient, URI.create(config.eventsEndpoint()), config.impressionsMode(), _telemetryStorageProducer);

        //UniqueKeysTracker
        _uniqueKeysTracker = createUniqueKeysTracker(config);

        // Impressions
        _impressionsManager = buildImpressionsManager(config, impressionsStorage, impressionsStorage);

        // EventClient
        EventsStorage eventsStorage = new InMemoryEventsStorage(config.eventsQueueSize(), _telemetryStorageProducer);
        EventsSender eventsSender = EventsSender.create(_httpclient, _eventsRootTarget, _telemetryStorageProducer);
        _eventsTask = EventsTask.create(config.eventSendIntervalInMillis(), eventsStorage, eventsSender);

        _telemetrySyncTask = new TelemetrySyncTask(config.get_telemetryRefreshRate(), _telemetrySynchronizer);

        // Evaluator
        _evaluator = new EvaluatorImp(splitCache, segmentCache);

        // SplitClient
        _client = new SplitClientImpl(this,
                splitCache,
                _impressionsManager,
                eventsStorage,
                config,
                _gates,
                _evaluator,
                _telemetryStorageProducer, //TelemetryEvaluation instance
                _telemetryStorageProducer); //TelemetryConfiguration instance

        // SplitManager
        _manager = new SplitManagerImpl(splitCache, config, _gates, _telemetryStorageProducer);

        // SyncManager
        SplitTasks splitTasks = SplitTasks.build(_splitSynchronizationTask, _segmentSynchronizationTaskImp,
                _impressionsManager, _eventsTask, _telemetrySyncTask);
        SplitAPI splitAPI = SplitAPI.build(_httpclient, buildSSEdHttpClient(apiToken, config, _sdkMetadata));

        _syncManager = SyncManagerImp.build(splitTasks, _splitFetcher, splitCache, splitAPI,
                segmentCache, _gates, _telemetryStorageProducer, _telemetrySynchronizer, config, _uniqueKeysTracker);
        _syncManager.start();

        // DestroyOnShutDown
        if (config.destroyOnShutDown()) {
            Thread shutdown = new Thread(() -> {
                // Using the full path to avoid conflicting with Thread.destroy()
                SplitFactoryImpl.this.destroy();
            });
            shutdown.setName("split-destroy-worker");
            Runtime.getRuntime().addShutdownHook(shutdown);
        }
    }


    //Constructor for consumer mode
    protected SplitFactoryImpl(String apiToken, SplitClientConfig config, CustomStorageWrapper customStorageWrapper) throws URISyntaxException {
        //Variables that are not used in Consumer mode.
        _telemetrySyncTask = null;
        _segmentSynchronizationTaskImp = null;
        _splitFetcher = null;
        _splitSynchronizationTask = null;
        _eventsTask = null;
        _syncManager = null;
        _httpclient = null;
        _rootTarget = null;
        _eventsRootTarget = null;

        Metadata metadata = new Metadata(config.ipAddressEnabled(), SplitClientConfig.splitSdkVersion);
        _userStorageWrapper = new UserStorageWrapper(customStorageWrapper);
        UserCustomSegmentAdapterConsumer userCustomSegmentAdapterConsumer= new UserCustomSegmentAdapterConsumer(customStorageWrapper);
        UserCustomSplitAdapterConsumer userCustomSplitAdapterConsumer = new UserCustomSplitAdapterConsumer(customStorageWrapper);
        UserCustomImpressionAdapterConsumer userCustomImpressionAdapterConsumer = new UserCustomImpressionAdapterConsumer(); // TODO migrate impressions sender to Task instead manager and not instantiate Producer here.
        UserCustomImpressionAdapterProducer userCustomImpressionAdapterProducer = new UserCustomImpressionAdapterProducer(customStorageWrapper, metadata);
        UserCustomEventAdapterProducer userCustomEventAdapterProducer = new UserCustomEventAdapterProducer(customStorageWrapper, metadata);

        _operationMode = config.operationMode();
        _sdkMetadata = createSdkMetadata(config.ipAddressEnabled(), SplitClientConfig.splitSdkVersion);
        _startTime = System.currentTimeMillis();
        _apiToken = apiToken;
        _apiKeyCounter = ApiKeyCounter.getApiKeyCounterInstance();
        _apiKeyCounter.add(apiToken);
        _telemetryStorageProducer = new UserCustomTelemetryAdapterProducer(customStorageWrapper, _sdkMetadata);

        _splitCache = userCustomSplitAdapterConsumer;
        _segmentCache = userCustomSegmentAdapterConsumer;

        if (config.blockUntilReady() == -1) {
            //BlockUntilReady not been set
            _log.warn("no setBlockUntilReadyTimeout parameter has been set - incorrect control treatments could be logged” " +
                    "if no ready config has been set when building factory");
        }

        // SDKReadinessGates
        _gates = new SDKReadinessGates();

        _telemetrySynchronizer = new TelemetryConsumerSubmitter(customStorageWrapper, _sdkMetadata);

        _evaluator = new EvaluatorImp(userCustomSplitAdapterConsumer, userCustomSegmentAdapterConsumer);
        _impressionsSender = PluggableImpressionSender.create(customStorageWrapper);

        _uniqueKeysTracker = createUniqueKeysTracker(config);

        _impressionsManager = buildImpressionsManager(config, userCustomImpressionAdapterConsumer, userCustomImpressionAdapterProducer);
        _impressionsManager.start();
        if (_uniqueKeysTracker != null){
            try {
                _uniqueKeysTracker.start();
            } catch (Exception e) {
                _log.error("Error trying to init Unique Keys Tracker synchronizer task.", e);
            }
        }

        _client = new SplitClientImpl(this,
                userCustomSplitAdapterConsumer,
                _impressionsManager,
                userCustomEventAdapterProducer,
                config,
                _gates,
                _evaluator,
                _telemetryStorageProducer, //TelemetryEvaluation instance
                _telemetryStorageProducer); //TelemetryConfiguration instance

        _manager = new SplitManagerImpl(userCustomSplitAdapterConsumer, config, _gates, _telemetryStorageProducer);
        manageSdkReady(config);
    }

    @Override
    public SplitClient client() {
        return _client;
    }

    @Override
    public SplitManager manager() {
        return _manager;
    }

    @Override
    public synchronized void destroy() {
        if (isTerminated) {
            return;
        }
        try {
            _log.info("Shutdown called for split");
            if(OperationMode.STANDALONE.equals(_operationMode)) {
                long splitCount = _splitCache.getAll().stream().count();
                long segmentCount = _segmentCache.getSegmentCount();
                long segmentKeyCount = _segmentCache.getKeyCount();
                _telemetryStorageProducer.recordSessionLength(System.currentTimeMillis() - _startTime);
                _syncManager.shutdown(splitCount, segmentCount, segmentKeyCount);
                _log.info("Successful shutdown of syncManager");
                }
            else if(OperationMode.CONSUMER.equals(_operationMode)) {
                _impressionsManager.close();
                _log.info("Successful shutdown of impressions manager");
                if (_uniqueKeysTracker != null){
                    _uniqueKeysTracker.stop();
                    _log.info("Successful stop of UniqueKeysTracker");
                }
                _userStorageWrapper.disconnect();
            }
        } catch (IOException e) {
            _log.error("We could not shutdown split", e);
        }
        _apiKeyCounter.remove(_apiToken);
        isTerminated = true;
    }

    @Override
    public boolean isDestroyed() {
        return isTerminated;
    }

    private static CloseableHttpClient buildHttpClient(String apiToken, SplitClientConfig config, SDKMetadata sdkMetadata) {
        SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder.create()
                .setSslContext(SSLContexts.createSystemDefault())
                .setTlsVersions(TLS.V_1_1, TLS.V_1_2)
                .build();

        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(Timeout.ofMilliseconds(config.connectionTimeout()))
                .setCookieSpec(StandardCookieSpec.STRICT)
                .build();

        PoolingHttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create()
                .setSSLSocketFactory(sslSocketFactory)
                .setDefaultSocketConfig(SocketConfig.custom()
                        .setSoTimeout(Timeout.ofMilliseconds(config.readTimeout()))
                        .build())
                .setValidateAfterInactivity(TimeValue.ofMilliseconds(config.validateAfterInactivityInMillis()))
                .build();
        cm.setMaxTotal(20);
        cm.setDefaultMaxPerRoute(20);

        HttpClientBuilder httpClientbuilder = HttpClients.custom()
                .setConnectionManager(cm)
                .setDefaultRequestConfig(requestConfig)
                .addRequestInterceptorLast(AuthorizationInterceptorFilter.instance(apiToken))
                .addRequestInterceptorLast(SdkMetadataInterceptorFilter.instance(sdkMetadata))
                .addRequestInterceptorLast(new GzipEncoderRequestInterceptor())
                .addResponseInterceptorLast((new GzipDecoderResponseInterceptor()));

        // Set up proxy is it exists
        if (config.proxy() != null) {
            httpClientbuilder = setupProxy(httpClientbuilder, config);
        }

        return httpClientbuilder.build();
    }

    private static CloseableHttpClient buildSSEdHttpClient(String apiToken, SplitClientConfig config, SDKMetadata sdkMetadata) {
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(Timeout.ofMilliseconds(SSE_CONNECT_TIMEOUT))
                .build();

        SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder.create()
                .setSslContext(SSLContexts.createSystemDefault())
                .setTlsVersions(TLS.V_1_1, TLS.V_1_2)
                .build();

        PoolingHttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create()
                .setSSLSocketFactory(sslSocketFactory)
                .setDefaultSocketConfig(SocketConfig.custom()
                        .setSoTimeout(Timeout.ofMilliseconds(SSE_SOCKET_TIMEOUT))
                        .build())
                .build();
        cm.setMaxTotal(1);
        cm.setDefaultMaxPerRoute(1);

        HttpClientBuilder httpClientbuilder = HttpClients.custom()
                .setConnectionManager(cm)
                .setDefaultRequestConfig(requestConfig)
                .addRequestInterceptorLast(SdkMetadataInterceptorFilter.instance(sdkMetadata))
                .addRequestInterceptorLast(ClientKeyInterceptorFilter.instance(apiToken));

        // Set up proxy is it exists
        if (config.proxy() != null) {
            httpClientbuilder = setupProxy(httpClientbuilder, config);
        }

        return httpClientbuilder.build();
    }

    private static HttpClientBuilder setupProxy(HttpClientBuilder httpClientbuilder, SplitClientConfig config) {
        _log.info("Initializing Split SDK with proxy settings");
        DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(config.proxy());
        httpClientbuilder.setRoutePlanner(routePlanner);

        if (config.proxyUsername() != null && config.proxyPassword() != null) {
            _log.debug("Proxy setup using credentials");
            BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
            AuthScope siteScope = new AuthScope(config.proxy().getHostName(), config.proxy().getPort());
            Credentials siteCreds = new UsernamePasswordCredentials(config.proxyUsername(), config.proxyPassword().toCharArray());
            credsProvider.setCredentials(siteScope, siteCreds);
            httpClientbuilder.setDefaultCredentialsProvider(credsProvider);
        }

        return  httpClientbuilder;
    }

    private SegmentSynchronizationTaskImp buildSegments(SplitClientConfig config, SegmentCacheProducer segmentCacheProducer, SplitCacheConsumer splitCacheConsumer) throws URISyntaxException {
        SegmentChangeFetcher segmentChangeFetcher = HttpSegmentChangeFetcher.create(_httpclient, _rootTarget, _telemetryStorageProducer);

        return new SegmentSynchronizationTaskImp(segmentChangeFetcher,
                config.segmentsRefreshRate(),
                config.numThreadsForSegmentFetch(),
                _gates,
                segmentCacheProducer,
                _telemetryStorageProducer,
                splitCacheConsumer);
    }

    private SplitFetcher buildSplitFetcher(SplitCacheConsumer splitCacheConsumer, SplitCacheProducer splitCacheProducer) throws URISyntaxException {
        SplitChangeFetcher splitChangeFetcher = HttpSplitChangeFetcher.create(_httpclient, _rootTarget, _telemetryStorageProducer);
        SplitParser splitParser = new SplitParser();

        return new SplitFetcherImp(splitChangeFetcher, splitParser, splitCacheConsumer, splitCacheProducer, _telemetryStorageProducer);
    }

    private ImpressionsManagerImpl buildImpressionsManager(SplitClientConfig config, ImpressionsStorageConsumer impressionsStorageConsumer, ImpressionsStorageProducer impressionsStorageProducer) throws URISyntaxException {
        List impressionListeners = new ArrayList<>();
        if (config.integrationsConfig() != null) {
            config.integrationsConfig().getImpressionsListeners(IntegrationsConfig.Execution.ASYNC).stream()
                    .map(l -> AsynchronousImpressionListener.build(l.listener(), l.queueSize()))
                    .collect(Collectors.toCollection(() -> impressionListeners));

            config.integrationsConfig().getImpressionsListeners(IntegrationsConfig.Execution.SYNC).stream()
                    .map(IntegrationsConfig.ImpressionListenerWithMeta::listener)
                    .collect(Collectors.toCollection(() -> impressionListeners));
        }
        ProcessImpressionStrategy processImpressionStrategy = null;
        ImpressionCounter counter = null;
        ImpressionListener listener = (null != impressionListeners && !impressionListeners.isEmpty()) ? new ImpressionListener.FederatedImpressionListener(impressionListeners)
                : null;
        switch (config.impressionsMode()){
            case OPTIMIZED:
                counter = new ImpressionCounter();
                ImpressionObserver impressionObserver = new ImpressionObserver(config.getLastSeenCacheSize());
                processImpressionStrategy = new ProcessImpressionOptimized(listener != null, impressionObserver, counter, _telemetryStorageProducer);
                break;
            case DEBUG:
                impressionObserver = new ImpressionObserver(config.getLastSeenCacheSize());
                processImpressionStrategy = new ProcessImpressionDebug(listener != null, impressionObserver);
                break;
            case NONE:
                counter = new ImpressionCounter();
                processImpressionStrategy = new ProcessImpressionNone(listener != null, _uniqueKeysTracker, counter);
                break;
        }
        return ImpressionsManagerImpl.instance(_httpclient, config, impressionListeners, _telemetryStorageProducer, impressionsStorageConsumer, impressionsStorageProducer, _impressionsSender, _uniqueKeysTracker, processImpressionStrategy, counter, listener);
    }

    private SDKMetadata createSdkMetadata(boolean ipAddressEnabled, String splitSdkVersion) {
        String machineName = "";
        String ip = "";

        if (ipAddressEnabled) {
            try {
                InetAddress localHost = InetAddress.getLocalHost();
                machineName = localHost.getHostName();
                ip = localHost.getHostAddress();
            } catch (Exception e) {
                _log.error("Could not resolve InetAddress", e);
            }
        }
        return new SDKMetadata(splitSdkVersion, ip, machineName);
    }

    private void manageSdkReady(SplitClientConfig config) {
        ExecutorService executorService = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder()
                .setNameFormat("SPLIT-SDKReadyForConsumer-%d")
                .setDaemon(true)
                .build());
        executorService.submit(() -> {
            while(!_userStorageWrapper.connect()) {
                try {
                    Thread.currentThread().sleep(1000);
                } catch (InterruptedException e) {
                    _log.warn("Sdk Initializer thread interrupted");
                    Thread.currentThread().interrupt();
                }
            }
            _gates.sdkInternalReady();
            _telemetrySynchronizer.synchronizeConfig(config, System.currentTimeMillis(), ApiKeyCounter.getApiKeyCounterInstance().getFactoryInstances(), new ArrayList<>());
        });
    }

    private UniqueKeysTracker createUniqueKeysTracker(SplitClientConfig config){
        if (config.impressionsMode().equals(ImpressionsManager.Mode.NONE)){
            int uniqueKeysRefreshRate = config.operationMode().equals(OperationMode.STANDALONE) ? config.uniqueKeysRefreshRateInMemory()
                    : config.uniqueKeysRefreshRateRedis();
            return new UniqueKeysTrackerImp(_telemetrySynchronizer, uniqueKeysRefreshRate, config.filterUniqueKeysRefreshRate());
        }
        return null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy