diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml
index e2ab0256..612abab5 100644
--- a/.github/workflows/merge.yml
+++ b/.github/workflows/merge.yml
@@ -20,9 +20,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@9a9194f87191a7e9055e3e9b95b8cfb13023bb08
+ - uses: actions/checkout@2d7d9f7ff5b310f983d059b68785b3c74d8b8edd
- name: Set up JDK 8
- uses: actions/setup-java@67fbd726daaf08212a7b021c1c4d117f94a81dd3
+ uses: actions/setup-java@8e04ddff28554375a9a1096c888a2ef2c9803cd7
with:
java-version: '8'
distribution: 'temurin'
diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml
index 95624732..4539fc16 100644
--- a/.github/workflows/pullrequest.yml
+++ b/.github/workflows/pullrequest.yml
@@ -10,17 +10,17 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out the code
- uses: actions/checkout@9a9194f87191a7e9055e3e9b95b8cfb13023bb08
+ uses: actions/checkout@2d7d9f7ff5b310f983d059b68785b3c74d8b8edd
- name: Set up JDK 8
- uses: actions/setup-java@67fbd726daaf08212a7b021c1c4d117f94a81dd3
+ uses: actions/setup-java@8e04ddff28554375a9a1096c888a2ef2c9803cd7
with:
java-version: '8'
distribution: 'temurin'
cache: maven
- name: Initialize CodeQL
- uses: github/codeql-action/init@fd5fa130e2c632f29b237077157766ea2ef07a13
+ uses: github/codeql-action/init@889597e41d183636b55d03e1a49c44753c626a2e
with:
languages: java
@@ -45,4 +45,4 @@ jobs:
verbose: true # optional (default = false)
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@fd5fa130e2c632f29b237077157766ea2ef07a13
+ uses: github/codeql-action/analyze@889597e41d183636b55d03e1a49c44753c626a2e
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index b1b86fe4..0cb1d8ad 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -28,10 +28,10 @@ jobs:
# These steps are only run if this was a merged release-please PR
- name: checkout
if: ${{ steps.release.outputs.release_created }}
- uses: actions/checkout@9a9194f87191a7e9055e3e9b95b8cfb13023bb08
+ uses: actions/checkout@2d7d9f7ff5b310f983d059b68785b3c74d8b8edd
- name: Set up JDK 8
if: ${{ steps.release.outputs.release_created }}
- uses: actions/setup-java@67fbd726daaf08212a7b021c1c4d117f94a81dd3
+ uses: actions/setup-java@8e04ddff28554375a9a1096c888a2ef2c9803cd7
with:
java-version: '8'
distribution: 'temurin'
diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml
index 1cf8476a..2f82be00 100644
--- a/.github/workflows/static-code-scanning.yaml
+++ b/.github/workflows/static-code-scanning.yaml
@@ -29,16 +29,16 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@9a9194f87191a7e9055e3e9b95b8cfb13023bb08
+ uses: actions/checkout@2d7d9f7ff5b310f983d059b68785b3c74d8b8edd
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
- uses: github/codeql-action/init@fd5fa130e2c632f29b237077157766ea2ef07a13
+ uses: github/codeql-action/init@889597e41d183636b55d03e1a49c44753c626a2e
with:
languages: java
- name: Autobuild
- uses: github/codeql-action/autobuild@fd5fa130e2c632f29b237077157766ea2ef07a13
+ uses: github/codeql-action/autobuild@889597e41d183636b55d03e1a49c44753c626a2e
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@fd5fa130e2c632f29b237077157766ea2ef07a13
+ uses: github/codeql-action/analyze@889597e41d183636b55d03e1a49c44753c626a2e
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index eefaab1f..9053c217 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1 +1 @@
-{".":"1.9.1"}
\ No newline at end of file
+{".":"1.10.0"}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 46d52e4d..5090ec3e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,38 @@
# Changelog
+## [1.10.0](https://github.com/open-feature/java-sdk/compare/v1.9.1...v1.10.0) (2024-09-05)
+
+
+### ✨ New Features
+
+* add logging hook, rm logging from evaluation ([#1084](https://github.com/open-feature/java-sdk/issues/1084)) ([037826f](https://github.com/open-feature/java-sdk/commit/037826fe1b1c7fecdac95b45bfcdef5d66d49f60))
+
+
+### 🧹 Chore
+
+* **deps:** update actions/checkout digest to 2d7d9f7 ([#1082](https://github.com/open-feature/java-sdk/issues/1082)) ([9196599](https://github.com/open-feature/java-sdk/commit/9196599f30388dd38b8fb11052772c01f16ed481))
+* **deps:** update actions/setup-java digest to 8e04ddf ([#1080](https://github.com/open-feature/java-sdk/issues/1080)) ([0cc5ca1](https://github.com/open-feature/java-sdk/commit/0cc5ca1397d33cd8802cf40d19130d03c84da340))
+* **deps:** update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.8.6.3 ([#1087](https://github.com/open-feature/java-sdk/issues/1087)) ([78e3371](https://github.com/open-feature/java-sdk/commit/78e3371c0578984b46d70328a8940425786cae4d))
+* **deps:** update dependency net.bytebuddy:byte-buddy to v1.15.0 ([#1063](https://github.com/open-feature/java-sdk/issues/1063)) ([7fea9b1](https://github.com/open-feature/java-sdk/commit/7fea9b106c1cf3ffe4ce7d5a9448a179d7041ed0))
+* **deps:** update dependency net.bytebuddy:byte-buddy to v1.15.1 ([#1078](https://github.com/open-feature/java-sdk/issues/1078)) ([9836006](https://github.com/open-feature/java-sdk/commit/98360061a889713fa4b67bd1d0721e5496a18714))
+* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.15.0 ([#1064](https://github.com/open-feature/java-sdk/issues/1064)) ([dd53021](https://github.com/open-feature/java-sdk/commit/dd53021153a192370a0cbf56fbccd42eeb870043))
+* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.15.1 ([#1079](https://github.com/open-feature/java-sdk/issues/1079)) ([a3285df](https://github.com/open-feature/java-sdk/commit/a3285df729aaa2c89941bfc180cf736228ab10ef))
+* **deps:** update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.5.0 ([#1073](https://github.com/open-feature/java-sdk/issues/1073)) ([c845035](https://github.com/open-feature/java-sdk/commit/c8450358c02d942f7772ccac6c740078f7594a51))
+* **deps:** update dependency org.apache.maven.plugins:maven-javadoc-plugin to v3.10.0 ([#1072](https://github.com/open-feature/java-sdk/issues/1072)) ([3eed950](https://github.com/open-feature/java-sdk/commit/3eed950d3c296888acc0abe486d6c34d57170141))
+* **deps:** update dependency org.apache.maven.plugins:maven-pmd-plugin to v3.25.0 ([#1074](https://github.com/open-feature/java-sdk/issues/1074)) ([5ee3851](https://github.com/open-feature/java-sdk/commit/5ee38510a87d089f4440657569fb34cc3f133415))
+* **deps:** update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.0 ([#1075](https://github.com/open-feature/java-sdk/issues/1075)) ([b772119](https://github.com/open-feature/java-sdk/commit/b772119977b8731668d809f50cacaa66f83d53b7))
+* **deps:** update github/codeql-action digest to 7233ec5 ([#1076](https://github.com/open-feature/java-sdk/issues/1076)) ([eb5526d](https://github.com/open-feature/java-sdk/commit/eb5526d75fb94c9b57b5124982e9b3510d654324))
+* **deps:** update github/codeql-action digest to 7e27807 ([#1067](https://github.com/open-feature/java-sdk/issues/1067)) ([a07eb67](https://github.com/open-feature/java-sdk/commit/a07eb6786546066b0e416c9e072db770833d3dbd))
+* **deps:** update github/codeql-action digest to 821ab42 ([#1081](https://github.com/open-feature/java-sdk/issues/1081)) ([a4d428c](https://github.com/open-feature/java-sdk/commit/a4d428c83c0d243d85b6bf82ffd15248d3dab570))
+* **deps:** update github/codeql-action digest to 864b979 ([#1070](https://github.com/open-feature/java-sdk/issues/1070)) ([ee6d8b0](https://github.com/open-feature/java-sdk/commit/ee6d8b094af3dcf83aa08f934035888bc0311c37))
+* **deps:** update github/codeql-action digest to 889597e ([#1086](https://github.com/open-feature/java-sdk/issues/1086)) ([dd7696f](https://github.com/open-feature/java-sdk/commit/dd7696f473a23f789098ca3103b474baa274a233))
+* **deps:** update github/codeql-action digest to a895f2e ([#1068](https://github.com/open-feature/java-sdk/issues/1068)) ([ea59e7f](https://github.com/open-feature/java-sdk/commit/ea59e7fa587768832f45a836d4da694a8ebcfde6))
+* **deps:** update github/codeql-action digest to b43ac1c ([#1077](https://github.com/open-feature/java-sdk/issues/1077)) ([3f5294c](https://github.com/open-feature/java-sdk/commit/3f5294c734278d6ce13bbfae9731c0b46e3e9e15))
+* **deps:** update github/codeql-action digest to b4a8631 ([#1083](https://github.com/open-feature/java-sdk/issues/1083)) ([90648d1](https://github.com/open-feature/java-sdk/commit/90648d1c9d9adffa85442b39bd0197ac7e032a51))
+* **deps:** update github/codeql-action digest to b8efe4d ([#1071](https://github.com/open-feature/java-sdk/issues/1071)) ([5668987](https://github.com/open-feature/java-sdk/commit/5668987274952693cad77bc37fa054ee1ed603fe))
+* **deps:** update github/codeql-action digest to d36c7aa ([#1069](https://github.com/open-feature/java-sdk/issues/1069)) ([0e048c1](https://github.com/open-feature/java-sdk/commit/0e048c1ff5eae3ec121c2219e8ce9685264135bb))
+* various non-functional refactors ([#1066](https://github.com/open-feature/java-sdk/issues/1066)) ([35d4cc2](https://github.com/open-feature/java-sdk/commit/35d4cc23c85a24f2d55992cb40b357e450f8e9b7))
+
## [1.9.1](https://github.com/open-feature/java-sdk/compare/v1.9.0...v1.9.1) (2024-08-22)
diff --git a/README.md b/README.md
index e59b0824..a7e98462 100644
--- a/README.md
+++ b/README.md
@@ -18,8 +18,8 @@
-
-
+
+
@@ -59,7 +59,7 @@ Note that this library is intended to be used in server-side contexts and has no
dev.openfeature
sdk
- 1.9.1
+ 1.10.0
```
@@ -84,7 +84,7 @@ If you would like snapshot builds, this is the relevant repository information:
```groovy
dependencies {
- implementation 'dev.openfeature:sdk:1.9.1'
+ implementation 'dev.openfeature:sdk:1.10.0'
}
```
@@ -218,6 +218,14 @@ Once you've added a hook as a dependency, it can be registered at the global, cl
### Logging
The Java SDK uses SLF4J. See the [SLF4J manual](https://slf4j.org/manual.html) for complete documentation.
+Note that in accordance with the OpenFeature specification, the SDK doesn't generally log messages during flag evaluation.
+
+#### Logging Hook
+
+The Java SDK includes a `LoggingHook`, which logs detailed information at key points during flag evaluation, using SLF4J's structured logging API.
+This hook can be particularly helpful for troubleshooting and debugging; simply attach it at the global, client or invocation level and ensure your log level is set to "debug".
+
+See [hooks](#hooks) for more information on configuring hooks.
### Domains
diff --git a/pom.xml b/pom.xml
index ecfa6e30..347d4edc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
dev.openfeature
sdk
- 1.9.1
+ 1.10.0
UTF-8
@@ -157,14 +157,14 @@
net.bytebuddy
byte-buddy
- 1.14.19
+ 1.15.1
test
net.bytebuddy
byte-buddy-agent
- 1.14.19
+ 1.15.1
test
@@ -253,7 +253,7 @@
org.apache.maven.plugins
maven-surefire-plugin
- 3.4.0
+ 3.5.0
${surefireArgLine}
@@ -268,7 +268,7 @@
org.apache.maven.plugins
maven-failsafe-plugin
- 3.4.0
+ 3.5.0
${surefireArgLine}
@@ -352,7 +352,7 @@
org.apache.maven.plugins
maven-pmd-plugin
- 3.24.0
+ 3.25.0
run-pmd
@@ -367,7 +367,7 @@
com.github.spotbugs
spotbugs-maven-plugin
- 4.8.6.2
+ 4.8.6.3
spotbugs-exclusions.xml
@@ -470,7 +470,7 @@
org.apache.maven.plugins
maven-javadoc-plugin
- 3.8.0
+ 3.10.0
true
all,-missing
diff --git a/src/main/java/dev/openfeature/sdk/BooleanHook.java b/src/main/java/dev/openfeature/sdk/BooleanHook.java
index bc07d898..e9277766 100644
--- a/src/main/java/dev/openfeature/sdk/BooleanHook.java
+++ b/src/main/java/dev/openfeature/sdk/BooleanHook.java
@@ -1,7 +1,10 @@
package dev.openfeature.sdk;
/**
- * {@inheritDoc}
+ * An extension point which can run around flag resolution. They are intended to be used as a way to add custom logic
+ * to the lifecycle of flag evaluation.
+ *
+ * @see Hook
*/
public interface BooleanHook extends Hook {
diff --git a/src/main/java/dev/openfeature/sdk/DoubleHook.java b/src/main/java/dev/openfeature/sdk/DoubleHook.java
index 1da0602d..3ccf88b1 100644
--- a/src/main/java/dev/openfeature/sdk/DoubleHook.java
+++ b/src/main/java/dev/openfeature/sdk/DoubleHook.java
@@ -1,7 +1,10 @@
package dev.openfeature.sdk;
/**
- * {@inheritDoc}
+ * An extension point which can run around flag resolution. They are intended to be used as a way to add custom logic
+ * to the lifecycle of flag evaluation.
+ *
+ * @see Hook
*/
public interface DoubleHook extends Hook {
diff --git a/src/main/java/dev/openfeature/sdk/HookSupport.java b/src/main/java/dev/openfeature/sdk/HookSupport.java
index 8563096e..52c5b972 100644
--- a/src/main/java/dev/openfeature/sdk/HookSupport.java
+++ b/src/main/java/dev/openfeature/sdk/HookSupport.java
@@ -17,9 +17,18 @@
@SuppressWarnings({ "unchecked", "rawtypes" })
class HookSupport {
- public void errorHooks(FlagValueType flagValueType, HookContext hookCtx, Exception e, List hooks,
+ public EvaluationContext beforeHooks(FlagValueType flagValueType, HookContext hookCtx, List hooks,
Map hints) {
- executeHooks(flagValueType, hooks, "error", hook -> hook.error(hookCtx, e, hints));
+ Stream result = callBeforeHooks(flagValueType, hookCtx, hooks, hints);
+ return hookCtx.getCtx().merge(
+ result.reduce(hookCtx.getCtx(), (EvaluationContext accumulated, EvaluationContext current) -> {
+ return accumulated.merge(current);
+ }));
+ }
+
+ public void afterHooks(FlagValueType flagValueType, HookContext hookContext, FlagEvaluationDetails details,
+ List hooks, Map hints) {
+ executeHooksUnchecked(flagValueType, hooks, hook -> hook.after(hookContext, details, hints));
}
public void afterAllHooks(FlagValueType flagValueType, HookContext hookCtx, List hooks,
@@ -27,9 +36,9 @@ public void afterAllHooks(FlagValueType flagValueType, HookContext hookCtx, List
executeHooks(flagValueType, hooks, "finally", hook -> hook.finallyAfter(hookCtx, hints));
}
- public void afterHooks(FlagValueType flagValueType, HookContext hookContext, FlagEvaluationDetails details,
- List hooks, Map hints) {
- executeHooksUnchecked(flagValueType, hooks, hook -> hook.after(hookContext, details, hints));
+ public void errorHooks(FlagValueType flagValueType, HookContext hookCtx, Exception e, List hooks,
+ Map hints) {
+ executeHooks(flagValueType, hooks, "error", hook -> hook.error(hookCtx, e, hints));
}
private void executeHooks(
@@ -44,6 +53,17 @@ private void executeHooks(
}
}
+ // before, error, and finally hooks shouldn't throw
+ private void executeChecked(Hook hook, Consumer> hookCode, String hookMethod) {
+ try {
+ hookCode.accept(hook);
+ } catch (Exception exception) {
+ log.error("Unhandled exception when running {} hook {} (only 'after' hooks should throw)", hookMethod,
+ hook.getClass(), exception);
+ }
+ }
+
+ // after hooks can throw in order to do validation
private void executeHooksUnchecked(
FlagValueType flagValueType, List hooks,
Consumer> hookCode) {
@@ -55,23 +75,6 @@ private void executeHooksUnchecked(
}
}
- private void executeChecked(Hook hook, Consumer> hookCode, String hookMethod) {
- try {
- hookCode.accept(hook);
- } catch (Exception exception) {
- log.error("Exception when running {} hooks {}", hookMethod, hook.getClass(), exception);
- }
- }
-
- public EvaluationContext beforeHooks(FlagValueType flagValueType, HookContext hookCtx, List hooks,
- Map hints) {
- Stream result = callBeforeHooks(flagValueType, hookCtx, hooks, hints);
- return hookCtx.getCtx().merge(
- result.reduce(hookCtx.getCtx(), (EvaluationContext accumulated, EvaluationContext current) -> {
- return accumulated.merge(current);
- }));
- }
-
private Stream callBeforeHooks(FlagValueType flagValueType, HookContext hookCtx,
List hooks, Map hints) {
// These traverse backwards from normal.
diff --git a/src/main/java/dev/openfeature/sdk/ImmutableContext.java b/src/main/java/dev/openfeature/sdk/ImmutableContext.java
index 57009987..fd2ff2a6 100644
--- a/src/main/java/dev/openfeature/sdk/ImmutableContext.java
+++ b/src/main/java/dev/openfeature/sdk/ImmutableContext.java
@@ -1,10 +1,11 @@
package dev.openfeature.sdk;
-import lombok.ToString;
-import lombok.experimental.Delegate;
-
import java.util.HashMap;
import java.util.Map;
+import java.util.function.Function;
+import dev.openfeature.sdk.internal.ExcludeFromGeneratedCoverageReport;
+import lombok.ToString;
+import lombok.experimental.Delegate;
/**
* The EvaluationContext is a container for arbitrary contextual data
@@ -16,8 +17,8 @@
@SuppressWarnings("PMD.BeanMembersShouldSerialize")
public final class ImmutableContext implements EvaluationContext {
- @Delegate
- private final Structure structure;
+ @Delegate(excludes = DelegateExclusions.class)
+ private final ImmutableStructure structure;
/**
* Create an immutable context with an empty targeting_key and attributes provided.
@@ -84,4 +85,15 @@ public EvaluationContext merge(EvaluationContext overridingContext) {
return new ImmutableContext(
this.merge(ImmutableStructure::new, this.asMap(), overridingContext.asMap()));
}
+
+ @SuppressWarnings("all")
+ private static class DelegateExclusions {
+ @ExcludeFromGeneratedCoverageReport
+ public Map merge(Function