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

Commit df98fec

Browse files
LaunchDarklyReleaseBoteli-darklyLaunchDarklyCIgwhelanLDssrm
authored
prepare 5.9.2 release (#270)
* (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) * 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 * make BigSegmentStoreWrapper.pollingDetectsStaleStatus test less timing-sensitive * make LDEndToEndClientTest.test____SpecialHttpConfigurations less timing-sensitive * make data source status tests less timing-sensitive * use streaming JSON parsing for incoming LD data * fix tests * rm unused * rm unused * use okhttp-eventsource 2.6.0 * update eventsource to 2.6.1 to fix pom/manifest problem * increase efficiency of summary event data structures (#335) * make reusable EvaluationDetail instances as part of flag preprocessing (#336) * make evaluator result object immutable and reuse instances * comment * avoid creating List iterators during evaluations * remove unnecessary copy * fix allFlagsState to not generate prereq eval events 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> Co-authored-by: Alex Engelberg <aengelberg@launchdarkly.com>
1 parent 22eb63e commit df98fec

29 files changed

+1599
-723
lines changed

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

Lines changed: 43 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22

33
import com.google.common.collect.ImmutableList;
44
import com.google.gson.annotations.JsonAdapter;
5-
import com.launchdarkly.sdk.EvaluationReason;
65
import com.launchdarkly.sdk.LDValue;
76
import com.launchdarkly.sdk.UserAttribute;
7+
import com.launchdarkly.sdk.server.DataModelPreprocessing.ClausePreprocessed;
8+
import com.launchdarkly.sdk.server.DataModelPreprocessing.FlagPreprocessed;
9+
import com.launchdarkly.sdk.server.DataModelPreprocessing.FlagRulePreprocessed;
10+
import com.launchdarkly.sdk.server.DataModelPreprocessing.PrerequisitePreprocessed;
11+
import com.launchdarkly.sdk.server.DataModelPreprocessing.TargetPreprocessed;
812
import com.launchdarkly.sdk.server.interfaces.DataStoreTypes.DataKind;
913
import com.launchdarkly.sdk.server.interfaces.DataStoreTypes.ItemDescriptor;
1014

@@ -15,6 +19,35 @@
1519
import static java.util.Collections.emptyList;
1620
import static java.util.Collections.emptySet;
1721

22+
// IMPLEMENTATION NOTES:
23+
//
24+
// - FeatureFlag, Segment, and all other data model classes contained within them, must be package-private.
25+
// We don't want application code to see these types, because we need to be free to change their details without
26+
// breaking the application.
27+
//
28+
// - We expose our DataKind instances publicly because application code may need to reference them if it is
29+
// implementing a custom component such as a data store. But beyond the mere fact of there being these kinds of
30+
// data, applications should not be considered with their structure.
31+
//
32+
// - For all classes that can be deserialized from JSON, there must be an empty constructor, and the fields
33+
// cannot be final. This is because of how Gson works: it creates an instance first, then sets the fields. If
34+
// we are able to move away from using Gson reflective deserialization in the future, we can make them final.
35+
//
36+
// - There should also be a constructor that takes all the fields; we should use that whenever we need to
37+
// create these objects programmatically (so that if we are able at some point to make the fields final, that
38+
// won't break anything).
39+
//
40+
// - For properties that have a collection type such as List, the getter method should always include a null
41+
// guard and return an empty collection if the field is null (so that we don't have to worry about null guards
42+
// every time we might want to iterate over these collections). Semantically there is no difference in the data
43+
// model between an empty list and a null list, and in some languages (particularly Go) it is easy for an
44+
// uninitialized list to be serialized to JSON as null.
45+
//
46+
// - Some classes have a "preprocessed" field containing types defined in DataModelPreprocessing. These fields
47+
// must always be marked transient, so Gson will not serialize them. They are populated when we deserialize a
48+
// FeatureFlag or Segment, because those types implement JsonHelpers.PostProcessingDeserializable (the
49+
// afterDeserialized() method).
50+
1851
/**
1952
* Contains information about the internal data model for feature flags and user segments.
2053
* <p>
@@ -104,6 +137,8 @@ static final class FeatureFlag implements VersionedData, JsonHelpers.PostProcess
104137
private Long debugEventsUntilDate;
105138
private boolean deleted;
106139

140+
transient FlagPreprocessed preprocessed;
141+
107142
// We need this so Gson doesn't complain in certain java environments that restrict unsafe allocation
108143
FeatureFlag() {}
109144

@@ -191,17 +226,16 @@ boolean isClientSide() {
191226
return clientSide;
192227
}
193228

194-
// Precompute some invariant values for improved efficiency during evaluations - called from JsonHelpers.PostProcessingDeserializableTypeAdapter
195229
public void afterDeserialized() {
196-
EvaluatorPreprocessing.preprocessFlag(this);
230+
DataModelPreprocessing.preprocessFlag(this);
197231
}
198232
}
199233

200234
static final class Prerequisite {
201235
private String key;
202236
private int variation;
203237

204-
private transient EvaluationReason prerequisiteFailedReason;
238+
transient PrerequisitePreprocessed preprocessed;
205239

206240
Prerequisite() {}
207241

@@ -217,21 +251,14 @@ String getKey() {
217251
int getVariation() {
218252
return variation;
219253
}
220-
221-
// This value is precomputed when we deserialize a FeatureFlag from JSON
222-
EvaluationReason getPrerequisiteFailedReason() {
223-
return prerequisiteFailedReason;
224-
}
225-
226-
void setPrerequisiteFailedReason(EvaluationReason prerequisiteFailedReason) {
227-
this.prerequisiteFailedReason = prerequisiteFailedReason;
228-
}
229254
}
230255

231256
static final class Target {
232257
private Set<String> values;
233258
private int variation;
234259

260+
transient TargetPreprocessed preprocessed;
261+
235262
Target() {}
236263

237264
Target(Set<String> values, int variation) {
@@ -259,7 +286,7 @@ static final class Rule extends VariationOrRollout {
259286
private List<Clause> clauses;
260287
private boolean trackEvents;
261288

262-
private transient EvaluationReason ruleMatchReason;
289+
transient FlagRulePreprocessed preprocessed;
263290

264291
Rule() {
265292
super();
@@ -284,15 +311,6 @@ List<Clause> getClauses() {
284311
boolean isTrackEvents() {
285312
return trackEvents;
286313
}
287-
288-
// This value is precomputed when we deserialize a FeatureFlag from JSON
289-
EvaluationReason getRuleMatchReason() {
290-
return ruleMatchReason;
291-
}
292-
293-
void setRuleMatchReason(EvaluationReason ruleMatchReason) {
294-
this.ruleMatchReason = ruleMatchReason;
295-
}
296314
}
297315

298316
static final class Clause {
@@ -301,9 +319,7 @@ static final class Clause {
301319
private List<LDValue> values; //interpreted as an OR of values
302320
private boolean negate;
303321

304-
// The following property is marked transient because it is not to be serialized or deserialized;
305-
// it is (if necessary) precomputed in FeatureFlag.afterDeserialized() to speed up evaluations.
306-
transient EvaluatorPreprocessing.ClauseExtra preprocessed;
322+
transient ClausePreprocessed preprocessed;
307323

308324
Clause() {
309325
}
@@ -331,14 +347,6 @@ List<LDValue> getValues() {
331347
boolean isNegate() {
332348
return negate;
333349
}
334-
335-
EvaluatorPreprocessing.ClauseExtra getPreprocessed() {
336-
return preprocessed;
337-
}
338-
339-
void setPreprocessed(EvaluatorPreprocessing.ClauseExtra preprocessed) {
340-
this.preprocessed = preprocessed;
341-
}
342350
}
343351

344352
static final class Rollout {
@@ -508,9 +516,8 @@ public Integer getGeneration() {
508516
return generation;
509517
}
510518

511-
// Precompute some invariant values for improved efficiency during evaluations - called from JsonHelpers.PostProcessingDeserializableTypeAdapter
512519
public void afterDeserialized() {
513-
EvaluatorPreprocessing.preprocessSegment(this);
520+
DataModelPreprocessing.preprocessSegment(this);
514521
}
515522
}
516523

0 commit comments

Comments
 (0)