Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -177,18 +177,6 @@
<artifactId>snakeyaml</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>logging-interceptor</artifactId>
<version>4.12.0</version>
<optional>true</optional>
</dependency>

<!-- Test deps -->
<dependency>
Expand Down
54 changes: 11 additions & 43 deletions client/src/main/java/io/split/client/SplitClientConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import io.split.client.impressions.ImpressionsManager;
import io.split.client.utils.FileTypeEnum;
import io.split.integrations.IntegrationsConfig;
import io.split.service.ProxyAuthScheme;
import io.split.service.CustomHttpModule;
import io.split.storages.enums.OperationMode;
import io.split.storages.enums.StorageMode;
import org.apache.hc.core5.http.HttpHost;
Expand Down Expand Up @@ -92,8 +92,7 @@ public class SplitClientConfig {
private final HashSet<String> _flagSetsFilter;
private final int _invalidSets;
private final CustomHeaderDecorator _customHeaderDecorator;
private final ProxyAuthScheme _proxyAuthScheme;
private final String _proxyKerberosPrincipalName;
private final CustomHttpModule _alternativeHTTPModule;

public static Builder builder() {
return new Builder();
Expand Down Expand Up @@ -151,8 +150,7 @@ private SplitClientConfig(String endpoint,
HashSet<String> flagSetsFilter,
int invalidSets,
CustomHeaderDecorator customHeaderDecorator,
ProxyAuthScheme proxyAuthScheme,
String proxyKerberosPrincipalName) {
CustomHttpModule alternativeHTTPModule) {
_endpoint = endpoint;
_eventsEndpoint = eventsEndpoint;
_featuresRefreshRate = pollForFeatureChangesEveryNSeconds;
Expand Down Expand Up @@ -205,8 +203,7 @@ private SplitClientConfig(String endpoint,
_flagSetsFilter = flagSetsFilter;
_invalidSets = invalidSets;
_customHeaderDecorator = customHeaderDecorator;
_proxyAuthScheme = proxyAuthScheme;
_proxyKerberosPrincipalName = proxyKerberosPrincipalName;
_alternativeHTTPModule = alternativeHTTPModule;

Properties props = new Properties();
try {
Expand Down Expand Up @@ -414,11 +411,8 @@ public int getInvalidSets() {
public CustomHeaderDecorator customHeaderDecorator() {
return _customHeaderDecorator;
}
public ProxyAuthScheme proxyAuthScheme() {
return _proxyAuthScheme;
}
public String proxyKerberosPrincipalName() { return _proxyKerberosPrincipalName; }

public CustomHttpModule alternativeHTTPModule() { return _alternativeHTTPModule; }
public static final class Builder {

private String _endpoint = SDK_ENDPOINT;
Expand Down Expand Up @@ -476,8 +470,7 @@ public static final class Builder {
private HashSet<String> _flagSetsFilter = new HashSet<>();
private int _invalidSetsCount = 0;
private CustomHeaderDecorator _customHeaderDecorator = null;
private ProxyAuthScheme _proxyAuthScheme = null;
private String _proxyKerberosPrincipalName = null;
private CustomHttpModule _alternativeHTTPModule = null;

public Builder() {
}
Expand Down Expand Up @@ -973,24 +966,13 @@ public Builder customHeaderDecorator(CustomHeaderDecorator customHeaderDecorator
}

/**
* Authentication Scheme
*
* @param proxyAuthScheme
* @return this builder
*/
public Builder proxyAuthScheme(ProxyAuthScheme proxyAuthScheme) {
_proxyAuthScheme = proxyAuthScheme;
return this;
}

/**
* Kerberos Principal Account Name
* Alternative Http Client
*
* @param proxyKerberosPrincipalName
* @param alternativeHTTPModule
* @return this builder
*/
public Builder proxyKerberosPrincipalName(String proxyKerberosPrincipalName) {
_proxyKerberosPrincipalName = proxyKerberosPrincipalName;
public Builder alternativeHTTPModule(CustomHttpModule alternativeHTTPModule) {
_alternativeHTTPModule = alternativeHTTPModule;
return this;
}

Expand Down Expand Up @@ -1052,17 +1034,6 @@ private void verifyEndPoints() {
}
}

private void verifyAuthScheme() {
if (_proxyAuthScheme == ProxyAuthScheme.KERBEROS) {
if (proxy() == null) {
throw new IllegalStateException("Kerberos mode require Proxy parameters.");
}
if (_proxyKerberosPrincipalName == null) {
throw new IllegalStateException("Kerberos mode require Kerberos Principal Name.");
}
}
}

private void verifyAllModes() {
switch (_impressionsMode) {
case OPTIMIZED:
Expand Down Expand Up @@ -1128,8 +1099,6 @@ public SplitClientConfig build() {
throw new IllegalArgumentException("Number of threads for fetching segments MUST be greater than zero");
}

verifyAuthScheme();

return new SplitClientConfig(
_endpoint,
_eventsEndpoint,
Expand Down Expand Up @@ -1183,8 +1152,7 @@ public SplitClientConfig build() {
_flagSetsFilter,
_invalidSetsCount,
_customHeaderDecorator,
_proxyAuthScheme,
_proxyKerberosPrincipalName);
_alternativeHTTPModule);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.split.inputValidation.ApiKeyValidator;
import io.split.grammar.Treatments;
import io.split.service.SplitHttpClient;
import io.split.storages.enums.StorageMode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down
72 changes: 12 additions & 60 deletions client/src/main/java/io/split/client/SplitFactoryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,9 @@
import io.split.engine.segments.SegmentChangeFetcher;
import io.split.engine.segments.SegmentSynchronizationTaskImp;
import io.split.integrations.IntegrationsConfig;
import io.split.service.ProxyAuthScheme;
import io.split.service.SplitHttpClientKerberosImpl;
import io.split.service.SplitHttpClientImpl;
import io.split.service.SplitHttpClient;
import io.split.service.HTTPKerberosAuthInterceptor;

import io.split.storages.SegmentCache;
import io.split.storages.SegmentCacheConsumer;
import io.split.storages.SegmentCacheProducer;
Expand All @@ -86,6 +84,7 @@
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;
Expand All @@ -108,26 +107,16 @@
import org.slf4j.LoggerFactory;
import pluggable.CustomStorageWrapper;

import okhttp3.Authenticator;
import okhttp3.OkHttpClient;
import okhttp3.OkHttpClient.Builder;
import okhttp3.logging.HttpLoggingInterceptor;

import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.Map;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
import java.util.HashSet;
import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

import static io.split.client.utils.SplitExecutorFactory.buildExecutorService;

Expand Down Expand Up @@ -167,12 +156,13 @@ public class SplitFactoryImpl implements SplitFactory {
private final SplitSynchronizationTask _splitSynchronizationTask;
private final EventsTask _eventsTask;
private final SyncManager _syncManager;
private final SplitHttpClient _splitHttpClient;
private SplitHttpClient _splitHttpClient;
private final UserStorageWrapper _userStorageWrapper;
private final ImpressionsSender _impressionsSender;
private final URI _rootTarget;
private final URI _eventsRootTarget;
private final UniqueKeysTracker _uniqueKeysTracker;
private RequestDecorator _requestDecorator;

// Constructor for standalone mode
public SplitFactoryImpl(String apiToken, SplitClientConfig config) throws URISyntaxException, IOException {
Expand All @@ -199,8 +189,12 @@ public SplitFactoryImpl(String apiToken, SplitClientConfig config) throws URISyn
_gates = new SDKReadinessGates();

// HttpClient
RequestDecorator requestDecorator = new RequestDecorator(config.customHeaderDecorator());
_splitHttpClient = buildSplitHttpClient(apiToken, config, _sdkMetadata, requestDecorator);
_requestDecorator = new RequestDecorator(config.customHeaderDecorator());
if (config.alternativeHTTPModule() == null) {
_splitHttpClient = buildSplitHttpClient(apiToken, config, _sdkMetadata, _requestDecorator);
} else {
_splitHttpClient = config.alternativeHTTPModule().createClient(apiToken, _sdkMetadata, _requestDecorator);
}

// Roots
_rootTarget = URI.create(config.endpoint());
Expand Down Expand Up @@ -269,7 +263,7 @@ public SplitFactoryImpl(String apiToken, SplitClientConfig config) throws URISyn
// SyncManager
SplitTasks splitTasks = SplitTasks.build(_splitSynchronizationTask, _segmentSynchronizationTaskImp,
_impressionsManager, _eventsTask, _telemetrySyncTask, _uniqueKeysTracker);
SplitAPI splitAPI = SplitAPI.build(_splitHttpClient, buildSSEdHttpClient(apiToken, config, _sdkMetadata), requestDecorator);
SplitAPI splitAPI = SplitAPI.build(_splitHttpClient, buildSSEdHttpClient(apiToken, config, _sdkMetadata), _requestDecorator);

_syncManager = SyncManagerImp.build(splitTasks, _splitFetcher, splitCache, splitAPI,
segmentCache, _gates, _telemetryStorageProducer, _telemetrySynchronizer, config, splitParser,
Expand Down Expand Up @@ -505,34 +499,7 @@ public boolean isDestroyed() {

protected static SplitHttpClient buildSplitHttpClient(String apiToken, SplitClientConfig config,
SDKMetadata sdkMetadata, RequestDecorator requestDecorator)
throws URISyntaxException, IOException {
// setup Kerberos client
if (config.proxyAuthScheme() == ProxyAuthScheme.KERBEROS) {
_log.info("Using Kerberos-Proxy Authentication Scheme.");
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(config.proxy().getHostName(), config.proxy().getPort()));
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
if (config.debugEnabled()) {
logging.setLevel(HttpLoggingInterceptor.Level.HEADERS);
} else {
logging.setLevel(HttpLoggingInterceptor.Level.NONE);
}

Map<String, String> kerberosOptions = new HashMap<>();
kerberosOptions.put("com.sun.security.auth.module.Krb5LoginModule", "required");
kerberosOptions.put("refreshKrb5Config", "false");
kerberosOptions.put("doNotPrompt", "false");
kerberosOptions.put("useTicketCache", "true");

Authenticator proxyAuthenticator = getProxyAuthenticator(config, kerberosOptions);
OkHttpClient client = buildOkHttpClient(proxy, config, logging, proxyAuthenticator);

return SplitHttpClientKerberosImpl.create(
client,
requestDecorator,
apiToken,
sdkMetadata);
}

throws URISyntaxException {
SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder.create()
.setSslContext(SSLContexts.createSystemDefault())
.setTlsVersions(TLS.V_1_1, TLS.V_1_2)
Expand Down Expand Up @@ -570,21 +537,6 @@ protected static SplitHttpClient buildSplitHttpClient(String apiToken, SplitClie
sdkMetadata);
}

protected static OkHttpClient buildOkHttpClient(Proxy proxy, SplitClientConfig config,
HttpLoggingInterceptor logging, Authenticator proxyAuthenticator) {
return new Builder()
.proxy(proxy)
.readTimeout(config.readTimeout(), TimeUnit.MILLISECONDS)
.connectTimeout(config.connectionTimeout(), TimeUnit.MILLISECONDS)
.addInterceptor(logging)
.proxyAuthenticator(proxyAuthenticator)
.build();
}

protected static HTTPKerberosAuthInterceptor getProxyAuthenticator(SplitClientConfig config,
Map<String, String> kerberosOptions) throws IOException {
return new HTTPKerberosAuthInterceptor(config.proxyKerberosPrincipalName(), kerberosOptions);
}
private static CloseableHttpClient buildSSEdHttpClient(String apiToken, SplitClientConfig config,
SDKMetadata sdkMetadata) {
RequestConfig requestConfig = RequestConfig.custom()
Expand Down
10 changes: 10 additions & 0 deletions client/src/main/java/io/split/service/CustomHttpModule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.split.service;

import io.split.client.RequestDecorator;
import io.split.client.utils.SDKMetadata;

import java.io.IOException;

public interface CustomHttpModule {
public SplitHttpClient createClient(String apiToken, SDKMetadata sdkMetadata, RequestDecorator requestDecorator) throws IOException;
}
2 changes: 1 addition & 1 deletion client/src/main/java/io/split/service/SplitHttpClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ public interface SplitHttpClient extends Closeable {
public SplitHttpResponse post(URI uri,
HttpEntity entity,
Map<String, List<String>> additionalHeaders) throws IOException;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.split.client.utils.LocalhostUtils;
import io.split.grammar.Treatments;
import io.split.service.SplitHttpClient;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
Expand Down
33 changes: 0 additions & 33 deletions client/src/test/java/io/split/client/SplitClientConfigTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import io.split.client.impressions.ImpressionsManager;
import io.split.client.dtos.RequestContext;
import io.split.integrations.IntegrationsConfig;
import io.split.service.ProxyAuthScheme;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
Expand Down Expand Up @@ -255,36 +254,4 @@ public Map<String, List<String>> getHeaderOverrides(RequestContext context) {
Assert.assertNull(config2.customHeaderDecorator());

}

@Test
public void checkExpectedAuthScheme() {
SplitClientConfig cfg = SplitClientConfig.builder()
.proxyAuthScheme(ProxyAuthScheme.KERBEROS)
.proxyKerberosPrincipalName("bilal@bilal")
.proxyHost("local")
.proxyPort(8080)
.build();
Assert.assertEquals(ProxyAuthScheme.KERBEROS, cfg.proxyAuthScheme());

cfg = SplitClientConfig.builder()
.build();
Assert.assertEquals(null, cfg.proxyAuthScheme());
}

@Test(expected = IllegalStateException.class)
public void testAuthSchemeWithoutProxy() {
SplitClientConfig.builder()
.proxyAuthScheme(ProxyAuthScheme.KERBEROS)
.proxyKerberosPrincipalName("bilal")
.build();
}

@Test(expected = IllegalStateException.class)
public void testAuthSchemeWithoutPrincipalName() {
SplitClientConfig.builder()
.proxyAuthScheme(ProxyAuthScheme.KERBEROS)
.proxyHost("local")
.proxyPort(8080)
.build();
}
}
Loading