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

Commit c7d4cab

Browse files
LaunchDarklyReleaseBoteli-darklyLaunchDarklyCIgwhelanLDssrm
authored
prepare 5.8.0 release (#263)
* CI fix * more event test improvements * misc cleanup + test improvements * misc cleanup + test improvements * make intVariation and doubleVariation non-nullable * (5.0) don't use jar magic to find out our own version string * 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 <sstokes@launchdarkly.com> * Update src/test/java/com/launchdarkly/sdk/server/EvaluatorTest.java Co-authored-by: Sam Stokes <sstokes@launchdarkly.com> * Update src/test/java/com/launchdarkly/sdk/server/EvaluatorTest.java Co-authored-by: Sam Stokes <sstokes@launchdarkly.com> * Update src/test/java/com/launchdarkly/sdk/server/EvaluatorTest.java Co-authored-by: Sam Stokes <sstokes@launchdarkly.com> * 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 <sstokes@launchdarkly.com> * 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) Co-authored-by: Eli Bishop <eli@launchdarkly.com> Co-authored-by: LaunchDarklyCI <dev@launchdarkly.com> Co-authored-by: LaunchDarklyCI <LaunchDarklyCI@users.noreply.github.com> Co-authored-by: Gavin Whelan <gwhelan@launchdarkly.com> Co-authored-by: ssrm <ssrm@users.noreply.github.com> Co-authored-by: Harpo Roeder <hroeder@launchdarkly.com> Co-authored-by: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com> Co-authored-by: Elliot <35050275+Apache-HB@users.noreply.github.com> Co-authored-by: Robert J. Neal <rneal@launchdarkly.com> Co-authored-by: Robert J. Neal <robertjneal@users.noreply.github.com> Co-authored-by: Sam Stokes <sstokes@launchdarkly.com> Co-authored-by: LaunchDarklyReleaseBot <launchdarklyreleasebot@launchdarkly.com> Co-authored-by: Ember Stevens <ember.stevens@launchdarkly.com> Co-authored-by: ember-stevens <79482775+ember-stevens@users.noreply.github.com> Co-authored-by: Alex Engelberg <alex.benjamin.engelberg@gmail.com>
1 parent c65c6e9 commit c7d4cab

19 files changed

+321
-13
lines changed

.circleci/config.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,11 @@ jobs:
8080
./gradlew jacocoTestReport
8181
mkdir -p coverage/
8282
cp -r build/reports/jacoco/test/* ./coverage
83-
- run: mkdir -p ~/junit/
8483
- run:
8584
name: Save test results
86-
command: find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/junit/ \;
85+
command: |
86+
mkdir -p ~/junit/
87+
find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/junit/ \;
8788
when: always
8889

8990
- run: make build-contract-tests
@@ -126,7 +127,8 @@ jobs:
126127
name: save test results
127128
command: |
128129
mkdir .\junit
129-
cp build/test-results/test/*.xml junit
130+
cp build/test-results/test/*.xml junit -ErrorAction SilentlyContinue
131+
when: always
130132
- store_test_results:
131133
path: .\junit
132134
- store_artifacts:

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public static class SdkConfigParams {
2525
SdkConfigStreamParams streaming;
2626
SdkConfigEventParams events;
2727
SdkConfigBigSegmentsParams bigSegments;
28+
SdkConfigTagParams tags;
2829
}
2930

3031
public static class SdkConfigStreamParams {
@@ -49,6 +50,11 @@ public static class SdkConfigBigSegmentsParams {
4950
Long statusPollIntervalMs;
5051
Long staleAfterMs;
5152
}
53+
54+
public static class SdkConfigTagParams {
55+
String applicationId;
56+
String applicationVersion;
57+
}
5258

5359
public static class CommandParams {
5460
String command;

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.launchdarkly.sdk.server.FlagsStateOption;
99
import com.launchdarkly.sdk.server.LDClient;
1010
import com.launchdarkly.sdk.server.LDConfig;
11+
import com.launchdarkly.sdk.server.integrations.ApplicationInfoBuilder;
1112
import com.launchdarkly.sdk.server.integrations.BigSegmentsConfigurationBuilder;
1213
import com.launchdarkly.sdk.server.integrations.EventProcessorBuilder;
1314
import com.launchdarkly.sdk.server.integrations.StreamingDataSourceBuilder;
@@ -235,6 +236,17 @@ private LDConfig buildSdkConfig(SdkConfigParams params) {
235236
}
236237
builder.bigSegments(bsb);
237238
}
239+
240+
if (params.tags != null) {
241+
ApplicationInfoBuilder ab = Components.applicationInfo();
242+
if (params.tags.applicationId != null) {
243+
ab.applicationId(params.tags.applicationId);
244+
}
245+
if (params.tags.applicationVersion != null) {
246+
ab.applicationVersion(params.tags.applicationVersion);
247+
}
248+
builder.applicationInfo(ab);
249+
}
238250

239251
return builder.build();
240252
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ public class TestService {
2626
"all-flags-client-side-only",
2727
"all-flags-details-only-for-tracked-flags",
2828
"all-flags-with-reasons",
29-
"big-segments"
29+
"big-segments",
30+
"tags"
3031
};
3132

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

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.launchdarkly.sdk.server;
22

3+
import com.launchdarkly.sdk.server.interfaces.ApplicationInfo;
34
import com.launchdarkly.sdk.server.interfaces.BasicConfiguration;
45
import com.launchdarkly.sdk.server.interfaces.ClientContext;
56
import com.launchdarkly.sdk.server.interfaces.HttpConfiguration;
@@ -51,7 +52,8 @@ private ClientContextImpl(
5152
ScheduledExecutorService sharedExecutor,
5253
DiagnosticAccumulator diagnosticAccumulator
5354
) {
54-
this.basicConfiguration = new BasicConfiguration(sdkKey, configuration.offline, configuration.threadPriority);
55+
ApplicationInfo applicationInfo = configuration.applicationInfoBuilder.createApplicationInfo();
56+
this.basicConfiguration = new BasicConfiguration(sdkKey, configuration.offline, configuration.threadPriority, applicationInfo);
5557

5658
this.httpConfiguration = configuration.httpConfigFactory.createHttpConfiguration(basicConfiguration);
5759
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
@@ -11,6 +11,7 @@
1111
import com.launchdarkly.sdk.server.ComponentsImpl.PersistentDataStoreBuilderImpl;
1212
import com.launchdarkly.sdk.server.ComponentsImpl.PollingDataSourceBuilderImpl;
1313
import com.launchdarkly.sdk.server.ComponentsImpl.StreamingDataSourceBuilderImpl;
14+
import com.launchdarkly.sdk.server.integrations.ApplicationInfoBuilder;
1415
import com.launchdarkly.sdk.server.integrations.BigSegmentsConfigurationBuilder;
1516
import com.launchdarkly.sdk.server.integrations.EventProcessorBuilder;
1617
import com.launchdarkly.sdk.server.integrations.HttpConfigurationBuilder;
@@ -320,4 +321,27 @@ public static HttpAuthentication httpBasicAuthentication(String username, String
320321
public static LoggingConfigurationBuilder logging() {
321322
return new LoggingConfigurationBuilderImpl();
322323
}
324+
325+
/**
326+
* Returns a configuration builder for the SDK's application metadata.
327+
* <p>
328+
* Passing this to {@link LDConfig.Builder#applicationInfo(com.launchdarkly.sdk.server.integrations.ApplicationInfoBuilder)},
329+
* after setting any desired properties on the builder, applies this configuration to the SDK.
330+
* <pre><code>
331+
* LDConfig config = new LDConfig.Builder()
332+
* .applicationInfo(
333+
* Components.applicationInfo()
334+
* .applicationId("authentication-service")
335+
* .applicationVersion("1.0.0")
336+
* )
337+
* .build();
338+
* </code></pre>
339+
*
340+
* @return a builder object
341+
* @since 5.8.0
342+
* @see LDConfig.Builder#applicationInfo(com.launchdarkly.sdk.server.integrations.ApplicationInfoBuilder)
343+
*/
344+
public static ApplicationInfoBuilder applicationInfo() {
345+
return new ApplicationInfoBuilder();
346+
}
323347
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,12 @@ public HttpConfiguration createHttpConfiguration(BasicConfiguration basicConfigu
253253
ImmutableMap.Builder<String, String> headers = ImmutableMap.builder();
254254
headers.put("Authorization", basicConfiguration.getSdkKey());
255255
headers.put("User-Agent", "JavaClient/" + Version.SDK_VERSION);
256+
if (basicConfiguration.getApplicationInfo() != null) {
257+
String tagHeader = Util.applicationTagHeader(basicConfiguration.getApplicationInfo());
258+
if (!tagHeader.isEmpty()) {
259+
headers.put("X-LaunchDarkly-Tags", tagHeader);
260+
}
261+
}
256262
if (wrapperName != null) {
257263
String wrapperId = wrapperVersion == null ? wrapperName : (wrapperName + "/" + wrapperVersion);
258264
headers.put("X-LaunchDarkly-Wrapper", wrapperId);

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.launchdarkly.sdk.server;
22

33
import com.launchdarkly.sdk.EvaluationReason;
4+
import com.launchdarkly.sdk.server.integrations.ApplicationInfoBuilder;
45
import com.launchdarkly.sdk.server.integrations.BigSegmentsConfigurationBuilder;
56
import com.launchdarkly.sdk.server.interfaces.BigSegmentStoreFactory;
67
import com.launchdarkly.sdk.server.interfaces.DataSourceFactory;
@@ -25,6 +26,7 @@ public final class LDConfig {
2526

2627
protected static final LDConfig DEFAULT = new Builder().build();
2728

29+
final ApplicationInfoBuilder applicationInfoBuilder;
2830
final BigSegmentsConfigurationBuilder bigSegmentsConfigBuilder;
2931
final DataSourceFactory dataSourceFactory;
3032
final DataStoreFactory dataStoreFactory;
@@ -46,6 +48,8 @@ protected LDConfig(Builder builder) {
4648
this.eventProcessorFactory = builder.eventProcessorFactory == null ? Components.sendEvents() :
4749
builder.eventProcessorFactory;
4850
}
51+
this.applicationInfoBuilder = builder.applicationInfoBuilder == null ? Components.applicationInfo() :
52+
builder.applicationInfoBuilder;
4953
this.bigSegmentsConfigBuilder = builder.bigSegmentsConfigBuilder == null ?
5054
Components.bigSegments(null) : builder.bigSegmentsConfigBuilder;
5155
this.dataStoreFactory = builder.dataStoreFactory == null ? Components.inMemoryDataStore() :
@@ -72,6 +76,7 @@ protected LDConfig(Builder builder) {
7276
* </pre>
7377
*/
7478
public static class Builder {
79+
private ApplicationInfoBuilder applicationInfoBuilder = null;
7580
private BigSegmentsConfigurationBuilder bigSegmentsConfigBuilder = null;
7681
private DataSourceFactory dataSourceFactory = null;
7782
private DataStoreFactory dataStoreFactory = null;
@@ -89,6 +94,22 @@ public static class Builder {
8994
public Builder() {
9095
}
9196

97+
/**
98+
* Sets the SDK's application metadata, which may be used in LaunchDarkly analytics or other product features,
99+
* but does not affect feature flag evaluations.
100+
* <p>
101+
* This object is normally a configuration builder obtained from {@link Components#applicationInfo()},
102+
* which has methods for setting individual logging-related properties.
103+
*
104+
* @param applicationInfoBuilder a configuration builder object returned by {@link Components#applicationInfo()}
105+
* @return the builder
106+
* @since 5.8.0
107+
*/
108+
public Builder applicationInfo(ApplicationInfoBuilder applicationInfoBuilder) {
109+
this.applicationInfoBuilder = applicationInfoBuilder;
110+
return this;
111+
}
112+
92113
/**
93114
* Sets the configuration of the SDK's Big Segments feature.
94115
* <p>

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.launchdarkly.sdk.server;
22

3+
import com.launchdarkly.sdk.server.Loggers;
4+
import com.launchdarkly.sdk.server.interfaces.ApplicationInfo;
35
import com.launchdarkly.sdk.server.interfaces.HttpAuthentication;
46
import com.launchdarkly.sdk.server.interfaces.HttpConfiguration;
57

@@ -13,7 +15,10 @@
1315
import java.nio.file.SimpleFileVisitor;
1416
import java.nio.file.attribute.BasicFileAttributes;
1517
import java.time.Duration;
18+
import java.util.ArrayList;
19+
import java.util.List;
1620
import java.util.Map;
21+
import java.util.regex.Pattern;
1722
import java.util.concurrent.TimeUnit;
1823

1924
import static com.google.common.collect.Iterables.transform;
@@ -207,4 +212,35 @@ static URI concatenateUriPath(URI baseUri, String path) {
207212
String addPath = path.startsWith("/") ? path.substring(1) : path;
208213
return URI.create(uriStr + (uriStr.endsWith("/") ? "" : "/") + addPath);
209214
}
215+
216+
// Tag values must not be empty, and only contain letters, numbers, `.`, `_`, or `-`.
217+
private static Pattern TAG_VALUE_REGEX = Pattern.compile("^[\\w.-]+$");
218+
219+
/**
220+
* Builds the "X-LaunchDarkly-Tags" HTTP header out of the configured application info.
221+
*
222+
* @param applicationInfo the application metadata
223+
* @return a space-separated string of tags, e.g. "application-id/authentication-service application-version/1.0.0"
224+
*/
225+
static String applicationTagHeader(ApplicationInfo applicationInfo) {
226+
String[][] tags = {
227+
{"applicationId", "application-id", applicationInfo.getApplicationId()},
228+
{"applicationVersion", "application-version", applicationInfo.getApplicationVersion()},
229+
};
230+
List<String> parts = new ArrayList<>();
231+
for (String[] row : tags) {
232+
String javaKey = row[0];
233+
String tagKey = row[1];
234+
String tagVal = row[2];
235+
if (tagVal == null) {
236+
continue;
237+
}
238+
if (!TAG_VALUE_REGEX.matcher(tagVal).matches()) {
239+
Loggers.MAIN.warn("Value of ApplicationInfo.{} contained invalid characters and was discarded", javaKey);
240+
continue;
241+
}
242+
parts.add(tagKey + "/" + tagVal);
243+
}
244+
return String.join(" ", parts);
245+
}
210246
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package com.launchdarkly.sdk.server.integrations;
2+
3+
import com.launchdarkly.sdk.server.Components;
4+
import com.launchdarkly.sdk.server.interfaces.ApplicationInfo;
5+
6+
/**
7+
* Contains methods for configuring the SDK's application metadata.
8+
* <p>
9+
* Application metadata may be used in LaunchDarkly analytics or other product features, but does not affect feature flag evaluations.
10+
* <p>
11+
* If you want to set non-default values for any of these fields, create a builder with
12+
* {@link Components#applicationInfo()}, change its properties with the methods of this class,
13+
* and pass it to {@link com.launchdarkly.sdk.server.LDConfig.Builder#applicationInfo(ApplicationInfoBuilder)}:
14+
* <pre><code>
15+
* LDConfig config = new LDConfig.Builder()
16+
* .applicationInfo(
17+
* Components.applicationInfo()
18+
* .applicationId("authentication-service")
19+
* .applicationVersion("1.0.0")
20+
* )
21+
* .build();
22+
* </code></pre>
23+
* <p>
24+
*
25+
* @since 5.8.0
26+
*/
27+
public final class ApplicationInfoBuilder {
28+
private String applicationId;
29+
private String applicationVersion;
30+
31+
/**
32+
* Create an empty ApplicationInfoBuilder.
33+
*
34+
* @see Components#applicationInfo()
35+
*/
36+
public ApplicationInfoBuilder() {}
37+
38+
/**
39+
* Sets a unique identifier representing the application where the LaunchDarkly SDK is running.
40+
* <p>
41+
* This can be specified as any string value as long as it only uses the following characters: ASCII
42+
* letters, ASCII digits, period, hyphen, underscore. A string containing any other characters will be
43+
* ignored.
44+
*
45+
* @param applicationId the application identifier
46+
* @return the builder
47+
*/
48+
public ApplicationInfoBuilder applicationId(String applicationId) {
49+
this.applicationId = applicationId;
50+
return this;
51+
}
52+
53+
/**
54+
* Sets a unique identifier representing the version of the application where the LaunchDarkly SDK
55+
* is running.
56+
* <p>
57+
* This can be specified as any string value as long as it only uses the following characters: ASCII
58+
* letters, ASCII digits, period, hyphen, underscore. A string containing any other characters will be
59+
* ignored.
60+
*
61+
* @param applicationVersion the application version
62+
* @return the builder
63+
*/
64+
public ApplicationInfoBuilder applicationVersion(String applicationVersion) {
65+
this.applicationVersion = applicationVersion;
66+
return this;
67+
}
68+
69+
/**
70+
* Called internally by the SDK to create the configuration object.
71+
*
72+
* @return the configuration object
73+
*/
74+
public ApplicationInfo createApplicationInfo() {
75+
return new ApplicationInfo(applicationId, applicationVersion);
76+
}
77+
}

0 commit comments

Comments
 (0)