Skip to content
This repository was archived by the owner on May 30, 2024. It is now read-only.

Commit e8f208d

Browse files
LaunchDarklyReleaseBoteli-darklyLaunchDarklyCIgwhelanLDssrm
authored
prepare 5.9.0 release (#267)
* fix test * make intVariation and doubleVariation non-nullable * better unit test coverage of LDClient and FeatureFlagsState * test coverage improvements + minor fixes * better temp file handling in file data source tests * revert file data source implementation change for now * revert unnecessary change * comment about file watching on Mac * add slight delay to avoid timing-dependent test flakiness * test fixes/comments * (5.0) use simpler and more stable logger names * better instructions * more convenient way to set EventSource logger name * (5.0) add HTTP default headers method + some component refactoring * don't need to pass the whole config object to describeConfiguration() * simplify test logic for HTTP headers * (5.0) final test coverage improvements, for now, with enforcement * re-simplify DataBuilder * increase timeouts * misc fixes * rm unnecessary override * indents * update benchmark code for API change * support loading file data from a classpath resource * update metadata so Releaser knows about 4.x branch * minor test fixes * make class final * rm beta changelog items * test data source * more info about coverage in CONTRIBUTING.md * misc fixes/tests * use java-sdk-common 1.0.0 * use okhttp-eventsource 2.3.0 * use okhttp-eventsource 2.3.1 for thread fix * fix flaky tests due to change in EventSource error reporting * remove support for indirect put and indirect patch * fix typo in javadoc example code * clean up polling logic, fix status updating after an outage, don't reinit store unnecessarily (#256) * slightly change semantics of boolean setters, improve tests, misc cleanup * avoid NPEs if LDUser was deserialized by Gson (#257) * avoid NPEs if LDUser was deserialized by Gson * add test * fix release metadata * prepare 4.14.1 release (#200) * Releasing version 4.14.1 * exclude Kotlin metadata from jar + fix misc Gradle problems * update CI and Gradle to test with newer JDKs (#259) * update okhttp to 3.14.9 (fixes incompatibility with OpenJDK 8.0.252) * prepare 4.14.2 release (#205) * Releasing version 4.14.2 * update okhttp to 4.8.1 (fixes incompatibility with OpenJDK 8.0.252) * gitignore * Bump SnakeYAML from 1.19 to 1.26 to address CVE-2017-18640 * prepare 4.14.3 release (#209) * Releasing version 4.14.3 * comments * only log initialization message once in polling mode * [ch89935] Correct some logging call format strings (#264) Also adds debug logs for full exception information in a couple locations. * [ch90109] Remove outdated trackMetric comment from before service support. (#265) * Fix compatibility with Java 7. * Remove import that is no longer used. * add Java 7 build (#267) * prepare 4.14.4 release (#214) * Releasing version 4.14.4 * add and use getSocketFactory * alignment * add socketFactory to builder * test socket factory builder * preserve dummy CI config file when pushing to gh-pages (#271) * fix concatenation when base URI has a context path (#270) * fix shaded jar builds to exclude Jackson classes and not modify Jackson return types (#268) * add test httpClientCanUseCustomSocketFactory for DefaultFeatureRequestor * add httpClientCanUseCustomSocketFactory() test for DefaultEventSenderTest * add httpClientCanUseCustomSocketFactory() test to StreamProcessorTest * pass URI to in customSocketFactory event test * make test less ambiguous * copy rules to new FlagBuilder instances (#273) * Bump guava version (#274) * Removed the guides link * increment versions when loading file data, so FlagTracker will work (#275) * increment versions when loading file data, so FlagTracker will work * update doc comment about flag change events with file data * add ability to ignore duplicate keys in file data (#276) * add alias events (#278) * add alias events and function * update tests for new functionality * update javadoc strings * add validation of javadoc build to CI * update commons-codec to 1.15 (#279) * Add support for experiment rollouts * add tests and use seed for allocating user to partition * test serialization and add check for isExperiment * fix PollingProcessorTest test race condition + other test issues (#282) * use launchdarkly-java-sdk-common 1.1.0-alpha-expalloc.2 * Update src/test/java/com/launchdarkly/sdk/server/EvaluatorTest.java Co-authored-by: Sam Stokes <[email protected]> * Update src/test/java/com/launchdarkly/sdk/server/EvaluatorTest.java Co-authored-by: Sam Stokes <[email protected]> * Update src/test/java/com/launchdarkly/sdk/server/EvaluatorTest.java Co-authored-by: Sam Stokes <[email protected]> * Update src/test/java/com/launchdarkly/sdk/server/EvaluatorTest.java Co-authored-by: Sam Stokes <[email protected]> * changes per code review comments * Please enter the commit message for your changes. Lines starting * fix null pointer exception * address code review comments * address more comments * missed a ! for isUntracked() * fix default boolean for json * make untracked FALSE by default * refactoring of bucketing logic to remove the need for an extra result object (#283) * add comment to enum * various JSON fixes, update common-sdk (#284) * simlpify the logic and make it match node/.Net sdks * Update src/main/java/com/launchdarkly/sdk/server/EventFactory.java Co-authored-by: Sam Stokes <[email protected]> * add the same comment as the Node SDK * Remove outdated/meaningless doc comment. (#286) * protect against NPEs if flag/segment JSON contains a null value * use java-sdk-common 1.2.0 * fix Jackson-related build issues (again) (#288) * update to okhttp-eventsource patch for stream retry bug, improve tests (#289) * update to okhttp-eventsource patch for stream retry bug, improve test * add test for appropriate stream retry * add public builder for FeatureFlagsState (#290) * add public builder for FeatureFlagsState * javadoc fixes * clarify FileData doc comment to say you shouldn't use offline mode (#291) * improve validation of SDK key so we won't throw an exception that contains the key (#293) * fix javadoc link in FileData comment (#294) * fix PollingProcessor 401 behavior and use new HTTP test helpers (#292) * re-fix metadata to remove Jackson dependencies, also remove Class-Path from manifest (#295) * make FeatureFlagsState.Builder.build() public (#297) * clean up tests using java-test-helpers 1.1.0 (#296) * use Releaser v2 config + newer CI images (#298) * [ch123129] Fix `PollingDataSourceBuilder` example. (#299) * Updates docs URLs * always use US locale when parsing HTTP dates * use Gson 2.8.9 * don't try to send more diagnostic events after an unrecoverable HTTP error * ensure module-info file isn't copied into our jars during build * use Gradle 7 * update build for benchmarks * more Gradle 7 compatibility changes for benchmark job * test with Java 17 in CI (#307) * test with Java 17 in CI * also test in Java 17 for Windows * fix choco install command * do date comparisons as absolute times, regardless of time zone (#310) * fix suppression of nulls in JSON representations (#311) * fix suppression of nulls in JSON representations * distinguish between situations where we do or do not want to suppress nulls * fix identify/track null user key check, also don't create index event for alias * use latest java-sdk-common * fix setting of trackEvents/trackReason in allFlagsState data when there's an experiment * implement contract tests (#314) * Merge Big Segments feature branch for 5.7.0 release (#316) Includes Big Segments implementation and contract test support for the new behavior. * Fix for pom including SDK common library as a dependency. (#317) * Upload JUnit XML to CircleCI on failure (#320) Fix a bug in the CircleCI config that was only uploading JUnit XML on _success_, not failure. * Add application tag support (#319) * Enforce 64 character limit on application tag values (#323) * fix "wrong type" logic in evaluations when default value is null * Rename master to main in .ldrelease/config.yml (#325) * Simpler way of setting base URIs in Java (#322) Now supports the `ServiceEndpoints` config for setting custom URIs for endpoints in a single place Co-authored-by: Eli Bishop <[email protected]> Co-authored-by: LaunchDarklyCI <[email protected]> Co-authored-by: LaunchDarklyCI <[email protected]> Co-authored-by: Gavin Whelan <[email protected]> Co-authored-by: ssrm <[email protected]> Co-authored-by: Harpo Roeder <[email protected]> Co-authored-by: Ben Woskow <[email protected]> Co-authored-by: Elliot <[email protected]> Co-authored-by: Robert J. Neal <[email protected]> Co-authored-by: Robert J. Neal <[email protected]> Co-authored-by: Sam Stokes <[email protected]> Co-authored-by: LaunchDarklyReleaseBot <[email protected]> Co-authored-by: Ember Stevens <[email protected]> Co-authored-by: ember-stevens <[email protected]> Co-authored-by: Alex Engelberg <[email protected]> Co-authored-by: Alex Engelberg <[email protected]>
1 parent 6e0be88 commit e8f208d

29 files changed

+682
-44
lines changed

contract-tests/service/src/main/java/sdktest/Representations.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public static class SdkConfigParams {
2626
SdkConfigEventParams events;
2727
SdkConfigBigSegmentsParams bigSegments;
2828
SdkConfigTagParams tags;
29+
SdkConfigServiceEndpointParams serviceEndpoints;
2930
}
3031

3132
public static class SdkConfigStreamParams {
@@ -55,6 +56,12 @@ public static class SdkConfigTagParams {
5556
String applicationId;
5657
String applicationVersion;
5758
}
59+
60+
public static class SdkConfigServiceEndpointParams {
61+
String streaming;
62+
String polling;
63+
String events;
64+
}
5865

5966
public static class CommandParams {
6067
String command;

contract-tests/service/src/main/java/sdktest/SdkClientEntity.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import com.launchdarkly.sdk.server.integrations.ApplicationInfoBuilder;
1212
import com.launchdarkly.sdk.server.integrations.BigSegmentsConfigurationBuilder;
1313
import com.launchdarkly.sdk.server.integrations.EventProcessorBuilder;
14+
import com.launchdarkly.sdk.server.integrations.ServiceEndpointsBuilder;
1415
import com.launchdarkly.sdk.server.integrations.StreamingDataSourceBuilder;
1516
import com.launchdarkly.sdk.server.interfaces.BigSegmentStoreStatusProvider;
1617

@@ -247,7 +248,16 @@ private LDConfig buildSdkConfig(SdkConfigParams params) {
247248
}
248249
builder.applicationInfo(ab);
249250
}
250-
251+
252+
if (params.serviceEndpoints != null) {
253+
builder.serviceEndpoints(
254+
Components.serviceEndpoints()
255+
.streaming(params.serviceEndpoints.streaming)
256+
.polling(params.serviceEndpoints.polling)
257+
.events(params.serviceEndpoints.events)
258+
);
259+
}
260+
251261
return builder.build();
252262
}
253263
}

contract-tests/service/src/main/java/sdktest/TestService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ public class TestService {
2727
"all-flags-details-only-for-tracked-flags",
2828
"all-flags-with-reasons",
2929
"big-segments",
30-
"tags"
30+
"tags",
31+
"service-endpoints"
3132
};
3233

3334
static final Gson gson = new GsonBuilder().serializeNulls().create();

src/main/java/com/launchdarkly/sdk/server/ClientContextImpl.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ private ClientContextImpl(
5252
ScheduledExecutorService sharedExecutor,
5353
DiagnosticAccumulator diagnosticAccumulator
5454
) {
55-
ApplicationInfo applicationInfo = configuration.applicationInfoBuilder.createApplicationInfo();
56-
this.basicConfiguration = new BasicConfiguration(sdkKey, configuration.offline, configuration.threadPriority, applicationInfo);
55+
this.basicConfiguration = new BasicConfiguration(sdkKey, configuration.offline, configuration.threadPriority, configuration.applicationInfo, configuration.serviceEndpoints);
5756

5857
this.httpConfiguration = configuration.httpConfigFactory.createHttpConfiguration(basicConfiguration);
5958
this.loggingConfiguration = configuration.loggingConfigFactory.createLoggingConfiguration(basicConfiguration);

src/main/java/com/launchdarkly/sdk/server/Components.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.launchdarkly.sdk.server.ComponentsImpl.NullDataSourceFactory;
1111
import com.launchdarkly.sdk.server.ComponentsImpl.PersistentDataStoreBuilderImpl;
1212
import com.launchdarkly.sdk.server.ComponentsImpl.PollingDataSourceBuilderImpl;
13+
import com.launchdarkly.sdk.server.ComponentsImpl.ServiceEndpointsBuilderImpl;
1314
import com.launchdarkly.sdk.server.ComponentsImpl.StreamingDataSourceBuilderImpl;
1415
import com.launchdarkly.sdk.server.integrations.ApplicationInfoBuilder;
1516
import com.launchdarkly.sdk.server.integrations.BigSegmentsConfigurationBuilder;
@@ -18,6 +19,7 @@
1819
import com.launchdarkly.sdk.server.integrations.LoggingConfigurationBuilder;
1920
import com.launchdarkly.sdk.server.integrations.PersistentDataStoreBuilder;
2021
import com.launchdarkly.sdk.server.integrations.PollingDataSourceBuilder;
22+
import com.launchdarkly.sdk.server.integrations.ServiceEndpointsBuilder;
2123
import com.launchdarkly.sdk.server.integrations.StreamingDataSourceBuilder;
2224
import com.launchdarkly.sdk.server.interfaces.BigSegmentStoreFactory;
2325
import com.launchdarkly.sdk.server.interfaces.DataSourceFactory;
@@ -344,4 +346,26 @@ public static LoggingConfigurationBuilder logging() {
344346
public static ApplicationInfoBuilder applicationInfo() {
345347
return new ApplicationInfoBuilder();
346348
}
349+
350+
/**
351+
* Returns a builder for configuring custom service URIs.
352+
* <p>
353+
* Passing this to {@link LDConfig.Builder#serviceEndpoints(com.launchdarkly.sdk.server.integrations.ServiceEndpointsBuilder)},
354+
* after setting any desired properties on the builder, applies this configuration to the SDK.
355+
* <pre><code>
356+
* LDConfig config = new LDConfig.Builder()
357+
* .serviceEndpoints(
358+
* Components.serviceEndpoints()
359+
* .relayProxy("http://my-relay-hostname:80")
360+
* )
361+
* .build();
362+
* </code></pre>
363+
*
364+
* @return a builder object
365+
* @since 5.9.0
366+
* @see LDConfig.Builder#serviceEndpoints(com.launchdarkly.sdk.server.integrations.ServiceEndpointsBuilder)
367+
*/
368+
public static ServiceEndpointsBuilder serviceEndpoints() {
369+
return new ServiceEndpointsBuilderImpl();
370+
}
347371
}

src/main/java/com/launchdarkly/sdk/server/ComponentsImpl.java

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.launchdarkly.sdk.server.integrations.LoggingConfigurationBuilder;
99
import com.launchdarkly.sdk.server.integrations.PersistentDataStoreBuilder;
1010
import com.launchdarkly.sdk.server.integrations.PollingDataSourceBuilder;
11+
import com.launchdarkly.sdk.server.integrations.ServiceEndpointsBuilder;
1112
import com.launchdarkly.sdk.server.integrations.StreamingDataSourceBuilder;
1213
import com.launchdarkly.sdk.server.interfaces.BasicConfiguration;
1314
import com.launchdarkly.sdk.server.interfaces.ClientContext;
@@ -28,6 +29,7 @@
2829
import com.launchdarkly.sdk.server.interfaces.LoggingConfiguration;
2930
import com.launchdarkly.sdk.server.interfaces.PersistentDataStore;
3031
import com.launchdarkly.sdk.server.interfaces.PersistentDataStoreFactory;
32+
import com.launchdarkly.sdk.server.interfaces.ServiceEndpoints;
3133

3234
import java.io.IOException;
3335
import java.net.InetSocketAddress;
@@ -139,7 +141,13 @@ public DataSource createDataSource(ClientContext context, DataSourceUpdates data
139141

140142
Loggers.DATA_SOURCE.info("Enabling streaming API");
141143

142-
URI streamUri = baseURI == null ? LDConfig.DEFAULT_STREAM_URI : baseURI;
144+
URI streamUri = StandardEndpoints.selectBaseUri(
145+
context.getBasic().getServiceEndpoints().getStreamingBaseUri(),
146+
baseURI,
147+
StandardEndpoints.DEFAULT_STREAMING_BASE_URI,
148+
"streaming",
149+
Loggers.MAIN
150+
);
143151

144152
return new StreamProcessor(
145153
context.getHttp(),
@@ -157,7 +165,10 @@ public LDValue describeConfiguration(BasicConfiguration basicConfiguration) {
157165
.put(ConfigProperty.STREAMING_DISABLED.name, false)
158166
.put(ConfigProperty.CUSTOM_BASE_URI.name, false)
159167
.put(ConfigProperty.CUSTOM_STREAM_URI.name,
160-
baseURI != null && !baseURI.equals(LDConfig.DEFAULT_STREAM_URI))
168+
StandardEndpoints.isCustomBaseUri(
169+
basicConfiguration.getServiceEndpoints().getStreamingBaseUri(),
170+
baseURI,
171+
StandardEndpoints.DEFAULT_STREAMING_BASE_URI))
161172
.put(ConfigProperty.RECONNECT_TIME_MILLIS.name, initialReconnectDelay.toMillis())
162173
.put(ConfigProperty.USING_RELAY_DAEMON.name, false)
163174
.build();
@@ -177,11 +188,16 @@ public DataSource createDataSource(ClientContext context, DataSourceUpdates data
177188

178189
Loggers.DATA_SOURCE.info("Disabling streaming API");
179190
Loggers.DATA_SOURCE.warn("You should only disable the streaming API if instructed to do so by LaunchDarkly support");
180-
181-
DefaultFeatureRequestor requestor = new DefaultFeatureRequestor(
182-
context.getHttp(),
183-
baseURI == null ? LDConfig.DEFAULT_BASE_URI : baseURI
191+
192+
URI pollUri = StandardEndpoints.selectBaseUri(
193+
context.getBasic().getServiceEndpoints().getPollingBaseUri(),
194+
baseURI,
195+
StandardEndpoints.DEFAULT_POLLING_BASE_URI,
196+
"polling",
197+
Loggers.MAIN
184198
);
199+
200+
DefaultFeatureRequestor requestor = new DefaultFeatureRequestor(context.getHttp(), pollUri);
185201
return new PollingProcessor(
186202
requestor,
187203
dataSourceUpdates,
@@ -195,7 +211,10 @@ public LDValue describeConfiguration(BasicConfiguration basicConfiguration) {
195211
return LDValue.buildObject()
196212
.put(ConfigProperty.STREAMING_DISABLED.name, true)
197213
.put(ConfigProperty.CUSTOM_BASE_URI.name,
198-
baseURI != null && !baseURI.equals(LDConfig.DEFAULT_BASE_URI))
214+
StandardEndpoints.isCustomBaseUri(
215+
basicConfiguration.getServiceEndpoints().getPollingBaseUri(),
216+
baseURI,
217+
StandardEndpoints.DEFAULT_POLLING_BASE_URI))
199218
.put(ConfigProperty.CUSTOM_STREAM_URI.name, false)
200219
.put(ConfigProperty.POLLING_INTERVAL_MILLIS.name, pollInterval.toMillis())
201220
.put(ConfigProperty.USING_RELAY_DAEMON.name, false)
@@ -210,12 +229,19 @@ public EventProcessor createEventProcessor(ClientContext context) {
210229
EventSender eventSender =
211230
(eventSenderFactory == null ? new DefaultEventSender.Factory() : eventSenderFactory)
212231
.createEventSender(context.getBasic(), context.getHttp());
232+
URI eventsUri = StandardEndpoints.selectBaseUri(
233+
context.getBasic().getServiceEndpoints().getEventsBaseUri(),
234+
baseURI,
235+
StandardEndpoints.DEFAULT_EVENTS_BASE_URI,
236+
"events",
237+
Loggers.MAIN
238+
);
213239
return new DefaultEventProcessor(
214240
new EventsConfiguration(
215241
allAttributesPrivate,
216242
capacity,
217243
eventSender,
218-
baseURI == null ? LDConfig.DEFAULT_EVENTS_URI : baseURI,
244+
eventsUri,
219245
flushInterval,
220246
inlineUsersInEvents,
221247
privateAttributes,
@@ -234,7 +260,11 @@ public EventProcessor createEventProcessor(ClientContext context) {
234260
public LDValue describeConfiguration(BasicConfiguration basicConfiguration) {
235261
return LDValue.buildObject()
236262
.put(ConfigProperty.ALL_ATTRIBUTES_PRIVATE.name, allAttributesPrivate)
237-
.put(ConfigProperty.CUSTOM_EVENTS_URI.name, baseURI != null && !baseURI.equals(LDConfig.DEFAULT_EVENTS_URI))
263+
.put(ConfigProperty.CUSTOM_EVENTS_URI.name,
264+
StandardEndpoints.isCustomBaseUri(
265+
basicConfiguration.getServiceEndpoints().getEventsBaseUri(),
266+
baseURI,
267+
StandardEndpoints.DEFAULT_EVENTS_BASE_URI))
238268
.put(ConfigProperty.DIAGNOSTIC_RECORDING_INTERVAL_MILLIS.name, diagnosticRecordingInterval.toMillis())
239269
.put(ConfigProperty.EVENTS_CAPACITY.name, capacity)
240270
.put(ConfigProperty.EVENTS_FLUSH_INTERVAL_MILLIS.name, flushInterval.toMillis())
@@ -333,4 +363,23 @@ public LoggingConfiguration createLoggingConfiguration(BasicConfiguration basicC
333363
return new LoggingConfigurationImpl(logDataSourceOutageAsErrorAfter);
334364
}
335365
}
366+
367+
static final class ServiceEndpointsBuilderImpl extends ServiceEndpointsBuilder {
368+
@Override
369+
public ServiceEndpoints createServiceEndpoints() {
370+
// If *any* custom URIs have been set, then we do not want to use default values for any that were not set,
371+
// so we will leave those null. That way, if we decide later on (in other component factories, such as
372+
// EventProcessorBuilder) that we are actually interested in one of these values, and we
373+
// see that it is null, we can assume that there was a configuration mistake and log an
374+
// error.
375+
if (streamingBaseUri == null && pollingBaseUri == null && eventsBaseUri == null) {
376+
return new ServiceEndpoints(
377+
StandardEndpoints.DEFAULT_STREAMING_BASE_URI,
378+
StandardEndpoints.DEFAULT_POLLING_BASE_URI,
379+
StandardEndpoints.DEFAULT_EVENTS_BASE_URI
380+
);
381+
}
382+
return new ServiceEndpoints(streamingBaseUri, pollingBaseUri, eventsBaseUri);
383+
}
384+
}
336385
}

src/main/java/com/launchdarkly/sdk/server/DefaultEventSender.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,14 @@ public Result sendEventData(EventDataKind kind, String data, int eventCount, URI
8080

8181
switch (kind) {
8282
case ANALYTICS:
83-
path = "bulk";
83+
path = StandardEndpoints.ANALYTICS_EVENTS_POST_REQUEST_PATH;
8484
String eventPayloadId = UUID.randomUUID().toString();
8585
headersBuilder.add(EVENT_PAYLOAD_ID_HEADER, eventPayloadId);
8686
headersBuilder.add(EVENT_SCHEMA_HEADER, EVENT_SCHEMA_VERSION);
8787
description = String.format("%d event(s)", eventCount);
8888
break;
8989
case DIAGNOSTICS:
90-
path = "diagnostic";
90+
path = StandardEndpoints.DIAGNOSTIC_EVENTS_POST_REQUEST_PATH;
9191
description = "diagnostic event";
9292
break;
9393
default:

src/main/java/com/launchdarkly/sdk/server/DefaultFeatureRequestor.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
*/
2828
final class DefaultFeatureRequestor implements FeatureRequestor {
2929
private static final Logger logger = Loggers.DATA_SOURCE;
30-
private static final String GET_LATEST_ALL_PATH = "sdk/latest-all";
3130
private static final long MAX_HTTP_CACHE_SIZE_BYTES = 10 * 1024 * 1024; // 10 MB
3231

3332
@VisibleForTesting final URI baseUri;
@@ -38,7 +37,7 @@ final class DefaultFeatureRequestor implements FeatureRequestor {
3837

3938
DefaultFeatureRequestor(HttpConfiguration httpConfig, URI baseUri) {
4039
this.baseUri = baseUri;
41-
this.pollingUri = concatenateUriPath(baseUri, GET_LATEST_ALL_PATH);
40+
this.pollingUri = concatenateUriPath(baseUri, StandardEndpoints.POLLING_REQUEST_PATH);
4241

4342
OkHttpClient.Builder httpBuilder = new OkHttpClient.Builder();
4443
configureHttpClientBuilder(httpConfig, httpBuilder);

src/main/java/com/launchdarkly/sdk/server/EventsConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ final class EventsConfiguration {
3737
this.allAttributesPrivate = allAttributesPrivate;
3838
this.capacity = capacity;
3939
this.eventSender = eventSender;
40-
this.eventsUri = eventsUri == null ? LDConfig.DEFAULT_EVENTS_URI : eventsUri;
40+
this.eventsUri = eventsUri;
4141
this.flushInterval = flushInterval;
4242
this.inlineUsersInEvents = inlineUsersInEvents;
4343
this.privateAttributes = privateAttributes == null ? ImmutableSet.of() : ImmutableSet.copyOf(privateAttributes);

src/main/java/com/launchdarkly/sdk/server/LDConfig.java

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
import com.launchdarkly.sdk.EvaluationReason;
44
import com.launchdarkly.sdk.server.integrations.ApplicationInfoBuilder;
55
import com.launchdarkly.sdk.server.integrations.BigSegmentsConfigurationBuilder;
6+
import com.launchdarkly.sdk.server.integrations.ServiceEndpointsBuilder;
7+
import com.launchdarkly.sdk.server.interfaces.ApplicationInfo;
68
import com.launchdarkly.sdk.server.interfaces.BigSegmentStoreFactory;
79
import com.launchdarkly.sdk.server.interfaces.DataSourceFactory;
810
import com.launchdarkly.sdk.server.interfaces.DataStoreFactory;
911
import com.launchdarkly.sdk.server.interfaces.EventProcessor;
1012
import com.launchdarkly.sdk.server.interfaces.EventProcessorFactory;
1113
import com.launchdarkly.sdk.server.interfaces.HttpConfigurationFactory;
1214
import com.launchdarkly.sdk.server.interfaces.LoggingConfigurationFactory;
15+
import com.launchdarkly.sdk.server.interfaces.ServiceEndpoints;
1316

1417
import java.net.URI;
1518
import java.time.Duration;
@@ -18,22 +21,19 @@
1821
* This class exposes advanced configuration options for the {@link LDClient}. Instances of this class must be constructed with a {@link com.launchdarkly.sdk.server.LDConfig.Builder}.
1922
*/
2023
public final class LDConfig {
21-
static final URI DEFAULT_BASE_URI = URI.create("https://app.launchdarkly.com");
22-
static final URI DEFAULT_EVENTS_URI = URI.create("https://events.launchdarkly.com");
23-
static final URI DEFAULT_STREAM_URI = URI.create("https://stream.launchdarkly.com");
24-
2524
static final Duration DEFAULT_START_WAIT = Duration.ofSeconds(5);
2625

2726
protected static final LDConfig DEFAULT = new Builder().build();
2827

29-
final ApplicationInfoBuilder applicationInfoBuilder;
28+
final ApplicationInfo applicationInfo;
3029
final BigSegmentsConfigurationBuilder bigSegmentsConfigBuilder;
3130
final DataSourceFactory dataSourceFactory;
3231
final DataStoreFactory dataStoreFactory;
3332
final boolean diagnosticOptOut;
3433
final EventProcessorFactory eventProcessorFactory;
3534
final HttpConfigurationFactory httpConfigFactory;
3635
final LoggingConfigurationFactory loggingConfigFactory;
36+
final ServiceEndpoints serviceEndpoints;
3737
final boolean offline;
3838
final Duration startWait;
3939
final int threadPriority;
@@ -48,8 +48,9 @@ protected LDConfig(Builder builder) {
4848
this.eventProcessorFactory = builder.eventProcessorFactory == null ? Components.sendEvents() :
4949
builder.eventProcessorFactory;
5050
}
51-
this.applicationInfoBuilder = builder.applicationInfoBuilder == null ? Components.applicationInfo() :
52-
builder.applicationInfoBuilder;
51+
this.applicationInfo = (builder.applicationInfoBuilder == null ? Components.applicationInfo() :
52+
builder.applicationInfoBuilder)
53+
.createApplicationInfo();
5354
this.bigSegmentsConfigBuilder = builder.bigSegmentsConfigBuilder == null ?
5455
Components.bigSegments(null) : builder.bigSegmentsConfigBuilder;
5556
this.dataStoreFactory = builder.dataStoreFactory == null ? Components.inMemoryDataStore() :
@@ -60,6 +61,9 @@ protected LDConfig(Builder builder) {
6061
this.loggingConfigFactory = builder.loggingConfigFactory == null ? Components.logging() :
6162
builder.loggingConfigFactory;
6263
this.offline = builder.offline;
64+
this.serviceEndpoints = (builder.serviceEndpointsBuilder == null ? Components.serviceEndpoints() :
65+
builder.serviceEndpointsBuilder)
66+
.createServiceEndpoints();
6367
this.startWait = builder.startWait;
6468
this.threadPriority = builder.threadPriority;
6569
}
@@ -84,6 +88,7 @@ public static class Builder {
8488
private EventProcessorFactory eventProcessorFactory = null;
8589
private HttpConfigurationFactory httpConfigFactory = null;
8690
private LoggingConfigurationFactory loggingConfigFactory = null;
91+
private ServiceEndpointsBuilder serviceEndpointsBuilder = null;
8792
private boolean offline = false;
8893
private Duration startWait = DEFAULT_START_WAIT;
8994
private int threadPriority = Thread.MIN_PRIORITY;
@@ -263,6 +268,21 @@ public Builder offline(boolean offline) {
263268
return this;
264269
}
265270

271+
/**
272+
* Sets the base service URIs used by SDK components.
273+
* <p>
274+
* This object is normally a configuration builder obtained from {@link Components#serviceEndpoints()},
275+
* which has methods for setting each external endpoint to a custom URI.
276+
*
277+
* @param serviceEndpointsBuilder a configuration builder object returned by {@link Components#applicationInfo()}
278+
* @return the builder
279+
* @since 5.9.0
280+
*/
281+
public Builder serviceEndpoints(ServiceEndpointsBuilder serviceEndpointsBuilder) {
282+
this.serviceEndpointsBuilder = serviceEndpointsBuilder;
283+
return this;
284+
}
285+
266286
/**
267287
* Set how long the constructor will block awaiting a successful connection to LaunchDarkly.
268288
* Setting this to a zero or negative duration will not block and cause the constructor to return immediately.

0 commit comments

Comments
 (0)