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

Commit

Permalink
prepare 5.10.6 release (#292)
Browse files Browse the repository at this point in the history
* 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)

* use new logging API

* update readme notes about logging

* set base logger name for SDK per test

* comment

* javadoc fixes

* revert accidental commit

* 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

* update logging info in readme

* use 1.0.0 release of logging package

* misc cleanup

* remove unnecessary extra interfaces, just use default methods instead

* 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

* add "...ForAll" TestData methods to replace "...ForAllUsers"

* bump okhttp & okhttp-eventsource dependencies

* update comment to clarify that level() doesn't apply to SLF4J

* update readme to mention different logging examples in hello-java

* switch to use snapshot build of java-logging, pending next release

* level setting does not apply to SLF4J and JUL

* use java-logging 1.1.0 release

* make sure META-INF files are never mistaken for classes and relocated

* update shared data store test logic to pass ClientContext with logger

* enable external javadoc links for com.launchdarkly.logging types

* use variable for dependency version

* fix flaky big segment status polling tests

* Update Windows orb, fix Windows JDK install in CI (#372)

* update snakeyaml for CVE-CVE-2022-25857

* latest snakeyaml is 1.31

* bump snakeyaml version for CVE-2022-38752

* disable Windows Java 11 build

* fix packaging of com.launchdarkly.logging classes

* rm debugging

* reconsidered - let's include the logging classes in the jars

* fix packaging test logic

* correct documentation

* use synchronous EventSource (5.x backport)

* backport YAML CVE fix from 6.x

* don't allow uncaught RuntimeException on stream thread and don't report errors on shutdown

Co-authored-by: Eli Bishop <eli@launchdarkly.com>
Co-authored-by: LaunchDarklyCI <LaunchDarklyCI@users.noreply.github.com>
Co-authored-by: LaunchDarklyCI <dev@launchdarkly.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>
  • Loading branch information
17 people authored Jan 6, 2023
1 parent fa22907 commit 45f3f2c
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 4 deletions.
29 changes: 25 additions & 4 deletions src/main/java/com/launchdarkly/sdk/server/StreamProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ final class StreamProcessor implements DataSource {
private final DataStoreStatusProvider.StatusListener statusListener;
private volatile EventSource es;
private final AtomicBoolean initialized = new AtomicBoolean(false);
private final AtomicBoolean closed = new AtomicBoolean(false);
private volatile long esStarted = 0;
private volatile boolean lastStoreUpdateFailed = false;
private final LDLogger logger;
Expand Down Expand Up @@ -183,11 +184,25 @@ public Future<Void> start() {
// EventSource will start the stream connection either way, but if we called start(), it
// would swallow any FaultEvents that happened during the initial conection attempt; we
// want to know about those.
for (StreamEvent event: es.anyEvents()) {
if (!handleEvent(event, initFuture)) {
// handleEvent returns false if we should fall through and end the thread
break;
try {
for (StreamEvent event: es.anyEvents()) {
if (!handleEvent(event, initFuture)) {
// handleEvent returns false if we should fall through and end the thread
break;
}
}
} catch (Exception e) {
// Any uncaught runtime exception at this point would be coming from es.anyEvents().
// That's not expected-- all deliberate EventSource exceptions are checked exceptions.
// So we have to assume something is wrong that we can't recover from at this point,
// and just let the thread terminate. That's better than having the thread be killed
// by an uncaught exception.
if (closed.get()) {
return; // ignore any exception that's just a side effect of stopping the EventSource
}
logger.error("Stream thread has ended due to unexpected exception: {}", LogValues.exceptionSummary(e));
// deliberately log stacktrace at error level since this is an unusual circumstance
logger.error(LogValues.exceptionTrace(e));
}
});
thread.setName("LaunchDarkly-streaming");
Expand All @@ -206,6 +221,9 @@ private void recordStreamInit(boolean failed) {

@Override
public void close() throws IOException {
if (closed.getAndSet(true)) {
return; // was already closed
}
logger.info("Closing LaunchDarkly StreamProcessor");
if (statusListener != null) {
dataSourceUpdates.getDataStoreStatusProvider().removeStatusListener(statusListener);
Expand All @@ -224,6 +242,9 @@ public boolean isInitialized() {
// Handles a single StreamEvent and returns true if we should keep the stream alive,
// or false if we should shut down permanently.
private boolean handleEvent(StreamEvent event, CompletableFuture<Void> initFuture) {
if (closed.get()) {
return false;
}
logger.debug("Received StreamEvent: {}", event);
if (event instanceof MessageEvent) {
handleMessage((MessageEvent)event, initFuture);
Expand Down
37 changes: 37 additions & 0 deletions src/test/java/com/launchdarkly/sdk/server/StreamProcessorTest.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.launchdarkly.sdk.server;

import com.launchdarkly.eventsource.MessageEvent;
import com.launchdarkly.logging.LDLogLevel;
import com.launchdarkly.logging.LogCapture;
import com.launchdarkly.sdk.server.DataModel.FeatureFlag;
import com.launchdarkly.sdk.server.DataModel.Segment;
import com.launchdarkly.sdk.server.DataModel.VersionedData;
Expand Down Expand Up @@ -46,13 +48,15 @@
import static com.launchdarkly.sdk.server.TestComponents.dataSourceUpdates;
import static com.launchdarkly.sdk.server.TestUtil.requireDataSourceStatus;
import static com.launchdarkly.testhelpers.ConcurrentHelpers.assertFutureIsCompleted;
import static com.launchdarkly.testhelpers.ConcurrentHelpers.assertNoMoreValues;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
Expand Down Expand Up @@ -685,6 +689,39 @@ public void testSpecialHttpConfigurations() throws Exception {
);
}

@Test
public void closingStreamProcessorDoesNotLogNetworkError() throws Exception {
// This verifies that we're not generating misleading log output or status updates
// due to simply seeing a broken connection when we have already decided to shut down.
BlockingQueue<Status> statuses = new LinkedBlockingQueue<>();
dataSourceUpdates.statusBroadcaster.register(statuses::add);

try (HttpServer server = HttpServer.start(streamResponse(EMPTY_DATA_EVENT))) {
try (StreamProcessor sp = createStreamProcessor(null, server.getUri())) {
sp.start();
dataSourceUpdates.awaitInit();
requireDataSourceStatus(statuses, State.VALID);

while (logCapture.awaitMessage(10) != null) {} // drain captured logs

sp.close();

requireDataSourceStatus(statuses, State.OFF); // should not see INTERRUPTED
assertNoMoreValues(statuses, 100, TimeUnit.MILLISECONDS);

assertThat(logCapture.requireMessage(10).getText(), startsWith("Closing LaunchDarkly"));
// There shouldn't be any other log output other than debugging
for (;;) {
LogCapture.Message message = logCapture.awaitMessage(10);
if (message == null) {
break;
}
assertThat(message.getLevel(), equalTo(LDLogLevel.DEBUG));
}
}
}
}

private void testUnrecoverableHttpError(int statusCode) throws Exception {
Handler errorResp = Handlers.status(statusCode);

Expand Down

0 comments on commit 45f3f2c

Please sign in to comment.