Skip to content

Commit

Permalink
Refactor kerberos code to sub module
Browse files Browse the repository at this point in the history
  • Loading branch information
Bilal Al committed Sep 10, 2024
1 parent 7d136d7 commit 9e46ad5
Show file tree
Hide file tree
Showing 15 changed files with 247 additions and 551 deletions.
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
25 changes: 23 additions & 2 deletions client/src/main/java/io/split/client/SplitClientConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.split.client.utils.FileTypeEnum;
import io.split.integrations.IntegrationsConfig;
import io.split.service.ProxyAuthScheme;
import io.split.service.SplitHttpClient;
import io.split.storages.enums.OperationMode;
import io.split.storages.enums.StorageMode;
import org.apache.hc.core5.http.HttpHost;
Expand Down Expand Up @@ -94,6 +95,7 @@ public class SplitClientConfig {
private final CustomHeaderDecorator _customHeaderDecorator;
private final ProxyAuthScheme _proxyAuthScheme;
private final String _proxyKerberosPrincipalName;
private final SplitHttpClient _proxyKerberosClient;

public static Builder builder() {
return new Builder();
Expand Down Expand Up @@ -152,7 +154,8 @@ private SplitClientConfig(String endpoint,
int invalidSets,
CustomHeaderDecorator customHeaderDecorator,
ProxyAuthScheme proxyAuthScheme,
String proxyKerberosPrincipalName) {
String proxyKerberosPrincipalName,
SplitHttpClient proxyKerberosClient) {
_endpoint = endpoint;
_eventsEndpoint = eventsEndpoint;
_featuresRefreshRate = pollForFeatureChangesEveryNSeconds;
Expand Down Expand Up @@ -207,6 +210,7 @@ private SplitClientConfig(String endpoint,
_customHeaderDecorator = customHeaderDecorator;
_proxyAuthScheme = proxyAuthScheme;
_proxyKerberosPrincipalName = proxyKerberosPrincipalName;
_proxyKerberosClient = proxyKerberosClient;

Properties props = new Properties();
try {
Expand Down Expand Up @@ -419,6 +423,7 @@ public ProxyAuthScheme proxyAuthScheme() {
}
public String proxyKerberosPrincipalName() { return _proxyKerberosPrincipalName; }

public SplitHttpClient proxyKerberosClient() { return _proxyKerberosClient; }
public static final class Builder {

private String _endpoint = SDK_ENDPOINT;
Expand Down Expand Up @@ -478,6 +483,7 @@ public static final class Builder {
private CustomHeaderDecorator _customHeaderDecorator = null;
private ProxyAuthScheme _proxyAuthScheme = null;
private String _proxyKerberosPrincipalName = null;
private SplitHttpClient _proxyKerberosClient = null;

public Builder() {
}
Expand Down Expand Up @@ -994,6 +1000,17 @@ public Builder proxyKerberosPrincipalName(String proxyKerberosPrincipalName) {
return this;
}

/**
* Kerberos Http Client
*
* @param proxyKerberosClient
* @return this builder
*/
public Builder proxyKerberosClient(SplitHttpClient proxyKerberosClient) {
_proxyKerberosClient = proxyKerberosClient;
return this;
}

/**
* Thread Factory
*
Expand Down Expand Up @@ -1060,6 +1077,9 @@ private void verifyAuthScheme() {
if (_proxyKerberosPrincipalName == null) {
throw new IllegalStateException("Kerberos mode require Kerberos Principal Name.");
}
if (_proxyKerberosClient == null) {
throw new IllegalStateException("Kerberos mode require Kerberos Http Client.");
}
}
}

Expand Down Expand Up @@ -1184,7 +1204,8 @@ public SplitClientConfig build() {
_invalidSetsCount,
_customHeaderDecorator,
_proxyAuthScheme,
_proxyKerberosPrincipalName);
_proxyKerberosPrincipalName,
_proxyKerberosClient);
}
}
}
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
86 changes: 26 additions & 60 deletions client/src/main/java/io/split/client/SplitFactoryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,9 @@
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 +85,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 +108,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,15 +157,16 @@ 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 {
public SplitFactoryImpl(String apiToken, SplitClientConfig config) throws URISyntaxException {
_userStorageWrapper = null;
_operationMode = config.operationMode();
_startTime = System.currentTimeMillis();
Expand All @@ -199,8 +190,14 @@ 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.proxyAuthScheme() != ProxyAuthScheme.KERBEROS) {
_splitHttpClient = buildSplitHttpClient(apiToken, config, _sdkMetadata, _requestDecorator);
} else {
_splitHttpClient = config.proxyKerberosClient();
_splitHttpClient.setMetaData(_sdkMetadata);
_splitHttpClient.setRequestDecorator(_requestDecorator);
}

// Roots
_rootTarget = URI.create(config.endpoint());
Expand Down Expand Up @@ -269,7 +266,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 All @@ -287,6 +284,14 @@ public SplitFactoryImpl(String apiToken, SplitClientConfig config) throws URISyn
}
}

public RequestDecorator getRequestDecorator() {
return _requestDecorator;
}

public SDKMetadata getSDKMetaData() {
return _sdkMetadata;
}

// Constructor for consumer mode
protected SplitFactoryImpl(String apiToken, SplitClientConfig config, CustomStorageWrapper customStorageWrapper)
throws URISyntaxException {
Expand Down Expand Up @@ -503,36 +508,12 @@ public boolean isDestroyed() {
return isTerminated;
}

public void setSplitHttpClient(SplitHttpClient splitHttpClient) {
_splitHttpClient = splitHttpClient;
}
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 +551,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
8 changes: 7 additions & 1 deletion client/src/main/java/io/split/service/SplitHttpClient.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.split.service;

import io.split.client.RequestDecorator;
import io.split.client.utils.SDKMetadata;
import io.split.engine.common.FetchOptions;
import io.split.client.dtos.SplitHttpResponse;

Expand Down Expand Up @@ -32,4 +34,8 @@ public interface SplitHttpClient extends Closeable {
public SplitHttpResponse post(URI uri,
HttpEntity entity,
Map<String, List<String>> additionalHeaders) throws IOException;
}

public void setMetaData(SDKMetadata metadata);

public void setRequestDecorator(RequestDecorator requestDecorator);
}
11 changes: 11 additions & 0 deletions client/src/main/java/io/split/service/SplitHttpClientImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,15 @@ private void setBasicHeaders(HttpRequest request) {
public void close() throws IOException {
_client.close();
}

@Override
public void setMetaData(SDKMetadata metadata) {
// only implemented for Kerberos client
}

@Override
public void setRequestDecorator(RequestDecorator requestDecorator) {
// only implemented for Kerberos client
}

}
Loading

0 comments on commit 9e46ad5

Please sign in to comment.