Skip to content

Commit cfdc429

Browse files
authored
Merge pull request #513 from splitio/kerberos-module-refactor
Refactor kerberos code to sub module
2 parents 7d136d7 + 4d888cb commit cfdc429

22 files changed

+564
-336
lines changed

client/pom.xml

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -177,18 +177,6 @@
177177
<artifactId>snakeyaml</artifactId>
178178
<version>2.0</version>
179179
</dependency>
180-
<dependency>
181-
<groupId>com.squareup.okhttp3</groupId>
182-
<artifactId>okhttp</artifactId>
183-
<version>4.12.0</version>
184-
<optional>true</optional>
185-
</dependency>
186-
<dependency>
187-
<groupId>com.squareup.okhttp3</groupId>
188-
<artifactId>logging-interceptor</artifactId>
189-
<version>4.12.0</version>
190-
<optional>true</optional>
191-
</dependency>
192180

193181
<!-- Test deps -->
194182
<dependency>

client/src/main/java/io/split/client/SplitClientConfig.java

Lines changed: 11 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import io.split.client.impressions.ImpressionsManager;
55
import io.split.client.utils.FileTypeEnum;
66
import io.split.integrations.IntegrationsConfig;
7-
import io.split.service.ProxyAuthScheme;
7+
import io.split.service.CustomHttpModule;
88
import io.split.storages.enums.OperationMode;
99
import io.split.storages.enums.StorageMode;
1010
import org.apache.hc.core5.http.HttpHost;
@@ -92,8 +92,7 @@ public class SplitClientConfig {
9292
private final HashSet<String> _flagSetsFilter;
9393
private final int _invalidSets;
9494
private final CustomHeaderDecorator _customHeaderDecorator;
95-
private final ProxyAuthScheme _proxyAuthScheme;
96-
private final String _proxyKerberosPrincipalName;
95+
private final CustomHttpModule _alternativeHTTPModule;
9796

9897
public static Builder builder() {
9998
return new Builder();
@@ -151,8 +150,7 @@ private SplitClientConfig(String endpoint,
151150
HashSet<String> flagSetsFilter,
152151
int invalidSets,
153152
CustomHeaderDecorator customHeaderDecorator,
154-
ProxyAuthScheme proxyAuthScheme,
155-
String proxyKerberosPrincipalName) {
153+
CustomHttpModule alternativeHTTPModule) {
156154
_endpoint = endpoint;
157155
_eventsEndpoint = eventsEndpoint;
158156
_featuresRefreshRate = pollForFeatureChangesEveryNSeconds;
@@ -205,8 +203,7 @@ private SplitClientConfig(String endpoint,
205203
_flagSetsFilter = flagSetsFilter;
206204
_invalidSets = invalidSets;
207205
_customHeaderDecorator = customHeaderDecorator;
208-
_proxyAuthScheme = proxyAuthScheme;
209-
_proxyKerberosPrincipalName = proxyKerberosPrincipalName;
206+
_alternativeHTTPModule = alternativeHTTPModule;
210207

211208
Properties props = new Properties();
212209
try {
@@ -414,11 +411,8 @@ public int getInvalidSets() {
414411
public CustomHeaderDecorator customHeaderDecorator() {
415412
return _customHeaderDecorator;
416413
}
417-
public ProxyAuthScheme proxyAuthScheme() {
418-
return _proxyAuthScheme;
419-
}
420-
public String proxyKerberosPrincipalName() { return _proxyKerberosPrincipalName; }
421414

415+
public CustomHttpModule alternativeHTTPModule() { return _alternativeHTTPModule; }
422416
public static final class Builder {
423417

424418
private String _endpoint = SDK_ENDPOINT;
@@ -476,8 +470,7 @@ public static final class Builder {
476470
private HashSet<String> _flagSetsFilter = new HashSet<>();
477471
private int _invalidSetsCount = 0;
478472
private CustomHeaderDecorator _customHeaderDecorator = null;
479-
private ProxyAuthScheme _proxyAuthScheme = null;
480-
private String _proxyKerberosPrincipalName = null;
473+
private CustomHttpModule _alternativeHTTPModule = null;
481474

482475
public Builder() {
483476
}
@@ -973,24 +966,13 @@ public Builder customHeaderDecorator(CustomHeaderDecorator customHeaderDecorator
973966
}
974967

975968
/**
976-
* Authentication Scheme
977-
*
978-
* @param proxyAuthScheme
979-
* @return this builder
980-
*/
981-
public Builder proxyAuthScheme(ProxyAuthScheme proxyAuthScheme) {
982-
_proxyAuthScheme = proxyAuthScheme;
983-
return this;
984-
}
985-
986-
/**
987-
* Kerberos Principal Account Name
969+
* Alternative Http Client
988970
*
989-
* @param proxyKerberosPrincipalName
971+
* @param alternativeHTTPModule
990972
* @return this builder
991973
*/
992-
public Builder proxyKerberosPrincipalName(String proxyKerberosPrincipalName) {
993-
_proxyKerberosPrincipalName = proxyKerberosPrincipalName;
974+
public Builder alternativeHTTPModule(CustomHttpModule alternativeHTTPModule) {
975+
_alternativeHTTPModule = alternativeHTTPModule;
994976
return this;
995977
}
996978

@@ -1052,17 +1034,6 @@ private void verifyEndPoints() {
10521034
}
10531035
}
10541036

1055-
private void verifyAuthScheme() {
1056-
if (_proxyAuthScheme == ProxyAuthScheme.KERBEROS) {
1057-
if (proxy() == null) {
1058-
throw new IllegalStateException("Kerberos mode require Proxy parameters.");
1059-
}
1060-
if (_proxyKerberosPrincipalName == null) {
1061-
throw new IllegalStateException("Kerberos mode require Kerberos Principal Name.");
1062-
}
1063-
}
1064-
}
1065-
10661037
private void verifyAllModes() {
10671038
switch (_impressionsMode) {
10681039
case OPTIMIZED:
@@ -1128,8 +1099,6 @@ public SplitClientConfig build() {
11281099
throw new IllegalArgumentException("Number of threads for fetching segments MUST be greater than zero");
11291100
}
11301101

1131-
verifyAuthScheme();
1132-
11331102
return new SplitClientConfig(
11341103
_endpoint,
11351104
_eventsEndpoint,
@@ -1183,8 +1152,7 @@ public SplitClientConfig build() {
11831152
_flagSetsFilter,
11841153
_invalidSetsCount,
11851154
_customHeaderDecorator,
1186-
_proxyAuthScheme,
1187-
_proxyKerberosPrincipalName);
1155+
_alternativeHTTPModule);
11881156
}
11891157
}
11901158
}

client/src/main/java/io/split/client/SplitFactoryBuilder.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import io.split.inputValidation.ApiKeyValidator;
44
import io.split.grammar.Treatments;
5+
import io.split.service.SplitHttpClient;
56
import io.split.storages.enums.StorageMode;
67
import org.slf4j.Logger;
78
import org.slf4j.LoggerFactory;

client/src/main/java/io/split/client/SplitFactoryImpl.java

Lines changed: 12 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,9 @@
5757
import io.split.engine.segments.SegmentChangeFetcher;
5858
import io.split.engine.segments.SegmentSynchronizationTaskImp;
5959
import io.split.integrations.IntegrationsConfig;
60-
import io.split.service.ProxyAuthScheme;
61-
import io.split.service.SplitHttpClientKerberosImpl;
6260
import io.split.service.SplitHttpClientImpl;
6361
import io.split.service.SplitHttpClient;
64-
import io.split.service.HTTPKerberosAuthInterceptor;
62+
6563
import io.split.storages.SegmentCache;
6664
import io.split.storages.SegmentCacheConsumer;
6765
import io.split.storages.SegmentCacheProducer;
@@ -86,6 +84,7 @@
8684
import io.split.telemetry.synchronizer.TelemetryInMemorySubmitter;
8785
import io.split.telemetry.synchronizer.TelemetrySyncTask;
8886
import io.split.telemetry.synchronizer.TelemetrySynchronizer;
87+
8988
import org.apache.hc.client5.http.auth.AuthScope;
9089
import org.apache.hc.client5.http.auth.Credentials;
9190
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
@@ -108,26 +107,16 @@
108107
import org.slf4j.LoggerFactory;
109108
import pluggable.CustomStorageWrapper;
110109

111-
import okhttp3.Authenticator;
112-
import okhttp3.OkHttpClient;
113-
import okhttp3.OkHttpClient.Builder;
114-
import okhttp3.logging.HttpLoggingInterceptor;
115-
116110
import java.io.IOException;
117111
import java.io.InputStream;
118112
import java.net.InetAddress;
119113
import java.net.URI;
120114
import java.net.URISyntaxException;
121-
import java.net.InetSocketAddress;
122-
import java.net.Proxy;
123-
import java.util.Map;
124-
import java.util.HashMap;
125115
import java.util.concurrent.ExecutorService;
126116
import java.util.stream.Collectors;
127117
import java.util.HashSet;
128118
import java.util.List;
129119
import java.util.ArrayList;
130-
import java.util.concurrent.TimeUnit;
131120

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

@@ -167,12 +156,13 @@ public class SplitFactoryImpl implements SplitFactory {
167156
private final SplitSynchronizationTask _splitSynchronizationTask;
168157
private final EventsTask _eventsTask;
169158
private final SyncManager _syncManager;
170-
private final SplitHttpClient _splitHttpClient;
159+
private SplitHttpClient _splitHttpClient;
171160
private final UserStorageWrapper _userStorageWrapper;
172161
private final ImpressionsSender _impressionsSender;
173162
private final URI _rootTarget;
174163
private final URI _eventsRootTarget;
175164
private final UniqueKeysTracker _uniqueKeysTracker;
165+
private RequestDecorator _requestDecorator;
176166

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

201191
// HttpClient
202-
RequestDecorator requestDecorator = new RequestDecorator(config.customHeaderDecorator());
203-
_splitHttpClient = buildSplitHttpClient(apiToken, config, _sdkMetadata, requestDecorator);
192+
_requestDecorator = new RequestDecorator(config.customHeaderDecorator());
193+
if (config.alternativeHTTPModule() == null) {
194+
_splitHttpClient = buildSplitHttpClient(apiToken, config, _sdkMetadata, _requestDecorator);
195+
} else {
196+
_splitHttpClient = config.alternativeHTTPModule().createClient(apiToken, _sdkMetadata, _requestDecorator);
197+
}
204198

205199
// Roots
206200
_rootTarget = URI.create(config.endpoint());
@@ -269,7 +263,7 @@ public SplitFactoryImpl(String apiToken, SplitClientConfig config) throws URISyn
269263
// SyncManager
270264
SplitTasks splitTasks = SplitTasks.build(_splitSynchronizationTask, _segmentSynchronizationTaskImp,
271265
_impressionsManager, _eventsTask, _telemetrySyncTask, _uniqueKeysTracker);
272-
SplitAPI splitAPI = SplitAPI.build(_splitHttpClient, buildSSEdHttpClient(apiToken, config, _sdkMetadata), requestDecorator);
266+
SplitAPI splitAPI = SplitAPI.build(_splitHttpClient, buildSSEdHttpClient(apiToken, config, _sdkMetadata), _requestDecorator);
273267

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

506500
protected static SplitHttpClient buildSplitHttpClient(String apiToken, SplitClientConfig config,
507501
SDKMetadata sdkMetadata, RequestDecorator requestDecorator)
508-
throws URISyntaxException, IOException {
509-
// setup Kerberos client
510-
if (config.proxyAuthScheme() == ProxyAuthScheme.KERBEROS) {
511-
_log.info("Using Kerberos-Proxy Authentication Scheme.");
512-
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(config.proxy().getHostName(), config.proxy().getPort()));
513-
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
514-
if (config.debugEnabled()) {
515-
logging.setLevel(HttpLoggingInterceptor.Level.HEADERS);
516-
} else {
517-
logging.setLevel(HttpLoggingInterceptor.Level.NONE);
518-
}
519-
520-
Map<String, String> kerberosOptions = new HashMap<>();
521-
kerberosOptions.put("com.sun.security.auth.module.Krb5LoginModule", "required");
522-
kerberosOptions.put("refreshKrb5Config", "false");
523-
kerberosOptions.put("doNotPrompt", "false");
524-
kerberosOptions.put("useTicketCache", "true");
525-
526-
Authenticator proxyAuthenticator = getProxyAuthenticator(config, kerberosOptions);
527-
OkHttpClient client = buildOkHttpClient(proxy, config, logging, proxyAuthenticator);
528-
529-
return SplitHttpClientKerberosImpl.create(
530-
client,
531-
requestDecorator,
532-
apiToken,
533-
sdkMetadata);
534-
}
535-
502+
throws URISyntaxException {
536503
SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder.create()
537504
.setSslContext(SSLContexts.createSystemDefault())
538505
.setTlsVersions(TLS.V_1_1, TLS.V_1_2)
@@ -570,21 +537,6 @@ protected static SplitHttpClient buildSplitHttpClient(String apiToken, SplitClie
570537
sdkMetadata);
571538
}
572539

573-
protected static OkHttpClient buildOkHttpClient(Proxy proxy, SplitClientConfig config,
574-
HttpLoggingInterceptor logging, Authenticator proxyAuthenticator) {
575-
return new Builder()
576-
.proxy(proxy)
577-
.readTimeout(config.readTimeout(), TimeUnit.MILLISECONDS)
578-
.connectTimeout(config.connectionTimeout(), TimeUnit.MILLISECONDS)
579-
.addInterceptor(logging)
580-
.proxyAuthenticator(proxyAuthenticator)
581-
.build();
582-
}
583-
584-
protected static HTTPKerberosAuthInterceptor getProxyAuthenticator(SplitClientConfig config,
585-
Map<String, String> kerberosOptions) throws IOException {
586-
return new HTTPKerberosAuthInterceptor(config.proxyKerberosPrincipalName(), kerberosOptions);
587-
}
588540
private static CloseableHttpClient buildSSEdHttpClient(String apiToken, SplitClientConfig config,
589541
SDKMetadata sdkMetadata) {
590542
RequestConfig requestConfig = RequestConfig.custom()
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package io.split.service;
2+
3+
import io.split.client.RequestDecorator;
4+
import io.split.client.utils.SDKMetadata;
5+
6+
import java.io.IOException;
7+
8+
public interface CustomHttpModule {
9+
public SplitHttpClient createClient(String apiToken, SDKMetadata sdkMetadata, RequestDecorator requestDecorator) throws IOException;
10+
}

client/src/main/java/io/split/service/SplitHttpClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,4 @@ public interface SplitHttpClient extends Closeable {
3232
public SplitHttpResponse post(URI uri,
3333
HttpEntity entity,
3434
Map<String, List<String>> additionalHeaders) throws IOException;
35-
}
35+
}

client/src/test/java/io/split/client/LocalhostSplitFactoryYamlTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import io.split.client.utils.LocalhostUtils;
44
import io.split.grammar.Treatments;
5+
import io.split.service.SplitHttpClient;
56
import org.junit.Rule;
67
import org.junit.Test;
78
import org.junit.rules.TemporaryFolder;

client/src/test/java/io/split/client/SplitClientConfigTest.java

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import io.split.client.impressions.ImpressionsManager;
77
import io.split.client.dtos.RequestContext;
88
import io.split.integrations.IntegrationsConfig;
9-
import io.split.service.ProxyAuthScheme;
109
import org.junit.Assert;
1110
import org.junit.Test;
1211
import org.mockito.Mockito;
@@ -255,36 +254,4 @@ public Map<String, List<String>> getHeaderOverrides(RequestContext context) {
255254
Assert.assertNull(config2.customHeaderDecorator());
256255

257256
}
258-
259-
@Test
260-
public void checkExpectedAuthScheme() {
261-
SplitClientConfig cfg = SplitClientConfig.builder()
262-
.proxyAuthScheme(ProxyAuthScheme.KERBEROS)
263-
.proxyKerberosPrincipalName("bilal@bilal")
264-
.proxyHost("local")
265-
.proxyPort(8080)
266-
.build();
267-
Assert.assertEquals(ProxyAuthScheme.KERBEROS, cfg.proxyAuthScheme());
268-
269-
cfg = SplitClientConfig.builder()
270-
.build();
271-
Assert.assertEquals(null, cfg.proxyAuthScheme());
272-
}
273-
274-
@Test(expected = IllegalStateException.class)
275-
public void testAuthSchemeWithoutProxy() {
276-
SplitClientConfig.builder()
277-
.proxyAuthScheme(ProxyAuthScheme.KERBEROS)
278-
.proxyKerberosPrincipalName("bilal")
279-
.build();
280-
}
281-
282-
@Test(expected = IllegalStateException.class)
283-
public void testAuthSchemeWithoutPrincipalName() {
284-
SplitClientConfig.builder()
285-
.proxyAuthScheme(ProxyAuthScheme.KERBEROS)
286-
.proxyHost("local")
287-
.proxyPort(8080)
288-
.build();
289-
}
290257
}

0 commit comments

Comments
 (0)