From 859a36cbfafc94d4601b87d304237e6ddf97c08d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2025 18:05:19 +0000 Subject: [PATCH 01/56] chore(deps): update github/codeql-action digest to 8c1551c (#1333) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 6e3c40f4..78ce975a 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -20,7 +20,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@1c15a48f3fb49ce535e9ee4e57e127315f669361 + uses: github/codeql-action/init@8c1551cdd4accfcf33820b75a096d845a88e8642 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1c15a48f3fb49ce535e9ee4e57e127315f669361 + uses: github/codeql-action/analyze@8c1551cdd4accfcf33820b75a096d845a88e8642 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 85313855..8143c1f4 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@1c15a48f3fb49ce535e9ee4e57e127315f669361 + uses: github/codeql-action/init@8c1551cdd4accfcf33820b75a096d845a88e8642 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@1c15a48f3fb49ce535e9ee4e57e127315f669361 + uses: github/codeql-action/autobuild@8c1551cdd4accfcf33820b75a096d845a88e8642 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1c15a48f3fb49ce535e9ee4e57e127315f669361 + uses: github/codeql-action/analyze@8c1551cdd4accfcf33820b75a096d845a88e8642 From 5436eb0d5db3a0e9bd9289fbef57b9eeada0a667 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 02:28:02 +0000 Subject: [PATCH 02/56] chore(deps): update github/codeql-action digest to acadfed (#1335) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 78ce975a..0f83d29a 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -20,7 +20,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@8c1551cdd4accfcf33820b75a096d845a88e8642 + uses: github/codeql-action/init@acadfedea5aa91c818900c9dbea3ec271259c919 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@8c1551cdd4accfcf33820b75a096d845a88e8642 + uses: github/codeql-action/analyze@acadfedea5aa91c818900c9dbea3ec271259c919 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 8143c1f4..b6e2a3f7 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@8c1551cdd4accfcf33820b75a096d845a88e8642 + uses: github/codeql-action/init@acadfedea5aa91c818900c9dbea3ec271259c919 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@8c1551cdd4accfcf33820b75a096d845a88e8642 + uses: github/codeql-action/autobuild@acadfedea5aa91c818900c9dbea3ec271259c919 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@8c1551cdd4accfcf33820b75a096d845a88e8642 + uses: github/codeql-action/analyze@acadfedea5aa91c818900c9dbea3ec271259c919 From e163ce1c060d0dc8812e4a8a3b37f52b0156324d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 14:48:26 +0000 Subject: [PATCH 03/56] chore(deps): update github/codeql-action digest to 1bb15d0 (#1336) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 0f83d29a..70dbb28f 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -20,7 +20,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@acadfedea5aa91c818900c9dbea3ec271259c919 + uses: github/codeql-action/init@1bb15d06a6fbb5d9d9ffd228746bf8ee208caec8 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@acadfedea5aa91c818900c9dbea3ec271259c919 + uses: github/codeql-action/analyze@1bb15d06a6fbb5d9d9ffd228746bf8ee208caec8 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index b6e2a3f7..8bf7512f 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@acadfedea5aa91c818900c9dbea3ec271259c919 + uses: github/codeql-action/init@1bb15d06a6fbb5d9d9ffd228746bf8ee208caec8 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@acadfedea5aa91c818900c9dbea3ec271259c919 + uses: github/codeql-action/autobuild@1bb15d06a6fbb5d9d9ffd228746bf8ee208caec8 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@acadfedea5aa91c818900c9dbea3ec271259c919 + uses: github/codeql-action/analyze@1bb15d06a6fbb5d9d9ffd228746bf8ee208caec8 From 88baa65dd0568b75d64f7f657563e04ee81c1d8c Mon Sep 17 00:00:00 2001 From: Simon Schrottner Date: Tue, 18 Feb 2025 19:19:18 +0100 Subject: [PATCH 04/56] test: Reduce usage of singelton within our tests and implementations (#1331) Our tests are great, but often we rely on our own Singelton for testing purposes. This can create concurrency issues or make testing really hard. By instantiating a own API object for each test we ensure that we are not messing with each other. Furthermore we should not use `.getInstance()` within our own implementation. Signed-off-by: Simon Schrottner Co-authored-by: Todd Baert --- pom.xml | 9 ++ .../dev/openfeature/sdk/OpenFeatureAPI.java | 4 +- .../openfeature/sdk/OpenFeatureClient.java | 4 +- .../openfeature/sdk/ProviderRepository.java | 7 +- .../sdk/AlwaysBrokenWithDetailsProvider.java | 8 +- ...=> AlwaysBrokenWithExceptionProvider.java} | 2 +- .../sdk/ClientProviderMappingTest.java | 7 +- .../sdk/DeveloperExperienceTest.java | 28 ++-- .../openfeature/sdk/EventProviderTest.java | 4 +- .../java/dev/openfeature/sdk/EventsTest.java | 128 +++++++++--------- .../sdk/FlagEvaluationSpecTest.java | 59 +++----- .../dev/openfeature/sdk/HookSpecTest.java | 38 +++--- .../sdk/InitializeBehaviorSpecTest.java | 14 +- ...ingTest.java => LockingSingeltonTest.java} | 2 +- .../sdk/OpenFeatureAPISingeltonTest.java | 17 +++ .../openfeature/sdk/OpenFeatureAPITest.java | 52 +++---- .../sdk/OpenFeatureAPITestUtil.java | 10 ++ .../sdk/OpenFeatureClientTest.java | 6 +- .../sdk/ProviderRepositoryTest.java | 2 +- .../sdk/ShutdownBehaviorSpecTest.java | 19 ++- .../dev/openfeature/sdk/TrackingSpecTest.java | 11 +- .../sdk/arch/ArchitectureTest.java | 27 ++++ .../memory/InMemoryProviderTest.java | 17 ++- .../testutils/FeatureProviderTestUtils.java | 31 ----- 24 files changed, 259 insertions(+), 247 deletions(-) rename src/test/java/dev/openfeature/sdk/{AlwaysBrokenProvider.java => AlwaysBrokenWithExceptionProvider.java} (94%) rename src/test/java/dev/openfeature/sdk/{LockingTest.java => LockingSingeltonTest.java} (99%) create mode 100644 src/test/java/dev/openfeature/sdk/OpenFeatureAPISingeltonTest.java create mode 100644 src/test/java/dev/openfeature/sdk/OpenFeatureAPITestUtil.java create mode 100644 src/test/java/dev/openfeature/sdk/arch/ArchitectureTest.java delete mode 100644 src/test/java/dev/openfeature/sdk/testutils/FeatureProviderTestUtils.java diff --git a/pom.xml b/pom.xml index a6a54e5a..bbc1b8db 100644 --- a/pom.xml +++ b/pom.xml @@ -67,6 +67,13 @@ + + com.tngtech.archunit + archunit-junit5 + 1.4.0 + test + + org.mockito mockito-core @@ -242,12 +249,14 @@ com.github.spotbugs:* org.junit* + com.tngtech.archunit* org.simplify4u:slf4j2-mock* com.google.guava* io.cucumber* org.junit* + com.tngtech.archunit* com.google.code.findbugs* com.github.spotbugs* org.simplify4u:slf4j-mock-common:* diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java b/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java index 9175a7cd..bd60cc78 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java @@ -29,7 +29,7 @@ public class OpenFeatureAPI implements EventBus { protected OpenFeatureAPI() { apiHooks = new ArrayList<>(); - providerRepository = new ProviderRepository(); + providerRepository = new ProviderRepository(this); eventSupport = new EventSupport(); transactionContextPropagator = new NoOpTransactionContextPropagator(); } @@ -333,7 +333,7 @@ public void shutdown() { providerRepository.shutdown(); eventSupport.shutdown(); - providerRepository = new ProviderRepository(); + providerRepository = new ProviderRepository(this); eventSupport = new EventSupport(); } } diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index 66f25f60..a393d83e 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -507,7 +507,7 @@ public Client onProviderStale(Consumer handler) { */ @Override public Client on(ProviderEvent event, Consumer handler) { - OpenFeatureAPI.getInstance().addHandler(domain, event, handler); + openfeatureApi.addHandler(domain, event, handler); return this; } @@ -516,7 +516,7 @@ public Client on(ProviderEvent event, Consumer handler) { */ @Override public Client removeHandler(ProviderEvent event, Consumer handler) { - OpenFeatureAPI.getInstance().removeHandler(domain, event, handler); + openfeatureApi.removeHandler(domain, event, handler); return this; } } diff --git a/src/main/java/dev/openfeature/sdk/ProviderRepository.java b/src/main/java/dev/openfeature/sdk/ProviderRepository.java index bec86682..ab024a75 100644 --- a/src/main/java/dev/openfeature/sdk/ProviderRepository.java +++ b/src/main/java/dev/openfeature/sdk/ProviderRepository.java @@ -28,6 +28,11 @@ class ProviderRepository { return thread; }); private final Object registerStateManagerLock = new Object(); + private final OpenFeatureAPI openFeatureAPI; + + public ProviderRepository(OpenFeatureAPI openFeatureAPI) { + this.openFeatureAPI = openFeatureAPI; + } FeatureProviderStateManager getFeatureProviderStateManager() { return defaultStateManger.get(); @@ -205,7 +210,7 @@ private void initializeProvider( FeatureProviderStateManager oldManager) { try { if (ProviderState.NOT_READY.equals(newManager.getState())) { - newManager.initialize(OpenFeatureAPI.getInstance().getEvaluationContext()); + newManager.initialize(openFeatureAPI.getEvaluationContext()); afterInit.accept(newManager.getProvider()); } shutDownOld(oldManager, afterShutdown); diff --git a/src/test/java/dev/openfeature/sdk/AlwaysBrokenWithDetailsProvider.java b/src/test/java/dev/openfeature/sdk/AlwaysBrokenWithDetailsProvider.java index 8f304eaa..bd0ac2c2 100644 --- a/src/test/java/dev/openfeature/sdk/AlwaysBrokenWithDetailsProvider.java +++ b/src/test/java/dev/openfeature/sdk/AlwaysBrokenWithDetailsProvider.java @@ -1,14 +1,12 @@ package dev.openfeature.sdk; -import dev.openfeature.sdk.exceptions.FlagNotFoundError; - public class AlwaysBrokenWithDetailsProvider implements FeatureProvider { + private final String name = "always broken with details"; + @Override public Metadata getMetadata() { - return () -> { - throw new FlagNotFoundError(TestConstants.BROKEN_MESSAGE); - }; + return () -> name; } @Override diff --git a/src/test/java/dev/openfeature/sdk/AlwaysBrokenProvider.java b/src/test/java/dev/openfeature/sdk/AlwaysBrokenWithExceptionProvider.java similarity index 94% rename from src/test/java/dev/openfeature/sdk/AlwaysBrokenProvider.java rename to src/test/java/dev/openfeature/sdk/AlwaysBrokenWithExceptionProvider.java index 2f214d8a..0ad09db2 100644 --- a/src/test/java/dev/openfeature/sdk/AlwaysBrokenProvider.java +++ b/src/test/java/dev/openfeature/sdk/AlwaysBrokenWithExceptionProvider.java @@ -2,7 +2,7 @@ import dev.openfeature.sdk.exceptions.FlagNotFoundError; -public class AlwaysBrokenProvider implements FeatureProvider { +public class AlwaysBrokenWithExceptionProvider implements FeatureProvider { private final String name = "always broken"; diff --git a/src/test/java/dev/openfeature/sdk/ClientProviderMappingTest.java b/src/test/java/dev/openfeature/sdk/ClientProviderMappingTest.java index cd7e8b29..beadf7aa 100644 --- a/src/test/java/dev/openfeature/sdk/ClientProviderMappingTest.java +++ b/src/test/java/dev/openfeature/sdk/ClientProviderMappingTest.java @@ -2,17 +2,16 @@ import static org.junit.jupiter.api.Assertions.*; -import dev.openfeature.sdk.testutils.FeatureProviderTestUtils; import org.junit.jupiter.api.Test; class ClientProviderMappingTest { @Test void clientProviderTest() { - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); + OpenFeatureAPI api = new OpenFeatureAPI(); - FeatureProviderTestUtils.setFeatureProvider("client1", new DoSomethingProvider()); - FeatureProviderTestUtils.setFeatureProvider("client2", new NoOpProvider()); + api.setProviderAndWait("client1", new DoSomethingProvider()); + api.setProviderAndWait("client2", new NoOpProvider()); Client c1 = api.getClient("client1"); Client c2 = api.getClient("client2"); diff --git a/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java b/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java index aacf0916..32fa605c 100644 --- a/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java +++ b/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java @@ -8,7 +8,6 @@ import static org.mockito.Mockito.verify; import dev.openfeature.sdk.fixtures.HookFixtures; -import dev.openfeature.sdk.testutils.FeatureProviderTestUtils; import dev.openfeature.sdk.testutils.TestEventsProvider; import java.util.Arrays; import java.util.HashMap; @@ -16,14 +15,20 @@ import java.util.Map; import java.util.Optional; import lombok.SneakyThrows; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; class DeveloperExperienceTest implements HookFixtures { transient String flagKey = "mykey"; + private OpenFeatureAPI api; + + @BeforeEach + public void setUp() throws Exception { + api = new OpenFeatureAPI(); + } @Test void simpleBooleanFlag() { - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); api.setProviderAndWait(new TestEventsProvider()); Client client = api.getClient(); Boolean retval = client.getBooleanValue(flagKey, false); @@ -34,7 +39,6 @@ void simpleBooleanFlag() { void clientHooks() { Hook exampleHook = mockBooleanHook(); - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); api.setProviderAndWait(new TestEventsProvider()); Client client = api.getClient(); client.addHooks(exampleHook); @@ -48,7 +52,6 @@ void evalHooks() { Hook clientHook = mockBooleanHook(); Hook evalHook = mockBooleanHook(); - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); api.setProviderAndWait(new TestEventsProvider()); Client client = api.getClient(); client.addHooks(clientHook); @@ -69,7 +72,6 @@ void evalHooks() { @Test void providingContext() { - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); api.setProviderAndWait(new TestEventsProvider()); Client client = api.getClient(); Map attributes = new HashMap<>(); @@ -86,8 +88,7 @@ void providingContext() { @Test void brokenProvider() { - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); - FeatureProviderTestUtils.setFeatureProvider(new AlwaysBrokenProvider()); + api.setProviderAndWait(new AlwaysBrokenWithExceptionProvider()); Client client = api.getClient(); FlagEvaluationDetails retval = client.getBooleanDetails(flagKey, false); assertEquals(ErrorCode.FLAG_NOT_FOUND, retval.getErrorCode()); @@ -99,6 +100,9 @@ void brokenProvider() { @Test void providerLockedPerTransaction() { + final String defaultValue = "string-value"; + final OpenFeatureAPI api = new OpenFeatureAPI(); + class MutatingHook implements Hook { @Override @@ -106,16 +110,14 @@ class MutatingHook implements Hook { // change the provider during a before hook - this should not impact the evaluation in progress public Optional before(HookContext ctx, Map hints) { - FeatureProviderTestUtils.setFeatureProvider(TestEventsProvider.newInitializedTestEventsProvider()); + api.setProviderAndWait(TestEventsProvider.newInitializedTestEventsProvider()); return Optional.empty(); } } - final String defaultValue = "string-value"; - final OpenFeatureAPI api = OpenFeatureAPI.getInstance(); final Client client = api.getClient(); - FeatureProviderTestUtils.setFeatureProvider(new DoSomethingProvider()); + api.setProviderAndWait(new DoSomethingProvider()); api.addHooks(new MutatingHook()); // if provider is changed during an evaluation transaction it should proceed with the original provider @@ -132,7 +134,6 @@ public Optional before(HookContext ctx, Map hints) { @Test void setProviderAndWaitShouldPutTheProviderInReadyState() { String domain = "domain"; - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); api.setProviderAndWait(domain, new TestEventsProvider()); Client client = api.getClient(domain); assertThat(client.getProviderState()).isEqualTo(ProviderState.READY); @@ -145,7 +146,6 @@ void setProviderAndWaitShouldPutTheProviderInReadyState() { @Test void shouldPutTheProviderInStateErrorAfterEmittingErrorEvent() { String domain = "domain"; - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); TestEventsProvider provider = new TestEventsProvider(); api.setProviderAndWait(domain, provider); Client client = api.getClient(domain); @@ -161,7 +161,6 @@ void shouldPutTheProviderInStateErrorAfterEmittingErrorEvent() { @Test void shouldPutTheProviderInStateStaleAfterEmittingStaleEvent() { String domain = "domain"; - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); TestEventsProvider provider = new TestEventsProvider(); api.setProviderAndWait(domain, provider); Client client = api.getClient(domain); @@ -177,7 +176,6 @@ void shouldPutTheProviderInStateStaleAfterEmittingStaleEvent() { @Test void shouldPutTheProviderInStateReadyAfterEmittingReadyEvent() { String domain = "domain"; - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); TestEventsProvider provider = new TestEventsProvider(); api.setProviderAndWait(domain, provider); Client client = api.getClient(domain); diff --git a/src/test/java/dev/openfeature/sdk/EventProviderTest.java b/src/test/java/dev/openfeature/sdk/EventProviderTest.java index a159877f..ebf8901c 100644 --- a/src/test/java/dev/openfeature/sdk/EventProviderTest.java +++ b/src/test/java/dev/openfeature/sdk/EventProviderTest.java @@ -28,7 +28,7 @@ void setup() { @AfterAll public static void resetDefaultProvider() { - OpenFeatureAPI.getInstance().setProviderAndWait(new NoOpProvider()); + new OpenFeatureAPI().setProviderAndWait(new NoOpProvider()); } @Test @@ -91,7 +91,7 @@ void doesNotThrowWhenOnEmitSame() { @DisplayName("should not deadlock on emit called during emit") void doesNotDeadlockOnEmitStackedCalls() { TestStackedEmitCallsProvider provider = new TestStackedEmitCallsProvider(); - OpenFeatureAPI.getInstance().setProviderAndWait(provider); + new OpenFeatureAPI().setProviderAndWait(provider); } static class TestEventProvider extends EventProvider { diff --git a/src/test/java/dev/openfeature/sdk/EventsTest.java b/src/test/java/dev/openfeature/sdk/EventsTest.java index e5902465..157c0baf 100644 --- a/src/test/java/dev/openfeature/sdk/EventsTest.java +++ b/src/test/java/dev/openfeature/sdk/EventsTest.java @@ -7,11 +7,11 @@ import static org.mockito.Mockito.*; import dev.openfeature.sdk.testutils.TestEventsProvider; -import io.cucumber.java.AfterAll; import java.util.Arrays; import java.util.List; import java.util.function.Consumer; import lombok.SneakyThrows; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -21,10 +21,11 @@ class EventsTest { private static final int TIMEOUT = 500; private static final int INIT_DELAY = TIMEOUT / 2; + private OpenFeatureAPI api; - @AfterAll - public static void resetDefaultProvider() { - OpenFeatureAPI.getInstance().setProviderAndWait(new NoOpProvider()); + @BeforeEach + public void setUp() throws Exception { + api = new OpenFeatureAPI(); } @Nested @@ -49,8 +50,8 @@ void apiInitReady() { final String name = "apiInitReady"; TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); - OpenFeatureAPI.getInstance().onProviderReady(handler); - OpenFeatureAPI.getInstance().setProviderAndWait(name, provider); + api.onProviderReady(handler); + api.setProviderAndWait(name, provider); verify(handler, timeout(TIMEOUT).atLeastOnce()).accept(any()); } @@ -66,8 +67,8 @@ void apiInitError() { final String errMessage = "oh no!"; TestEventsProvider provider = new TestEventsProvider(INIT_DELAY, true, errMessage); - OpenFeatureAPI.getInstance().onProviderError(handler); - OpenFeatureAPI.getInstance().setProvider(name, provider); + api.onProviderError(handler); + api.setProvider(name, provider); verify(handler, timeout(TIMEOUT)).accept(argThat(details -> { return errMessage.equals(details.getMessage()); })); @@ -89,8 +90,8 @@ void apiShouldPropagateEvents() { final String name = "apiShouldPropagateEvents"; TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); - OpenFeatureAPI.getInstance().setProviderAndWait(name, provider); - OpenFeatureAPI.getInstance().onProviderConfigurationChanged(handler); + api.setProviderAndWait(name, provider); + api.onProviderConfigurationChanged(handler); provider.mockEvent( ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, @@ -118,12 +119,12 @@ void apiShouldSupportAllEventTypes() { final Consumer handler4 = mockHandler(); TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); - OpenFeatureAPI.getInstance().setProviderAndWait(name, provider); + api.setProviderAndWait(name, provider); - OpenFeatureAPI.getInstance().onProviderReady(handler1); - OpenFeatureAPI.getInstance().onProviderConfigurationChanged(handler2); - OpenFeatureAPI.getInstance().onProviderStale(handler3); - OpenFeatureAPI.getInstance().onProviderError(handler4); + api.onProviderReady(handler1); + api.onProviderConfigurationChanged(handler2); + api.onProviderStale(handler3); + api.onProviderError(handler4); Arrays.asList(ProviderEvent.values()).stream().forEach(eventType -> { provider.mockEvent( @@ -162,8 +163,8 @@ void shouldPropagateDefaultAndAnon() { TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); // set provider before getting a client - OpenFeatureAPI.getInstance().setProviderAndWait(provider); - Client client = OpenFeatureAPI.getInstance().getClient(); + api.setProviderAndWait(provider); + Client client = api.getClient(); client.onProviderStale(handler); provider.mockEvent( @@ -183,8 +184,8 @@ void shouldPropagateDefaultAndNamed() { TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); // set provider before getting a client - OpenFeatureAPI.getInstance().setProviderAndWait(provider); - Client client = OpenFeatureAPI.getInstance().getClient(name); + api.setProviderAndWait(provider); + Client client = api.getClient(name); client.onProviderStale(handler); provider.mockEvent( @@ -213,10 +214,10 @@ void initReadyProviderBefore() { final String name = "initReadyProviderBefore"; TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); - Client client = OpenFeatureAPI.getInstance().getClient(name); + Client client = api.getClient(name); client.onProviderReady(handler); // set provider after getting a client - OpenFeatureAPI.getInstance().setProviderAndWait(name, provider); + api.setProviderAndWait(name, provider); verify(handler, timeout(TIMEOUT).atLeastOnce()) .accept(argThat(details -> details.getDomain().equals(name))); } @@ -233,8 +234,8 @@ void initReadyProviderAfter() { TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); // set provider before getting a client - OpenFeatureAPI.getInstance().setProviderAndWait(name, provider); - Client client = OpenFeatureAPI.getInstance().getClient(name); + api.setProviderAndWait(name, provider); + Client client = api.getClient(name); client.onProviderReady(handler); verify(handler, timeout(TIMEOUT).atLeastOnce()) .accept(argThat(details -> details.getDomain().equals(name))); @@ -252,10 +253,10 @@ void initErrorProviderAfter() { final String errMessage = "oh no!"; TestEventsProvider provider = new TestEventsProvider(INIT_DELAY, true, errMessage); - Client client = OpenFeatureAPI.getInstance().getClient(name); + Client client = api.getClient(name); client.onProviderError(handler); // set provider after getting a client - OpenFeatureAPI.getInstance().setProvider(name, provider); + api.setProvider(name, provider); verify(handler, timeout(TIMEOUT)).accept(argThat(details -> { return name.equals(details.getDomain()) && errMessage.equals(details.getMessage()); })); @@ -274,8 +275,8 @@ void initErrorProviderBefore() { TestEventsProvider provider = new TestEventsProvider(INIT_DELAY, true, errMessage); // set provider after getting a client - OpenFeatureAPI.getInstance().setProvider(name, provider); - Client client = OpenFeatureAPI.getInstance().getClient(name); + api.setProvider(name, provider); + Client client = api.getClient(name); client.onProviderError(handler); verify(handler, timeout(TIMEOUT)).accept(argThat(details -> { return name.equals(details.getDomain()) && errMessage.equals(details.getMessage()); @@ -299,8 +300,8 @@ void shouldPropagateBefore() { TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); // set provider before getting a client - OpenFeatureAPI.getInstance().setProviderAndWait(name, provider); - Client client = OpenFeatureAPI.getInstance().getClient(name); + api.setProviderAndWait(name, provider); + Client client = api.getClient(name); client.onProviderConfigurationChanged(handler); provider.mockEvent( @@ -322,10 +323,10 @@ void shouldPropagateAfter() { final String name = "shouldPropagateAfter"; TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); - Client client = OpenFeatureAPI.getInstance().getClient(name); + Client client = api.getClient(name); client.onProviderConfigurationChanged(handler); // set provider after getting a client - OpenFeatureAPI.getInstance().setProviderAndWait(name, provider); + api.setProviderAndWait(name, provider); provider.mockEvent( ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, @@ -354,8 +355,8 @@ void shouldSupportAllEventTypes() { final Consumer handler4 = mockHandler(); TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); - OpenFeatureAPI.getInstance().setProviderAndWait(name, provider); - Client client = OpenFeatureAPI.getInstance().getClient(name); + api.setProviderAndWait(name, provider); + Client client = api.getClient(name); client.onProviderReady(handler1); client.onProviderConfigurationChanged(handler2); @@ -384,14 +385,14 @@ void shouldNotRunHandlers() { TestEventsProvider provider1 = new TestEventsProvider(INIT_DELAY); TestEventsProvider provider2 = new TestEventsProvider(INIT_DELAY); - OpenFeatureAPI.getInstance().setProviderAndWait(name, provider1); - Client client = OpenFeatureAPI.getInstance().getClient(name); + api.setProviderAndWait(name, provider1); + Client client = api.getClient(name); // attached handlers - OpenFeatureAPI.getInstance().onProviderConfigurationChanged(handler1); + api.onProviderConfigurationChanged(handler1); client.onProviderConfigurationChanged(handler2); - OpenFeatureAPI.getInstance().setProviderAndWait(name, provider2); + api.setProviderAndWait(name, provider2); // wait for the new provider to be ready and make sure things are cleaned up. await().until(() -> provider1.isShutDown()); @@ -421,11 +422,11 @@ void otherClientHandlersShouldNotRun() { TestEventsProvider provider1 = new TestEventsProvider(INIT_DELAY); TestEventsProvider provider2 = new TestEventsProvider(INIT_DELAY); - OpenFeatureAPI.getInstance().setProviderAndWait(name1, provider1); - OpenFeatureAPI.getInstance().setProviderAndWait(name2, provider2); + api.setProviderAndWait(name1, provider1); + api.setProviderAndWait(name2, provider2); - Client client1 = OpenFeatureAPI.getInstance().getClient(name1); - Client client2 = OpenFeatureAPI.getInstance().getClient(name2); + Client client1 = api.getClient(name1); + Client client2 = api.getClient(name2); client1.onProviderConfigurationChanged(handlerToRun); client2.onProviderConfigurationChanged(handlerNotToRun); @@ -450,11 +451,11 @@ void boundShouldNotRunWithDefault() { TestEventsProvider namedProvider = new TestEventsProvider(INIT_DELAY); TestEventsProvider defaultProvider = new TestEventsProvider(INIT_DELAY); - OpenFeatureAPI.getInstance().setProviderAndWait(defaultProvider); + api.setProviderAndWait(defaultProvider); - Client client = OpenFeatureAPI.getInstance().getClient(name); + Client client = api.getClient(name); client.onProviderConfigurationChanged(handlerNotToRun); - OpenFeatureAPI.getInstance().setProviderAndWait(name, namedProvider); + api.setProviderAndWait(name, namedProvider); // await the new provider to make sure the old one is shut down await().until(() -> namedProvider.getState().equals(ProviderState.READY)); @@ -465,7 +466,7 @@ void boundShouldNotRunWithDefault() { ProviderEventDetails.builder().build()); verify(handlerNotToRun, after(TIMEOUT).never()).accept(any()); - OpenFeatureAPI.getInstance().setProviderAndWait(new NoOpProvider()); + api.setProviderAndWait(new NoOpProvider()); } @Test @@ -479,9 +480,9 @@ void unboundShouldRunWithDefault() { final Consumer handlerToRun = mockHandler(); TestEventsProvider defaultProvider = new TestEventsProvider(INIT_DELAY); - OpenFeatureAPI.getInstance().setProviderAndWait(defaultProvider); + api.setProviderAndWait(defaultProvider); - Client client = OpenFeatureAPI.getInstance().getClient(name); + Client client = api.getClient(name); client.onProviderConfigurationChanged(handlerToRun); // await the new provider to make sure the old one is shut down @@ -493,7 +494,7 @@ void unboundShouldRunWithDefault() { ProviderEventDetails.builder().build()); verify(handlerToRun, timeout(TIMEOUT)).accept(any()); - OpenFeatureAPI.getInstance().setProviderAndWait(new NoOpProvider()); + api.setProviderAndWait(new NoOpProvider()); } @Test @@ -509,9 +510,9 @@ void handlersRunIfOneThrows() { final Consumer lastHandler = mockHandler(); TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); - OpenFeatureAPI.getInstance().setProviderAndWait(name, provider); + api.setProviderAndWait(name, provider); - Client client1 = OpenFeatureAPI.getInstance().getClient(name); + Client client1 = api.getClient(name); client1.onProviderConfigurationChanged(errorHandler); client1.onProviderConfigurationChanged(nextHandler); @@ -537,11 +538,11 @@ void shouldHaveAllProperties() { final String name = "shouldHaveAllProperties"; TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); - OpenFeatureAPI.getInstance().setProviderAndWait(name, provider); - Client client = OpenFeatureAPI.getInstance().getClient(name); + api.setProviderAndWait(name, provider); + Client client = api.getClient(name); // attached handlers - OpenFeatureAPI.getInstance().onProviderConfigurationChanged(handler1); + api.onProviderConfigurationChanged(handler1); client.onProviderConfigurationChanged(handler2); List flagsChanged = Arrays.asList("flag"); @@ -582,10 +583,10 @@ void matchingReadyEventsMustRunImmediately() { // provider which is already ready TestEventsProvider provider = new TestEventsProvider(); - OpenFeatureAPI.getInstance().setProviderAndWait(name, provider); + api.setProviderAndWait(name, provider); // should run even thought handler was added after ready - Client client = OpenFeatureAPI.getInstance().getClient(name); + Client client = api.getClient(name); client.onProviderReady(handler); verify(handler, timeout(TIMEOUT)).accept(any()); } @@ -598,7 +599,6 @@ void matchingReadyEventsMustRunImmediately() { void matchingStaleEventsMustRunImmediately() { final String name = "matchingEventsMustRunImmediately"; final Consumer handler = mockHandler(); - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); // provider which is already stale TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); @@ -620,7 +620,6 @@ void matchingStaleEventsMustRunImmediately() { void matchingErrorEventsMustRunImmediately() { final String name = "matchingEventsMustRunImmediately"; final Consumer handler = mockHandler(); - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); // provider which is already in error TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); @@ -629,6 +628,7 @@ void matchingErrorEventsMustRunImmediately() { provider.emitProviderError(ProviderEventDetails.builder().build()); assertThat(client.getProviderState()).isEqualTo(ProviderState.ERROR); + verify(handler, never()).accept(any()); // should run even though handler was added after error client.onProviderError(handler); verify(handler, timeout(TIMEOUT)).accept(any()); @@ -644,8 +644,8 @@ void mustPersistAcrossChanges() { TestEventsProvider provider1 = new TestEventsProvider(INIT_DELAY); TestEventsProvider provider2 = new TestEventsProvider(INIT_DELAY); - OpenFeatureAPI.getInstance().setProviderAndWait(name, provider1); - Client client = OpenFeatureAPI.getInstance().getClient(name); + api.setProviderAndWait(name, provider1); + Client client = api.getClient(name); client.onProviderConfigurationChanged(handler); provider1.mockEvent( @@ -657,7 +657,7 @@ void mustPersistAcrossChanges() { verify(handler, timeout(TIMEOUT).times(1)).accept(argThat(nameMatches)); // wait for the new provider to be ready. - OpenFeatureAPI.getInstance().setProviderAndWait(name, provider2); + api.setProviderAndWait(name, provider2); // verify that with the new provider under the same name, the handler is called // again. @@ -681,14 +681,14 @@ void removedEventsShouldNotRun() { final Consumer handler2 = mockHandler(); TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); - OpenFeatureAPI.getInstance().setProviderAndWait(name, provider); - Client client = OpenFeatureAPI.getInstance().getClient(name); + api.setProviderAndWait(name, provider); + Client client = api.getClient(name); // attached handlers - OpenFeatureAPI.getInstance().onProviderStale(handler1); + api.onProviderStale(handler1); client.onProviderConfigurationChanged(handler2); - OpenFeatureAPI.getInstance().removeHandler(ProviderEvent.PROVIDER_STALE, handler1); + api.removeHandler(ProviderEvent.PROVIDER_STALE, handler1); client.removeHandler(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, handler2); // emit event diff --git a/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java b/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java index 2ad88d32..3b02b172 100644 --- a/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java @@ -9,7 +9,6 @@ import dev.openfeature.sdk.exceptions.GeneralError; import dev.openfeature.sdk.fixtures.HookFixtures; -import dev.openfeature.sdk.testutils.FeatureProviderTestUtils; import dev.openfeature.sdk.testutils.TestEventsProvider; import java.util.HashMap; import java.util.List; @@ -29,7 +28,7 @@ class FlagEvaluationSpecTest implements HookFixtures { private OpenFeatureAPI api; private Client _client() { - FeatureProviderTestUtils.setFeatureProvider(new NoOpProvider()); + api.setProviderAndWait(new NoOpProvider()); return api.getClient(); } @@ -37,18 +36,13 @@ private Client _client() { private Client _initializedClient() { TestEventsProvider provider = new TestEventsProvider(); provider.initialize(null); - FeatureProviderTestUtils.setFeatureProvider(provider); + api.setProviderAndWait(provider); return api.getClient(); } @BeforeEach void getApiInstance() { - api = OpenFeatureAPI.getInstance(); - } - - @AfterEach - void reset_ctx() { - api.setEvaluationContext(null); + api = new OpenFeatureAPI(); } @BeforeEach @@ -62,15 +56,6 @@ void reset_logs() { LoggerMock.setMock(OpenFeatureClient.class, logger); } - @Specification( - number = "1.1.1", - text = - "The API, and any state it maintains SHOULD exist as a global singleton, even in cases wherein multiple versions of the API are present at runtime.") - @Test - void global_singleton() { - assertSame(OpenFeatureAPI.getInstance(), OpenFeatureAPI.getInstance()); - } - @Specification( number = "1.1.2.1", text = @@ -78,7 +63,7 @@ void global_singleton() { @Test void provider() { FeatureProvider mockProvider = mock(FeatureProvider.class); - FeatureProviderTestUtils.setFeatureProvider(mockProvider); + api.setProviderAndWait(mockProvider); assertThat(api.getProvider()).isEqualTo(mockProvider); } @@ -90,13 +75,13 @@ void provider() { @Test void providerAndWait() { FeatureProvider provider = new TestEventsProvider(500); - OpenFeatureAPI.getInstance().setProviderAndWait(provider); + api.setProviderAndWait(provider); Client client = api.getClient(); assertThat(client.getProviderState()).isEqualTo(ProviderState.READY); provider = new TestEventsProvider(500); String providerName = "providerAndWait"; - OpenFeatureAPI.getInstance().setProviderAndWait(providerName, provider); + api.setProviderAndWait(providerName, provider); Client client2 = api.getClient(providerName); assertThat(client2.getProviderState()).isEqualTo(ProviderState.READY); } @@ -124,8 +109,8 @@ void providerAndWaitError() { void shouldReturnNotReadyIfNotInitialized() { FeatureProvider provider = new TestEventsProvider(100); String providerName = "shouldReturnNotReadyIfNotInitialized"; - OpenFeatureAPI.getInstance().setProvider(providerName, provider); - Client client = OpenFeatureAPI.getInstance().getClient(providerName); + api.setProvider(providerName, provider); + Client client = api.getClient(providerName); FlagEvaluationDetails details = client.getBooleanDetails("return_error_when_not_initialized", false); assertEquals(ErrorCode.PROVIDER_NOT_READY, details.getErrorCode()); assertEquals(Reason.ERROR.toString(), details.getReason()); @@ -136,7 +121,7 @@ void shouldReturnNotReadyIfNotInitialized() { text = "The API MUST provide a function for retrieving the metadata field of the configured provider.") @Test void provider_metadata() { - FeatureProviderTestUtils.setFeatureProvider(new DoSomethingProvider()); + api.setProviderAndWait(new DoSomethingProvider()); assertThat(api.getProviderMetadata().getName()).isEqualTo(DoSomethingProvider.name); } @@ -198,7 +183,7 @@ void hookRegistration() { "The client SHOULD provide functions for floating-point numbers and integers, consistent with language idioms.") @Test void value_flags() { - FeatureProviderTestUtils.setFeatureProvider(new DoSomethingProvider()); + api.setProviderAndWait(new DoSomethingProvider()); Client c = api.getClient(); String key = "key"; @@ -279,7 +264,7 @@ void value_flags() { "In cases of normal execution, the `evaluation details` structure's `reason` field MUST contain the value of the `reason` field in the `flag resolution` structure returned by the configured `provider`, if the field is set.") @Test void detail_flags() { - FeatureProviderTestUtils.setFeatureProvider(new DoSomethingProvider()); + api.setProviderAndWait(new DoSomethingProvider()); Client c = api.getClient(); String key = "key"; @@ -386,7 +371,7 @@ void hooks() { "In cases of abnormal execution, the `evaluation details` structure's `error message` field **MAY** contain a string containing additional details about the nature of the error.") @Test void broken_provider() { - FeatureProviderTestUtils.setFeatureProvider(new AlwaysBrokenProvider()); + api.setProviderAndWait(new AlwaysBrokenWithExceptionProvider()); Client c = api.getClient(); boolean defaultValue = false; assertFalse(c.getBooleanValue("key", defaultValue)); @@ -414,8 +399,8 @@ void broken_provider() { text = "In cases of abnormal execution, the `evaluation details` structure's `error message` field **MAY** contain a string containing additional details about the nature of the error.") @Test - void broken_provider_withDetails() { - FeatureProviderTestUtils.setFeatureProvider(new AlwaysBrokenWithDetailsProvider()); + void broken_provider_withDetails() throws InterruptedException { + api.setProviderAndWait(new AlwaysBrokenWithDetailsProvider()); Client c = api.getClient(); boolean defaultValue = false; assertFalse(c.getBooleanValue("key", defaultValue)); @@ -431,7 +416,7 @@ void broken_provider_withDetails() { text = "Methods, functions, or operations on the client SHOULD NOT write log messages.") @Test void log_on_error() throws NotImplementedException { - FeatureProviderTestUtils.setFeatureProvider(new AlwaysBrokenProvider()); + api.setProviderAndWait(new AlwaysBrokenWithExceptionProvider()); Client c = api.getClient(); FlagEvaluationDetails result = c.getBooleanDetails("test", false); @@ -450,7 +435,7 @@ void clientMetadata() { assertNull(c.getMetadata().getDomain()); String domainName = "test domain"; - FeatureProviderTestUtils.setFeatureProvider(new AlwaysBrokenProvider()); + api.setProviderAndWait(new AlwaysBrokenWithExceptionProvider()); Client c2 = api.getClient(domainName); assertEquals(domainName, c2.getMetadata().getName()); @@ -463,7 +448,7 @@ void clientMetadata() { "In cases of abnormal execution (network failure, unhandled error, etc) the reason field in the evaluation details SHOULD indicate an error.") @Test void reason_is_error_when_there_are_errors() { - FeatureProviderTestUtils.setFeatureProvider(new AlwaysBrokenProvider()); + api.setProviderAndWait(new AlwaysBrokenWithExceptionProvider()); Client c = api.getClient(); FlagEvaluationDetails result = c.getBooleanDetails("test", false); assertEquals(Reason.ERROR.toString(), result.getReason()); @@ -475,7 +460,7 @@ void reason_is_error_when_there_are_errors() { "If the flag metadata field in the flag resolution structure returned by the configured provider is set, the evaluation details structure's flag metadata field MUST contain that value. Otherwise, it MUST contain an empty record.") @Test void flag_metadata_passed() { - FeatureProviderTestUtils.setFeatureProvider(new DoSomethingProvider(null)); + api.setProviderAndWait(new DoSomethingProvider(null)); Client c = api.getClient(); FlagEvaluationDetails result = c.getBooleanDetails("test", false); assertNotNull(result.getFlagMetadata()); @@ -487,7 +472,7 @@ void api_context() { String contextKey = "some-key"; String contextValue = "some-value"; DoSomethingProvider provider = spy(new DoSomethingProvider()); - FeatureProviderTestUtils.setFeatureProvider(provider); + api.setProviderAndWait(provider); Map attributes = new HashMap<>(); attributes.put(contextKey, new Value(contextValue)); @@ -514,7 +499,7 @@ void api_context() { @Test void multi_layer_context_merges_correctly() { DoSomethingProvider provider = spy(new DoSomethingProvider()); - FeatureProviderTestUtils.setFeatureProvider(provider); + api.setProviderAndWait(provider); TransactionContextPropagator transactionContextPropagator = new ThreadLocalTransactionContextPropagator(); api.setTransactionContextPropagator(transactionContextPropagator); Hook hook = spy(new Hook() { @@ -702,7 +687,7 @@ public void after( @Test void setting_transaction_context_propagator() { DoSomethingProvider provider = new DoSomethingProvider(); - FeatureProviderTestUtils.setFeatureProvider(provider); + api.setProviderAndWait(provider); TransactionContextPropagator transactionContextPropagator = new ThreadLocalTransactionContextPropagator(); api.setTransactionContextPropagator(transactionContextPropagator); @@ -716,7 +701,7 @@ void setting_transaction_context_propagator() { @Test void setting_transaction_context() { DoSomethingProvider provider = new DoSomethingProvider(); - FeatureProviderTestUtils.setFeatureProvider(provider); + api.setProviderAndWait(provider); TransactionContextPropagator transactionContextPropagator = new ThreadLocalTransactionContextPropagator(); api.setTransactionContextPropagator(transactionContextPropagator); diff --git a/src/test/java/dev/openfeature/sdk/HookSpecTest.java b/src/test/java/dev/openfeature/sdk/HookSpecTest.java index d6247c64..4b08510d 100644 --- a/src/test/java/dev/openfeature/sdk/HookSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSpecTest.java @@ -18,7 +18,6 @@ import dev.openfeature.sdk.exceptions.FlagNotFoundError; import dev.openfeature.sdk.fixtures.HookFixtures; -import dev.openfeature.sdk.testutils.FeatureProviderTestUtils; import dev.openfeature.sdk.testutils.TestEventsProvider; import java.util.ArrayList; import java.util.Arrays; @@ -28,16 +27,18 @@ import java.util.Map; import java.util.Optional; import lombok.SneakyThrows; -import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.mockito.InOrder; class HookSpecTest implements HookFixtures { - @AfterEach - void emptyApiHooks() { - // it's a singleton. Don't pollute each test. - OpenFeatureAPI.getInstance().clearHooks(); + + private OpenFeatureAPI api; + + @BeforeEach + void setUp() { + this.api = new OpenFeatureAPI(); } @Specification( @@ -163,7 +164,7 @@ void optional_properties() { .type(FlagValueType.INTEGER) .ctx(new ImmutableContext()) .defaultValue(1) - .clientMetadata(OpenFeatureAPI.getInstance().getClient().getMetadata()) + .clientMetadata(api.getClient().getMetadata()) .build(); } @@ -173,8 +174,8 @@ void optional_properties() { "The before stage MUST run before flag resolution occurs. It accepts a hook context (required) and hook hints (optional) as parameters and returns either an evaluation context or nothing.") @Test void before_runs_ahead_of_evaluation() { - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); - api.setProviderAndWait(new AlwaysBrokenProvider()); + + api.setProviderAndWait(new AlwaysBrokenWithExceptionProvider()); Client client = api.getClient(); Hook evalHook = mockBooleanHook(); @@ -216,8 +217,7 @@ void error_hook_must_run_if_resolution_details_returns_an_error_code() { .errorMessage(errorMessage) .build()); - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); - FeatureProviderTestUtils.setFeatureProvider("errorHookMustRun", provider); + api.setProviderAndWait("errorHookMustRun", provider); Client client = api.getClient("errorHookMustRun"); client.getBooleanValue( "key", @@ -259,7 +259,7 @@ void error_hook_must_run_if_resolution_details_returns_an_error_code() { @Test void hook_eval_order() { List evalOrder = new ArrayList<>(); - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); + api.setProviderAndWait("evalOrder", new TestEventsProvider() { public List getProviderHooks() { return Collections.singletonList(new BooleanHook() { @@ -411,8 +411,7 @@ void error_stops_before() { doThrow(RuntimeException.class).when(h).before(any(), any()); Hook h2 = mockBooleanHook(); - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); - api.setProviderAndWait(new AlwaysBrokenProvider()); + api.setProviderAndWait(new AlwaysBrokenWithExceptionProvider()); Client c = api.getClient(); c.getBooleanDetails( @@ -516,8 +515,7 @@ void flag_eval_hook_order() { .thenReturn(ProviderEvaluation.builder().value(true).build()); InOrder order = inOrder(hook, provider); - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); - FeatureProviderTestUtils.setFeatureProvider(provider); + api.setProviderAndWait(provider); Client client = api.getClient(); client.getBooleanValue( "key", @@ -695,8 +693,7 @@ void mergeHappensCorrectly() { when(provider.getBooleanEvaluation(any(), any(), any())) .thenReturn(ProviderEvaluation.builder().value(true).build()); - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); - FeatureProviderTestUtils.setFeatureProvider(provider); + api.setProviderAndWait(provider); Client client = api.getClient(); client.getBooleanValue( "key", @@ -761,11 +758,10 @@ void first_error_broken() { } private Client getClient(FeatureProvider provider) { - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); if (provider == null) { - FeatureProviderTestUtils.setFeatureProvider(TestEventsProvider.newInitializedTestEventsProvider()); + api.setProviderAndWait(TestEventsProvider.newInitializedTestEventsProvider()); } else { - FeatureProviderTestUtils.setFeatureProvider(provider); + api.setProviderAndWait(provider); } return api.getClient(); } diff --git a/src/test/java/dev/openfeature/sdk/InitializeBehaviorSpecTest.java b/src/test/java/dev/openfeature/sdk/InitializeBehaviorSpecTest.java index 3353f564..4bcd7312 100644 --- a/src/test/java/dev/openfeature/sdk/InitializeBehaviorSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/InitializeBehaviorSpecTest.java @@ -17,10 +17,12 @@ class InitializeBehaviorSpecTest { private static final String DOMAIN_NAME = "mydomain"; + private OpenFeatureAPI api; @BeforeEach void setupTest() { - OpenFeatureAPI.getInstance().setProvider(new NoOpProvider()); + this.api = new OpenFeatureAPI(); + api.setProvider(new NoOpProvider()); } @Nested @@ -37,7 +39,7 @@ void mustCallInitializeFunctionOfTheNewlyRegisteredProviderBeforeUsingItForFlagE FeatureProvider featureProvider = mock(FeatureProvider.class); doReturn(ProviderState.NOT_READY).when(featureProvider).getState(); - OpenFeatureAPI.getInstance().setProvider(featureProvider); + api.setProvider(featureProvider); verify(featureProvider, timeout(1000)).initialize(any()); } @@ -55,8 +57,7 @@ void shouldCatchExceptionThrownByTheProviderOnInitialization() throws Exception doReturn(ProviderState.NOT_READY).when(featureProvider).getState(); doThrow(TestException.class).when(featureProvider).initialize(any()); - assertThatCode(() -> OpenFeatureAPI.getInstance().setProvider(featureProvider)) - .doesNotThrowAnyException(); + assertThatCode(() -> api.setProvider(featureProvider)).doesNotThrowAnyException(); verify(featureProvider, timeout(1000)).initialize(any()); } @@ -77,7 +78,7 @@ void mustCallInitializeFunctionOfTheNewlyRegisteredNamedProviderBeforeUsingItFor FeatureProvider featureProvider = mock(FeatureProvider.class); doReturn(ProviderState.NOT_READY).when(featureProvider).getState(); - OpenFeatureAPI.getInstance().setProvider(DOMAIN_NAME, featureProvider); + api.setProvider(DOMAIN_NAME, featureProvider); verify(featureProvider, timeout(1000)).initialize(any()); } @@ -95,8 +96,7 @@ void shouldCatchExceptionThrownByTheNamedClientProviderOnInitialization() throws doReturn(ProviderState.NOT_READY).when(featureProvider).getState(); doThrow(TestException.class).when(featureProvider).initialize(any()); - assertThatCode(() -> OpenFeatureAPI.getInstance().setProvider(DOMAIN_NAME, featureProvider)) - .doesNotThrowAnyException(); + assertThatCode(() -> api.setProvider(DOMAIN_NAME, featureProvider)).doesNotThrowAnyException(); verify(featureProvider, timeout(1000)).initialize(any()); } diff --git a/src/test/java/dev/openfeature/sdk/LockingTest.java b/src/test/java/dev/openfeature/sdk/LockingSingeltonTest.java similarity index 99% rename from src/test/java/dev/openfeature/sdk/LockingTest.java rename to src/test/java/dev/openfeature/sdk/LockingSingeltonTest.java index 4b7af553..ad86f4bc 100644 --- a/src/test/java/dev/openfeature/sdk/LockingTest.java +++ b/src/test/java/dev/openfeature/sdk/LockingSingeltonTest.java @@ -15,7 +15,7 @@ import org.junit.jupiter.api.parallel.Isolated; @Isolated() -class LockingTest { +class LockingSingeltonTest { private static OpenFeatureAPI api; private OpenFeatureClient client; diff --git a/src/test/java/dev/openfeature/sdk/OpenFeatureAPISingeltonTest.java b/src/test/java/dev/openfeature/sdk/OpenFeatureAPISingeltonTest.java new file mode 100644 index 00000000..dd9916ee --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/OpenFeatureAPISingeltonTest.java @@ -0,0 +1,17 @@ +package dev.openfeature.sdk; + +import static org.junit.jupiter.api.Assertions.assertSame; + +import org.junit.jupiter.api.Test; + +class OpenFeatureAPISingeltonTest { + + @Specification( + number = "1.1.1", + text = + "The API, and any state it maintains SHOULD exist as a global singleton, even in cases wherein multiple versions of the API are present at runtime.") + @Test + void global_singleton() { + assertSame(OpenFeatureAPI.getInstance(), OpenFeatureAPI.getInstance()); + } +} diff --git a/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java b/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java index 63145ecb..e8e8b27b 100644 --- a/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java +++ b/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java @@ -8,7 +8,6 @@ import static org.mockito.Mockito.verify; import dev.openfeature.sdk.providers.memory.InMemoryProvider; -import dev.openfeature.sdk.testutils.FeatureProviderTestUtils; import dev.openfeature.sdk.testutils.TestEventsProvider; import java.util.Collections; import java.util.HashMap; @@ -23,13 +22,13 @@ class OpenFeatureAPITest { @BeforeEach void setupTest() { - api = OpenFeatureAPI.getInstance(); + api = new OpenFeatureAPI(); } @Test void namedProviderTest() { FeatureProvider provider = new NoOpProvider(); - FeatureProviderTestUtils.setFeatureProvider("namedProviderTest", provider); + api.setProviderAndWait("namedProviderTest", provider); assertThat(provider.getMetadata().getName()) .isEqualTo(api.getProviderMetadata("namedProviderTest").getName()); @@ -44,14 +43,10 @@ void namedProviderOverwrittenTest() { String domain = "namedProviderOverwrittenTest"; FeatureProvider provider1 = new NoOpProvider(); FeatureProvider provider2 = new DoSomethingProvider(); - FeatureProviderTestUtils.setFeatureProvider(domain, provider1); - FeatureProviderTestUtils.setFeatureProvider(domain, provider2); - - assertThat(OpenFeatureAPI.getInstance() - .getProvider(domain) - .getMetadata() - .getName()) - .isEqualTo(DoSomethingProvider.name); + api.setProviderAndWait(domain, provider1); + api.setProviderAndWait(domain, provider2); + + assertThat(api.getProvider(domain).getMetadata().getName()).isEqualTo(DoSomethingProvider.name); } @Test @@ -60,17 +55,17 @@ void providerToMultipleNames() throws Exception { FeatureProvider noOpAsNonEventingProvider = new NoOpProvider(); // register same provider for multiple names & as default provider - OpenFeatureAPI.getInstance().setProviderAndWait(inMemAsEventingProvider); - OpenFeatureAPI.getInstance().setProviderAndWait("clientA", inMemAsEventingProvider); - OpenFeatureAPI.getInstance().setProviderAndWait("clientB", inMemAsEventingProvider); - OpenFeatureAPI.getInstance().setProviderAndWait("clientC", noOpAsNonEventingProvider); - OpenFeatureAPI.getInstance().setProviderAndWait("clientD", noOpAsNonEventingProvider); - - assertEquals(inMemAsEventingProvider, OpenFeatureAPI.getInstance().getProvider()); - assertEquals(inMemAsEventingProvider, OpenFeatureAPI.getInstance().getProvider("clientA")); - assertEquals(inMemAsEventingProvider, OpenFeatureAPI.getInstance().getProvider("clientB")); - assertEquals(noOpAsNonEventingProvider, OpenFeatureAPI.getInstance().getProvider("clientC")); - assertEquals(noOpAsNonEventingProvider, OpenFeatureAPI.getInstance().getProvider("clientD")); + api.setProviderAndWait(inMemAsEventingProvider); + api.setProviderAndWait("clientA", inMemAsEventingProvider); + api.setProviderAndWait("clientB", inMemAsEventingProvider); + api.setProviderAndWait("clientC", noOpAsNonEventingProvider); + api.setProviderAndWait("clientD", noOpAsNonEventingProvider); + + assertEquals(inMemAsEventingProvider, api.getProvider()); + assertEquals(inMemAsEventingProvider, api.getProvider("clientA")); + assertEquals(inMemAsEventingProvider, api.getProvider("clientB")); + assertEquals(noOpAsNonEventingProvider, api.getProvider("clientC")); + assertEquals(noOpAsNonEventingProvider, api.getProvider("clientD")); } @Test @@ -101,23 +96,20 @@ void getStateReturnsTheStateOfTheAppropriateProvider() throws Exception { String domain = "namedProviderOverwrittenTest"; FeatureProvider provider1 = new NoOpProvider(); FeatureProvider provider2 = new TestEventsProvider(); - FeatureProviderTestUtils.setFeatureProvider(domain, provider1); - FeatureProviderTestUtils.setFeatureProvider(domain, provider2); + api.setProviderAndWait(domain, provider1); + api.setProviderAndWait(domain, provider2); provider2.initialize(null); - assertThat(OpenFeatureAPI.getInstance().getClient(domain).getProviderState()) - .isEqualTo(ProviderState.READY); + assertThat(api.getClient(domain).getProviderState()).isEqualTo(ProviderState.READY); } @Test void featureProviderTrackIsCalled() throws Exception { FeatureProvider featureProvider = mock(FeatureProvider.class); - FeatureProviderTestUtils.setFeatureProvider(featureProvider); + api.setProviderAndWait(featureProvider); - OpenFeatureAPI.getInstance() - .getClient() - .track("track-event", new ImmutableContext(), new MutableTrackingEventDetails(22.2f)); + api.getClient().track("track-event", new ImmutableContext(), new MutableTrackingEventDetails(22.2f)); verify(featureProvider).initialize(any()); verify(featureProvider).getMetadata(); diff --git a/src/test/java/dev/openfeature/sdk/OpenFeatureAPITestUtil.java b/src/test/java/dev/openfeature/sdk/OpenFeatureAPITestUtil.java new file mode 100644 index 00000000..f33c5b4d --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/OpenFeatureAPITestUtil.java @@ -0,0 +1,10 @@ +package dev.openfeature.sdk; + +public class OpenFeatureAPITestUtil { + + private OpenFeatureAPITestUtil() {} + + public static OpenFeatureAPI createAPI() { + return new OpenFeatureAPI(); + } +} diff --git a/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java b/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java index 4f4d3200..97a1417a 100644 --- a/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java +++ b/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java @@ -38,7 +38,7 @@ void reset_logs() { @Test @DisplayName("should not throw exception if hook has different type argument than hookContext") void shouldNotThrowExceptionIfHookHasDifferentTypeArgumentThanHookContext() { - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); + OpenFeatureAPI api = new OpenFeatureAPI(); api.setProviderAndWait( "shouldNotThrowExceptionIfHookHasDifferentTypeArgumentThanHookContext", new DoSomethingProvider()); Client client = api.getClient("shouldNotThrowExceptionIfHookHasDifferentTypeArgumentThanHookContext"); @@ -82,7 +82,7 @@ void setEvaluationContextShouldAllowChaining() { @DisplayName("Should not call evaluation methods when the provider has state FATAL") void shouldNotCallEvaluationMethodsWhenProviderIsInFatalErrorState() { FeatureProvider provider = new TestEventsProvider(100, true, "fake fatal", true); - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); + OpenFeatureAPI api = new OpenFeatureAPI(); Client client = api.getClient("shouldNotCallEvaluationMethodsWhenProviderIsInFatalErrorState"); assertThrows( @@ -97,7 +97,7 @@ void shouldNotCallEvaluationMethodsWhenProviderIsInFatalErrorState() { @DisplayName("Should not call evaluation methods when the provider has state NOT_READY") void shouldNotCallEvaluationMethodsWhenProviderIsInNotReadyState() { FeatureProvider provider = new TestEventsProvider(5000); - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); + OpenFeatureAPI api = new OpenFeatureAPI(); api.setProvider("shouldNotCallEvaluationMethodsWhenProviderIsInNotReadyState", provider); Client client = api.getClient("shouldNotCallEvaluationMethodsWhenProviderIsInNotReadyState"); FlagEvaluationDetails details = client.getBooleanDetails("key", true); diff --git a/src/test/java/dev/openfeature/sdk/ProviderRepositoryTest.java b/src/test/java/dev/openfeature/sdk/ProviderRepositoryTest.java index 98652635..7041df5c 100644 --- a/src/test/java/dev/openfeature/sdk/ProviderRepositoryTest.java +++ b/src/test/java/dev/openfeature/sdk/ProviderRepositoryTest.java @@ -35,7 +35,7 @@ class ProviderRepositoryTest { @BeforeEach void setupTest() { - providerRepository = new ProviderRepository(); + providerRepository = new ProviderRepository(new OpenFeatureAPI()); } @Nested diff --git a/src/test/java/dev/openfeature/sdk/ShutdownBehaviorSpecTest.java b/src/test/java/dev/openfeature/sdk/ShutdownBehaviorSpecTest.java index e7caf927..1bb7d4b6 100644 --- a/src/test/java/dev/openfeature/sdk/ShutdownBehaviorSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/ShutdownBehaviorSpecTest.java @@ -1,6 +1,5 @@ package dev.openfeature.sdk; -import static dev.openfeature.sdk.testutils.FeatureProviderTestUtils.setFeatureProvider; import static org.mockito.Mockito.*; import dev.openfeature.sdk.fixtures.ProviderFixture; @@ -15,9 +14,19 @@ class ShutdownBehaviorSpecTest { private String DOMAIN = "myDomain"; + private OpenFeatureAPI api; + + void setFeatureProvider(FeatureProvider featureProvider) { + api.setProviderAndWait(featureProvider); + } + + void setFeatureProvider(String domain, FeatureProvider featureProvider) { + api.setProviderAndWait(domain, featureProvider); + } @BeforeEach void resetFeatureProvider() { + api = new OpenFeatureAPI(); setFeatureProvider(new NoOpProvider()); } @@ -110,7 +119,6 @@ void mustShutdownAllProvidersOnShuttingDownApi() { FeatureProvider namedProvider = ProviderFixture.createMockedProvider(); setFeatureProvider(defaultProvider); setFeatureProvider(DOMAIN, namedProvider); - OpenFeatureAPI api = OpenFeatureAPI.getInstance(); synchronized (OpenFeatureAPI.class) { api.shutdown(); @@ -125,15 +133,14 @@ void mustShutdownAllProvidersOnShuttingDownApi() { @Test @DisplayName("once shutdown is complete, api must be ready to use again") void apiIsReadyToUseAfterShutdown() { - final OpenFeatureAPI openFeatureAPI = OpenFeatureAPI.getInstance(); NoOpProvider p1 = new NoOpProvider(); - openFeatureAPI.setProvider(p1); + api.setProvider(p1); - openFeatureAPI.shutdown(); + api.shutdown(); NoOpProvider p2 = new NoOpProvider(); - openFeatureAPI.setProvider(p2); + api.setProvider(p2); } } } diff --git a/src/test/java/dev/openfeature/sdk/TrackingSpecTest.java b/src/test/java/dev/openfeature/sdk/TrackingSpecTest.java index a8f6e30f..ba354374 100644 --- a/src/test/java/dev/openfeature/sdk/TrackingSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/TrackingSpecTest.java @@ -15,7 +15,6 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import dev.openfeature.sdk.fixtures.ProviderFixture; -import dev.openfeature.sdk.testutils.FeatureProviderTestUtils; import java.util.HashMap; import java.util.Map; import lombok.SneakyThrows; @@ -29,7 +28,7 @@ class TrackingSpecTest { @BeforeEach void getApiInstance() { - api = OpenFeatureAPI.getInstance(); + api = new OpenFeatureAPI(); client = api.getClient(); } @@ -116,7 +115,7 @@ void contextsGetMerged() { client.setEvaluationContext(clCtx); FeatureProvider provider = ProviderFixture.createMockedProvider(); - FeatureProviderTestUtils.setFeatureProvider(provider); + api.setProviderAndWait(provider); client.track("event", new MutableContext().add("my-key", "final"), new MutableTrackingEventDetails(0.0f)); @@ -170,8 +169,7 @@ void eventDetails() { .add("my-struct", new Value(new MutableTrackingEventDetails())); assertEquals(expectedMap, details.asMap()); - assertThatCode(() -> OpenFeatureAPI.getInstance() - .getClient() + assertThatCode(() -> api.getClient() .track("tracking-event-name", new ImmutableContext(), new MutableTrackingEventDetails())) .doesNotThrowAnyException(); @@ -188,8 +186,7 @@ void eventDetails() { ImmutableTrackingEventDetails immutableDetails = new ImmutableTrackingEventDetails(2, expectedMap); assertEquals(expectedImmutable, immutableDetails.asMap()); - assertThatCode(() -> OpenFeatureAPI.getInstance() - .getClient() + assertThatCode(() -> api.getClient() .track("tracking-event-name", new ImmutableContext(), new ImmutableTrackingEventDetails())) .doesNotThrowAnyException(); } diff --git a/src/test/java/dev/openfeature/sdk/arch/ArchitectureTest.java b/src/test/java/dev/openfeature/sdk/arch/ArchitectureTest.java new file mode 100644 index 00000000..8bf8b288 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/arch/ArchitectureTest.java @@ -0,0 +1,27 @@ +package dev.openfeature.sdk.arch; + +import static com.tngtech.archunit.base.DescribedPredicate.describe; +import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; + +import com.tngtech.archunit.junit.AnalyzeClasses; +import com.tngtech.archunit.junit.ArchTest; +import com.tngtech.archunit.lang.ArchRule; + +@AnalyzeClasses(packages = "dev.openfeature.sdk") +public class ArchitectureTest { + + @ArchTest + public static final ArchRule avoidGetInstances = noClasses() + .that() + .resideOutsideOfPackages("..benchmark", "..e2e.*") + .and() + .haveSimpleNameNotEndingWith("SingeltonTest") + .should() + .callMethodWhere(describe( + "Avoid Internal usage of OpenFeatureAPI.GetInstances", + // Target method may not reside in class annotated with BusinessException + methodCall -> + methodCall.getTarget().getOwner().getFullName().equals("dev.openfeature.sdk.OpenFeatureAPI") + // And target method may not have the static modifier + && methodCall.getTarget().getName().equals("getInstance"))); +} diff --git a/src/test/java/dev/openfeature/sdk/providers/memory/InMemoryProviderTest.java b/src/test/java/dev/openfeature/sdk/providers/memory/InMemoryProviderTest.java index 86782b39..4d2a8b28 100644 --- a/src/test/java/dev/openfeature/sdk/providers/memory/InMemoryProviderTest.java +++ b/src/test/java/dev/openfeature/sdk/providers/memory/InMemoryProviderTest.java @@ -12,6 +12,7 @@ import dev.openfeature.sdk.EventDetails; import dev.openfeature.sdk.ImmutableContext; import dev.openfeature.sdk.OpenFeatureAPI; +import dev.openfeature.sdk.OpenFeatureAPITestUtil; import dev.openfeature.sdk.Value; import dev.openfeature.sdk.exceptions.FlagNotFoundError; import dev.openfeature.sdk.exceptions.ProviderNotReadyError; @@ -25,18 +26,20 @@ class InMemoryProviderTest { - private static Client client; + private Client client; - private static InMemoryProvider provider; + private InMemoryProvider provider; + private OpenFeatureAPI api; @SneakyThrows @BeforeEach void beforeEach() { Map> flags = buildFlags(); provider = spy(new InMemoryProvider(flags)); - OpenFeatureAPI.getInstance().onProviderConfigurationChanged(eventDetails -> {}); - OpenFeatureAPI.getInstance().setProviderAndWait(provider); - client = OpenFeatureAPI.getInstance().getClient(); + api = OpenFeatureAPITestUtil.createAPI(); + api.onProviderConfigurationChanged(eventDetails -> {}); + api.setProviderAndWait(provider); + client = api.getClient(); provider.updateFlags(flags); provider.updateFlag( "addedFlag", @@ -107,8 +110,8 @@ void emitChangedFlagsOnlyIfThereAreChangedFlags() { Consumer handler = mock(Consumer.class); Map> flags = buildFlags(); - OpenFeatureAPI.getInstance().onProviderConfigurationChanged(handler); - OpenFeatureAPI.getInstance().setProviderAndWait(provider); + api.onProviderConfigurationChanged(handler); + api.setProviderAndWait(provider); provider.updateFlags(flags); diff --git a/src/test/java/dev/openfeature/sdk/testutils/FeatureProviderTestUtils.java b/src/test/java/dev/openfeature/sdk/testutils/FeatureProviderTestUtils.java deleted file mode 100644 index c9ad77d8..00000000 --- a/src/test/java/dev/openfeature/sdk/testutils/FeatureProviderTestUtils.java +++ /dev/null @@ -1,31 +0,0 @@ -package dev.openfeature.sdk.testutils; - -import static org.awaitility.Awaitility.await; - -import dev.openfeature.sdk.FeatureProvider; -import dev.openfeature.sdk.OpenFeatureAPI; -import java.time.Duration; -import java.util.function.Function; -import lombok.experimental.UtilityClass; - -// todo check the need of this utility class as we now have setProviderAndWait capability -@UtilityClass -public class FeatureProviderTestUtils { - - public static void setFeatureProvider(FeatureProvider provider) { - OpenFeatureAPI.getInstance().setProvider(provider); - waitForProviderInitializationComplete(OpenFeatureAPI::getProvider, provider); - } - - private static void waitForProviderInitializationComplete( - Function extractor, FeatureProvider provider) { - await().pollDelay(Duration.ofMillis(1)) - .atMost(Duration.ofSeconds(1)) - .until(() -> extractor.apply(OpenFeatureAPI.getInstance()).equals(provider)); - } - - public static void setFeatureProvider(String domain, FeatureProvider provider) { - OpenFeatureAPI.getInstance().setProvider(domain, provider); - waitForProviderInitializationComplete(api -> api.getProvider(domain), provider); - } -} From 90217b2083a2ba92c623365dc450326d49b46fab Mon Sep 17 00:00:00 2001 From: Simon Schrottner Date: Tue, 18 Feb 2025 21:58:17 +0100 Subject: [PATCH 05/56] chore: update build and tooling to utilize new java version (#1321) * chore: update build and tooling to utilize new java version Signed-off-by: Simon Schrottner * Fix failing test Signed-off-by: christian.lutnik * chore: update build and tooling to utilize new java version Signed-off-by: Simon Schrottner --------- Signed-off-by: Simon Schrottner Signed-off-by: christian.lutnik Co-authored-by: christian.lutnik --- .github/workflows/merge.yml | 11 +- .github/workflows/pullrequest.yml | 30 +- .github/workflows/release.yml | 8 +- pom.xml | 563 ++++++++++++++++++------------ 4 files changed, 377 insertions(+), 235 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index 6ef83234..4016b9e1 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -16,15 +16,14 @@ permissions: jobs: build: - runs-on: ubuntu-latest steps: - uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - - name: Set up JDK 8 + - name: Set up JDK 17 uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 with: - java-version: '8' + java-version: '17' distribution: 'temurin' cache: maven server-id: ossrh @@ -35,9 +34,9 @@ jobs: uses: actions/cache@9fa7e61ec7e1f44ac75218e7aaea81da8856fd11 with: path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + key: ${{ runner.os }}-17-maven-${{ hashFiles('**/pom.xml') }} restore-keys: | - ${{ runner.os }}-maven- + ${{ runner.os }}-17-maven- - name: Configure GPG Key run: | @@ -60,7 +59,7 @@ jobs: # Add -SNAPSHOT before deploy - name: Add SNAPSHOT run: mvn versions:set -DnewVersion='${project.version}-SNAPSHOT' - + - name: Deploy run: | mvn --batch-mode \ diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 70dbb28f..3a22db33 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -7,7 +7,16 @@ permissions: jobs: build: - runs-on: ubuntu-latest + strategy: + matrix: + os: [ubuntu-latest] + build: + - java: 17 + profile: codequality + - java: 8 + profile: java8 + name: with Java ${{ matrix.build.java }} + runs-on: ${{ matrix.os}} steps: - name: Check out the code uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 @@ -15,9 +24,9 @@ jobs: - name: Set up JDK 8 uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 with: - java-version: '8' - distribution: 'temurin' - cache: maven + java-version: ${{ matrix.build.java }} + distribution: 'temurin' + cache: maven - name: Initialize CodeQL uses: github/codeql-action/init@1bb15d06a6fbb5d9d9ffd228746bf8ee208caec8 @@ -27,15 +36,16 @@ jobs: - name: Cache local Maven repository uses: actions/cache@9fa7e61ec7e1f44ac75218e7aaea81da8856fd11 with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- + path: ~/.m2/repository + key: ${{ runner.os }}${{ matrix.build.java }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}${{ matrix.build.java }}-maven- - name: Verify with Maven - run: mvn --batch-mode --update-snapshots --activate-profiles e2e verify + run: mvn --batch-mode --update-snapshots --activate-profiles e2e,${{ matrix.build.profile }} verify - - name: Upload coverage to Codecov + - if: matrix.build.java == '17' + name: Upload coverage to Codecov uses: codecov/codecov-action@v5.3.1 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7342889d..3e491447 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,17 +23,17 @@ jobs: id: release with: token: ${{secrets.GITHUB_TOKEN}} - default-branch: main + target-branch: main # These steps are only run if this was a merged release-please PR - name: checkout if: ${{ steps.release.outputs.release_created }} uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - - name: Set up JDK 8 + - name: Set up JDK 17 if: ${{ steps.release.outputs.release_created }} uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 with: - java-version: '8' + java-version: '17' distribution: 'temurin' cache: maven server-id: ossrh @@ -54,4 +54,4 @@ jobs: --settings release/m2-settings.xml clean deploy env: OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} - OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} \ No newline at end of file + OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} diff --git a/pom.xml b/pom.xml index bbc1b8db..de54a7ce 100644 --- a/pom.xml +++ b/pom.xml @@ -8,13 +8,19 @@ 1.14.1 + [17,) UTF-8 1.8 ${maven.compiler.source} 5.11.4 + 7.21.1 + 5.2.0 **/e2e/*.java ${project.groupId}.${project.artifactId} + false + + 8 OpenFeature Java SDK @@ -77,7 +83,7 @@ org.mockito mockito-core - 4.11.0 + ${org.mockito.version} test @@ -126,12 +132,14 @@ io.cucumber cucumber-java + ${io.cucumber.version} test io.cucumber cucumber-junit-platform-engine + ${io.cucumber.version} test @@ -207,6 +215,18 @@ + + org.apache.maven.plugins + maven-toolchains-plugin + 3.2.0 + + + + select-jdk-toolchain + + + + org.cyclonedx cyclonedx-maven-plugin @@ -233,37 +253,6 @@ - - maven-dependency-plugin - 3.8.1 - - - verify - - analyze - - - - - true - - com.github.spotbugs:* - org.junit* - com.tngtech.archunit* - org.simplify4u:slf4j2-mock* - - - com.google.guava* - io.cucumber* - org.junit* - com.tngtech.archunit* - com.google.code.findbugs* - com.github.spotbugs* - org.simplify4u:slf4j-mock-common:* - - - - maven-compiler-plugin 3.13.0 @@ -278,6 +267,8 @@ false ${surefireArgLine} + --add-opens java.base/java.util=ALL-UNNAMED + --add-opens java.base/java.lang=ALL-UNNAMED @@ -297,65 +288,6 @@ - - org.jacoco - jacoco-maven-plugin - 0.8.12 - - - - prepare-agent - - prepare-agent - - - - ${project.build.directory}/coverage-reports/jacoco-ut.exec - surefireArgLine - - - - - report - verify - - report - - - - ${project.build.directory}/coverage-reports/jacoco-ut.exec - ${project.reporting.outputDirectory}/jacoco-ut - - - - - jacoco-check - - check - - - ${project.build.directory}/coverage-reports/jacoco-ut.exec - - dev/openfeature/sdk/exceptions/** - - - - - PACKAGE - - - LINE - COVEREDRATIO - 0.80 - - - - - - - - - org.apache.maven.plugins @@ -370,134 +302,264 @@ - - org.apache.maven.plugins - maven-pmd-plugin - 3.26.0 - - - run-pmd - verify - - check - - - - - - - com.github.spotbugs - spotbugs-maven-plugin - 4.8.6.6 - - spotbugs-exclusions.xml - - - com.h3xstream.findsecbugs - findsecbugs-plugin - 1.13.0 - - - - - - - com.github.spotbugs - spotbugs - 4.8.6 - - - - - run-spotbugs - verify - - check - - - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - 3.6.0 - - checkstyle.xml - UTF-8 - true - true - false - - - - com.puppycrawl.tools - checkstyle - 9.3 - - - - - validate - validate - - check - - - - - - com.diffplug.spotless - spotless-maven-plugin - 2.30.0 - - - - - - - - - .gitattributes - .gitignore - - - - - - true - 4 - - - - - - - - - true - 4 - - - - - - - - - - - - check - - - - - + + codequality + + true + + + + + maven-dependency-plugin + 3.8.1 + + + verify + + analyze + + + + + true + + com.github.spotbugs:* + org.junit* + com.tngtech.archunit* + org.simplify4u:slf4j2-mock* + + + com.google.guava* + io.cucumber* + org.junit* + com.tngtech.archunit* + com.google.code.findbugs* + com.github.spotbugs* + org.simplify4u:slf4j-mock-common:* + + + + + + org.jacoco + jacoco-maven-plugin + 0.8.12 + + + + prepare-agent + + prepare-agent + + + + ${project.build.directory}/coverage-reports/jacoco-ut.exec + surefireArgLine + + + + + report + verify + + report + + + + ${project.build.directory}/coverage-reports/jacoco-ut.exec + ${project.reporting.outputDirectory}/jacoco-ut + + + + + jacoco-check + + check + + + ${project.build.directory}/coverage-reports/jacoco-ut.exec + + dev/openfeature/sdk/exceptions/** + + + + + PACKAGE + + + LINE + COVEREDRATIO + 0.80 + + + + + + + + + + + com.github.spotbugs + spotbugs-maven-plugin + 4.8.6.6 + + spotbugs-exclusions.xml + + + com.h3xstream.findsecbugs + findsecbugs-plugin + 1.13.0 + + + + + + + com.github.spotbugs + spotbugs + 4.8.6 + + + + + run-spotbugs + verify + + check + + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.6.0 + + checkstyle.xml + true + true + false + + + + com.puppycrawl.tools + checkstyle + 9.3 + + + + + validate + validate + + check + + + + + + com.diffplug.spotless + spotless-maven-plugin + 2.30.0 + + + + + + + + + .gitattributes + .gitignore + + + + + + true + 4 + + + + + + + + + true + 4 + + + + + + + + + + + + check + + + + + + com.diffplug.spotless + spotless-maven-plugin + 2.43.0 + + + + + + + + + .gitattributes + .gitignore + + + + + + true + 4 + + + + + + + + + true + 4 + + + + + + + + + + + + check + + + + + + + deploy @@ -639,6 +701,77 @@ + + + + java8 + + + + (1.8,9) + true + + + + + + org.apache.maven.plugins + maven-toolchains-plugin + 3.2.0 + + + + select-jdk-toolchain + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.5.2 + + + ${surefireArgLine} + + + + ${testExclusions} + + + ${skip.tests} + + + + org.apache.maven.plugins + maven-failsafe-plugin + 3.5.2 + + + ${surefireArgLine} + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + + default-testCompile + test-compile + + testCompile + + + true + + + + + + + From 4817864fd7ae70c1e19c3c09e82e1fb03dd88942 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 22:10:34 +0100 Subject: [PATCH 06/56] chore(deps): update dependency org.mockito:mockito-core to v5.15.2 (#1339) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index de54a7ce..83d06efb 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ ${maven.compiler.source} 5.11.4 7.21.1 - 5.2.0 + 5.15.2 **/e2e/*.java ${project.groupId}.${project.artifactId} From 4e535fd10fac742ca472faa62c941fa51b282ca7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 19 Feb 2025 02:13:36 +0000 Subject: [PATCH 07/56] chore(deps): update github/codeql-action digest to d99c7e8 (#1338) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 3a22db33..cf8e85cb 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,7 +29,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@1bb15d06a6fbb5d9d9ffd228746bf8ee208caec8 + uses: github/codeql-action/init@d99c7e8e5b6aca5b6a17459f07d4dc8f8a3b7823 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1bb15d06a6fbb5d9d9ffd228746bf8ee208caec8 + uses: github/codeql-action/analyze@d99c7e8e5b6aca5b6a17459f07d4dc8f8a3b7823 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 8bf7512f..acca30a4 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@1bb15d06a6fbb5d9d9ffd228746bf8ee208caec8 + uses: github/codeql-action/init@d99c7e8e5b6aca5b6a17459f07d4dc8f8a3b7823 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@1bb15d06a6fbb5d9d9ffd228746bf8ee208caec8 + uses: github/codeql-action/autobuild@d99c7e8e5b6aca5b6a17459f07d4dc8f8a3b7823 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1bb15d06a6fbb5d9d9ffd228746bf8ee208caec8 + uses: github/codeql-action/analyze@d99c7e8e5b6aca5b6a17459f07d4dc8f8a3b7823 From 3920c638a49caddfb07041f812cc6bc0bf3101f9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 19 Feb 2025 06:22:52 +0000 Subject: [PATCH 08/56] chore(deps): update actions/cache digest to 7921ae2 (#1337) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/merge.yml | 2 +- .github/workflows/pullrequest.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index 4016b9e1..a76348f9 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -31,7 +31,7 @@ jobs: server-password: ${{ secrets.OSSRH_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@9fa7e61ec7e1f44ac75218e7aaea81da8856fd11 + uses: actions/cache@7921ae235bdcb376cc8f22558dc5f8ddc3c3c2f9 with: path: ~/.m2/repository key: ${{ runner.os }}-17-maven-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index cf8e85cb..1c5bdf1e 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -34,7 +34,7 @@ jobs: languages: java - name: Cache local Maven repository - uses: actions/cache@9fa7e61ec7e1f44ac75218e7aaea81da8856fd11 + uses: actions/cache@7921ae235bdcb376cc8f22558dc5f8ddc3c3c2f9 with: path: ~/.m2/repository key: ${{ runner.os }}${{ matrix.build.java }}-maven-${{ hashFiles('**/pom.xml') }} From cdcdc143ea5ad2f003cb3f5450ec78314e619ea3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 19 Feb 2025 10:06:15 +0000 Subject: [PATCH 09/56] chore(deps): update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.1.0 (#1332) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 83d06efb..728d45b9 100644 --- a/pom.xml +++ b/pom.xml @@ -406,7 +406,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.8.6.6 + 4.9.1.0 spotbugs-exclusions.xml From dd9227a9242451c57250de85701c10ddcc75dc71 Mon Sep 17 00:00:00 2001 From: chrfwow Date: Wed, 19 Feb 2025 16:27:46 +0100 Subject: [PATCH 10/56] feat: update test harness with metadata assertions #1467 (#1319) * feat: implement gherkin tests Signed-off-by: christian.lutnik * fixup! feat: implement gherkin tests Signed-off-by: christian.lutnik * fixup! feat: implement gherkin tests Signed-off-by: christian.lutnik * fixup! feat: implement gherkin tests Signed-off-by: christian.lutnik * fixup: add version for dependency Signed-off-by: Simon Schrottner --------- Signed-off-by: christian.lutnik Signed-off-by: Simon Schrottner Co-authored-by: Simon Schrottner --- pom.xml | 22 ++-- .../openfeature/sdk/ImmutableMetadata.java | 4 + .../openfeature/sdk/OpenFeatureClient.java | 2 +- .../sdk/providers/memory/Flag.java | 2 + .../providers/memory/InMemoryProvider.java | 1 + .../dev/openfeature/sdk/FlagMetadataTest.java | 29 ++++- .../openfeature/sdk/e2e/EvaluationTest.java | 8 +- .../java/dev/openfeature/sdk/e2e/Flag.java | 13 +++ .../dev/openfeature/sdk/e2e/MockHook.java | 50 +++++++++ .../java/dev/openfeature/sdk/e2e/State.java | 13 +++ .../java/dev/openfeature/sdk/e2e/Utils.java | 28 +++++ .../sdk/e2e/steps/FlagStepDefinitions.java | 104 ++++++++++++++++++ .../openfeature/sdk/e2e/steps/HookSteps.java | 84 ++++++++++++++ .../sdk/e2e/steps/ProviderSteps.java | 26 +++++ .../StepDefinitions.java | 2 +- .../sdk/testutils/TestFlagsUtils.java | 16 +++ 16 files changed, 381 insertions(+), 23 deletions(-) create mode 100644 src/test/java/dev/openfeature/sdk/e2e/Flag.java create mode 100644 src/test/java/dev/openfeature/sdk/e2e/MockHook.java create mode 100644 src/test/java/dev/openfeature/sdk/e2e/State.java create mode 100644 src/test/java/dev/openfeature/sdk/e2e/Utils.java create mode 100644 src/test/java/dev/openfeature/sdk/e2e/steps/FlagStepDefinitions.java create mode 100644 src/test/java/dev/openfeature/sdk/e2e/steps/HookSteps.java create mode 100644 src/test/java/dev/openfeature/sdk/e2e/steps/ProviderSteps.java rename src/test/java/dev/openfeature/sdk/e2e/{evaluation => steps}/StepDefinitions.java (99%) diff --git a/pom.xml b/pom.xml index 728d45b9..d850e4f0 100644 --- a/pom.xml +++ b/pom.xml @@ -143,6 +143,13 @@ test + + io.cucumber + cucumber-picocontainer + ${io.cucumber.version} + test + + org.simplify4u slf4j2-mock @@ -681,21 +688,6 @@ - - copy-evaluation-gherkin-tests - validate - - exec - - - - cp - - spec/specification/assets/gherkin/evaluation.feature - src/test/resources/features/ - - - diff --git a/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java b/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java index c2b6f583..f8311a9a 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java @@ -97,6 +97,10 @@ public T getValue(final String key, final Class type) { } } + public boolean isEmpty() { + return metadata.isEmpty(); + } + /** * Obtain a builder for {@link ImmutableMetadata}. */ diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index a393d83e..3022ff00 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -217,7 +217,7 @@ private FlagEvaluationDetails evaluateFlag( } } catch (Exception e) { if (details == null) { - details = FlagEvaluationDetails.builder().build(); + details = FlagEvaluationDetails.builder().flagKey(key).build(); } if (e instanceof OpenFeatureError) { details.setErrorCode(((OpenFeatureError) e).getErrorCode()); diff --git a/src/main/java/dev/openfeature/sdk/providers/memory/Flag.java b/src/main/java/dev/openfeature/sdk/providers/memory/Flag.java index 61778d85..f2dc6b49 100644 --- a/src/main/java/dev/openfeature/sdk/providers/memory/Flag.java +++ b/src/main/java/dev/openfeature/sdk/providers/memory/Flag.java @@ -1,5 +1,6 @@ package dev.openfeature.sdk.providers.memory; +import dev.openfeature.sdk.ImmutableMetadata; import java.util.Map; import lombok.Builder; import lombok.Getter; @@ -18,4 +19,5 @@ public class Flag { private String defaultVariant; private ContextEvaluator contextEvaluator; + private ImmutableMetadata flagMetadata; } diff --git a/src/main/java/dev/openfeature/sdk/providers/memory/InMemoryProvider.java b/src/main/java/dev/openfeature/sdk/providers/memory/InMemoryProvider.java index d3fdb985..3be1b631 100644 --- a/src/main/java/dev/openfeature/sdk/providers/memory/InMemoryProvider.java +++ b/src/main/java/dev/openfeature/sdk/providers/memory/InMemoryProvider.java @@ -152,6 +152,7 @@ private ProviderEvaluation getEvaluation( .value(value) .variant(flag.getDefaultVariant()) .reason(Reason.STATIC.toString()) + .flagMetadata(flag.getFlagMetadata()) .build(); } } diff --git a/src/test/java/dev/openfeature/sdk/FlagMetadataTest.java b/src/test/java/dev/openfeature/sdk/FlagMetadataTest.java index f8b9ba58..26d0421c 100644 --- a/src/test/java/dev/openfeature/sdk/FlagMetadataTest.java +++ b/src/test/java/dev/openfeature/sdk/FlagMetadataTest.java @@ -1,6 +1,8 @@ package dev.openfeature.sdk; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -9,7 +11,7 @@ class FlagMetadataTest { @Test @DisplayName("Test metadata payload construction and retrieval") - public void builder_validation() { + void builder_validation() { // given ImmutableMetadata flagMetadata = ImmutableMetadata.builder() .addString("string", "string") @@ -42,7 +44,7 @@ public void builder_validation() { @Test @DisplayName("Value type mismatch returns a null") - public void value_type_validation() { + void value_type_validation() { // given ImmutableMetadata flagMetadata = ImmutableMetadata.builder().addString("string", "string").build(); @@ -53,11 +55,32 @@ public void value_type_validation() { @Test @DisplayName("A null is returned if key does not exist") - public void notfound_error_validation() { + void notfound_error_validation() { // given ImmutableMetadata flagMetadata = ImmutableMetadata.builder().build(); // then assertThat(flagMetadata.getBoolean("string")).isNull(); } + + @Test + @DisplayName("isEmpty returns true iff the metadata is empty") + void isEmpty_returns_true_if_metadata_is_empty() { + // given + ImmutableMetadata flagMetadata = ImmutableMetadata.builder().build(); + + // then + assertTrue(flagMetadata.isEmpty()); + } + + @Test + @DisplayName("isEmpty returns false iff the metadata is not empty") + void isEmpty_returns_false_if_metadata_is_not_empty() { + // given + ImmutableMetadata flagMetadata = + ImmutableMetadata.builder().addString("a", "b").build(); + + // then + assertFalse(flagMetadata.isEmpty()); + } } diff --git a/src/test/java/dev/openfeature/sdk/e2e/EvaluationTest.java b/src/test/java/dev/openfeature/sdk/e2e/EvaluationTest.java index 8a338141..b7c83431 100644 --- a/src/test/java/dev/openfeature/sdk/e2e/EvaluationTest.java +++ b/src/test/java/dev/openfeature/sdk/e2e/EvaluationTest.java @@ -1,16 +1,18 @@ package dev.openfeature.sdk.e2e; import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME; +import static io.cucumber.junit.platform.engine.Constants.OBJECT_FACTORY_PROPERTY_NAME; import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME; import org.junit.platform.suite.api.ConfigurationParameter; import org.junit.platform.suite.api.IncludeEngines; -import org.junit.platform.suite.api.SelectClasspathResource; +import org.junit.platform.suite.api.SelectDirectories; import org.junit.platform.suite.api.Suite; @Suite @IncludeEngines("cucumber") -@SelectClasspathResource("features/evaluation.feature") +@SelectDirectories("spec/specification/assets/gherkin") @ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "pretty") -@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "dev.openfeature.sdk.e2e.evaluation") +@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "dev.openfeature.sdk.e2e.steps") +@ConfigurationParameter(key = OBJECT_FACTORY_PROPERTY_NAME, value = "io.cucumber.picocontainer.PicoFactory") public class EvaluationTest {} diff --git a/src/test/java/dev/openfeature/sdk/e2e/Flag.java b/src/test/java/dev/openfeature/sdk/e2e/Flag.java new file mode 100644 index 00000000..2c4ffdb5 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/e2e/Flag.java @@ -0,0 +1,13 @@ +package dev.openfeature.sdk.e2e; + +public class Flag { + public String name; + public Object defaultValue; + public String type; + + public Flag(String type, String name, Object defaultValue) { + this.name = name; + this.defaultValue = defaultValue; + this.type = type; + } +} diff --git a/src/test/java/dev/openfeature/sdk/e2e/MockHook.java b/src/test/java/dev/openfeature/sdk/e2e/MockHook.java new file mode 100644 index 00000000..ac107cfd --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/e2e/MockHook.java @@ -0,0 +1,50 @@ +package dev.openfeature.sdk.e2e; + +import dev.openfeature.sdk.EvaluationContext; +import dev.openfeature.sdk.FlagEvaluationDetails; +import dev.openfeature.sdk.Hook; +import dev.openfeature.sdk.HookContext; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import lombok.Getter; + +public class MockHook implements Hook { + @Getter + private boolean beforeCalled; + + @Getter + private boolean afterCalled; + + @Getter + private boolean errorCalled; + + @Getter + private boolean finallyAfterCalled; + + @Getter + private final Map evaluationDetails = new HashMap<>(); + + @Override + public Optional before(HookContext ctx, Map hints) { + beforeCalled = true; + return Optional.of(ctx.getCtx()); + } + + @Override + public void after(HookContext ctx, FlagEvaluationDetails details, Map hints) { + afterCalled = true; + evaluationDetails.put("after", details); + } + + @Override + public void error(HookContext ctx, Exception error, Map hints) { + errorCalled = true; + } + + @Override + public void finallyAfter(HookContext ctx, FlagEvaluationDetails details, Map hints) { + finallyAfterCalled = true; + evaluationDetails.put("finally", details); + } +} diff --git a/src/test/java/dev/openfeature/sdk/e2e/State.java b/src/test/java/dev/openfeature/sdk/e2e/State.java new file mode 100644 index 00000000..ee513b00 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/e2e/State.java @@ -0,0 +1,13 @@ +package dev.openfeature.sdk.e2e; + +import dev.openfeature.sdk.Client; +import dev.openfeature.sdk.FlagEvaluationDetails; +import dev.openfeature.sdk.MutableContext; + +public class State { + public Client client; + public Flag flag; + public MutableContext context = new MutableContext(); + public FlagEvaluationDetails evaluation; + public MockHook hook; +} diff --git a/src/test/java/dev/openfeature/sdk/e2e/Utils.java b/src/test/java/dev/openfeature/sdk/e2e/Utils.java new file mode 100644 index 00000000..902ee11d --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/e2e/Utils.java @@ -0,0 +1,28 @@ +package dev.openfeature.sdk.e2e; + +import java.util.Objects; + +public final class Utils { + + private Utils() {} + + public static Object convert(String value, String type) { + if (Objects.equals(value, "null")) { + return null; + } + switch (type.toLowerCase()) { + case "boolean": + return Boolean.parseBoolean(value); + case "string": + return value; + case "integer": + return Integer.parseInt(value); + case "float": + case "double": + return Double.parseDouble(value); + case "long": + return Long.parseLong(value); + } + throw new RuntimeException("Unknown config type: " + type); + } +} diff --git a/src/test/java/dev/openfeature/sdk/e2e/steps/FlagStepDefinitions.java b/src/test/java/dev/openfeature/sdk/e2e/steps/FlagStepDefinitions.java new file mode 100644 index 00000000..390e067f --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/e2e/steps/FlagStepDefinitions.java @@ -0,0 +1,104 @@ +package dev.openfeature.sdk.e2e.steps; + +import static org.assertj.core.api.Assertions.assertThat; + +import dev.openfeature.sdk.FlagEvaluationDetails; +import dev.openfeature.sdk.ImmutableMetadata; +import dev.openfeature.sdk.Value; +import dev.openfeature.sdk.e2e.Flag; +import dev.openfeature.sdk.e2e.State; +import dev.openfeature.sdk.e2e.Utils; +import io.cucumber.datatable.DataTable; +import io.cucumber.java.en.Given; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.List; + +public class FlagStepDefinitions { + private final State state; + + public FlagStepDefinitions(State state) { + this.state = state; + } + + @Given("a {}-flag with key {string} and a default value {string}") + public void givenAFlag(String type, String name, String defaultValue) { + state.flag = new Flag(type, name, Utils.convert(defaultValue, type)); + } + + @When("the flag was evaluated with details") + public void the_flag_was_evaluated_with_details() { + FlagEvaluationDetails details; + switch (state.flag.type.toLowerCase()) { + case "string": + details = + state.client.getStringDetails(state.flag.name, (String) state.flag.defaultValue, state.context); + break; + case "boolean": + details = state.client.getBooleanDetails( + state.flag.name, (Boolean) state.flag.defaultValue, state.context); + break; + case "float": + details = + state.client.getDoubleDetails(state.flag.name, (Double) state.flag.defaultValue, state.context); + break; + case "integer": + details = state.client.getIntegerDetails( + state.flag.name, (Integer) state.flag.defaultValue, state.context); + break; + case "object": + details = + state.client.getObjectDetails(state.flag.name, (Value) state.flag.defaultValue, state.context); + break; + default: + throw new AssertionError(); + } + state.evaluation = details; + } + + @Then("the resolved details value should be {string}") + public void the_resolved_details_value_should_be(String value) { + assertThat(state.evaluation.getValue()).isEqualTo(Utils.convert(value, state.flag.type)); + } + + @Then("the reason should be {string}") + public void the_reason_should_be(String reason) { + assertThat(state.evaluation.getReason()).isEqualTo(reason); + } + + @Then("the variant should be {string}") + public void the_variant_should_be(String variant) { + assertThat(state.evaluation.getVariant()).isEqualTo(variant); + } + + @Then("the resolved metadata value \"{}\" with type \"{}\" should be \"{}\"") + public void theResolvedMetadataValueShouldBe(String key, String type, String value) + throws NoSuchFieldException, IllegalAccessException { + Field f = state.evaluation.getFlagMetadata().getClass().getDeclaredField("metadata"); + f.setAccessible(true); + HashMap metadata = (HashMap) f.get(state.evaluation.getFlagMetadata()); + assertThat(metadata).containsEntry(key, Utils.convert(value, type)); + } + + @Then("the resolved metadata is empty") + public void theResolvedMetadataIsEmpty() { + assertThat(state.evaluation.getFlagMetadata().isEmpty()).isTrue(); + } + + @Then("the resolved metadata should contain") + public void theResolvedMetadataShouldContain(DataTable dataTable) { + ImmutableMetadata evaluationMetadata = state.evaluation.getFlagMetadata(); + List> asLists = dataTable.asLists(); + for (int i = 1; i < asLists.size(); i++) { // skip the header of the table + List line = asLists.get(i); + String key = line.get(0); + String metadataType = line.get(1); + Object value = Utils.convert(line.get(2), metadataType); + + assertThat(value).isNotNull(); + assertThat(evaluationMetadata.getValue(key, value.getClass())).isEqualTo(value); + } + } +} diff --git a/src/test/java/dev/openfeature/sdk/e2e/steps/HookSteps.java b/src/test/java/dev/openfeature/sdk/e2e/steps/HookSteps.java new file mode 100644 index 00000000..1e6a9172 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/e2e/steps/HookSteps.java @@ -0,0 +1,84 @@ +package dev.openfeature.sdk.e2e.steps; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import dev.openfeature.sdk.FlagEvaluationDetails; +import dev.openfeature.sdk.e2e.MockHook; +import dev.openfeature.sdk.e2e.State; +import dev.openfeature.sdk.e2e.Utils; +import io.cucumber.datatable.DataTable; +import io.cucumber.java.en.And; +import io.cucumber.java.en.Given; +import io.cucumber.java.en.Then; +import java.util.List; +import java.util.Map; + +public class HookSteps { + private final State state; + + public HookSteps(State state) { + this.state = state; + } + + @Given("a client with added hook") + public void aClientWithAddedHook() { + MockHook hook = new MockHook(); + state.hook = hook; + state.client.addHooks(hook); + } + + @Then("the {string} hook should have been executed") + public void theHookShouldHaveBeenExecuted(String hookName) { + assertHookCalled(hookName); + } + + public void assertHookCalled(String hookName) { + if ("before".equals(hookName)) { + assertTrue(state.hook.isBeforeCalled()); + } else if ("after".equals(hookName)) { + assertTrue(state.hook.isAfterCalled()); + } else if ("error".equals(hookName)) { + assertTrue(state.hook.isErrorCalled()); + } else if ("finally".equals(hookName)) { + assertTrue(state.hook.isFinallyAfterCalled()); + } else { + throw new IllegalArgumentException(hookName + " is not a valid hook name"); + } + } + + @And("the {string} hooks should be called with evaluation details") + public void theHooksShouldBeCalledWithEvaluationDetails(String hookNames, DataTable data) { + for (String hookName : hookNames.split(", ")) { + assertHookCalled(hookName); + FlagEvaluationDetails evaluationDetails = + state.hook.getEvaluationDetails().get(hookName); + assertNotNull(evaluationDetails); + List> dataEntries = data.asMaps(); + for (Map line : dataEntries) { + String key = line.get("key"); + Object expected = Utils.convert(line.get("value"), line.get("data_type")); + Object actual; + if ("flag_key".equals(key)) { + actual = evaluationDetails.getFlagKey(); + } else if ("value".equals(key)) { + actual = evaluationDetails.getValue(); + } else if ("variant".equals(key)) { + actual = evaluationDetails.getVariant(); + } else if ("reason".equals(key)) { + actual = evaluationDetails.getReason(); + } else if ("error_code".equals(key)) { + actual = evaluationDetails.getErrorCode(); + if (actual != null) { + actual = actual.toString(); + } + } else { + throw new IllegalArgumentException(key + " is not a valid key"); + } + + assertEquals(expected, actual); + } + } + } +} diff --git a/src/test/java/dev/openfeature/sdk/e2e/steps/ProviderSteps.java b/src/test/java/dev/openfeature/sdk/e2e/steps/ProviderSteps.java new file mode 100644 index 00000000..82cdb2e7 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/e2e/steps/ProviderSteps.java @@ -0,0 +1,26 @@ +package dev.openfeature.sdk.e2e.steps; + +import static dev.openfeature.sdk.testutils.TestFlagsUtils.buildFlags; + +import dev.openfeature.sdk.OpenFeatureAPI; +import dev.openfeature.sdk.e2e.State; +import dev.openfeature.sdk.providers.memory.Flag; +import dev.openfeature.sdk.providers.memory.InMemoryProvider; +import io.cucumber.java.en.Given; +import java.util.Map; + +public class ProviderSteps { + private final State state; + + public ProviderSteps(State state) { + this.state = state; + } + + @Given("a stable provider") + public void aStableProvider() { + Map> flags = buildFlags(); + InMemoryProvider provider = new InMemoryProvider(flags); + OpenFeatureAPI.getInstance().setProviderAndWait(provider); + state.client = OpenFeatureAPI.getInstance().getClient(); + } +} diff --git a/src/test/java/dev/openfeature/sdk/e2e/evaluation/StepDefinitions.java b/src/test/java/dev/openfeature/sdk/e2e/steps/StepDefinitions.java similarity index 99% rename from src/test/java/dev/openfeature/sdk/e2e/evaluation/StepDefinitions.java rename to src/test/java/dev/openfeature/sdk/e2e/steps/StepDefinitions.java index c1e56429..6897e273 100644 --- a/src/test/java/dev/openfeature/sdk/e2e/evaluation/StepDefinitions.java +++ b/src/test/java/dev/openfeature/sdk/e2e/steps/StepDefinitions.java @@ -1,4 +1,4 @@ -package dev.openfeature.sdk.e2e.evaluation; +package dev.openfeature.sdk.e2e.steps; import static dev.openfeature.sdk.testutils.TestFlagsUtils.buildFlags; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/dev/openfeature/sdk/testutils/TestFlagsUtils.java b/src/test/java/dev/openfeature/sdk/testutils/TestFlagsUtils.java index 157b0717..c1767ff6 100644 --- a/src/test/java/dev/openfeature/sdk/testutils/TestFlagsUtils.java +++ b/src/test/java/dev/openfeature/sdk/testutils/TestFlagsUtils.java @@ -3,6 +3,7 @@ import static dev.openfeature.sdk.Structure.mapToStructure; import com.google.common.collect.ImmutableMap; +import dev.openfeature.sdk.ImmutableMetadata; import dev.openfeature.sdk.Value; import dev.openfeature.sdk.providers.memory.Flag; import java.util.HashMap; @@ -22,9 +23,11 @@ public class TestFlagsUtils { public static final String OBJECT_FLAG_KEY = "object-flag"; public static final String CONTEXT_AWARE_FLAG_KEY = "context-aware"; public static final String WRONG_FLAG_KEY = "wrong-flag"; + public static final String METADATA_FLAG_KEY = "metadata-flag"; /** * Building flags for testing purposes. + * * @return map of flags */ public static Map> buildFlags() { @@ -90,6 +93,19 @@ public static Map> buildFlags() { .variant("two", "dos") .defaultVariant("one") .build()); + flags.put( + METADATA_FLAG_KEY, + Flag.builder() + .variant("on", true) + .variant("off", false) + .defaultVariant("on") + .flagMetadata(ImmutableMetadata.builder() + .addString("string", "1.0.2") + .addInteger("integer", 2) + .addBoolean("boolean", true) + .addDouble("float", 0.1d) + .build()) + .build()); return flags; } } From 50b45b2be442bb89a431c9bcc45d825f63bd93a6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 21 Feb 2025 21:38:42 +0000 Subject: [PATCH 11/56] chore(deps): update github/codeql-action digest to ff79de6 (#1340) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 1c5bdf1e..e53191f9 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,7 +29,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@d99c7e8e5b6aca5b6a17459f07d4dc8f8a3b7823 + uses: github/codeql-action/init@ff79de67cc25c7617163ae1e4b8aa23b902fdf15 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@d99c7e8e5b6aca5b6a17459f07d4dc8f8a3b7823 + uses: github/codeql-action/analyze@ff79de67cc25c7617163ae1e4b8aa23b902fdf15 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index acca30a4..4883c626 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@d99c7e8e5b6aca5b6a17459f07d4dc8f8a3b7823 + uses: github/codeql-action/init@ff79de67cc25c7617163ae1e4b8aa23b902fdf15 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@d99c7e8e5b6aca5b6a17459f07d4dc8f8a3b7823 + uses: github/codeql-action/autobuild@ff79de67cc25c7617163ae1e4b8aa23b902fdf15 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@d99c7e8e5b6aca5b6a17459f07d4dc8f8a3b7823 + uses: github/codeql-action/analyze@ff79de67cc25c7617163ae1e4b8aa23b902fdf15 From 88a778cc03e112d45756428d1f0ae1ef0fe02c84 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 22 Feb 2025 01:27:57 +0000 Subject: [PATCH 12/56] chore(deps): update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.14.0 (#1342) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index d850e4f0..c67645f5 100644 --- a/pom.xml +++ b/pom.xml @@ -262,7 +262,7 @@ maven-compiler-plugin - 3.13.0 + 3.14.0 @@ -747,7 +747,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.13.0 + 3.14.0 default-testCompile From 1504d0f7982757a2b413eda593ce7057b90519e5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 22 Feb 2025 07:00:59 +0000 Subject: [PATCH 13/56] chore(deps): update dependency org.awaitility:awaitility to v4.3.0 (#1343) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c67645f5..a435bc89 100644 --- a/pom.xml +++ b/pom.xml @@ -167,7 +167,7 @@ org.awaitility awaitility - 4.2.2 + 4.3.0 test From d95e2706532259bd5739e5b4ea4813ef9f2196a6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 22 Feb 2025 09:50:37 +0000 Subject: [PATCH 14/56] fix(deps): update junit5 monorepo (#1344) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index a435bc89..c90352b3 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ UTF-8 1.8 ${maven.compiler.source} - 5.11.4 + 5.12.0 7.21.1 5.15.2 @@ -125,7 +125,7 @@ org.junit.platform junit-platform-suite - 1.11.4 + 1.12.0 test @@ -212,7 +212,7 @@ org.junit junit-bom - 5.11.4 + 5.12.0 pom import From de64eddfb3a6cc117bb108dbcf167830e9f6729d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 06:00:41 +0000 Subject: [PATCH 15/56] chore(deps): update github/codeql-action digest to a8849fb (#1345) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index e53191f9..3e5645e4 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,7 +29,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@ff79de67cc25c7617163ae1e4b8aa23b902fdf15 + uses: github/codeql-action/init@a8849fbe6341625acb2e18f7f32e53b734d6e1e3 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ff79de67cc25c7617163ae1e4b8aa23b902fdf15 + uses: github/codeql-action/analyze@a8849fbe6341625acb2e18f7f32e53b734d6e1e3 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 4883c626..039a43de 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@ff79de67cc25c7617163ae1e4b8aa23b902fdf15 + uses: github/codeql-action/init@a8849fbe6341625acb2e18f7f32e53b734d6e1e3 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@ff79de67cc25c7617163ae1e4b8aa23b902fdf15 + uses: github/codeql-action/autobuild@a8849fbe6341625acb2e18f7f32e53b734d6e1e3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ff79de67cc25c7617163ae1e4b8aa23b902fdf15 + uses: github/codeql-action/analyze@a8849fbe6341625acb2e18f7f32e53b734d6e1e3 From 5de33c02a675db6ca5966bfa3f58d99c8e53e36b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 08:15:15 +0100 Subject: [PATCH 16/56] chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v2.44.3 (#1341) * chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v2.44.3 * fixup: fix spotless violation Signed-off-by: Simon Schrottner --------- Signed-off-by: Simon Schrottner Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Simon Schrottner --- .gitattributes | 1 - pom.xml | 49 +------------------------------------------------ 2 files changed, 1 insertion(+), 49 deletions(-) diff --git a/.gitattributes b/.gitattributes index 00a51aff..022b8414 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,4 +3,3 @@ # # These are explicitly windows files and should use crlf *.bat text eol=crlf - diff --git a/pom.xml b/pom.xml index c90352b3..36797998 100644 --- a/pom.xml +++ b/pom.xml @@ -473,54 +473,7 @@ com.diffplug.spotless spotless-maven-plugin - 2.30.0 - - - - - - - - - .gitattributes - .gitignore - - - - - - true - 4 - - - - - - - - - true - 4 - - - - - - - - - - - - check - - - - - - com.diffplug.spotless - spotless-maven-plugin - 2.43.0 + 2.44.3 From 698756856ba40e98d91ccf661dab409798861aa5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 21:49:59 +0000 Subject: [PATCH 17/56] chore(deps): update github/codeql-action digest to 8c69433 (#1347) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 3e5645e4..819a7abe 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,7 +29,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@a8849fbe6341625acb2e18f7f32e53b734d6e1e3 + uses: github/codeql-action/init@8c69433c34fe91b0644d83e6f14bb77eb3e46812 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@a8849fbe6341625acb2e18f7f32e53b734d6e1e3 + uses: github/codeql-action/analyze@8c69433c34fe91b0644d83e6f14bb77eb3e46812 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 039a43de..4361546f 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@a8849fbe6341625acb2e18f7f32e53b734d6e1e3 + uses: github/codeql-action/init@8c69433c34fe91b0644d83e6f14bb77eb3e46812 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@a8849fbe6341625acb2e18f7f32e53b734d6e1e3 + uses: github/codeql-action/autobuild@8c69433c34fe91b0644d83e6f14bb77eb3e46812 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@a8849fbe6341625acb2e18f7f32e53b734d6e1e3 + uses: github/codeql-action/analyze@8c69433c34fe91b0644d83e6f14bb77eb3e46812 From 2ec7c6c7ff704380fdfd8116378adf78734e4f2b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 02:09:26 +0000 Subject: [PATCH 18/56] fix(deps): update dependency org.slf4j:slf4j-api to v2.0.17 (#1348) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 36797998..29a37193 100644 --- a/pom.xml +++ b/pom.xml @@ -69,7 +69,7 @@ org.slf4j slf4j-api - 2.0.16 + 2.0.17 From 7df9565691731d164b534116b8a6b933b171d103 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 23:30:46 +0000 Subject: [PATCH 19/56] chore(deps): update github/codeql-action digest to 97aac9b (#1350) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 819a7abe..cbc5b0db 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,7 +29,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@8c69433c34fe91b0644d83e6f14bb77eb3e46812 + uses: github/codeql-action/init@97aac9bb5668e73a3626129e9abc4164b2de3a7a with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@8c69433c34fe91b0644d83e6f14bb77eb3e46812 + uses: github/codeql-action/analyze@97aac9bb5668e73a3626129e9abc4164b2de3a7a diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 4361546f..58f4adbc 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@8c69433c34fe91b0644d83e6f14bb77eb3e46812 + uses: github/codeql-action/init@97aac9bb5668e73a3626129e9abc4164b2de3a7a with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@8c69433c34fe91b0644d83e6f14bb77eb3e46812 + uses: github/codeql-action/autobuild@97aac9bb5668e73a3626129e9abc4164b2de3a7a - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@8c69433c34fe91b0644d83e6f14bb77eb3e46812 + uses: github/codeql-action/analyze@97aac9bb5668e73a3626129e9abc4164b2de3a7a From b133c2fa527a0dddb6de7f7781a00fc84feaa813 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Feb 2025 06:59:17 +0000 Subject: [PATCH 20/56] chore(deps): update codecov/codecov-action action to v5.4.0 (#1351) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/merge.yml | 2 +- .github/workflows/pullrequest.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index a76348f9..e8bfeac7 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -48,7 +48,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.3.1 + uses: codecov/codecov-action@v5.4.0 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index cbc5b0db..144abda8 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -46,7 +46,7 @@ jobs: - if: matrix.build.java == '17' name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.3.1 + uses: codecov/codecov-action@v5.4.0 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From 989f4ae54263b46ca2c81561acc70b39918c382d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Feb 2025 16:13:25 +0000 Subject: [PATCH 21/56] chore(deps): update github/codeql-action digest to 8392354 (#1352) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 144abda8..c605e05d 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,7 +29,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@97aac9bb5668e73a3626129e9abc4164b2de3a7a + uses: github/codeql-action/init@83923549f688e42b34d0b90ee94725f7c30532fc with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@97aac9bb5668e73a3626129e9abc4164b2de3a7a + uses: github/codeql-action/analyze@83923549f688e42b34d0b90ee94725f7c30532fc diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 58f4adbc..c3bb651d 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@97aac9bb5668e73a3626129e9abc4164b2de3a7a + uses: github/codeql-action/init@83923549f688e42b34d0b90ee94725f7c30532fc with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@97aac9bb5668e73a3626129e9abc4164b2de3a7a + uses: github/codeql-action/autobuild@83923549f688e42b34d0b90ee94725f7c30532fc - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@97aac9bb5668e73a3626129e9abc4164b2de3a7a + uses: github/codeql-action/analyze@83923549f688e42b34d0b90ee94725f7c30532fc From 59017977a487a36c8a39f63b83299bc657134c0d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Feb 2025 18:39:13 +0000 Subject: [PATCH 22/56] chore(deps): update actions/cache digest to d4323d4 (#1353) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/merge.yml | 2 +- .github/workflows/pullrequest.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index e8bfeac7..d17b2eae 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -31,7 +31,7 @@ jobs: server-password: ${{ secrets.OSSRH_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@7921ae235bdcb376cc8f22558dc5f8ddc3c3c2f9 + uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf with: path: ~/.m2/repository key: ${{ runner.os }}-17-maven-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index c605e05d..40a9431a 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -34,7 +34,7 @@ jobs: languages: java - name: Cache local Maven repository - uses: actions/cache@7921ae235bdcb376cc8f22558dc5f8ddc3c3c2f9 + uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf with: path: ~/.m2/repository key: ${{ runner.os }}${{ matrix.build.java }}-maven-${{ hashFiles('**/pom.xml') }} From 2a1adca8c2ed8d61d51530969290793a5d3d15f3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 17:40:45 +0000 Subject: [PATCH 23/56] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.17.2 (#1355) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 29a37193..5213c470 100644 --- a/pom.xml +++ b/pom.xml @@ -189,7 +189,7 @@ net.bytebuddy byte-buddy - 1.17.1 + 1.17.2 test From dd83114c4d9389753575392fafcd56585d7178ae Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 23:33:51 +0000 Subject: [PATCH 24/56] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.17.2 (#1356) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5213c470..d89ae290 100644 --- a/pom.xml +++ b/pom.xml @@ -196,7 +196,7 @@ net.bytebuddy byte-buddy-agent - 1.17.1 + 1.17.2 test From 31444d6c8f30f0dd35debacc9dab8da7397e11ed Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 02:12:10 +0000 Subject: [PATCH 25/56] chore(deps): update actions/setup-java digest to 799ee7c (#1359) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/merge.yml | 2 +- .github/workflows/pullrequest.yml | 2 +- .github/workflows/release.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index d17b2eae..f98c51af 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -21,7 +21,7 @@ jobs: steps: - uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 17 - uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 + uses: actions/setup-java@799ee7c97e9721ef38d1a7e8486c39753b9d6102 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 40a9431a..7555d95f 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -22,7 +22,7 @@ jobs: uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 8 - uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 + uses: actions/setup-java@799ee7c97e9721ef38d1a7e8486c39753b9d6102 with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3e491447..7f12331f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 17 if: ${{ steps.release.outputs.release_created }} - uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 + uses: actions/setup-java@799ee7c97e9721ef38d1a7e8486c39753b9d6102 with: java-version: '17' distribution: 'temurin' From 6c03e5d84aacee11f5b8e608a6114c11fced72b8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 06:25:17 +0000 Subject: [PATCH 26/56] chore(deps): update github/codeql-action digest to 80f9930 (#1357) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 7555d95f..dd1b97f2 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,7 +29,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@83923549f688e42b34d0b90ee94725f7c30532fc + uses: github/codeql-action/init@80f993039571a6de66594ecaa432875a6942e8e0 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@83923549f688e42b34d0b90ee94725f7c30532fc + uses: github/codeql-action/analyze@80f993039571a6de66594ecaa432875a6942e8e0 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index c3bb651d..7016c969 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@83923549f688e42b34d0b90ee94725f7c30532fc + uses: github/codeql-action/init@80f993039571a6de66594ecaa432875a6942e8e0 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@83923549f688e42b34d0b90ee94725f7c30532fc + uses: github/codeql-action/autobuild@80f993039571a6de66594ecaa432875a6942e8e0 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@83923549f688e42b34d0b90ee94725f7c30532fc + uses: github/codeql-action/analyze@80f993039571a6de66594ecaa432875a6942e8e0 From ecea9df932ee4874613f219b73640fe964c99593 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 10:30:29 +0000 Subject: [PATCH 27/56] chore(deps): update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.2.0 (#1360) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d89ae290..b7401c8b 100644 --- a/pom.xml +++ b/pom.xml @@ -413,7 +413,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.9.1.0 + 4.9.2.0 spotbugs-exclusions.xml From 30b6d004aaf3464547805f7eda6fad0e122de4f9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 15:10:03 +0000 Subject: [PATCH 28/56] chore(deps): update dependency org.mockito:mockito-core to v5.16.0 (#1358) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b7401c8b..8c95d14f 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ ${maven.compiler.source} 5.12.0 7.21.1 - 5.15.2 + 5.16.0 **/e2e/*.java ${project.groupId}.${project.artifactId} From 67b34f84a373512013ab2f7649faaddfd2d61048 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 5 Mar 2025 19:07:16 +0000 Subject: [PATCH 29/56] chore(deps): update github/codeql-action digest to 608ccd6 (#1361) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index dd1b97f2..9bc2309f 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,7 +29,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@80f993039571a6de66594ecaa432875a6942e8e0 + uses: github/codeql-action/init@608ccd6cd915d2c43d3059c3da518f36f07a56b0 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@80f993039571a6de66594ecaa432875a6942e8e0 + uses: github/codeql-action/analyze@608ccd6cd915d2c43d3059c3da518f36f07a56b0 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 7016c969..89d5cae4 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@80f993039571a6de66594ecaa432875a6942e8e0 + uses: github/codeql-action/init@608ccd6cd915d2c43d3059c3da518f36f07a56b0 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@80f993039571a6de66594ecaa432875a6942e8e0 + uses: github/codeql-action/autobuild@608ccd6cd915d2c43d3059c3da518f36f07a56b0 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@80f993039571a6de66594ecaa432875a6942e8e0 + uses: github/codeql-action/analyze@608ccd6cd915d2c43d3059c3da518f36f07a56b0 From 959e675e4c2363e5fd80d1d2f1edbfab11794fc8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 6 Mar 2025 19:34:13 +0000 Subject: [PATCH 30/56] chore(deps): update github/codeql-action digest to 56b25d5 (#1365) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 9bc2309f..433d057c 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,7 +29,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@608ccd6cd915d2c43d3059c3da518f36f07a56b0 + uses: github/codeql-action/init@56b25d5d5251df651f82070735778784aa383094 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@608ccd6cd915d2c43d3059c3da518f36f07a56b0 + uses: github/codeql-action/analyze@56b25d5d5251df651f82070735778784aa383094 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 89d5cae4..5bde3c9e 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@608ccd6cd915d2c43d3059c3da518f36f07a56b0 + uses: github/codeql-action/init@56b25d5d5251df651f82070735778784aa383094 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@608ccd6cd915d2c43d3059c3da518f36f07a56b0 + uses: github/codeql-action/autobuild@56b25d5d5251df651f82070735778784aa383094 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@608ccd6cd915d2c43d3059c3da518f36f07a56b0 + uses: github/codeql-action/analyze@56b25d5d5251df651f82070735778784aa383094 From c37d2497764889710ff9cde70cc456712088fe68 Mon Sep 17 00:00:00 2001 From: chrfwow Date: Fri, 7 Mar 2025 11:04:46 +0100 Subject: [PATCH 31/56] feat: implement gherkin tests for context merging (#1363) feat: implement gherkin tests for context merging (#1363) --- .../openfeature/sdk/ImmutableMetadata.java | 4 + .../dev/openfeature/sdk/FlagMetadataTest.java | 10 +- .../sdk/e2e/ContextStoringProvider.java | 48 ++++++++ .../java/dev/openfeature/sdk/e2e/State.java | 6 + .../sdk/e2e/steps/ContextSteps.java | 104 ++++++++++++++++++ .../sdk/e2e/steps/StepDefinitions.java | 22 +++- 6 files changed, 187 insertions(+), 7 deletions(-) create mode 100644 src/test/java/dev/openfeature/sdk/e2e/ContextStoringProvider.java create mode 100644 src/test/java/dev/openfeature/sdk/e2e/steps/ContextSteps.java diff --git a/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java b/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java index f8311a9a..7f57a174 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java @@ -101,6 +101,10 @@ public boolean isEmpty() { return metadata.isEmpty(); } + public boolean isNotEmpty() { + return !metadata.isEmpty(); + } + /** * Obtain a builder for {@link ImmutableMetadata}. */ diff --git a/src/test/java/dev/openfeature/sdk/FlagMetadataTest.java b/src/test/java/dev/openfeature/sdk/FlagMetadataTest.java index 26d0421c..22912661 100644 --- a/src/test/java/dev/openfeature/sdk/FlagMetadataTest.java +++ b/src/test/java/dev/openfeature/sdk/FlagMetadataTest.java @@ -64,23 +64,25 @@ void notfound_error_validation() { } @Test - @DisplayName("isEmpty returns true iff the metadata is empty") - void isEmpty_returns_true_if_metadata_is_empty() { + @DisplayName("isEmpty and isNotEmpty return correctly when the metadata is empty") + void isEmpty_isNotEmpty_return_correctly_when_metadata_is_empty() { // given ImmutableMetadata flagMetadata = ImmutableMetadata.builder().build(); // then assertTrue(flagMetadata.isEmpty()); + assertFalse(flagMetadata.isNotEmpty()); } @Test - @DisplayName("isEmpty returns false iff the metadata is not empty") - void isEmpty_returns_false_if_metadata_is_not_empty() { + @DisplayName("isEmpty and isNotEmpty return correctly when the metadata is not empty") + void isEmpty_isNotEmpty_return_correctly_when_metadata_is_not_empty() { // given ImmutableMetadata flagMetadata = ImmutableMetadata.builder().addString("a", "b").build(); // then assertFalse(flagMetadata.isEmpty()); + assertTrue(flagMetadata.isNotEmpty()); } } diff --git a/src/test/java/dev/openfeature/sdk/e2e/ContextStoringProvider.java b/src/test/java/dev/openfeature/sdk/e2e/ContextStoringProvider.java new file mode 100644 index 00000000..e06e862a --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/e2e/ContextStoringProvider.java @@ -0,0 +1,48 @@ +package dev.openfeature.sdk.e2e; + +import dev.openfeature.sdk.EvaluationContext; +import dev.openfeature.sdk.FeatureProvider; +import dev.openfeature.sdk.Metadata; +import dev.openfeature.sdk.ProviderEvaluation; +import dev.openfeature.sdk.Value; +import lombok.Getter; + +@Getter +public class ContextStoringProvider implements FeatureProvider { + private EvaluationContext evaluationContext; + + @Override + public Metadata getMetadata() { + return () -> getClass().getSimpleName(); + } + + @Override + public ProviderEvaluation getBooleanEvaluation(String key, Boolean defaultValue, EvaluationContext ctx) { + this.evaluationContext = ctx; + return null; + } + + @Override + public ProviderEvaluation getStringEvaluation(String key, String defaultValue, EvaluationContext ctx) { + this.evaluationContext = ctx; + return null; + } + + @Override + public ProviderEvaluation getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx) { + this.evaluationContext = ctx; + return null; + } + + @Override + public ProviderEvaluation getDoubleEvaluation(String key, Double defaultValue, EvaluationContext ctx) { + this.evaluationContext = ctx; + return null; + } + + @Override + public ProviderEvaluation getObjectEvaluation(String key, Value defaultValue, EvaluationContext ctx) { + this.evaluationContext = ctx; + return null; + } +} diff --git a/src/test/java/dev/openfeature/sdk/e2e/State.java b/src/test/java/dev/openfeature/sdk/e2e/State.java index ee513b00..68c708b4 100644 --- a/src/test/java/dev/openfeature/sdk/e2e/State.java +++ b/src/test/java/dev/openfeature/sdk/e2e/State.java @@ -1,8 +1,11 @@ package dev.openfeature.sdk.e2e; import dev.openfeature.sdk.Client; +import dev.openfeature.sdk.EvaluationContext; +import dev.openfeature.sdk.FeatureProvider; import dev.openfeature.sdk.FlagEvaluationDetails; import dev.openfeature.sdk.MutableContext; +import java.util.List; public class State { public Client client; @@ -10,4 +13,7 @@ public class State { public MutableContext context = new MutableContext(); public FlagEvaluationDetails evaluation; public MockHook hook; + public FeatureProvider provider; + public EvaluationContext invocationContext; + public List levels; } diff --git a/src/test/java/dev/openfeature/sdk/e2e/steps/ContextSteps.java b/src/test/java/dev/openfeature/sdk/e2e/steps/ContextSteps.java new file mode 100644 index 00000000..ccb78e72 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/e2e/steps/ContextSteps.java @@ -0,0 +1,104 @@ +package dev.openfeature.sdk.e2e.steps; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import dev.openfeature.sdk.EvaluationContext; +import dev.openfeature.sdk.Hook; +import dev.openfeature.sdk.HookContext; +import dev.openfeature.sdk.ImmutableContext; +import dev.openfeature.sdk.OpenFeatureAPI; +import dev.openfeature.sdk.ThreadLocalTransactionContextPropagator; +import dev.openfeature.sdk.Value; +import dev.openfeature.sdk.e2e.ContextStoringProvider; +import dev.openfeature.sdk.e2e.State; +import io.cucumber.datatable.DataTable; +import io.cucumber.java.en.And; +import io.cucumber.java.en.Given; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +public class ContextSteps { + private final State state; + + public ContextSteps(State state) { + this.state = state; + } + + @Given("a stable provider with retrievable context is registered") + public void setup() { + ContextStoringProvider provider = new ContextStoringProvider(); + state.provider = provider; + OpenFeatureAPI.getInstance().setProviderAndWait(provider); + state.client = OpenFeatureAPI.getInstance().getClient(); + OpenFeatureAPI.getInstance().setTransactionContextPropagator(new ThreadLocalTransactionContextPropagator()); + } + + @When("A context entry with key {string} and value {string} is added to the {string} level") + public void aContextWithKeyAndValueIsAddedToTheLevel(String contextKey, String contextValue, String level) { + addContextEntry(contextKey, contextValue, level); + } + + private void addContextEntry(String contextKey, String contextValue, String level) { + Map data = new HashMap<>(); + data.put(contextKey, new Value(contextValue)); + EvaluationContext context = new ImmutableContext(data); + if ("API".equals(level)) { + OpenFeatureAPI.getInstance().setEvaluationContext(context); + } else if ("Transaction".equals(level)) { + OpenFeatureAPI.getInstance().setTransactionContext(context); + } else if ("Client".equals(level)) { + state.client.setEvaluationContext(context); + } else if ("Invocation".equals(level)) { + state.invocationContext = context; + } else if ("Before Hooks".equals(level)) { + state.client.addHooks(new Hook() { + @Override + public Optional before(HookContext ctx, Map hints) { + return Optional.of(context); + } + }); + } else { + throw new IllegalArgumentException("Unknown level: " + level); + } + } + + @When("Some flag was evaluated") + public void someFlagWasEvaluated() { + state.evaluation = state.client.getStringDetails("unused", "unused", state.invocationContext); + } + + @Then("The merged context contains an entry with key {string} and value {string}") + public void theMergedContextContainsAnEntryWithKeyAndValue(String contextKey, String contextValue) { + assertInstanceOf( + ContextStoringProvider.class, + state.provider, + "In order to use this step, you need to set a ContextStoringProvider"); + EvaluationContext ctx = ((ContextStoringProvider) state.provider).getEvaluationContext(); + assertNotNull(ctx); + assertNotNull(ctx.getValue(contextKey)); + assertNotNull(ctx.getValue(contextKey).asString()); + assertEquals(contextValue, ctx.getValue(contextKey).asString()); + } + + @Given("A table with levels of increasing precedence") + public void aTableWithLevelsOfIncreasingPrecedence(DataTable levelsTable) { + state.levels = levelsTable.asList(); + } + + @And( + "Context entries for each level from API level down to the {string} level, with key {string} and value {string}") + public void contextEntriesForEachLevelFromAPILevelDownToTheLevelWithKeyAndValue( + String maxLevel, String key, String value) { + for (String level : state.levels) { + addContextEntry(key, value, level); + if (level.equals(maxLevel)) { + return; + } + } + } +} diff --git a/src/test/java/dev/openfeature/sdk/e2e/steps/StepDefinitions.java b/src/test/java/dev/openfeature/sdk/e2e/steps/StepDefinitions.java index 6897e273..924c9d59 100644 --- a/src/test/java/dev/openfeature/sdk/e2e/steps/StepDefinitions.java +++ b/src/test/java/dev/openfeature/sdk/e2e/steps/StepDefinitions.java @@ -2,7 +2,6 @@ import static dev.openfeature.sdk.testutils.TestFlagsUtils.buildFlags; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; import dev.openfeature.sdk.Client; import dev.openfeature.sdk.EvaluationContext; @@ -289,7 +288,7 @@ public void then_the_default_string_value_should_be_returned() { @Then("the reason should indicate an error and the error code should indicate a missing flag with {string}") public void the_reason_should_indicate_an_error_and_the_error_code_should_be_flag_not_found(String errorCode) { assertEquals(Reason.ERROR.toString(), notFoundDetails.getReason()); - assertTrue(notFoundDetails.getErrorCode().name().equals(errorCode)); + assertEquals(errorCode, notFoundDetails.getErrorCode().name()); } // type mismatch @@ -309,6 +308,23 @@ public void then_the_default_integer_value_should_be_returned() { @Then("the reason should indicate an error and the error code should indicate a type mismatch with {string}") public void the_reason_should_indicate_an_error_and_the_error_code_should_be_type_mismatch(String errorCode) { assertEquals(Reason.ERROR.toString(), typeErrorDetails.getReason()); - assertTrue(typeErrorDetails.getErrorCode().name().equals(errorCode)); + assertEquals(errorCode, typeErrorDetails.getErrorCode().name()); + } + + @SuppressWarnings("java:S2925") + @When("sleep for {int} milliseconds") + public void sleepForMilliseconds(int millis) { + long startTime = System.currentTimeMillis(); + long endTime = startTime + millis; + long now; + while ((now = System.currentTimeMillis()) < endTime) { + long remainingTime = endTime - now; + try { + //noinspection BusyWait + Thread.sleep(remainingTime); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } } } From d00e4b5b24621aa55085827fbe6ea982491376de Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 7 Mar 2025 22:43:13 +0000 Subject: [PATCH 32/56] chore(deps): update github/codeql-action digest to b2e6519 (#1366) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 433d057c..4547a278 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,7 +29,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@56b25d5d5251df651f82070735778784aa383094 + uses: github/codeql-action/init@b2e6519679e446e7bb7c3466d70f13a6b5461fcd with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@56b25d5d5251df651f82070735778784aa383094 + uses: github/codeql-action/analyze@b2e6519679e446e7bb7c3466d70f13a6b5461fcd diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 5bde3c9e..b1379a3e 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@56b25d5d5251df651f82070735778784aa383094 + uses: github/codeql-action/init@b2e6519679e446e7bb7c3466d70f13a6b5461fcd with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@56b25d5d5251df651f82070735778784aa383094 + uses: github/codeql-action/autobuild@b2e6519679e446e7bb7c3466d70f13a6b5461fcd - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@56b25d5d5251df651f82070735778784aa383094 + uses: github/codeql-action/analyze@b2e6519679e446e7bb7c3466d70f13a6b5461fcd From c550d597227bfc1e0e17357139f1fd8a87593be0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 22:21:34 +0000 Subject: [PATCH 33/56] chore(deps): update github/codeql-action digest to b46b37a (#1367) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 4547a278..4629ea47 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,7 +29,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@b2e6519679e446e7bb7c3466d70f13a6b5461fcd + uses: github/codeql-action/init@b46b37a8a348d1768fde58498025680784561136 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b2e6519679e446e7bb7c3466d70f13a6b5461fcd + uses: github/codeql-action/analyze@b46b37a8a348d1768fde58498025680784561136 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index b1379a3e..1a937206 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@b2e6519679e446e7bb7c3466d70f13a6b5461fcd + uses: github/codeql-action/init@b46b37a8a348d1768fde58498025680784561136 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@b2e6519679e446e7bb7c3466d70f13a6b5461fcd + uses: github/codeql-action/autobuild@b46b37a8a348d1768fde58498025680784561136 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b2e6519679e446e7bb7c3466d70f13a6b5461fcd + uses: github/codeql-action/analyze@b46b37a8a348d1768fde58498025680784561136 From d54c68a8e9e4a0f67c99e7d76621a1c5724e4cd1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Mar 2025 23:00:23 +0000 Subject: [PATCH 34/56] chore(deps): update github/codeql-action digest to 7254660 (#1368) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 4629ea47..8cb6af5f 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,7 +29,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@b46b37a8a348d1768fde58498025680784561136 + uses: github/codeql-action/init@7254660adc34cef611559b5423694b5266923899 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b46b37a8a348d1768fde58498025680784561136 + uses: github/codeql-action/analyze@7254660adc34cef611559b5423694b5266923899 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 1a937206..4e749aa4 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@b46b37a8a348d1768fde58498025680784561136 + uses: github/codeql-action/init@7254660adc34cef611559b5423694b5266923899 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@b46b37a8a348d1768fde58498025680784561136 + uses: github/codeql-action/autobuild@7254660adc34cef611559b5423694b5266923899 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b46b37a8a348d1768fde58498025680784561136 + uses: github/codeql-action/analyze@7254660adc34cef611559b5423694b5266923899 From f8df5fb84a765af917587dd509f9cec38103f787 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Mar 2025 03:22:53 +0000 Subject: [PATCH 35/56] chore(deps): update github/codeql-action digest to dc49dca (#1369) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 8cb6af5f..b6165dd3 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,7 +29,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@7254660adc34cef611559b5423694b5266923899 + uses: github/codeql-action/init@dc49dcabdb86371d19197fcae2585f548bbbc395 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7254660adc34cef611559b5423694b5266923899 + uses: github/codeql-action/analyze@dc49dcabdb86371d19197fcae2585f548bbbc395 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 4e749aa4..efffa1fb 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@7254660adc34cef611559b5423694b5266923899 + uses: github/codeql-action/init@dc49dcabdb86371d19197fcae2585f548bbbc395 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@7254660adc34cef611559b5423694b5266923899 + uses: github/codeql-action/autobuild@dc49dcabdb86371d19197fcae2585f548bbbc395 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7254660adc34cef611559b5423694b5266923899 + uses: github/codeql-action/analyze@dc49dcabdb86371d19197fcae2585f548bbbc395 From 69b571eda73b6f43c99864420b8663ae54ebf0ad Mon Sep 17 00:00:00 2001 From: chrfwow Date: Thu, 13 Mar 2025 08:33:21 +0100 Subject: [PATCH 36/56] fix: equals and hashcode of several classes (#1364) fix: equals and hashcode of several classes --- .../openfeature/sdk/AbstractStructure.java | 4 +- .../dev/openfeature/sdk/EventDetails.java | 2 + .../dev/openfeature/sdk/ImmutableContext.java | 2 + .../openfeature/sdk/ImmutableStructure.java | 18 ++--- .../dev/openfeature/sdk/MutableStructure.java | 2 +- .../openfeature/sdk/ImmutableContextTest.java | 28 ++++++++ .../sdk/ImmutableMetadataTest.java | 28 ++++++++ .../sdk/ImmutableStructureTest.java | 45 ++++++++++++- .../openfeature/sdk/MutableContextTest.java | 28 ++++++++ .../openfeature/sdk/MutableStructureTest.java | 67 +++++++++++++++++++ .../java/dev/openfeature/sdk/ValueTest.java | 45 ++++++++----- 11 files changed, 243 insertions(+), 26 deletions(-) create mode 100644 src/test/java/dev/openfeature/sdk/ImmutableMetadataTest.java create mode 100644 src/test/java/dev/openfeature/sdk/MutableStructureTest.java diff --git a/src/main/java/dev/openfeature/sdk/AbstractStructure.java b/src/main/java/dev/openfeature/sdk/AbstractStructure.java index 6c652114..7962705c 100644 --- a/src/main/java/dev/openfeature/sdk/AbstractStructure.java +++ b/src/main/java/dev/openfeature/sdk/AbstractStructure.java @@ -3,15 +3,17 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import lombok.EqualsAndHashCode; @SuppressWarnings({"PMD.BeanMembersShouldSerialize", "checkstyle:MissingJavadocType"}) +@EqualsAndHashCode abstract class AbstractStructure implements Structure { protected final Map attributes; @Override public boolean isEmpty() { - return attributes == null || attributes.size() == 0; + return attributes == null || attributes.isEmpty(); } AbstractStructure() { diff --git a/src/main/java/dev/openfeature/sdk/EventDetails.java b/src/main/java/dev/openfeature/sdk/EventDetails.java index e32e6101..c75b046e 100644 --- a/src/main/java/dev/openfeature/sdk/EventDetails.java +++ b/src/main/java/dev/openfeature/sdk/EventDetails.java @@ -1,11 +1,13 @@ package dev.openfeature.sdk; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.experimental.SuperBuilder; /** * The details of a particular event. */ +@EqualsAndHashCode(callSuper = true) @Data @SuperBuilder(toBuilder = true) public class EventDetails extends ProviderEventDetails { diff --git a/src/main/java/dev/openfeature/sdk/ImmutableContext.java b/src/main/java/dev/openfeature/sdk/ImmutableContext.java index 23a452e0..8560c369 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableContext.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableContext.java @@ -4,6 +4,7 @@ import java.util.HashMap; import java.util.Map; import java.util.function.Function; +import lombok.EqualsAndHashCode; import lombok.ToString; import lombok.experimental.Delegate; @@ -15,6 +16,7 @@ * not be modified after instantiation. */ @ToString +@EqualsAndHashCode @SuppressWarnings("PMD.BeanMembersShouldSerialize") public final class ImmutableContext implements EvaluationContext { diff --git a/src/main/java/dev/openfeature/sdk/ImmutableStructure.java b/src/main/java/dev/openfeature/sdk/ImmutableStructure.java index c47a49eb..84935942 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableStructure.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableStructure.java @@ -18,7 +18,7 @@ * not be modified after instantiation. All references are clones. */ @ToString -@EqualsAndHashCode +@EqualsAndHashCode(callSuper = true) @SuppressWarnings({"PMD.BeanMembersShouldSerialize", "checkstyle:MissingJavadocType"}) public final class ImmutableStructure extends AbstractStructure { @@ -38,7 +38,7 @@ public ImmutableStructure(Map attributes) { super(copyAttributes(attributes, null)); } - protected ImmutableStructure(String targetingKey, Map attributes) { + ImmutableStructure(String targetingKey, Map attributes) { super(copyAttributes(attributes, targetingKey)); } @@ -70,12 +70,14 @@ private static Map copyAttributes(Map in) { private static Map copyAttributes(Map in, String targetingKey) { Map copy = new HashMap<>(); - for (Entry entry : in.entrySet()) { - copy.put( - entry.getKey(), - Optional.ofNullable(entry.getValue()) - .map((Value val) -> val.clone()) - .orElse(null)); + if (in != null) { + for (Entry entry : in.entrySet()) { + copy.put( + entry.getKey(), + Optional.ofNullable(entry.getValue()) + .map((Value val) -> val.clone()) + .orElse(null)); + } } if (targetingKey != null) { copy.put(EvaluationContext.TARGETING_KEY, new Value(targetingKey)); diff --git a/src/main/java/dev/openfeature/sdk/MutableStructure.java b/src/main/java/dev/openfeature/sdk/MutableStructure.java index a06e2f2d..f3158456 100644 --- a/src/main/java/dev/openfeature/sdk/MutableStructure.java +++ b/src/main/java/dev/openfeature/sdk/MutableStructure.java @@ -15,8 +15,8 @@ * be modified after instantiation. */ @ToString -@EqualsAndHashCode @SuppressWarnings({"PMD.BeanMembersShouldSerialize", "checkstyle:MissingJavadocType"}) +@EqualsAndHashCode(callSuper = true) public class MutableStructure extends AbstractStructure { public MutableStructure() { diff --git a/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java b/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java index e69a974b..2b39be74 100644 --- a/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java +++ b/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java @@ -3,6 +3,7 @@ import static dev.openfeature.sdk.EvaluationContext.TARGETING_KEY; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Collections; @@ -133,4 +134,31 @@ void mergeShouldRetainItsSubkeysWhenOverridingContextHasNoTargetingKey() { Structure value = key1.asStructure(); assertArrayEquals(new Object[] {"key1_1"}, value.keySet().toArray()); } + + @DisplayName("Two different MutableContext objects with the different contents are not considered equal") + @Test + void unequalImmutableContextsAreNotEqual() { + final Map attributes = new HashMap<>(); + attributes.put("key1", new Value("val1")); + final ImmutableContext ctx = new ImmutableContext(attributes); + + final Map attributes2 = new HashMap<>(); + final ImmutableContext ctx2 = new ImmutableContext(attributes2); + + assertNotEquals(ctx, ctx2); + } + + @DisplayName("Two different MutableContext objects with the same content are considered equal") + @Test + void equalImmutableContextsAreEqual() { + final Map attributes = new HashMap<>(); + attributes.put("key1", new Value("val1")); + final ImmutableContext ctx = new ImmutableContext(attributes); + + final Map attributes2 = new HashMap<>(); + attributes2.put("key1", new Value("val1")); + final ImmutableContext ctx2 = new ImmutableContext(attributes2); + + assertEquals(ctx, ctx2); + } } diff --git a/src/test/java/dev/openfeature/sdk/ImmutableMetadataTest.java b/src/test/java/dev/openfeature/sdk/ImmutableMetadataTest.java new file mode 100644 index 00000000..e3bd0316 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/ImmutableMetadataTest.java @@ -0,0 +1,28 @@ +package dev.openfeature.sdk; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import org.junit.jupiter.api.Test; + +class ImmutableMetadataTest { + @Test + void unequalImmutableMetadataAreUnequal() { + ImmutableMetadata i1 = + ImmutableMetadata.builder().addString("key1", "value1").build(); + ImmutableMetadata i2 = + ImmutableMetadata.builder().addString("key1", "value2").build(); + + assertNotEquals(i1, i2); + } + + @Test + void equalImmutableMetadataAreEqual() { + ImmutableMetadata i1 = + ImmutableMetadata.builder().addString("key1", "value1").build(); + ImmutableMetadata i2 = + ImmutableMetadata.builder().addString("key1", "value1").build(); + + assertEquals(i1, i2); + } +} diff --git a/src/test/java/dev/openfeature/sdk/ImmutableStructureTest.java b/src/test/java/dev/openfeature/sdk/ImmutableStructureTest.java index dff95adc..6a0eed59 100644 --- a/src/test/java/dev/openfeature/sdk/ImmutableStructureTest.java +++ b/src/test/java/dev/openfeature/sdk/ImmutableStructureTest.java @@ -1,6 +1,11 @@ package dev.openfeature.sdk; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.time.Instant; import java.time.temporal.ChronoUnit; @@ -154,4 +159,42 @@ void constructorHandlesNullValue() { attrs.put("null", null); new ImmutableStructure(attrs); } + + @Test + void unequalImmutableStructuresAreNotEqual() { + Map attrs1 = new HashMap<>(); + attrs1.put("test", new Value(45)); + ImmutableStructure structure1 = new ImmutableStructure(attrs1); + + Map attrs2 = new HashMap<>(); + attrs2.put("test", new Value(2)); + ImmutableStructure structure2 = new ImmutableStructure(attrs2); + + assertNotEquals(structure1, structure2); + } + + @Test + void equalImmutableStructuresAreEqual() { + Map attrs1 = new HashMap<>(); + attrs1.put("test", new Value(45)); + ImmutableStructure structure1 = new ImmutableStructure(attrs1); + + Map attrs2 = new HashMap<>(); + attrs2.put("test", new Value(45)); + ImmutableStructure structure2 = new ImmutableStructure(attrs2); + + assertEquals(structure1, structure2); + } + + @Test + void emptyImmutableStructureIsEmpty() { + ImmutableStructure m1 = new ImmutableStructure(); + assertTrue(m1.isEmpty()); + } + + @Test + void immutableStructureWithNullAttributesIsEmpty() { + ImmutableStructure m1 = new ImmutableStructure(null); + assertTrue(m1.isEmpty()); + } } diff --git a/src/test/java/dev/openfeature/sdk/MutableContextTest.java b/src/test/java/dev/openfeature/sdk/MutableContextTest.java index 953e3f63..6c471d09 100644 --- a/src/test/java/dev/openfeature/sdk/MutableContextTest.java +++ b/src/test/java/dev/openfeature/sdk/MutableContextTest.java @@ -3,6 +3,7 @@ import static dev.openfeature.sdk.EvaluationContext.TARGETING_KEY; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Collections; @@ -137,4 +138,31 @@ void shouldAllowChainingOfMutations() { assertEquals(2, context.getValue("key2").asInteger()); assertEquals(3.0, context.getValue("key3").asDouble()); } + + @DisplayName("Two different MutableContext objects with the different contents are not considered equal") + @Test + void unequalMutableContextsAreNotEqual() { + final Map attributes = new HashMap<>(); + attributes.put("key1", new Value("val1")); + final MutableContext ctx = new MutableContext(attributes); + + final Map attributes2 = new HashMap<>(); + final MutableContext ctx2 = new MutableContext(attributes2); + + assertNotEquals(ctx, ctx2); + } + + @DisplayName("Two different MutableContext objects with the same content are considered equal") + @Test + void equalMutableContextsAreEqual() { + final Map attributes = new HashMap<>(); + attributes.put("key1", new Value("val1")); + final MutableContext ctx = new MutableContext(attributes); + + final Map attributes2 = new HashMap<>(); + attributes2.put("key1", new Value("val1")); + final MutableContext ctx2 = new MutableContext(attributes2); + + assertEquals(ctx, ctx2); + } } diff --git a/src/test/java/dev/openfeature/sdk/MutableStructureTest.java b/src/test/java/dev/openfeature/sdk/MutableStructureTest.java new file mode 100644 index 00000000..ebd11af0 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/MutableStructureTest.java @@ -0,0 +1,67 @@ +package dev.openfeature.sdk; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import org.junit.jupiter.api.Test; + +class MutableStructureTest { + + @Test + void emptyMutableStructureIsEmpty() { + MutableStructure m1 = new MutableStructure(); + assertTrue(m1.isEmpty()); + } + + @Test + void mutableStructureWithNullBackingStructureIsEmpty() { + MutableStructure m1 = new MutableStructure(null); + assertTrue(m1.isEmpty()); + } + + @Test + void unequalMutableStructuresAreNotEqual() { + MutableStructure m1 = new MutableStructure(); + m1.add("key1", "val1"); + MutableStructure m2 = new MutableStructure(); + m2.add("key2", "val2"); + assertNotEquals(m1, m2); + } + + @Test + void equalMutableStructuresAreEqual() { + MutableStructure m1 = new MutableStructure(); + m1.add("key1", "val1"); + MutableStructure m2 = new MutableStructure(); + m2.add("key1", "val1"); + assertEquals(m1, m2); + } + + @Test + void equalAbstractStructuresOfDifferentTypesAreNotEqual() { + MutableStructure m1 = new MutableStructure(); + m1.add("key1", "val1"); + HashMap map = new HashMap<>(); + map.put("key1", new Value("val1")); + AbstractStructure m2 = new AbstractStructure(map) { + @Override + public Set keySet() { + return attributes.keySet(); + } + + @Override + public Value getValue(String key) { + return attributes.get(key); + } + + @Override + public Map asMap() { + return attributes; + } + }; + + assertNotEquals(m1, m2); + } +} diff --git a/src/test/java/dev/openfeature/sdk/ValueTest.java b/src/test/java/dev/openfeature/sdk/ValueTest.java index c2553850..697edb7b 100644 --- a/src/test/java/dev/openfeature/sdk/ValueTest.java +++ b/src/test/java/dev/openfeature/sdk/ValueTest.java @@ -2,6 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -11,15 +12,15 @@ import java.util.List; import org.junit.jupiter.api.Test; -public class ValueTest { +class ValueTest { @Test - public void noArgShouldContainNull() { + void noArgShouldContainNull() { Value value = new Value(); assertTrue(value.isNull()); } @Test - public void objectArgShouldContainObject() { + void objectArgShouldContainObject() { try { // int is a special case, see intObjectArgShouldConvertToInt() List list = new ArrayList<>(); @@ -42,7 +43,7 @@ public void objectArgShouldContainObject() { } @Test - public void intObjectArgShouldConvertToInt() { + void intObjectArgShouldConvertToInt() { try { Object innerValue = 1; Value value = new Value(innerValue); @@ -53,7 +54,7 @@ public void intObjectArgShouldConvertToInt() { } @Test - public void invalidObjectArgShouldThrow() { + void invalidObjectArgShouldThrow() { class Something {} @@ -63,7 +64,7 @@ class Something {} } @Test - public void boolArgShouldContainBool() { + void boolArgShouldContainBool() { boolean innerValue = true; Value value = new Value(innerValue); assertTrue(value.isBoolean()); @@ -71,7 +72,7 @@ public void boolArgShouldContainBool() { } @Test - public void numericArgShouldReturnDoubleOrInt() { + void numericArgShouldReturnDoubleOrInt() { double innerDoubleValue = 1.75; Value doubleValue = new Value(innerDoubleValue); assertTrue(doubleValue.isNumber()); @@ -86,7 +87,7 @@ public void numericArgShouldReturnDoubleOrInt() { } @Test - public void stringArgShouldContainString() { + void stringArgShouldContainString() { String innerValue = "hi!"; Value value = new Value(innerValue); assertTrue(value.isString()); @@ -94,7 +95,7 @@ public void stringArgShouldContainString() { } @Test - public void dateShouldContainDate() { + void dateShouldContainDate() { Instant innerValue = Instant.now(); Value value = new Value(innerValue); assertTrue(value.isInstant()); @@ -102,7 +103,7 @@ public void dateShouldContainDate() { } @Test - public void structureShouldContainStructure() { + void structureShouldContainStructure() { String INNER_KEY = "key"; String INNER_VALUE = "val"; MutableStructure innerValue = new MutableStructure().add(INNER_KEY, INNER_VALUE); @@ -112,7 +113,7 @@ public void structureShouldContainStructure() { } @Test - public void listArgShouldContainList() { + void listArgShouldContainList() { String ITEM_VALUE = "val"; List innerValue = new ArrayList(); innerValue.add(new Value(ITEM_VALUE)); @@ -122,7 +123,7 @@ public void listArgShouldContainList() { } @Test - public void listMustBeOfValues() { + void listMustBeOfValues() { String item = "item"; List list = new ArrayList<>(); list.add(item); @@ -135,7 +136,7 @@ public void listMustBeOfValues() { } @Test - public void emptyListAllowed() { + void emptyListAllowed() { List list = new ArrayList<>(); try { Value value = new Value((Object) list); @@ -148,7 +149,7 @@ public void emptyListAllowed() { } @Test - public void valueConstructorValidateListInternals() { + void valueConstructorValidateListInternals() { List list = new ArrayList<>(); list.add(new Value("item")); list.add("item"); @@ -157,8 +158,22 @@ public void valueConstructorValidateListInternals() { } @Test - public void noOpFinalize() { + void noOpFinalize() { Value val = new Value(); assertDoesNotThrow(val::finalize); // does nothing, but we want to defined in and make it final. } + + @Test + void equalValuesShouldBeEqual() { + Value val1 = new Value(12312312); + Value val2 = new Value(12312312); + assertEquals(val1, val2); + } + + @Test + void unequalValuesShouldNotBeEqual() { + Value val1 = new Value("a"); + Value val2 = new Value("b"); + assertNotEquals(val1, val2); + } } From d233480912f1d5e095f5034f36a838535d1ecdff Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 01:29:33 +0000 Subject: [PATCH 37/56] chore(deps): update github/codeql-action digest to 70df9de (#1372) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index b6165dd3..a34dfc22 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,7 +29,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@dc49dcabdb86371d19197fcae2585f548bbbc395 + uses: github/codeql-action/init@70df9def86d22bf0ea4e7f8b956e7b92e7c1ea22 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@dc49dcabdb86371d19197fcae2585f548bbbc395 + uses: github/codeql-action/analyze@70df9def86d22bf0ea4e7f8b956e7b92e7c1ea22 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index efffa1fb..5bf01677 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@dc49dcabdb86371d19197fcae2585f548bbbc395 + uses: github/codeql-action/init@70df9def86d22bf0ea4e7f8b956e7b92e7c1ea22 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@dc49dcabdb86371d19197fcae2585f548bbbc395 + uses: github/codeql-action/autobuild@70df9def86d22bf0ea4e7f8b956e7b92e7c1ea22 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@dc49dcabdb86371d19197fcae2585f548bbbc395 + uses: github/codeql-action/analyze@70df9def86d22bf0ea4e7f8b956e7b92e7c1ea22 From 6b65e26c7439895652c3f64f2b4a7307a7ca582e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 06:28:22 +0000 Subject: [PATCH 38/56] fix(deps): update junit5 monorepo (#1373) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 8c95d14f..9572b3c7 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ UTF-8 1.8 ${maven.compiler.source} - 5.12.0 + 5.12.1 7.21.1 5.16.0 @@ -125,7 +125,7 @@ org.junit.platform junit-platform-suite - 1.12.0 + 1.12.1 test @@ -212,7 +212,7 @@ org.junit junit-bom - 5.12.0 + 5.12.1 pom import From de3e213ac8b8931121904a3d12929405512e74dd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 16 Mar 2025 02:24:15 +0000 Subject: [PATCH 39/56] chore(deps): update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.3.0 (#1375) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9572b3c7..c2205ec1 100644 --- a/pom.xml +++ b/pom.xml @@ -413,7 +413,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.9.2.0 + 4.9.3.0 spotbugs-exclusions.xml From 9750f75d04beb8339fc2e972f0ee97120eaff354 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 16 Mar 2025 05:21:02 +0000 Subject: [PATCH 40/56] chore(deps): update dependency org.mockito:mockito-core to v5.16.1 (#1376) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c2205ec1..a5c57d53 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ ${maven.compiler.source} 5.12.1 7.21.1 - 5.16.0 + 5.16.1 **/e2e/*.java ${project.groupId}.${project.artifactId} From 706565581d78856dd73605b1a16b131f974c0731 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Mar 2025 02:01:21 +0000 Subject: [PATCH 41/56] chore(deps): update github/codeql-action digest to 6a151cd (#1377) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index a34dfc22..139ec099 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,7 +29,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@70df9def86d22bf0ea4e7f8b956e7b92e7c1ea22 + uses: github/codeql-action/init@6a151cd77488e58567da1dcf953e7aeeaca4950c with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@70df9def86d22bf0ea4e7f8b956e7b92e7c1ea22 + uses: github/codeql-action/analyze@6a151cd77488e58567da1dcf953e7aeeaca4950c diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 5bf01677..1d52b734 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@70df9def86d22bf0ea4e7f8b956e7b92e7c1ea22 + uses: github/codeql-action/init@6a151cd77488e58567da1dcf953e7aeeaca4950c with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@70df9def86d22bf0ea4e7f8b956e7b92e7c1ea22 + uses: github/codeql-action/autobuild@6a151cd77488e58567da1dcf953e7aeeaca4950c - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@70df9def86d22bf0ea4e7f8b956e7b92e7c1ea22 + uses: github/codeql-action/analyze@6a151cd77488e58567da1dcf953e7aeeaca4950c From dbf92df33bf5657d50dc3b2f129207b0097c1f27 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Mar 2025 18:41:01 +0000 Subject: [PATCH 42/56] chore(deps): update github/codeql-action digest to 6349095 (#1378) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 139ec099..9a0b3f77 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,7 +29,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@6a151cd77488e58567da1dcf953e7aeeaca4950c + uses: github/codeql-action/init@6349095d19ec30397ffb02a63b7aa4f867deb563 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6a151cd77488e58567da1dcf953e7aeeaca4950c + uses: github/codeql-action/analyze@6349095d19ec30397ffb02a63b7aa4f867deb563 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 1d52b734..afffc816 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@6a151cd77488e58567da1dcf953e7aeeaca4950c + uses: github/codeql-action/init@6349095d19ec30397ffb02a63b7aa4f867deb563 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@6a151cd77488e58567da1dcf953e7aeeaca4950c + uses: github/codeql-action/autobuild@6349095d19ec30397ffb02a63b7aa4f867deb563 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6a151cd77488e58567da1dcf953e7aeeaca4950c + uses: github/codeql-action/analyze@6349095d19ec30397ffb02a63b7aa4f867deb563 From 8359ef13bb935ac1d144787cfd7181814a0b286c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 19 Mar 2025 21:41:15 +0000 Subject: [PATCH 43/56] chore(deps): update actions/cache digest to 5a3ec84 (#1380) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/merge.yml | 2 +- .github/workflows/pullrequest.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index f98c51af..bd4ffe80 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -31,7 +31,7 @@ jobs: server-password: ${{ secrets.OSSRH_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf + uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 with: path: ~/.m2/repository key: ${{ runner.os }}-17-maven-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 9a0b3f77..1a1f2af7 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -34,7 +34,7 @@ jobs: languages: java - name: Cache local Maven repository - uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf + uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 with: path: ~/.m2/repository key: ${{ runner.os }}${{ matrix.build.java }}-maven-${{ hashFiles('**/pom.xml') }} From 2239f054b90734dde6cdd4a23daec1c1daa96f07 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 20 Mar 2025 01:33:47 +0000 Subject: [PATCH 44/56] chore(deps): update actions/setup-java digest to b8ebb8b (#1381) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/merge.yml | 2 +- .github/workflows/pullrequest.yml | 2 +- .github/workflows/release.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index bd4ffe80..091f14b4 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -21,7 +21,7 @@ jobs: steps: - uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 17 - uses: actions/setup-java@799ee7c97e9721ef38d1a7e8486c39753b9d6102 + uses: actions/setup-java@b8ebb8ba1d9655f7f159c0a8b8135606ae11b5c9 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 1a1f2af7..1e1424be 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -22,7 +22,7 @@ jobs: uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 8 - uses: actions/setup-java@799ee7c97e9721ef38d1a7e8486c39753b9d6102 + uses: actions/setup-java@b8ebb8ba1d9655f7f159c0a8b8135606ae11b5c9 with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7f12331f..a3b669e7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 17 if: ${{ steps.release.outputs.release_created }} - uses: actions/setup-java@799ee7c97e9721ef38d1a7e8486c39753b9d6102 + uses: actions/setup-java@b8ebb8ba1d9655f7f159c0a8b8135606ae11b5c9 with: java-version: '17' distribution: 'temurin' From d61c33e466336c7120b870ca5e3843eba5f7175c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 20 Mar 2025 07:07:31 +0000 Subject: [PATCH 45/56] chore(deps): update github/codeql-action digest to c50c157 (#1379) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 1e1424be..9ca39ef1 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,7 +29,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@6349095d19ec30397ffb02a63b7aa4f867deb563 + uses: github/codeql-action/init@c50c157cc388ea631f085f4e95e948f51cdc742a with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6349095d19ec30397ffb02a63b7aa4f867deb563 + uses: github/codeql-action/analyze@c50c157cc388ea631f085f4e95e948f51cdc742a diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index afffc816..bba3e4b5 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@6349095d19ec30397ffb02a63b7aa4f867deb563 + uses: github/codeql-action/init@c50c157cc388ea631f085f4e95e948f51cdc742a with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@6349095d19ec30397ffb02a63b7aa4f867deb563 + uses: github/codeql-action/autobuild@c50c157cc388ea631f085f4e95e948f51cdc742a - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6349095d19ec30397ffb02a63b7aa4f867deb563 + uses: github/codeql-action/analyze@c50c157cc388ea631f085f4e95e948f51cdc742a From 922e17e677e15690e3df2fe93a961f16f21ff283 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 21 Mar 2025 22:54:41 +0000 Subject: [PATCH 46/56] chore(deps): update github/codeql-action digest to bd1d9ab (#1383) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 9ca39ef1..8554c833 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,7 +29,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@c50c157cc388ea631f085f4e95e948f51cdc742a + uses: github/codeql-action/init@bd1d9ab4eda903e1b5caa241368836575c6c476b with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c50c157cc388ea631f085f4e95e948f51cdc742a + uses: github/codeql-action/analyze@bd1d9ab4eda903e1b5caa241368836575c6c476b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index bba3e4b5..520afd09 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@c50c157cc388ea631f085f4e95e948f51cdc742a + uses: github/codeql-action/init@bd1d9ab4eda903e1b5caa241368836575c6c476b with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@c50c157cc388ea631f085f4e95e948f51cdc742a + uses: github/codeql-action/autobuild@bd1d9ab4eda903e1b5caa241368836575c6c476b - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c50c157cc388ea631f085f4e95e948f51cdc742a + uses: github/codeql-action/analyze@bd1d9ab4eda903e1b5caa241368836575c6c476b From b6becac2c4e0f98a8651cc2f77d4c0b081548991 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 22 Mar 2025 03:00:07 +0000 Subject: [PATCH 47/56] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.17.3 (#1384) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a5c57d53..f04d32ee 100644 --- a/pom.xml +++ b/pom.xml @@ -189,7 +189,7 @@ net.bytebuddy byte-buddy - 1.17.2 + 1.17.3 test From 387e5f2e3bd24ccea6691b0d6dbfe542cfd05b52 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 22 Mar 2025 05:11:28 +0000 Subject: [PATCH 48/56] chore(deps): update github/codeql-action digest to e0ea141 (#1386) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 8554c833..4409f152 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,7 +29,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@bd1d9ab4eda903e1b5caa241368836575c6c476b + uses: github/codeql-action/init@e0ea141027937784e3c10ed1679e503fcc2245bc with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@bd1d9ab4eda903e1b5caa241368836575c6c476b + uses: github/codeql-action/analyze@e0ea141027937784e3c10ed1679e503fcc2245bc diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 520afd09..e43a306b 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@bd1d9ab4eda903e1b5caa241368836575c6c476b + uses: github/codeql-action/init@e0ea141027937784e3c10ed1679e503fcc2245bc with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@bd1d9ab4eda903e1b5caa241368836575c6c476b + uses: github/codeql-action/autobuild@e0ea141027937784e3c10ed1679e503fcc2245bc - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@bd1d9ab4eda903e1b5caa241368836575c6c476b + uses: github/codeql-action/analyze@e0ea141027937784e3c10ed1679e503fcc2245bc From 4125ae83801a9f485059a9edaca090ee47b7632f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 22 Mar 2025 10:02:36 +0000 Subject: [PATCH 49/56] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.17.3 (#1385) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f04d32ee..1ab82f46 100644 --- a/pom.xml +++ b/pom.xml @@ -196,7 +196,7 @@ net.bytebuddy byte-buddy-agent - 1.17.2 + 1.17.3 test From cb574d93b6210c89a188aa104ef4f1db68daf1c0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Mar 2025 07:03:02 +0000 Subject: [PATCH 50/56] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.17.4 (#1387) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1ab82f46..93a1d43d 100644 --- a/pom.xml +++ b/pom.xml @@ -189,7 +189,7 @@ net.bytebuddy byte-buddy - 1.17.3 + 1.17.4 test From d8f6514598d53f43cb084ee746742a59d271363b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Mar 2025 13:00:33 +0000 Subject: [PATCH 51/56] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.17.4 (#1388) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 93a1d43d..f0d531da 100644 --- a/pom.xml +++ b/pom.xml @@ -196,7 +196,7 @@ net.bytebuddy byte-buddy-agent - 1.17.3 + 1.17.4 test From 85fd5e0997ff1a5e5d7226d8bbfe2775769a6ca6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Mar 2025 02:02:27 +0000 Subject: [PATCH 52/56] chore(deps): update github/codeql-action digest to 486ab5a (#1389) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 4409f152..6e72dfb2 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,7 +29,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@e0ea141027937784e3c10ed1679e503fcc2245bc + uses: github/codeql-action/init@486ab5a2922b634015408a83e10f6867efb5922c with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e0ea141027937784e3c10ed1679e503fcc2245bc + uses: github/codeql-action/analyze@486ab5a2922b634015408a83e10f6867efb5922c diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index e43a306b..a9b7a349 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@e0ea141027937784e3c10ed1679e503fcc2245bc + uses: github/codeql-action/init@486ab5a2922b634015408a83e10f6867efb5922c with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@e0ea141027937784e3c10ed1679e503fcc2245bc + uses: github/codeql-action/autobuild@486ab5a2922b634015408a83e10f6867efb5922c - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e0ea141027937784e3c10ed1679e503fcc2245bc + uses: github/codeql-action/analyze@486ab5a2922b634015408a83e10f6867efb5922c From 87c06d9edd935287daf7ebc8db1e7da4831531de Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Mar 2025 16:35:34 +0000 Subject: [PATCH 53/56] chore(deps): update amannn/action-semantic-pull-request digest to 04501d4 (#1390) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/lint-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint-pr.yml b/.github/workflows/lint-pr.yml index bce13406..1b909c15 100644 --- a/.github/workflows/lint-pr.yml +++ b/.github/workflows/lint-pr.yml @@ -18,6 +18,6 @@ jobs: name: Validate PR title runs-on: ubuntu-latest steps: - - uses: amannn/action-semantic-pull-request@40166f00814508ec3201fc8595b393d451c8cd80 + - uses: amannn/action-semantic-pull-request@04501d43b574e4c1d23c629ffe4dcec27acfdeff env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 753667925a8803b3b227f762936ae397dde95484 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Mar 2025 07:41:23 +0000 Subject: [PATCH 54/56] chore(deps): update actions/setup-java digest to 3b6c050 (#1391) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/merge.yml | 2 +- .github/workflows/pullrequest.yml | 2 +- .github/workflows/release.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index 091f14b4..b156383e 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -21,7 +21,7 @@ jobs: steps: - uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 17 - uses: actions/setup-java@b8ebb8ba1d9655f7f159c0a8b8135606ae11b5c9 + uses: actions/setup-java@3b6c050358614dd082e53cdbc55580431fc4e437 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 6e72dfb2..fc1ac720 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -22,7 +22,7 @@ jobs: uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 8 - uses: actions/setup-java@b8ebb8ba1d9655f7f159c0a8b8135606ae11b5c9 + uses: actions/setup-java@3b6c050358614dd082e53cdbc55580431fc4e437 with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a3b669e7..28b5798e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 17 if: ${{ steps.release.outputs.release_created }} - uses: actions/setup-java@b8ebb8ba1d9655f7f159c0a8b8135606ae11b5c9 + uses: actions/setup-java@3b6c050358614dd082e53cdbc55580431fc4e437 with: java-version: '17' distribution: 'temurin' From 24ef9dd2903d01ec029b70cd1e39e71ffe327499 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Thu, 27 Mar 2025 09:22:19 -0400 Subject: [PATCH 55/56] fix: hooks not run in NOT_READY/FATAL (#1392) * fix: hooks not run in NOT_READY/FATAL Signed-off-by: Todd Baert --------- Signed-off-by: Todd Baert --- .../openfeature/sdk/OpenFeatureClient.java | 14 +++--- .../openfeature/sdk/FatalErrorProvider.java | 45 +++++++++++++++++++ .../dev/openfeature/sdk/HookSpecTest.java | 19 ++++++++ 3 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 src/test/java/dev/openfeature/sdk/FatalErrorProvider.java diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index 3022ff00..e68d28f7 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -178,12 +178,6 @@ private FlagEvaluationDetails evaluateFlag( // provider must be accessed once to maintain a consistent reference provider = stateManager.getProvider(); ProviderState state = stateManager.getState(); - if (ProviderState.NOT_READY.equals(state)) { - throw new ProviderNotReadyError("provider not yet initialized"); - } - if (ProviderState.FATAL.equals(state)) { - throw new FatalError("provider is in an irrecoverable error state"); - } mergedHooks = ObjectUtils.merge( provider.getProviderHooks(), flagOptions.getHooks(), clientHooks, openfeatureApi.getHooks()); @@ -203,6 +197,14 @@ private FlagEvaluationDetails evaluateFlag( afterHookContext = HookContext.from(key, type, this.getMetadata(), provider.getMetadata(), mergedCtx, defaultValue); + // "short circuit" if the provider is in NOT_READY or FATAL state + if (ProviderState.NOT_READY.equals(state)) { + throw new ProviderNotReadyError("Provider not yet initialized"); + } + if (ProviderState.FATAL.equals(state)) { + throw new FatalError("Provider is in an irrecoverable error state"); + } + ProviderEvaluation providerEval = (ProviderEvaluation) createProviderEvaluation(type, key, defaultValue, provider, mergedCtx); diff --git a/src/test/java/dev/openfeature/sdk/FatalErrorProvider.java b/src/test/java/dev/openfeature/sdk/FatalErrorProvider.java new file mode 100644 index 00000000..9ebd2475 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/FatalErrorProvider.java @@ -0,0 +1,45 @@ +package dev.openfeature.sdk; + +import dev.openfeature.sdk.exceptions.FatalError; +import dev.openfeature.sdk.exceptions.GeneralError; + +public class FatalErrorProvider implements FeatureProvider { + + private final String name = "fatal"; + + @Override + public Metadata getMetadata() { + return () -> name; + } + + @Override + public void initialize(EvaluationContext evaluationContext) throws Exception { + throw new FatalError(); // throw a fatal error on startup (this will cause the SDK to short circuit evaluations) + } + + @Override + public ProviderEvaluation getBooleanEvaluation(String key, Boolean defaultValue, EvaluationContext ctx) { + throw new GeneralError(TestConstants.BROKEN_MESSAGE); + } + + @Override + public ProviderEvaluation getStringEvaluation(String key, String defaultValue, EvaluationContext ctx) { + throw new GeneralError(TestConstants.BROKEN_MESSAGE); + } + + @Override + public ProviderEvaluation getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx) { + throw new GeneralError(TestConstants.BROKEN_MESSAGE); + } + + @Override + public ProviderEvaluation getDoubleEvaluation(String key, Double defaultValue, EvaluationContext ctx) { + throw new GeneralError(TestConstants.BROKEN_MESSAGE); + } + + @Override + public ProviderEvaluation getObjectEvaluation( + String key, Value defaultValue, EvaluationContext invocationContext) { + throw new GeneralError(TestConstants.BROKEN_MESSAGE); + } +} diff --git a/src/test/java/dev/openfeature/sdk/HookSpecTest.java b/src/test/java/dev/openfeature/sdk/HookSpecTest.java index 4b08510d..3a953d18 100644 --- a/src/test/java/dev/openfeature/sdk/HookSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSpecTest.java @@ -594,6 +594,25 @@ void erroneous_flagResolution_setsAppropriateFieldsInFlagEvaluationDetails() { assertThat(evaluationDetails.getValue()).isTrue(); } + @Test + void shortCircuit_flagResolution_runsHooksWithAllFields() { + String domain = "shortCircuit_flagResolution_setsAppropriateFieldsInFlagEvaluationDetails"; + api.setProvider(domain, new FatalErrorProvider()); + + Hook hook = mockBooleanHook(); + String flagKey = "test-flag-key"; + Client client = api.getClient(domain); + client.getBooleanValue( + flagKey, + true, + new ImmutableContext(), + FlagEvaluationOptions.builder().hook(hook).build()); + + verify(hook).before(any(), any()); + verify(hook).error(any(HookContext.class), any(Exception.class), any(Map.class)); + verify(hook).finallyAfter(any(HookContext.class), any(FlagEvaluationDetails.class), any(Map.class)); + } + @Test void successful_flagResolution_setsAppropriateFieldsInFlagEvaluationDetails() { Hook hook = mockBooleanHook(); From 7f54c334da017ff8395edffefd51d02956ec8134 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 27 Mar 2025 15:48:06 -0400 Subject: [PATCH 56/56] chore(main): release 1.14.2 (#1334) * chore(main): release 1.15.0 * Update CHANGELOG.md Signed-off-by: Todd Baert * Update .release-please-manifest.json Signed-off-by: Todd Baert * Update CHANGELOG.md Signed-off-by: Todd Baert * Update version.txt Signed-off-by: Todd Baert * Update README.md Signed-off-by: Todd Baert * Update README.md Signed-off-by: Todd Baert * Update pom.xml Signed-off-by: Todd Baert --------- Signed-off-by: Todd Baert Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Todd Baert --- .release-please-manifest.json | 2 +- CHANGELOG.md | 63 +++++++++++++++++++++++++++++++++++ README.md | 8 ++--- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 70 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index f459d7af..762e32db 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"1.14.1"} \ No newline at end of file +{".":"1.14.2"} diff --git a/CHANGELOG.md b/CHANGELOG.md index 6301fce0..914cbfef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,68 @@ # Changelog +## [1.14.2](https://github.com/open-feature/java-sdk/compare/v1.14.1...v1.14.2) (2025-03-27) + + +### ๐Ÿ› Bug Fixes + +* **deps:** update dependency org.slf4j:slf4j-api to v2.0.17 ([#1348](https://github.com/open-feature/java-sdk/issues/1348)) ([2ec7c6c](https://github.com/open-feature/java-sdk/commit/2ec7c6c7ff704380fdfd8116378adf78734e4f2b)) +* **deps:** update junit5 monorepo ([#1344](https://github.com/open-feature/java-sdk/issues/1344)) ([d95e270](https://github.com/open-feature/java-sdk/commit/d95e2706532259bd5739e5b4ea4813ef9f2196a6)) +* **deps:** update junit5 monorepo ([#1373](https://github.com/open-feature/java-sdk/issues/1373)) ([6b65e26](https://github.com/open-feature/java-sdk/commit/6b65e26c7439895652c3f64f2b4a7307a7ca582e)) +* equals and hashcode of several classes ([69b571e](https://github.com/open-feature/java-sdk/commit/69b571eda73b6f43c99864420b8663ae54ebf0ad)) +* equals and hashcode of several classes ([#1364](https://github.com/open-feature/java-sdk/issues/1364)) ([69b571e](https://github.com/open-feature/java-sdk/commit/69b571eda73b6f43c99864420b8663ae54ebf0ad)) +* hooks not run in NOT_READY/FATAL ([#1392](https://github.com/open-feature/java-sdk/issues/1392)) ([24ef9dd](https://github.com/open-feature/java-sdk/commit/24ef9dd2903d01ec029b70cd1e39e71ffe327499)) + + +### ๐Ÿงน Chore + +* **deps:** update actions/cache digest to 5a3ec84 ([#1380](https://github.com/open-feature/java-sdk/issues/1380)) ([8359ef1](https://github.com/open-feature/java-sdk/commit/8359ef13bb935ac1d144787cfd7181814a0b286c)) +* **deps:** update actions/cache digest to 7921ae2 ([#1337](https://github.com/open-feature/java-sdk/issues/1337)) ([3920c63](https://github.com/open-feature/java-sdk/commit/3920c638a49caddfb07041f812cc6bc0bf3101f9)) +* **deps:** update actions/cache digest to d4323d4 ([#1353](https://github.com/open-feature/java-sdk/issues/1353)) ([5901797](https://github.com/open-feature/java-sdk/commit/59017977a487a36c8a39f63b83299bc657134c0d)) +* **deps:** update actions/setup-java digest to 3b6c050 ([#1391](https://github.com/open-feature/java-sdk/issues/1391)) ([7536679](https://github.com/open-feature/java-sdk/commit/753667925a8803b3b227f762936ae397dde95484)) +* **deps:** update actions/setup-java digest to 799ee7c ([#1359](https://github.com/open-feature/java-sdk/issues/1359)) ([31444d6](https://github.com/open-feature/java-sdk/commit/31444d6c8f30f0dd35debacc9dab8da7397e11ed)) +* **deps:** update actions/setup-java digest to b8ebb8b ([#1381](https://github.com/open-feature/java-sdk/issues/1381)) ([2239f05](https://github.com/open-feature/java-sdk/commit/2239f054b90734dde6cdd4a23daec1c1daa96f07)) +* **deps:** update amannn/action-semantic-pull-request digest to 04501d4 ([#1390](https://github.com/open-feature/java-sdk/issues/1390)) ([87c06d9](https://github.com/open-feature/java-sdk/commit/87c06d9edd935287daf7ebc8db1e7da4831531de)) +* **deps:** update codecov/codecov-action action to v5.4.0 ([#1351](https://github.com/open-feature/java-sdk/issues/1351)) ([b133c2f](https://github.com/open-feature/java-sdk/commit/b133c2fa527a0dddb6de7f7781a00fc84feaa813)) +* **deps:** update dependency com.diffplug.spotless:spotless-maven-plugin to v2.44.3 ([#1341](https://github.com/open-feature/java-sdk/issues/1341)) ([5de33c0](https://github.com/open-feature/java-sdk/commit/5de33c02a675db6ca5966bfa3f58d99c8e53e36b)) +* **deps:** update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.1.0 ([#1332](https://github.com/open-feature/java-sdk/issues/1332)) ([cdcdc14](https://github.com/open-feature/java-sdk/commit/cdcdc143ea5ad2f003cb3f5450ec78314e619ea3)) +* **deps:** update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.2.0 ([#1360](https://github.com/open-feature/java-sdk/issues/1360)) ([ecea9df](https://github.com/open-feature/java-sdk/commit/ecea9df932ee4874613f219b73640fe964c99593)) +* **deps:** update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.3.0 ([#1375](https://github.com/open-feature/java-sdk/issues/1375)) ([de3e213](https://github.com/open-feature/java-sdk/commit/de3e213ac8b8931121904a3d12929405512e74dd)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.17.2 ([#1355](https://github.com/open-feature/java-sdk/issues/1355)) ([2a1adca](https://github.com/open-feature/java-sdk/commit/2a1adca8c2ed8d61d51530969290793a5d3d15f3)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.17.3 ([#1384](https://github.com/open-feature/java-sdk/issues/1384)) ([b6becac](https://github.com/open-feature/java-sdk/commit/b6becac2c4e0f98a8651cc2f77d4c0b081548991)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.17.4 ([#1387](https://github.com/open-feature/java-sdk/issues/1387)) ([cb574d9](https://github.com/open-feature/java-sdk/commit/cb574d93b6210c89a188aa104ef4f1db68daf1c0)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.17.2 ([#1356](https://github.com/open-feature/java-sdk/issues/1356)) ([dd83114](https://github.com/open-feature/java-sdk/commit/dd83114c4d9389753575392fafcd56585d7178ae)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.17.3 ([#1385](https://github.com/open-feature/java-sdk/issues/1385)) ([4125ae8](https://github.com/open-feature/java-sdk/commit/4125ae83801a9f485059a9edaca090ee47b7632f)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.17.4 ([#1388](https://github.com/open-feature/java-sdk/issues/1388)) ([d8f6514](https://github.com/open-feature/java-sdk/commit/d8f6514598d53f43cb084ee746742a59d271363b)) +* **deps:** update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.14.0 ([#1342](https://github.com/open-feature/java-sdk/issues/1342)) ([88a778c](https://github.com/open-feature/java-sdk/commit/88a778cc03e112d45756428d1f0ae1ef0fe02c84)) +* **deps:** update dependency org.awaitility:awaitility to v4.3.0 ([#1343](https://github.com/open-feature/java-sdk/issues/1343)) ([1504d0f](https://github.com/open-feature/java-sdk/commit/1504d0f7982757a2b413eda593ce7057b90519e5)) +* **deps:** update dependency org.mockito:mockito-core to v5.15.2 ([#1339](https://github.com/open-feature/java-sdk/issues/1339)) ([4817864](https://github.com/open-feature/java-sdk/commit/4817864fd7ae70c1e19c3c09e82e1fb03dd88942)) +* **deps:** update dependency org.mockito:mockito-core to v5.16.0 ([#1358](https://github.com/open-feature/java-sdk/issues/1358)) ([30b6d00](https://github.com/open-feature/java-sdk/commit/30b6d004aaf3464547805f7eda6fad0e122de4f9)) +* **deps:** update dependency org.mockito:mockito-core to v5.16.1 ([#1376](https://github.com/open-feature/java-sdk/issues/1376)) ([9750f75](https://github.com/open-feature/java-sdk/commit/9750f75d04beb8339fc2e972f0ee97120eaff354)) +* **deps:** update github/codeql-action digest to 1bb15d0 ([#1336](https://github.com/open-feature/java-sdk/issues/1336)) ([e163ce1](https://github.com/open-feature/java-sdk/commit/e163ce1c060d0dc8812e4a8a3b37f52b0156324d)) +* **deps:** update github/codeql-action digest to 486ab5a ([#1389](https://github.com/open-feature/java-sdk/issues/1389)) ([85fd5e0](https://github.com/open-feature/java-sdk/commit/85fd5e0997ff1a5e5d7226d8bbfe2775769a6ca6)) +* **deps:** update github/codeql-action digest to 56b25d5 ([#1365](https://github.com/open-feature/java-sdk/issues/1365)) ([959e675](https://github.com/open-feature/java-sdk/commit/959e675e4c2363e5fd80d1d2f1edbfab11794fc8)) +* **deps:** update github/codeql-action digest to 608ccd6 ([#1361](https://github.com/open-feature/java-sdk/issues/1361)) ([67b34f8](https://github.com/open-feature/java-sdk/commit/67b34f84a373512013ab2f7649faaddfd2d61048)) +* **deps:** update github/codeql-action digest to 6349095 ([#1378](https://github.com/open-feature/java-sdk/issues/1378)) ([dbf92df](https://github.com/open-feature/java-sdk/commit/dbf92df33bf5657d50dc3b2f129207b0097c1f27)) +* **deps:** update github/codeql-action digest to 6a151cd ([#1377](https://github.com/open-feature/java-sdk/issues/1377)) ([7065655](https://github.com/open-feature/java-sdk/commit/706565581d78856dd73605b1a16b131f974c0731)) +* **deps:** update github/codeql-action digest to 70df9de ([#1372](https://github.com/open-feature/java-sdk/issues/1372)) ([d233480](https://github.com/open-feature/java-sdk/commit/d233480912f1d5e095f5034f36a838535d1ecdff)) +* **deps:** update github/codeql-action digest to 7254660 ([#1368](https://github.com/open-feature/java-sdk/issues/1368)) ([d54c68a](https://github.com/open-feature/java-sdk/commit/d54c68a8e9e4a0f67c99e7d76621a1c5724e4cd1)) +* **deps:** update github/codeql-action digest to 80f9930 ([#1357](https://github.com/open-feature/java-sdk/issues/1357)) ([6c03e5d](https://github.com/open-feature/java-sdk/commit/6c03e5d84aacee11f5b8e608a6114c11fced72b8)) +* **deps:** update github/codeql-action digest to 8392354 ([#1352](https://github.com/open-feature/java-sdk/issues/1352)) ([989f4ae](https://github.com/open-feature/java-sdk/commit/989f4ae54263b46ca2c81561acc70b39918c382d)) +* **deps:** update github/codeql-action digest to 8c1551c ([#1333](https://github.com/open-feature/java-sdk/issues/1333)) ([859a36c](https://github.com/open-feature/java-sdk/commit/859a36cbfafc94d4601b87d304237e6ddf97c08d)) +* **deps:** update github/codeql-action digest to 8c69433 ([#1347](https://github.com/open-feature/java-sdk/issues/1347)) ([6987568](https://github.com/open-feature/java-sdk/commit/698756856ba40e98d91ccf661dab409798861aa5)) +* **deps:** update github/codeql-action digest to 97aac9b ([#1350](https://github.com/open-feature/java-sdk/issues/1350)) ([7df9565](https://github.com/open-feature/java-sdk/commit/7df9565691731d164b534116b8a6b933b171d103)) +* **deps:** update github/codeql-action digest to a8849fb ([#1345](https://github.com/open-feature/java-sdk/issues/1345)) ([de64edd](https://github.com/open-feature/java-sdk/commit/de64eddfb3a6cc117bb108dbcf167830e9f6729d)) +* **deps:** update github/codeql-action digest to acadfed ([#1335](https://github.com/open-feature/java-sdk/issues/1335)) ([5436eb0](https://github.com/open-feature/java-sdk/commit/5436eb0d5db3a0e9bd9289fbef57b9eeada0a667)) +* **deps:** update github/codeql-action digest to b2e6519 ([#1366](https://github.com/open-feature/java-sdk/issues/1366)) ([d00e4b5](https://github.com/open-feature/java-sdk/commit/d00e4b5b24621aa55085827fbe6ea982491376de)) +* **deps:** update github/codeql-action digest to b46b37a ([#1367](https://github.com/open-feature/java-sdk/issues/1367)) ([c550d59](https://github.com/open-feature/java-sdk/commit/c550d597227bfc1e0e17357139f1fd8a87593be0)) +* **deps:** update github/codeql-action digest to bd1d9ab ([#1383](https://github.com/open-feature/java-sdk/issues/1383)) ([922e17e](https://github.com/open-feature/java-sdk/commit/922e17e677e15690e3df2fe93a961f16f21ff283)) +* **deps:** update github/codeql-action digest to c50c157 ([#1379](https://github.com/open-feature/java-sdk/issues/1379)) ([d61c33e](https://github.com/open-feature/java-sdk/commit/d61c33e466336c7120b870ca5e3843eba5f7175c)) +* **deps:** update github/codeql-action digest to d99c7e8 ([#1338](https://github.com/open-feature/java-sdk/issues/1338)) ([4e535fd](https://github.com/open-feature/java-sdk/commit/4e535fd10fac742ca472faa62c941fa51b282ca7)) +* **deps:** update github/codeql-action digest to dc49dca ([#1369](https://github.com/open-feature/java-sdk/issues/1369)) ([f8df5fb](https://github.com/open-feature/java-sdk/commit/f8df5fb84a765af917587dd509f9cec38103f787)) +* **deps:** update github/codeql-action digest to e0ea141 ([#1386](https://github.com/open-feature/java-sdk/issues/1386)) ([387e5f2](https://github.com/open-feature/java-sdk/commit/387e5f2e3bd24ccea6691b0d6dbfe542cfd05b52)) +* **deps:** update github/codeql-action digest to ff79de6 ([#1340](https://github.com/open-feature/java-sdk/issues/1340)) ([50b45b2](https://github.com/open-feature/java-sdk/commit/50b45b2be442bb89a431c9bcc45d825f63bd93a6)) +* update build and tooling to utilize new java version ([#1321](https://github.com/open-feature/java-sdk/issues/1321)) ([90217b2](https://github.com/open-feature/java-sdk/commit/90217b2083a2ba92c623365dc450326d49b46fab)) + ## [1.14.1](https://github.com/open-feature/java-sdk/compare/v1.14.0...v1.14.1) (2025-02-14) diff --git a/README.md b/README.md index 49d5562e..22d85bd2 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,8 @@ - - Release + + Release @@ -59,7 +59,7 @@ Note that this library is intended to be used in server-side contexts and has no dev.openfeature sdk - 1.14.1 + 1.14.2 ``` @@ -84,7 +84,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:1.14.1' + implementation 'dev.openfeature:sdk:1.14.2' } ``` diff --git a/pom.xml b/pom.xml index f0d531da..7b8e0d58 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ dev.openfeature sdk - 1.14.1 + 1.14.2 [17,) diff --git a/version.txt b/version.txt index 63e799cf..a4cc5571 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.14.1 +1.14.2