From 0db0a50cf40d62e9880ca68f577c43fe86497532 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 12:39:25 +0000 Subject: [PATCH 001/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.15.7 (#1179) 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 8ca7dcff0..a21e40650 100644 --- a/pom.xml +++ b/pom.xml @@ -164,7 +164,7 @@ net.bytebuddy byte-buddy - 1.15.5 + 1.15.7 test From 36620f84081bb38cc542330ea44e84f6f5754093 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 16:29:05 +0000 Subject: [PATCH 002/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.15.7 (#1180) 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 a21e40650..2085ff726 100644 --- a/pom.xml +++ b/pom.xml @@ -171,7 +171,7 @@ net.bytebuddy byte-buddy-agent - 1.15.5 + 1.15.7 test From 0009e23c7b38dff78afc7addede41fed16937976 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Wed, 23 Oct 2024 12:33:02 -0400 Subject: [PATCH 003/745] chore: improve benchmark realism; add more context (#1182) Signed-off-by: Todd Baert --- benchmark.txt | 233 +++++++++++------- .../sdk/benchmark/AllocationBenchmark.java | 16 +- 2 files changed, 159 insertions(+), 90 deletions(-) diff --git a/benchmark.txt b/benchmark.txt index 696ffa24c..d028a3f87 100644 --- a/benchmark.txt +++ b/benchmark.txt @@ -1,12 +1,15 @@ [INFO] Scanning for projects... [INFO] [INFO] ------------------------< dev.openfeature:sdk >------------------------- -[INFO] Building OpenFeature Java SDK 1.12.0 +[INFO] Building OpenFeature Java SDK 1.12.1 [INFO] from pom.xml [INFO] --------------------------------[ jar ]--------------------------------- [WARNING] Parameter 'encoding' is unknown for plugin 'maven-checkstyle-plugin:3.5.0:check (validate)' +[WARNING] Parameter 'encoding' is unknown for plugin 'maven-checkstyle-plugin:3.5.0:check (validate)' +[WARNING] Parameter 'encoding' is unknown for plugin 'maven-checkstyle-plugin:3.5.0:check (validate)' [INFO] -[INFO] >>> jmh:0.2.2:benchmark (default-cli) > process-test-resources @ sdk >>> +[INFO] --- clean:3.2.0:clean (default-clean) @ sdk --- +[INFO] Deleting /home/todd/git/java-sdk/target [INFO] [INFO] --- checkstyle:3.5.0:check (validate) @ sdk --- [INFO] Starting audit... @@ -33,15 +36,67 @@ Audit done. processing is enabled explicitly (-proc:only, -proc:full). Use -Xlint:-options to suppress this message. Use -proc:none to disable annotation processing. -[WARNING] /home/todd/git/java-sdk/src/main/java/dev/openfeature/sdk/MutableStructure.java:[19,1] Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type. -[WARNING] /home/todd/git/java-sdk/src/main/java/dev/openfeature/sdk/ImmutableStructure.java:[22,1] Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type. [WARNING] /home/todd/git/java-sdk/src/main/java/dev/openfeature/sdk/EventDetails.java:[9,1] Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type. +[WARNING] /home/todd/git/java-sdk/src/main/java/dev/openfeature/sdk/ImmutableStructure.java:[22,1] Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type. +[WARNING] /home/todd/git/java-sdk/src/main/java/dev/openfeature/sdk/MutableStructure.java:[19,1] Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type. [WARNING] /home/todd/git/java-sdk/src/main/java/dev/openfeature/sdk/Value.java:[27,26] finalize() in java.lang.Object has been deprecated and marked for removal [INFO] /home/todd/git/java-sdk/src/main/java/dev/openfeature/sdk/NoOpProvider.java: Some input files use or override a deprecated API. [INFO] /home/todd/git/java-sdk/src/main/java/dev/openfeature/sdk/NoOpProvider.java: Recompile with -Xlint:deprecation for details. [INFO] /home/todd/git/java-sdk/src/main/java/dev/openfeature/sdk/Value.java: Some input files use unchecked or unsafe operations. [INFO] /home/todd/git/java-sdk/src/main/java/dev/openfeature/sdk/Value.java: Recompile with -Xlint:unchecked for details. [INFO] +[INFO] --- checkstyle:3.5.0:check (validate) @ sdk --- +[INFO] Starting audit... +Audit done. +[INFO] You have 0 Checkstyle violations. +[INFO] +[INFO] --- jacoco:0.8.12:prepare-agent (prepare-agent) @ sdk --- +[INFO] surefireArgLine set to -javaagent:/home/todd/.m2/repository/org/jacoco/org.jacoco.agent/0.8.12/org.jacoco.agent-0.8.12-runtime.jar=destfile=/home/todd/git/java-sdk/target/coverage-reports/jacoco-ut.exec +[INFO] +[INFO] --- resources:3.3.1:resources (default-resources) @ sdk --- +[INFO] skip non existing resourceDirectory /home/todd/git/java-sdk/src/main/resources +[INFO] +[INFO] --- compiler:3.13.0:compile (default-compile) @ sdk --- +[INFO] Nothing to compile - all classes are up to date. +[INFO] +[INFO] --- resources:3.3.1:testResources (default-testResources) @ sdk --- +[INFO] Copying 2 resources from src/test/resources to target/test-classes +[INFO] +[INFO] --- compiler:3.13.0:testCompile (default-testCompile) @ sdk --- +[INFO] Recompiling the module because of changed dependency. +[INFO] Compiling 52 source files with javac [debug target 1.8] to target/test-classes +[WARNING] bootstrap class path not set in conjunction with -source 8 +[WARNING] source value 8 is obsolete and will be removed in a future release +[WARNING] target value 8 is obsolete and will be removed in a future release +[WARNING] To suppress warnings about obsolete options, use -Xlint:-options. +[INFO] Annotation processing is enabled because one or more processors were found + on the class path. A future release of javac may disable annotation processing + unless at least one processor is specified by name (-processor), or a search + path is specified (--processor-path, --processor-module-path), or annotation + processing is enabled explicitly (-proc:only, -proc:full). + Use -Xlint:-options to suppress this message. + Use -proc:none to disable annotation processing. +[INFO] /home/todd/git/java-sdk/src/test/java/dev/openfeature/sdk/EventsTest.java: Some input files use or override a deprecated API. +[INFO] /home/todd/git/java-sdk/src/test/java/dev/openfeature/sdk/EventsTest.java: Recompile with -Xlint:deprecation for details. +[INFO] /home/todd/git/java-sdk/src/test/java/dev/openfeature/sdk/HookSpecTest.java: Some input files use unchecked or unsafe operations. +[INFO] /home/todd/git/java-sdk/src/test/java/dev/openfeature/sdk/HookSpecTest.java: Recompile with -Xlint:unchecked for details. +[INFO] +[INFO] >>> jmh:0.2.2:benchmark (default-cli) > process-test-resources @ sdk >>> +[INFO] +[INFO] --- checkstyle:3.5.0:check (validate) @ sdk --- +[INFO] Starting audit... +Audit done. +[INFO] You have 0 Checkstyle violations. +[INFO] +[INFO] --- jacoco:0.8.12:prepare-agent (prepare-agent) @ sdk --- +[INFO] surefireArgLine set to -javaagent:/home/todd/.m2/repository/org/jacoco/org.jacoco.agent/0.8.12/org.jacoco.agent-0.8.12-runtime.jar=destfile=/home/todd/git/java-sdk/target/coverage-reports/jacoco-ut.exec +[INFO] +[INFO] --- resources:3.3.1:resources (default-resources) @ sdk --- +[INFO] skip non existing resourceDirectory /home/todd/git/java-sdk/src/main/resources +[INFO] +[INFO] --- compiler:3.13.0:compile (default-compile) @ sdk --- +[INFO] Nothing to compile - all classes are up to date. +[INFO] [INFO] --- resources:3.3.1:testResources (default-testResources) @ sdk --- [INFO] Copying 2 resources from src/test/resources to target/test-classes [INFO] @@ -59,7 +114,7 @@ Audit done. # JMH version: 1.37 # VM version: JDK 21.0.4, OpenJDK 64-Bit Server VM, 21.0.4+7 # VM invoker: /usr/lib/jvm/java-21-openjdk/bin/java -# VM options: -Xmx1024m -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xmx1024m -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC +# VM options: -Xmx1024m -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC # Blackhole mode: compiler (auto-detected, use -Djmh.blackhole.autoDetect=false to disable) # Warmup: # Measurement: 1 iterations, single-shot each @@ -74,74 +129,74 @@ Audit done. [0.001s][warning][gc,init] Consider enabling -XX:+AlwaysPreTouch to avoid memory commit hiccups Iteration 1: num #instances #bytes class name (module) ------------------------------------------------------- - 1: 1146984 55055232 java.util.HashMap (java.base@21.0.4) - 2: 700056 11200896 java.util.HashMap$EntrySet (java.base@21.0.4) - 3: 47757 9295888 [B (java.base@21.0.4) - 4: 305989 8105752 [Ljava.lang.Object; (java.base@21.0.4) - 5: 482225 7715600 dev.openfeature.sdk.ImmutableStructure - 6: 472225 7555600 dev.openfeature.sdk.ImmutableContext - 7: 100000 4000000 dev.openfeature.sdk.HookContext - 8: 100000 4000000 dev.openfeature.sdk.HookContext$HookContextBuilder - 9: 154 2995712 [Ljdk.internal.vm.FillerElement; (java.base@21.0.4) - 10: 122807 2947368 java.util.ArrayList (java.base@21.0.4) - 11: 50000 2000000 dev.openfeature.sdk.FlagEvaluationDetails - 12: 50000 2000000 dev.openfeature.sdk.ProviderEvaluation - 13: 50002 1600064 java.util.Collections$UnmodifiableMap (java.base@21.0.4) - 14: 100001 1600016 dev.openfeature.sdk.NoOpProvider$$Lambda/0x000074760c02fa78 - 15: 50000 1600000 [Ljava.util.List; (java.base@21.0.4) - 16: 100000 1600000 dev.openfeature.sdk.ImmutableMetadata - 17: 100000 1600000 dev.openfeature.sdk.ImmutableMetadata$ImmutableMetadataBuilder - 18: 100000 1600000 dev.openfeature.sdk.OpenFeatureClient$$Lambda/0x000074760c0821f8 - 19: 43808 1401856 java.util.ArrayList$Itr (java.base@21.0.4) - 20: 50000 1200000 dev.openfeature.sdk.FlagEvaluationOptions - 21: 56919 910704 java.util.Optional (java.base@21.0.4) - 22: 34754 834096 dev.openfeature.sdk.FlagEvaluationOptions$FlagEvaluationOptionsBuilder - 23: 4489 679248 [I (java.base@21.0.4) - 24: 26554 637296 java.lang.String (java.base@21.0.4) - 25: 12462 598176 dev.openfeature.sdk.FlagEvaluationDetails$FlagEvaluationDetailsBuilder - 26: 13748 549920 dev.openfeature.sdk.ProviderEvaluation$ProviderEvaluationBuilder - 27: 16418 394032 dev.openfeature.sdk.HookSupport$$Lambda/0x000074760c081230 - 28: 1461 390008 [J (java.base@21.0.4) - 29: 24033 384528 dev.openfeature.sdk.internal.AutoCloseableReentrantReadWriteLock$$Lambda/0x000074760c02eae8 - 30: 14591 350184 dev.openfeature.sdk.HookSupport$$Lambda/0x000074760c081000 - 31: 2355 288104 java.lang.Class (java.base@21.0.4) - 32: 8141 260512 java.util.HashMap$EntryIterator (java.base@21.0.4) - 33: 4610 258160 jdk.internal.org.objectweb.asm.SymbolTable$Entry (java.base@21.0.4) - 34: 10001 240024 java.lang.Double (java.base@21.0.4) - 35: 2502 180144 java.lang.reflect.Field (java.base@21.0.4) - 36: 10000 160000 dev.openfeature.sdk.Value - 37: 6004 144096 java.lang.StringBuilder (java.base@21.0.4) - 38: 179 139928 [Ljdk.internal.org.objectweb.asm.SymbolTable$Entry; (java.base@21.0.4) - 39: 3824 122368 java.util.concurrent.ConcurrentHashMap$Node (java.base@21.0.4) - 40: 48 122168 [C (java.base@21.0.4) - 41: 1440 113512 [S (java.base@21.0.4) - 42: 1201 105688 java.lang.reflect.Method (java.base@21.0.4) - 43: 3030 79616 [Ljava.lang.Class; (java.base@21.0.4) - 44: 1349 75544 jdk.internal.org.objectweb.asm.Label (java.base@21.0.4) - 45: 1550 74400 java.lang.invoke.MemberName (java.base@21.0.4) - 46: 332 74368 jdk.internal.org.objectweb.asm.MethodWriter (java.base@21.0.4) - 47: 1794 71760 java.lang.invoke.MethodType (java.base@21.0.4) - 48: 1089 69696 java.net.URL (java.base@21.0.4) - 49: 2011 64352 java.util.HashMap$Node (java.base@21.0.4) - 50: 121 50512 [Ljava.util.concurrent.ConcurrentHashMap$Node; (java.base@21.0.4) - 51: 3140 50240 jdk.internal.util.StrongReferenceKey (java.base@21.0.4) - 52: 491 49608 [Ljava.util.HashMap$Node; (java.base@21.0.4) + 1: 1407606 67565088 java.util.HashMap (java.base@21.0.4) + 2: 780500 45970160 [Ljava.util.HashMap$Node; (java.base@21.0.4) + 3: 1152020 36864640 java.util.HashMap$Node (java.base@21.0.4) + 4: 860065 13761040 java.util.HashMap$EntrySet (java.base@21.0.4) + 5: 690006 11040096 dev.openfeature.sdk.Value + 6: 47842 9731792 [B (java.base@21.0.4) + 7: 305994 8105936 [Ljava.lang.Object; (java.base@21.0.4) + 8: 360370 5765920 dev.openfeature.sdk.ImmutableStructure + 9: 350370 5605920 dev.openfeature.sdk.ImmutableContext + 10: 100000 4000000 dev.openfeature.sdk.HookContext + 11: 100000 4000000 dev.openfeature.sdk.HookContext$HookContextBuilder + 12: 116586 2798064 java.util.ArrayList (java.base@21.0.4) + 13: 174 2171368 [Ljdk.internal.vm.FillerElement; (java.base@21.0.4) + 14: 50000 2000000 dev.openfeature.sdk.FlagEvaluationDetails + 15: 50000 2000000 dev.openfeature.sdk.ProviderEvaluation + 16: 62056 1985792 java.util.HashMap$EntryIterator (java.base@21.0.4) + 17: 118262 1892192 java.util.Optional (java.base@21.0.4) + 18: 41643 1665720 dev.openfeature.sdk.ProviderEvaluation$ProviderEvaluationBuilder + 19: 50002 1600064 java.util.Collections$UnmodifiableMap (java.base@21.0.4) + 20: 100001 1600016 dev.openfeature.sdk.NoOpProvider$$Lambda/0x000070b4d802fa78 + 21: 50000 1600000 [Ljava.util.List; (java.base@21.0.4) + 22: 100000 1600000 dev.openfeature.sdk.OpenFeatureClient$$Lambda/0x000070b4d8082a18 + 23: 50000 1200000 dev.openfeature.sdk.FlagEvaluationOptions + 24: 29392 940544 java.util.ArrayList$Itr (java.base@21.0.4) + 25: 57139 914224 dev.openfeature.sdk.ImmutableMetadata + 26: 34240 821760 dev.openfeature.sdk.FlagEvaluationOptions$FlagEvaluationOptionsBuilder + 27: 48782 780512 dev.openfeature.sdk.ImmutableMetadata$ImmutableMetadataBuilder + 28: 4491 721464 [I (java.base@21.0.4) + 29: 26608 638592 java.lang.String (java.base@21.0.4) + 30: 1461 390008 [J (java.base@21.0.4) + 31: 7139 342672 dev.openfeature.sdk.FlagEvaluationDetails$FlagEvaluationDetailsBuilder + 32: 18300 292800 dev.openfeature.sdk.internal.AutoCloseableReentrantReadWriteLock$$Lambda/0x000070b4d802eae8 + 33: 2357 288328 java.lang.Class (java.base@21.0.4) + 34: 4651 260456 jdk.internal.org.objectweb.asm.SymbolTable$Entry (java.base@21.0.4) + 35: 10001 240024 java.lang.Double (java.base@21.0.4) + 36: 9315 223560 dev.openfeature.sdk.HookSupport$$Lambda/0x000070b4d8081bb8 + 37: 7921 190104 dev.openfeature.sdk.HookSupport$$Lambda/0x000070b4d8081988 + 38: 2502 180144 java.lang.reflect.Field (java.base@21.0.4) + 39: 6011 144264 java.lang.StringBuilder (java.base@21.0.4) + 40: 181 142008 [Ljdk.internal.org.objectweb.asm.SymbolTable$Entry; (java.base@21.0.4) + 41: 3829 122528 java.util.concurrent.ConcurrentHashMap$Node (java.base@21.0.4) + 42: 48 122168 [C (java.base@21.0.4) + 43: 1440 113512 [S (java.base@21.0.4) + 44: 1201 105688 java.lang.reflect.Method (java.base@21.0.4) + 45: 3035 79672 [Ljava.lang.Class; (java.base@21.0.4) + 46: 1353 75768 jdk.internal.org.objectweb.asm.Label (java.base@21.0.4) + 47: 1570 75360 java.lang.invoke.MemberName (java.base@21.0.4) + 48: 336 75264 jdk.internal.org.objectweb.asm.MethodWriter (java.base@21.0.4) + 49: 1807 72280 java.lang.invoke.MethodType (java.base@21.0.4) + 50: 1089 69696 java.net.URL (java.base@21.0.4) + 51: 3159 50544 jdk.internal.util.StrongReferenceKey (java.base@21.0.4) + 52: 121 50512 [Ljava.util.concurrent.ConcurrentHashMap$Node; (java.base@21.0.4) 53: 1057 42280 java.io.ObjectStreamField (java.base@21.0.4) 54: 1225 39200 java.io.File (java.base@21.0.4) 55: 779 37392 jdk.internal.org.objectweb.asm.Frame (java.base@21.0.4) - 56: 243 25272 java.util.jar.JarFile$JarFileEntry (java.base@21.0.4) - 57: 793 25224 [Ljava.lang.String; (java.base@21.0.4) + 56: 795 25272 [Ljava.lang.String; (java.base@21.0.4) + 57: 243 25272 java.util.jar.JarFile$JarFileEntry (java.base@21.0.4) 58: 622 24880 java.lang.NoSuchFieldException (java.base@21.0.4) 59: 571 22840 java.util.LinkedHashMap$Entry (java.base@21.0.4) - 60: 473 22704 jdk.internal.ref.CleanerImpl$PhantomCleanableRef (java.base@21.0.4) - 61: 689 22048 jdk.internal.util.WeakReferenceKey (java.base@21.0.4) - 62: 824 19776 jdk.internal.org.objectweb.asm.ByteVector (java.base@21.0.4) + 60: 475 22800 jdk.internal.ref.CleanerImpl$PhantomCleanableRef (java.base@21.0.4) + 61: 692 22144 jdk.internal.util.WeakReferenceKey (java.base@21.0.4) + 62: 832 19968 jdk.internal.org.objectweb.asm.ByteVector (java.base@21.0.4) 63: 248 18848 [Ljava.lang.ref.SoftReference; (java.base@21.0.4) - 64: 117 17784 jdk.internal.org.objectweb.asm.ClassWriter (java.base@21.0.4) + 64: 119 18088 jdk.internal.org.objectweb.asm.ClassWriter (java.base@21.0.4) 65: 380 16824 [Ljava.lang.invoke.LambdaForm$Name; (java.base@21.0.4) 66: 625 15000 java.lang.Long (java.base@21.0.4) 67: 463 14816 java.lang.invoke.LambdaForm$Name (java.base@21.0.4) - 68: 903 14448 java.lang.Object (java.base@21.0.4) + 68: 904 14464 java.lang.Object (java.base@21.0.4) 69: 198 14256 java.lang.reflect.Constructor (java.base@21.0.4) 70: 249 13944 java.util.zip.ZipFile$ZipFileInputStream (java.base@21.0.4) 71: 334 13360 jdk.internal.org.objectweb.asm.Handler (java.base@21.0.4) @@ -151,34 +206,34 @@ Iteration 1: num #instances #bytes class name (module) 75: 102 12240 java.io.ObjectStreamClass (java.base@21.0.4) 76: 249 11952 java.util.zip.ZipFile$ZipFileInflaterInputStream (java.base@21.0.4) 77: 359 11488 jdk.internal.org.objectweb.asm.Type (java.base@21.0.4) - 78: 464 11136 jdk.internal.org.objectweb.asm.Edge (java.base@21.0.4) - 79: 463 11112 java.lang.invoke.ResolvedMethodName (java.base@21.0.4) + 78: 467 11208 java.lang.invoke.ResolvedMethodName (java.base@21.0.4) + 79: 464 11136 jdk.internal.org.objectweb.asm.Edge (java.base@21.0.4) 80: 341 10912 jdk.internal.math.FDBigInteger (java.base@21.0.4) 81: 94 10728 [Ljava.lang.reflect.Field; (java.base@21.0.4) - 82: 266 10640 java.lang.NoSuchMethodException (java.base@21.0.4) - 83: 266 10640 java.security.CodeSource (java.base@21.0.4) - 84: 264 10560 sun.security.util.KnownOIDs (java.base@21.0.4) - 85: 218 10464 java.lang.invoke.DirectMethodHandle$Constructor (java.base@21.0.4) + 82: 223 10704 java.lang.invoke.DirectMethodHandle$Constructor (java.base@21.0.4) + 83: 266 10640 java.lang.NoSuchMethodException (java.base@21.0.4) + 84: 266 10640 java.security.CodeSource (java.base@21.0.4) + 85: 264 10560 sun.security.util.KnownOIDs (java.base@21.0.4) 86: 75 10200 sun.nio.fs.UnixFileAttributes (java.base@21.0.4) - 87: 123 9840 jdk.internal.event.DeserializationEvent (java.base@21.0.4) - 88: 245 9800 java.lang.ref.SoftReference (java.base@21.0.4) + 87: 245 9800 java.lang.ref.SoftReference (java.base@21.0.4) + 88: 118 9440 jdk.internal.event.DeserializationEvent (java.base@21.0.4) 89: 115 9200 [Ljava.util.WeakHashMap$Entry; (java.base@21.0.4) 90: 368 8832 java.lang.module.ModuleDescriptor$Exports (java.base@21.0.4) 91: 63 8384 [Ljava.lang.invoke.MethodHandle; (java.base@21.0.4) 92: 146 8176 java.io.FileCleanable (java.base@21.0.4) 93: 125 8000 java.lang.Class$ReflectionData (java.base@21.0.4) - 94: 322 7728 java.util.ImmutableCollections$Set12 (java.base@21.0.4) - 95: 120 7680 jdk.internal.org.objectweb.asm.SymbolTable (java.base@21.0.4) - 96: 69 7176 java.lang.invoke.InnerClassLambdaMetafactory (java.base@21.0.4) + 94: 122 7808 jdk.internal.org.objectweb.asm.SymbolTable (java.base@21.0.4) + 95: 324 7776 java.util.ImmutableCollections$Set12 (java.base@21.0.4) + 96: 71 7384 java.lang.invoke.InnerClassLambdaMetafactory (java.base@21.0.4) 97: 144 6912 jdk.internal.org.objectweb.asm.AnnotationWriter (java.base@21.0.4) 98: 167 6680 jdk.internal.loader.URLClassPath$JarLoader$2 (java.base@21.0.4) - 99: 196 6272 java.lang.invoke.MethodHandles$Lookup (java.base@21.0.4) + 99: 202 6464 java.lang.invoke.MethodHandles$Lookup (java.base@21.0.4) 100: 156 6240 java.util.StringJoiner (java.base@21.0.4) 101: 153 6120 java.io.FileDescriptor (java.base@21.0.4) 102: 126 6048 java.lang.invoke.LambdaForm (java.base@21.0.4) 103: 77 6016 [Ljava.lang.reflect.Method; (java.base@21.0.4) - 104: 249 5976 java.util.zip.ZipFile$InflaterCleanupAction (java.base@21.0.4) - 105: 370 5920 java.lang.Byte (java.base@21.0.4) + 104: 375 6000 java.lang.Byte (java.base@21.0.4) + 105: 249 5976 java.util.zip.ZipFile$InflaterCleanupAction (java.base@21.0.4) 106: 74 5920 java.util.zip.ZipFile$Source (java.base@21.0.4) 107: 82 5720 [Ljava.io.ObjectStreamField; (java.base@21.0.4) 108: 40 5640 [Ljava.lang.ClassValue$Entry; (java.base@21.0.4) @@ -193,20 +248,20 @@ Iteration 1: num #instances #bytes class name (module) 117: 301 4816 java.util.HashSet (java.base@21.0.4) 118: 75 4800 java.util.zip.Inflater (java.base@21.0.4) truncated... -Total 4474389 138762960 +Total 7264791 244216640 -0.113 s/op - +totalAllocatedBytes: 138762960.000 bytes - +totalAllocatedInstances: 4474389.000 instances +0.166 s/op + +totalAllocatedBytes: 244216640.000 bytes + +totalAllocatedInstances: 7264791.000 instances +totalHeap: 521412608.000 bytes Secondary result "dev.openfeature.sdk.benchmark.AllocationBenchmark.run:+totalAllocatedBytes": - 138762960.000 bytes + 244216640.000 bytes Secondary result "dev.openfeature.sdk.benchmark.AllocationBenchmark.run:+totalAllocatedInstances": - 4474389.000 instances + 7264791.000 instances Secondary result "dev.openfeature.sdk.benchmark.AllocationBenchmark.run:+totalHeap": 521412608.000 bytes @@ -227,13 +282,13 @@ different JVMs are already problematic, the performance difference caused by dif modes can be very significant. Please make sure you use the consistent Blackhole mode for comparisons. Benchmark Mode Cnt Score Error Units -AllocationBenchmark.run ss 0.113 s/op -AllocationBenchmark.run:+totalAllocatedBytes ss 138762960.000 bytes -AllocationBenchmark.run:+totalAllocatedInstances ss 4474389.000 instances +AllocationBenchmark.run ss 0.166 s/op +AllocationBenchmark.run:+totalAllocatedBytes ss 244216640.000 bytes +AllocationBenchmark.run:+totalAllocatedInstances ss 7264791.000 instances AllocationBenchmark.run:+totalHeap ss 521412608.000 bytes [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ -[INFO] Total time: 8.073 s -[INFO] Finished at: 2024-10-10T12:26:18-04:00 +[INFO] Total time: 8.760 s +[INFO] Finished at: 2024-10-23T12:22:21-04:00 [INFO] ------------------------------------------------------------------------ diff --git a/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java b/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java index e6f63a98d..cb9422e32 100644 --- a/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java +++ b/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java @@ -7,6 +7,7 @@ import static dev.openfeature.sdk.testutils.TestFlagsUtils.STRING_FLAG_KEY; import java.util.Map; +import java.util.HashMap; import java.util.Optional; import org.openjdk.jmh.annotations.Benchmark; @@ -41,7 +42,16 @@ public class AllocationBenchmark { public void run() { OpenFeatureAPI.getInstance().setProviderAndWait(new NoOpProvider()); + Map globalAttrs = new HashMap<>(); + globalAttrs.put("global", new Value(1)); + EvaluationContext globalContext = new ImmutableContext(globalAttrs); + OpenFeatureAPI.getInstance().setEvaluationContext(globalContext); + Client client = OpenFeatureAPI.getInstance().getClient(); + + Map clientAttrs = new HashMap<>(); + clientAttrs.put("client", new Value(2)); + client.setEvaluationContext(new ImmutableContext(clientAttrs)); client.addHooks(new Hook() { @Override public Optional before(HookContext ctx, Map hints) { @@ -49,12 +59,16 @@ public Optional before(HookContext ctx, Map invocationAttrs = new HashMap<>(); + invocationAttrs.put("invoke", new Value(3)); + EvaluationContext invocationContext = new ImmutableContext(invocationAttrs); + for (int i = 0; i < ITERATIONS; i++) { client.getBooleanValue(BOOLEAN_FLAG_KEY, false); client.getStringValue(STRING_FLAG_KEY, "default"); client.getIntegerValue(INT_FLAG_KEY, 0); client.getDoubleValue(FLOAT_FLAG_KEY, 0.0); - client.getObjectDetails(OBJECT_FLAG_KEY, new Value(new ImmutableStructure()), new ImmutableContext()); + client.getObjectDetails(OBJECT_FLAG_KEY, new Value(new ImmutableStructure()), invocationContext); } } } From 74958fd261b0154d156d684e0e01360b8f3ba589 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 19:08:29 +0000 Subject: [PATCH 004/745] chore(deps): update actions/checkout digest to 11bd719 (#1183) 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 +- .github/workflows/static-code-scanning.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index 20bd297d2..d3d0569e5 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@163217dfcd28294438ea1c1c149cfaf66eec283e + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - name: Set up JDK 8 uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b with: diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 3dcd59a72..fbff15c1b 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out the code - uses: actions/checkout@163217dfcd28294438ea1c1c149cfaf66eec283e + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - name: Set up JDK 8 uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8ddbd8647..9b1ac3408 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,7 +28,7 @@ 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@163217dfcd28294438ea1c1c149cfaf66eec283e + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - name: Set up JDK 8 if: ${{ steps.release.outputs.release_created }} uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 1da47efc0..8f8ae2b5d 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@163217dfcd28294438ea1c1c149cfaf66eec283e + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL From 7a1eb9b9e94db003e2ada37ecb32cf912eef8766 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 23:25:51 +0000 Subject: [PATCH 005/745] chore(deps): update github/codeql-action digest to 467d7e6 (#1181) 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 fbff15c1b..1a8ee2e80 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@b7cdb7fd39e52d1018799033ccd11eeb108aed85 + uses: github/codeql-action/init@467d7e6d9e138cb28eeebd638e6f0dbab1fd435e with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b7cdb7fd39e52d1018799033ccd11eeb108aed85 + uses: github/codeql-action/analyze@467d7e6d9e138cb28eeebd638e6f0dbab1fd435e diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 8f8ae2b5d..ebd6739fc 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@b7cdb7fd39e52d1018799033ccd11eeb108aed85 + uses: github/codeql-action/init@467d7e6d9e138cb28eeebd638e6f0dbab1fd435e with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@b7cdb7fd39e52d1018799033ccd11eeb108aed85 + uses: github/codeql-action/autobuild@467d7e6d9e138cb28eeebd638e6f0dbab1fd435e - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b7cdb7fd39e52d1018799033ccd11eeb108aed85 + uses: github/codeql-action/analyze@467d7e6d9e138cb28eeebd638e6f0dbab1fd435e From fd7659a46fa7a8c4a04a09217abe7ab228779c7e Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Thu, 24 Oct 2024 08:41:55 -0400 Subject: [PATCH 006/745] perf: reduce hashmap allocations (#1178) * chore: reduce hashmap allocations Signed-off-by: Todd Baert --- CONTRIBUTING.md | 5 +- benchmark.txt | 262 +++++++++--------- .../openfeature/sdk/AbstractStructure.java | 11 +- .../openfeature/sdk/EvaluationContext.java | 39 +++ .../dev/openfeature/sdk/ImmutableContext.java | 29 +- .../openfeature/sdk/ImmutableStructure.java | 13 +- .../dev/openfeature/sdk/MutableContext.java | 11 +- .../openfeature/sdk/OpenFeatureClient.java | 84 +++--- .../java/dev/openfeature/sdk/Structure.java | 47 +--- src/main/java/dev/openfeature/sdk/Value.java | 2 +- 10 files changed, 277 insertions(+), 226 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a5c05c305..2aafb314f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,10 +35,13 @@ mvn test -P e2e There is a small JMH benchmark suite for testing allocations that can be run with: ```sh -mvn -P benchmark test-compile jmh:benchmark -Djmh.f=1 -Djmh.prof='dev.openfeature.sdk.benchmark.AllocationProfiler' +mvn -P benchmark clean compile test-compile jmh:benchmark -Djmh.f=1 -Djmh.prof='dev.openfeature.sdk.benchmark.AllocationProfiler' ``` If you are concerned about the repercussions of a change on memory usage, run this an compare the results to the committed. `benchmark.txt` file. +Note that the ONLY MEANINGFUL RESULTS of this benchmark are the `totalAllocatedBytes` and the `totalAllocatedInstances`. +The `run` score, and maven task time are not relevant since this benchmark is purely memory-related and has nothing to do with speed. +You can also view the heap breakdown to see which objects are taking up the most memory. ## Releasing diff --git a/benchmark.txt b/benchmark.txt index d028a3f87..e43e684d0 100644 --- a/benchmark.txt +++ b/benchmark.txt @@ -36,9 +36,9 @@ Audit done. processing is enabled explicitly (-proc:only, -proc:full). Use -Xlint:-options to suppress this message. Use -proc:none to disable annotation processing. -[WARNING] /home/todd/git/java-sdk/src/main/java/dev/openfeature/sdk/EventDetails.java:[9,1] Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type. -[WARNING] /home/todd/git/java-sdk/src/main/java/dev/openfeature/sdk/ImmutableStructure.java:[22,1] Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type. [WARNING] /home/todd/git/java-sdk/src/main/java/dev/openfeature/sdk/MutableStructure.java:[19,1] Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type. +[WARNING] /home/todd/git/java-sdk/src/main/java/dev/openfeature/sdk/ImmutableStructure.java:[22,1] Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type. +[WARNING] /home/todd/git/java-sdk/src/main/java/dev/openfeature/sdk/EventDetails.java:[9,1] Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type. [WARNING] /home/todd/git/java-sdk/src/main/java/dev/openfeature/sdk/Value.java:[27,26] finalize() in java.lang.Object has been deprecated and marked for removal [INFO] /home/todd/git/java-sdk/src/main/java/dev/openfeature/sdk/NoOpProvider.java: Some input files use or override a deprecated API. [INFO] /home/todd/git/java-sdk/src/main/java/dev/openfeature/sdk/NoOpProvider.java: Recompile with -Xlint:deprecation for details. @@ -129,139 +129,139 @@ Audit done. [0.001s][warning][gc,init] Consider enabling -XX:+AlwaysPreTouch to avoid memory commit hiccups Iteration 1: num #instances #bytes class name (module) ------------------------------------------------------- - 1: 1407606 67565088 java.util.HashMap (java.base@21.0.4) - 2: 780500 45970160 [Ljava.util.HashMap$Node; (java.base@21.0.4) - 3: 1152020 36864640 java.util.HashMap$Node (java.base@21.0.4) - 4: 860065 13761040 java.util.HashMap$EntrySet (java.base@21.0.4) - 5: 690006 11040096 dev.openfeature.sdk.Value - 6: 47842 9731792 [B (java.base@21.0.4) - 7: 305994 8105936 [Ljava.lang.Object; (java.base@21.0.4) - 8: 360370 5765920 dev.openfeature.sdk.ImmutableStructure - 9: 350370 5605920 dev.openfeature.sdk.ImmutableContext - 10: 100000 4000000 dev.openfeature.sdk.HookContext - 11: 100000 4000000 dev.openfeature.sdk.HookContext$HookContextBuilder - 12: 116586 2798064 java.util.ArrayList (java.base@21.0.4) - 13: 174 2171368 [Ljdk.internal.vm.FillerElement; (java.base@21.0.4) - 14: 50000 2000000 dev.openfeature.sdk.FlagEvaluationDetails - 15: 50000 2000000 dev.openfeature.sdk.ProviderEvaluation - 16: 62056 1985792 java.util.HashMap$EntryIterator (java.base@21.0.4) - 17: 118262 1892192 java.util.Optional (java.base@21.0.4) - 18: 41643 1665720 dev.openfeature.sdk.ProviderEvaluation$ProviderEvaluationBuilder - 19: 50002 1600064 java.util.Collections$UnmodifiableMap (java.base@21.0.4) - 20: 100001 1600016 dev.openfeature.sdk.NoOpProvider$$Lambda/0x000070b4d802fa78 - 21: 50000 1600000 [Ljava.util.List; (java.base@21.0.4) - 22: 100000 1600000 dev.openfeature.sdk.OpenFeatureClient$$Lambda/0x000070b4d8082a18 - 23: 50000 1200000 dev.openfeature.sdk.FlagEvaluationOptions - 24: 29392 940544 java.util.ArrayList$Itr (java.base@21.0.4) - 25: 57139 914224 dev.openfeature.sdk.ImmutableMetadata - 26: 34240 821760 dev.openfeature.sdk.FlagEvaluationOptions$FlagEvaluationOptionsBuilder - 27: 48782 780512 dev.openfeature.sdk.ImmutableMetadata$ImmutableMetadataBuilder - 28: 4491 721464 [I (java.base@21.0.4) - 29: 26608 638592 java.lang.String (java.base@21.0.4) - 30: 1461 390008 [J (java.base@21.0.4) - 31: 7139 342672 dev.openfeature.sdk.FlagEvaluationDetails$FlagEvaluationDetailsBuilder - 32: 18300 292800 dev.openfeature.sdk.internal.AutoCloseableReentrantReadWriteLock$$Lambda/0x000070b4d802eae8 - 33: 2357 288328 java.lang.Class (java.base@21.0.4) - 34: 4651 260456 jdk.internal.org.objectweb.asm.SymbolTable$Entry (java.base@21.0.4) - 35: 10001 240024 java.lang.Double (java.base@21.0.4) - 36: 9315 223560 dev.openfeature.sdk.HookSupport$$Lambda/0x000070b4d8081bb8 - 37: 7921 190104 dev.openfeature.sdk.HookSupport$$Lambda/0x000070b4d8081988 - 38: 2502 180144 java.lang.reflect.Field (java.base@21.0.4) - 39: 6011 144264 java.lang.StringBuilder (java.base@21.0.4) - 40: 181 142008 [Ljdk.internal.org.objectweb.asm.SymbolTable$Entry; (java.base@21.0.4) - 41: 3829 122528 java.util.concurrent.ConcurrentHashMap$Node (java.base@21.0.4) - 42: 48 122168 [C (java.base@21.0.4) - 43: 1440 113512 [S (java.base@21.0.4) - 44: 1201 105688 java.lang.reflect.Method (java.base@21.0.4) - 45: 3035 79672 [Ljava.lang.Class; (java.base@21.0.4) - 46: 1353 75768 jdk.internal.org.objectweb.asm.Label (java.base@21.0.4) - 47: 1570 75360 java.lang.invoke.MemberName (java.base@21.0.4) - 48: 336 75264 jdk.internal.org.objectweb.asm.MethodWriter (java.base@21.0.4) - 49: 1807 72280 java.lang.invoke.MethodType (java.base@21.0.4) - 50: 1089 69696 java.net.URL (java.base@21.0.4) - 51: 3159 50544 jdk.internal.util.StrongReferenceKey (java.base@21.0.4) - 52: 121 50512 [Ljava.util.concurrent.ConcurrentHashMap$Node; (java.base@21.0.4) - 53: 1057 42280 java.io.ObjectStreamField (java.base@21.0.4) - 54: 1225 39200 java.io.File (java.base@21.0.4) - 55: 779 37392 jdk.internal.org.objectweb.asm.Frame (java.base@21.0.4) - 56: 795 25272 [Ljava.lang.String; (java.base@21.0.4) - 57: 243 25272 java.util.jar.JarFile$JarFileEntry (java.base@21.0.4) - 58: 622 24880 java.lang.NoSuchFieldException (java.base@21.0.4) - 59: 571 22840 java.util.LinkedHashMap$Entry (java.base@21.0.4) - 60: 475 22800 jdk.internal.ref.CleanerImpl$PhantomCleanableRef (java.base@21.0.4) - 61: 692 22144 jdk.internal.util.WeakReferenceKey (java.base@21.0.4) - 62: 832 19968 jdk.internal.org.objectweb.asm.ByteVector (java.base@21.0.4) - 63: 248 18848 [Ljava.lang.ref.SoftReference; (java.base@21.0.4) - 64: 119 18088 jdk.internal.org.objectweb.asm.ClassWriter (java.base@21.0.4) - 65: 380 16824 [Ljava.lang.invoke.LambdaForm$Name; (java.base@21.0.4) - 66: 625 15000 java.lang.Long (java.base@21.0.4) - 67: 463 14816 java.lang.invoke.LambdaForm$Name (java.base@21.0.4) - 68: 904 14464 java.lang.Object (java.base@21.0.4) - 69: 198 14256 java.lang.reflect.Constructor (java.base@21.0.4) - 70: 249 13944 java.util.zip.ZipFile$ZipFileInputStream (java.base@21.0.4) - 71: 334 13360 jdk.internal.org.objectweb.asm.Handler (java.base@21.0.4) - 72: 202 12928 java.util.concurrent.ConcurrentHashMap (java.base@21.0.4) - 73: 201 12864 jdk.internal.org.objectweb.asm.FieldWriter (java.base@21.0.4) - 74: 316 12640 java.util.WeakHashMap$Entry (java.base@21.0.4) - 75: 102 12240 java.io.ObjectStreamClass (java.base@21.0.4) - 76: 249 11952 java.util.zip.ZipFile$ZipFileInflaterInputStream (java.base@21.0.4) - 77: 359 11488 jdk.internal.org.objectweb.asm.Type (java.base@21.0.4) - 78: 467 11208 java.lang.invoke.ResolvedMethodName (java.base@21.0.4) - 79: 464 11136 jdk.internal.org.objectweb.asm.Edge (java.base@21.0.4) - 80: 341 10912 jdk.internal.math.FDBigInteger (java.base@21.0.4) - 81: 94 10728 [Ljava.lang.reflect.Field; (java.base@21.0.4) - 82: 223 10704 java.lang.invoke.DirectMethodHandle$Constructor (java.base@21.0.4) - 83: 266 10640 java.lang.NoSuchMethodException (java.base@21.0.4) - 84: 266 10640 java.security.CodeSource (java.base@21.0.4) - 85: 264 10560 sun.security.util.KnownOIDs (java.base@21.0.4) - 86: 75 10200 sun.nio.fs.UnixFileAttributes (java.base@21.0.4) - 87: 245 9800 java.lang.ref.SoftReference (java.base@21.0.4) - 88: 118 9440 jdk.internal.event.DeserializationEvent (java.base@21.0.4) - 89: 115 9200 [Ljava.util.WeakHashMap$Entry; (java.base@21.0.4) - 90: 368 8832 java.lang.module.ModuleDescriptor$Exports (java.base@21.0.4) - 91: 63 8384 [Ljava.lang.invoke.MethodHandle; (java.base@21.0.4) - 92: 146 8176 java.io.FileCleanable (java.base@21.0.4) - 93: 125 8000 java.lang.Class$ReflectionData (java.base@21.0.4) - 94: 122 7808 jdk.internal.org.objectweb.asm.SymbolTable (java.base@21.0.4) - 95: 324 7776 java.util.ImmutableCollections$Set12 (java.base@21.0.4) - 96: 71 7384 java.lang.invoke.InnerClassLambdaMetafactory (java.base@21.0.4) - 97: 144 6912 jdk.internal.org.objectweb.asm.AnnotationWriter (java.base@21.0.4) - 98: 167 6680 jdk.internal.loader.URLClassPath$JarLoader$2 (java.base@21.0.4) - 99: 202 6464 java.lang.invoke.MethodHandles$Lookup (java.base@21.0.4) - 100: 156 6240 java.util.StringJoiner (java.base@21.0.4) - 101: 153 6120 java.io.FileDescriptor (java.base@21.0.4) - 102: 126 6048 java.lang.invoke.LambdaForm (java.base@21.0.4) - 103: 77 6016 [Ljava.lang.reflect.Method; (java.base@21.0.4) - 104: 375 6000 java.lang.Byte (java.base@21.0.4) - 105: 249 5976 java.util.zip.ZipFile$InflaterCleanupAction (java.base@21.0.4) - 106: 74 5920 java.util.zip.ZipFile$Source (java.base@21.0.4) - 107: 82 5720 [Ljava.io.ObjectStreamField; (java.base@21.0.4) - 108: 40 5640 [Ljava.lang.ClassValue$Entry; (java.base@21.0.4) - 109: 234 5616 java.util.jar.Attributes$Name (java.base@21.0.4) - 110: 174 5568 java.util.concurrent.locks.ReentrantLock$NonfairSync (java.base@21.0.4) - 111: 98 5488 java.lang.Module (java.base@21.0.4) - 112: 219 5256 java.lang.PublicMethods$MethodList (java.base@21.0.4) - 113: 65 5200 java.net.URI (java.base@21.0.4) - 114: 215 5104 [Ljdk.internal.org.objectweb.asm.Type; (java.base@21.0.4) - 115: 158 5056 java.lang.invoke.MethodTypeForm (java.base@21.0.4) - 116: 152 4864 java.nio.file.attribute.FileTime (java.base@21.0.4) - 117: 301 4816 java.util.HashSet (java.base@21.0.4) - 118: 75 4800 java.util.zip.Inflater (java.base@21.0.4) + 1: 480234 23051232 java.util.HashMap (java.base@21.0.4) + 2: 150497 12050088 [Ljava.util.HashMap$Node; (java.base@21.0.4) + 3: 332017 10624544 java.util.HashMap$Node (java.base@21.0.4) + 4: 47815 9732480 [B (java.base@21.0.4) + 5: 305991 8105872 [Ljava.lang.Object; (java.base@21.0.4) + 6: 366682 5866912 java.util.Optional (java.base@21.0.4) + 7: 183332 5866624 java.util.HashMap$EntryIterator (java.base@21.0.4) + 8: 172970 5535040 java.util.Collections$UnmodifiableMap (java.base@21.0.4) + 9: 100000 4000000 dev.openfeature.sdk.HookContext + 10: 100000 4000000 dev.openfeature.sdk.HookContext$HookContextBuilder + 11: 230006 3680096 dev.openfeature.sdk.Value + 12: 200062 3200992 java.util.HashMap$EntrySet (java.base@21.0.4) + 13: 132870 3188880 java.util.ArrayList (java.base@21.0.4) + 14: 192292 3076672 dev.openfeature.sdk.ImmutableStructure + 15: 182292 2916672 dev.openfeature.sdk.ImmutableContext + 16: 50000 2000000 dev.openfeature.sdk.FlagEvaluationDetails + 17: 50000 2000000 dev.openfeature.sdk.ProviderEvaluation + 18: 122968 1967488 java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet (java.base@21.0.4) + 19: 149 1884376 [Ljdk.internal.vm.FillerElement; (java.base@21.0.4) + 20: 56476 1807232 java.util.ArrayList$Itr (java.base@21.0.4) + 21: 37481 1799088 dev.openfeature.sdk.FlagEvaluationDetails$FlagEvaluationDetailsBuilder + 22: 100001 1600016 dev.openfeature.sdk.NoOpProvider$$Lambda/0x000076e79c02fa78 + 23: 50000 1600000 [Ldev.openfeature.sdk.EvaluationContext; + 24: 50000 1600000 [Ljava.util.List; (java.base@21.0.4) + 25: 100000 1600000 dev.openfeature.sdk.OpenFeatureClient$$Lambda/0x000076e79c082800 + 26: 36720 1468800 dev.openfeature.sdk.ProviderEvaluation$ProviderEvaluationBuilder + 27: 87481 1399696 dev.openfeature.sdk.ImmutableMetadata + 28: 50000 1200000 dev.openfeature.sdk.FlagEvaluationOptions + 29: 74201 1187216 dev.openfeature.sdk.ImmutableMetadata$ImmutableMetadataBuilder + 30: 73235 1171760 java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry (java.base@21.0.4) + 31: 45869 1100856 java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$1 (java.base@21.0.4) + 32: 43776 1050624 dev.openfeature.sdk.FlagEvaluationOptions$FlagEvaluationOptionsBuilder + 33: 40016 960384 dev.openfeature.sdk.HookSupport$$Lambda/0x000076e79c081b78 + 34: 39967 959208 dev.openfeature.sdk.HookSupport$$Lambda/0x000076e79c081da8 + 35: 57783 924528 dev.openfeature.sdk.internal.AutoCloseableReentrantReadWriteLock$$Lambda/0x000076e79c02eae8 + 36: 4490 721440 [I (java.base@21.0.4) + 37: 26594 638256 java.lang.String (java.base@21.0.4) + 38: 1461 390008 [J (java.base@21.0.4) + 39: 2361 288784 java.lang.Class (java.base@21.0.4) + 40: 4632 259392 jdk.internal.org.objectweb.asm.SymbolTable$Entry (java.base@21.0.4) + 41: 10001 240024 java.lang.Double (java.base@21.0.4) + 42: 2502 180144 java.lang.reflect.Field (java.base@21.0.4) + 43: 6007 144168 java.lang.StringBuilder (java.base@21.0.4) + 44: 180 140968 [Ljdk.internal.org.objectweb.asm.SymbolTable$Entry; (java.base@21.0.4) + 45: 3827 122464 java.util.concurrent.ConcurrentHashMap$Node (java.base@21.0.4) + 46: 48 122168 [C (java.base@21.0.4) + 47: 1440 113512 [S (java.base@21.0.4) + 48: 1201 105688 java.lang.reflect.Method (java.base@21.0.4) + 49: 3031 79600 [Ljava.lang.Class; (java.base@21.0.4) + 50: 1351 75656 jdk.internal.org.objectweb.asm.Label (java.base@21.0.4) + 51: 1561 74928 java.lang.invoke.MemberName (java.base@21.0.4) + 52: 334 74816 jdk.internal.org.objectweb.asm.MethodWriter (java.base@21.0.4) + 53: 1799 71960 java.lang.invoke.MethodType (java.base@21.0.4) + 54: 1089 69696 java.net.URL (java.base@21.0.4) + 55: 121 50512 [Ljava.util.concurrent.ConcurrentHashMap$Node; (java.base@21.0.4) + 56: 3147 50352 jdk.internal.util.StrongReferenceKey (java.base@21.0.4) + 57: 1057 42280 java.io.ObjectStreamField (java.base@21.0.4) + 58: 1225 39200 java.io.File (java.base@21.0.4) + 59: 779 37392 jdk.internal.org.objectweb.asm.Frame (java.base@21.0.4) + 60: 243 25272 java.util.jar.JarFile$JarFileEntry (java.base@21.0.4) + 61: 794 25248 [Ljava.lang.String; (java.base@21.0.4) + 62: 622 24880 java.lang.NoSuchFieldException (java.base@21.0.4) + 63: 571 22840 java.util.LinkedHashMap$Entry (java.base@21.0.4) + 64: 474 22752 jdk.internal.ref.CleanerImpl$PhantomCleanableRef (java.base@21.0.4) + 65: 690 22080 jdk.internal.util.WeakReferenceKey (java.base@21.0.4) + 66: 828 19872 jdk.internal.org.objectweb.asm.ByteVector (java.base@21.0.4) + 67: 248 18848 [Ljava.lang.ref.SoftReference; (java.base@21.0.4) + 68: 118 17936 jdk.internal.org.objectweb.asm.ClassWriter (java.base@21.0.4) + 69: 380 16824 [Ljava.lang.invoke.LambdaForm$Name; (java.base@21.0.4) + 70: 625 15000 java.lang.Long (java.base@21.0.4) + 71: 463 14816 java.lang.invoke.LambdaForm$Name (java.base@21.0.4) + 72: 904 14464 java.lang.Object (java.base@21.0.4) + 73: 198 14256 java.lang.reflect.Constructor (java.base@21.0.4) + 74: 249 13944 java.util.zip.ZipFile$ZipFileInputStream (java.base@21.0.4) + 75: 334 13360 jdk.internal.org.objectweb.asm.Handler (java.base@21.0.4) + 76: 202 12928 java.util.concurrent.ConcurrentHashMap (java.base@21.0.4) + 77: 201 12864 jdk.internal.org.objectweb.asm.FieldWriter (java.base@21.0.4) + 78: 316 12640 java.util.WeakHashMap$Entry (java.base@21.0.4) + 79: 102 12240 java.io.ObjectStreamClass (java.base@21.0.4) + 80: 249 11952 java.util.zip.ZipFile$ZipFileInflaterInputStream (java.base@21.0.4) + 81: 359 11488 jdk.internal.org.objectweb.asm.Type (java.base@21.0.4) + 82: 465 11160 java.lang.invoke.ResolvedMethodName (java.base@21.0.4) + 83: 464 11136 jdk.internal.org.objectweb.asm.Edge (java.base@21.0.4) + 84: 341 10912 jdk.internal.math.FDBigInteger (java.base@21.0.4) + 85: 94 10728 [Ljava.lang.reflect.Field; (java.base@21.0.4) + 86: 266 10640 java.lang.NoSuchMethodException (java.base@21.0.4) + 87: 266 10640 java.security.CodeSource (java.base@21.0.4) + 88: 221 10608 java.lang.invoke.DirectMethodHandle$Constructor (java.base@21.0.4) + 89: 264 10560 sun.security.util.KnownOIDs (java.base@21.0.4) + 90: 75 10200 sun.nio.fs.UnixFileAttributes (java.base@21.0.4) + 91: 245 9800 java.lang.ref.SoftReference (java.base@21.0.4) + 92: 118 9440 jdk.internal.event.DeserializationEvent (java.base@21.0.4) + 93: 115 9200 [Ljava.util.WeakHashMap$Entry; (java.base@21.0.4) + 94: 368 8832 java.lang.module.ModuleDescriptor$Exports (java.base@21.0.4) + 95: 63 8384 [Ljava.lang.invoke.MethodHandle; (java.base@21.0.4) + 96: 146 8176 java.io.FileCleanable (java.base@21.0.4) + 97: 125 8000 java.lang.Class$ReflectionData (java.base@21.0.4) + 98: 323 7752 java.util.ImmutableCollections$Set12 (java.base@21.0.4) + 99: 121 7744 jdk.internal.org.objectweb.asm.SymbolTable (java.base@21.0.4) + 100: 70 7280 java.lang.invoke.InnerClassLambdaMetafactory (java.base@21.0.4) + 101: 144 6912 jdk.internal.org.objectweb.asm.AnnotationWriter (java.base@21.0.4) + 102: 167 6680 jdk.internal.loader.URLClassPath$JarLoader$2 (java.base@21.0.4) + 103: 199 6368 java.lang.invoke.MethodHandles$Lookup (java.base@21.0.4) + 104: 156 6240 java.util.StringJoiner (java.base@21.0.4) + 105: 153 6120 java.io.FileDescriptor (java.base@21.0.4) + 106: 126 6048 java.lang.invoke.LambdaForm (java.base@21.0.4) + 107: 77 6016 [Ljava.lang.reflect.Method; (java.base@21.0.4) + 108: 249 5976 java.util.zip.ZipFile$InflaterCleanupAction (java.base@21.0.4) + 109: 373 5968 java.lang.Byte (java.base@21.0.4) + 110: 74 5920 java.util.zip.ZipFile$Source (java.base@21.0.4) + 111: 82 5720 [Ljava.io.ObjectStreamField; (java.base@21.0.4) + 112: 40 5640 [Ljava.lang.ClassValue$Entry; (java.base@21.0.4) + 113: 234 5616 java.util.jar.Attributes$Name (java.base@21.0.4) + 114: 174 5568 java.util.concurrent.locks.ReentrantLock$NonfairSync (java.base@21.0.4) + 115: 98 5488 java.lang.Module (java.base@21.0.4) + 116: 219 5256 java.lang.PublicMethods$MethodList (java.base@21.0.4) + 117: 65 5200 java.net.URI (java.base@21.0.4) + 118: 215 5104 [Ljdk.internal.org.objectweb.asm.Type; (java.base@21.0.4) truncated... -Total 7264791 244216640 +Total 4452140 139359040 -0.166 s/op - +totalAllocatedBytes: 244216640.000 bytes - +totalAllocatedInstances: 7264791.000 instances +0.186 s/op + +totalAllocatedBytes: 139359040.000 bytes + +totalAllocatedInstances: 4452140.000 instances +totalHeap: 521412608.000 bytes Secondary result "dev.openfeature.sdk.benchmark.AllocationBenchmark.run:+totalAllocatedBytes": - 244216640.000 bytes + 139359040.000 bytes Secondary result "dev.openfeature.sdk.benchmark.AllocationBenchmark.run:+totalAllocatedInstances": - 7264791.000 instances + 4452140.000 instances Secondary result "dev.openfeature.sdk.benchmark.AllocationBenchmark.run:+totalHeap": 521412608.000 bytes @@ -282,13 +282,13 @@ different JVMs are already problematic, the performance difference caused by dif modes can be very significant. Please make sure you use the consistent Blackhole mode for comparisons. Benchmark Mode Cnt Score Error Units -AllocationBenchmark.run ss 0.166 s/op -AllocationBenchmark.run:+totalAllocatedBytes ss 244216640.000 bytes -AllocationBenchmark.run:+totalAllocatedInstances ss 7264791.000 instances +AllocationBenchmark.run ss 0.186 s/op +AllocationBenchmark.run:+totalAllocatedBytes ss 139359040.000 bytes +AllocationBenchmark.run:+totalAllocatedInstances ss 4452140.000 instances AllocationBenchmark.run:+totalHeap ss 521412608.000 bytes [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ -[INFO] Total time: 8.760 s -[INFO] Finished at: 2024-10-23T12:22:21-04:00 +[INFO] Total time: 8.280 s +[INFO] Finished at: 2024-10-23T12:37:24-04:00 [INFO] ------------------------------------------------------------------------ diff --git a/src/main/java/dev/openfeature/sdk/AbstractStructure.java b/src/main/java/dev/openfeature/sdk/AbstractStructure.java index 13a6cf6cb..86fdde41a 100644 --- a/src/main/java/dev/openfeature/sdk/AbstractStructure.java +++ b/src/main/java/dev/openfeature/sdk/AbstractStructure.java @@ -2,6 +2,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.Collections; @SuppressWarnings({ "PMD.BeanMembersShouldSerialize", "checkstyle:MissingJavadocType" }) abstract class AbstractStructure implements Structure { @@ -18,7 +19,15 @@ public boolean isEmpty() { } AbstractStructure(Map attributes) { - this.attributes = new HashMap<>(attributes); + this.attributes = attributes; + } + + /** + * Returns an unmodifiable representation of the internal attribute map. + * @return immutable map + */ + public Map asUnmodifiableMap() { + return Collections.unmodifiableMap(attributes); } /** diff --git a/src/main/java/dev/openfeature/sdk/EvaluationContext.java b/src/main/java/dev/openfeature/sdk/EvaluationContext.java index b95ea454d..5b2a33113 100644 --- a/src/main/java/dev/openfeature/sdk/EvaluationContext.java +++ b/src/main/java/dev/openfeature/sdk/EvaluationContext.java @@ -1,5 +1,9 @@ package dev.openfeature.sdk; +import java.util.Map; +import java.util.Map.Entry; +import java.util.function.Function; + /** * The EvaluationContext is a container for arbitrary contextual data * that can be used as a basis for dynamic evaluation. @@ -19,4 +23,39 @@ public interface EvaluationContext extends Structure { * @return resulting merged context */ EvaluationContext merge(EvaluationContext overridingContext); + + /** + * Recursively merges the overriding map into the base Value map. + * The base map is mutated, the overriding map is not. + * Null maps will cause no-op. + * + * @param newStructure function to create the right structure(s) for Values + * @param base base map to merge + * @param overriding overriding map to merge + */ + static void mergeMaps(Function, Structure> newStructure, + Map base, + Map overriding) { + + if (base == null) { + return; + } + if (overriding == null || overriding.isEmpty()) { + return; + } + + for (Entry overridingEntry : overriding.entrySet()) { + String key = overridingEntry.getKey(); + if (overridingEntry.getValue().isStructure() && base.containsKey(key) && base.get(key).isStructure()) { + Structure mergedValue = base.get(key).asStructure(); + Structure overridingValue = overridingEntry.getValue().asStructure(); + Map newMap = mergedValue.asMap(); + mergeMaps(newStructure, newMap, + overridingValue.asUnmodifiableMap()); + base.put(key, new Value(newStructure.apply(newMap))); + } else { + base.put(key, overridingEntry.getValue()); + } + } + } } diff --git a/src/main/java/dev/openfeature/sdk/ImmutableContext.java b/src/main/java/dev/openfeature/sdk/ImmutableContext.java index 9b27cdd59..d0dae6051 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableContext.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableContext.java @@ -3,6 +3,7 @@ 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; @@ -10,7 +11,8 @@ /** * The EvaluationContext is a container for arbitrary contextual data * that can be used as a basis for dynamic evaluation. - * The ImmutableContext is an EvaluationContext implementation which is threadsafe, and whose attributes can + * The ImmutableContext is an EvaluationContext implementation which is + * threadsafe, and whose attributes can * not be modified after instantiation. */ @ToString @@ -21,7 +23,8 @@ public final class ImmutableContext implements EvaluationContext { private final ImmutableStructure structure; /** - * Create an immutable context with an empty targeting_key and attributes provided. + * Create an immutable context with an empty targeting_key and attributes + * provided. */ public ImmutableContext() { this(new HashMap<>()); @@ -42,7 +45,7 @@ public ImmutableContext(String targetingKey) { * @param attributes evaluation context attributes */ public ImmutableContext(Map attributes) { - this("", attributes); + this(null, attributes); } /** @@ -53,9 +56,7 @@ public ImmutableContext(Map attributes) { */ public ImmutableContext(String targetingKey, Map attributes) { if (targetingKey != null && !targetingKey.trim().isEmpty()) { - final Map actualAttribs = new HashMap<>(attributes); - actualAttribs.put(TARGETING_KEY, new Value(targetingKey)); - this.structure = new ImmutableStructure(actualAttribs); + this.structure = new ImmutableStructure(targetingKey, attributes); } else { this.structure = new ImmutableStructure(attributes); } @@ -71,7 +72,8 @@ public String getTargetingKey() { } /** - * Merges this EvaluationContext object with the passed EvaluationContext, overriding in case of conflict. + * Merges this EvaluationContext object with the passed EvaluationContext, + * overriding in case of conflict. * * @param overridingContext overriding context * @return new, resulting merged context @@ -79,23 +81,24 @@ public String getTargetingKey() { @Override public EvaluationContext merge(EvaluationContext overridingContext) { if (overridingContext == null || overridingContext.isEmpty()) { - return new ImmutableContext(this.asMap()); + return new ImmutableContext(this.asUnmodifiableMap()); } if (this.isEmpty()) { - return new ImmutableContext(overridingContext.asMap()); + return new ImmutableContext(overridingContext.asUnmodifiableMap()); } - return new ImmutableContext( - this.merge(ImmutableStructure::new, this.asMap(), overridingContext.asMap())); + Map attributes = this.asMap(); + EvaluationContext.mergeMaps(ImmutableStructure::new, attributes, + overridingContext.asUnmodifiableMap()); + return new ImmutableContext(attributes); } @SuppressWarnings("all") private static class DelegateExclusions { @ExcludeFromGeneratedCoverageReport - public Map merge(Function, Structure> newStructure, + public Map merge(Function, Structure> newStructure, Map base, Map overriding) { - return null; } } diff --git a/src/main/java/dev/openfeature/sdk/ImmutableStructure.java b/src/main/java/dev/openfeature/sdk/ImmutableStructure.java index 170602000..06c2551ff 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableStructure.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableStructure.java @@ -36,7 +36,11 @@ public ImmutableStructure() { * @param attributes attributes. */ public ImmutableStructure(Map attributes) { - super(copyAttributes(attributes)); + super(copyAttributes(attributes, null)); + } + + protected ImmutableStructure(String targetingKey, Map attributes) { + super(copyAttributes(attributes, targetingKey)); } @Override @@ -62,11 +66,18 @@ public Map asMap() { } private static Map copyAttributes(Map in) { + return copyAttributes(in, null); + } + + 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 (targetingKey != null) { + copy.put(EvaluationContext.TARGETING_KEY, new Value(targetingKey)); + } return copy; } diff --git a/src/main/java/dev/openfeature/sdk/MutableContext.java b/src/main/java/dev/openfeature/sdk/MutableContext.java index 6a47c83ef..ffab28af2 100644 --- a/src/main/java/dev/openfeature/sdk/MutableContext.java +++ b/src/main/java/dev/openfeature/sdk/MutableContext.java @@ -33,7 +33,7 @@ public MutableContext(String targetingKey) { } public MutableContext(Map attributes) { - this("", attributes); + this(null, new HashMap<>(attributes)); } /** @@ -44,7 +44,7 @@ public MutableContext(Map attributes) { * @param attributes evaluation context attributes */ public MutableContext(String targetingKey, Map attributes) { - this.structure = new MutableStructure(attributes); + this.structure = new MutableStructure(new HashMap<>(attributes)); if (targetingKey != null && !targetingKey.trim().isEmpty()) { this.structure.attributes.put(TARGETING_KEY, new Value(targetingKey)); } @@ -121,9 +121,10 @@ public EvaluationContext merge(EvaluationContext overridingContext) { return overridingContext; } - Map merged = this.merge( - MutableStructure::new, this.asMap(), overridingContext.asMap()); - return new MutableContext(merged); + Map attributes = this.asMap(); + EvaluationContext.mergeMaps( + MutableStructure::new, attributes, overridingContext.asUnmodifiableMap()); + return new MutableContext(attributes); } /** diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index 2162f4130..f56df15a0 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -1,15 +1,24 @@ package dev.openfeature.sdk; -import dev.openfeature.sdk.exceptions.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.List; +import java.util.function.Consumer; + +import dev.openfeature.sdk.exceptions.ExceptionUtils; +import dev.openfeature.sdk.exceptions.FatalError; +import dev.openfeature.sdk.exceptions.GeneralError; +import dev.openfeature.sdk.exceptions.OpenFeatureError; +import dev.openfeature.sdk.exceptions.ProviderNotReadyError; import dev.openfeature.sdk.internal.AutoCloseableLock; import dev.openfeature.sdk.internal.AutoCloseableReentrantReadWriteLock; import dev.openfeature.sdk.internal.ObjectUtils; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import java.util.*; -import java.util.function.Consumer; - /** * OpenFeature Client implementation. * You should not instantiate this or reference this class. @@ -19,8 +28,8 @@ * @deprecated // TODO: eventually we will make this non-public. See issue #872 */ @Slf4j -@SuppressWarnings({"PMD.DataflowAnomalyAnalysis", "PMD.BeanMembersShouldSerialize", "PMD.UnusedLocalVariable", - "unchecked", "rawtypes"}) +@SuppressWarnings({ "PMD.DataflowAnomalyAnalysis", "PMD.BeanMembersShouldSerialize", "PMD.UnusedLocalVariable", + "unchecked", "rawtypes" }) @Deprecated() // TODO: eventually we will make this non-public. See issue #872 public class OpenFeatureClient implements Client { @@ -39,18 +48,18 @@ public class OpenFeatureClient implements Client { * Deprecated public constructor. Use OpenFeature.API.getClient() instead. * * @param openFeatureAPI Backing global singleton - * @param domain An identifier which logically binds clients with providers (used by observability tools). + * @param domain An identifier which logically binds clients with + * providers (used by observability tools). * @param version Version of the client (used by observability tools). * @deprecated Do not use this constructor. It's for internal use only. - * Clients created using it will not run event handlers. - * Use the OpenFeatureAPI's getClient factory method instead. + * Clients created using it will not run event handlers. + * Use the OpenFeatureAPI's getClient factory method instead. */ @Deprecated() // TODO: eventually we will make this non-public. See issue #872 public OpenFeatureClient( OpenFeatureAPI openFeatureAPI, String domain, - String version - ) { + String version) { this.openfeatureApi = openFeatureAPI; this.domain = domain; this.version = version; @@ -106,11 +115,10 @@ public EvaluationContext getEvaluationContext() { } private FlagEvaluationDetails evaluateFlag(FlagValueType type, String key, T defaultValue, - EvaluationContext ctx, FlagEvaluationOptions options) { + EvaluationContext ctx, FlagEvaluationOptions options) { FlagEvaluationOptions flagOptions = ObjectUtils.defaultIfNull(options, () -> FlagEvaluationOptions.builder().build()); Map hints = Collections.unmodifiableMap(flagOptions.getHookHints()); - ctx = ObjectUtils.defaultIfNull(ctx, () -> new ImmutableContext()); FlagEvaluationDetails details = null; List mergedHooks = null; @@ -183,17 +191,23 @@ private static void enrichDetailsWithErrorDefaults(T defaultValue, FlagEvalu * @return merged evaluation context */ private EvaluationContext mergeEvaluationContext(EvaluationContext invocationContext) { - final EvaluationContext apiContext = openfeatureApi.getEvaluationContext() != null - ? openfeatureApi.getEvaluationContext() - : new ImmutableContext(); - final EvaluationContext clientContext = this.getEvaluationContext() != null - ? this.getEvaluationContext() - : new ImmutableContext(); - final EvaluationContext transactionContext = openfeatureApi.getTransactionContext() != null - ? openfeatureApi.getTransactionContext() - : new ImmutableContext(); - - return apiContext.merge(transactionContext.merge(clientContext.merge(invocationContext))); + final EvaluationContext apiContext = openfeatureApi.getEvaluationContext(); + final EvaluationContext clientContext = this.getEvaluationContext(); + final EvaluationContext transactionContext = openfeatureApi.getTransactionContext(); + return mergeContextMaps(apiContext, transactionContext, clientContext, invocationContext); + } + + private EvaluationContext mergeContextMaps(EvaluationContext... contexts) { + // avoid any unnecessary context instantiations and stream usage here; this is + // called with every evaluation. + Map merged = new HashMap<>(); + for (EvaluationContext evaluationContext : contexts) { + if (evaluationContext != null && !evaluationContext.isEmpty()) { + EvaluationContext.mergeMaps(ImmutableStructure::new, merged, + evaluationContext.asUnmodifiableMap()); + } + } + return new ImmutableContext(merged); } private ProviderEvaluation createProviderEvaluation( @@ -230,7 +244,7 @@ public Boolean getBooleanValue(String key, Boolean defaultValue, EvaluationConte @Override public Boolean getBooleanValue(String key, Boolean defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + FlagEvaluationOptions options) { return getBooleanDetails(key, defaultValue, ctx, options).getValue(); } @@ -246,7 +260,7 @@ public FlagEvaluationDetails getBooleanDetails(String key, Boolean defa @Override public FlagEvaluationDetails getBooleanDetails(String key, Boolean defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + FlagEvaluationOptions options) { return this.evaluateFlag(FlagValueType.BOOLEAN, key, defaultValue, ctx, options); } @@ -262,7 +276,7 @@ public String getStringValue(String key, String defaultValue, EvaluationContext @Override public String getStringValue(String key, String defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + FlagEvaluationOptions options) { return getStringDetails(key, defaultValue, ctx, options).getValue(); } @@ -278,7 +292,7 @@ public FlagEvaluationDetails getStringDetails(String key, String default @Override public FlagEvaluationDetails getStringDetails(String key, String defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + FlagEvaluationOptions options) { return this.evaluateFlag(FlagValueType.STRING, key, defaultValue, ctx, options); } @@ -294,7 +308,7 @@ public Integer getIntegerValue(String key, Integer defaultValue, EvaluationConte @Override public Integer getIntegerValue(String key, Integer defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + FlagEvaluationOptions options) { return getIntegerDetails(key, defaultValue, ctx, options).getValue(); } @@ -310,7 +324,7 @@ public FlagEvaluationDetails getIntegerDetails(String key, Integer defa @Override public FlagEvaluationDetails getIntegerDetails(String key, Integer defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + FlagEvaluationOptions options) { return this.evaluateFlag(FlagValueType.INTEGER, key, defaultValue, ctx, options); } @@ -326,7 +340,7 @@ public Double getDoubleValue(String key, Double defaultValue, EvaluationContext @Override public Double getDoubleValue(String key, Double defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + FlagEvaluationOptions options) { return this.evaluateFlag(FlagValueType.DOUBLE, key, defaultValue, ctx, options).getValue(); } @@ -342,7 +356,7 @@ public FlagEvaluationDetails getDoubleDetails(String key, Double default @Override public FlagEvaluationDetails getDoubleDetails(String key, Double defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + FlagEvaluationOptions options) { return this.evaluateFlag(FlagValueType.DOUBLE, key, defaultValue, ctx, options); } @@ -358,7 +372,7 @@ public Value getObjectValue(String key, Value defaultValue, EvaluationContext ct @Override public Value getObjectValue(String key, Value defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + FlagEvaluationOptions options) { return getObjectDetails(key, defaultValue, ctx, options).getValue(); } @@ -369,13 +383,13 @@ public FlagEvaluationDetails getObjectDetails(String key, Value defaultVa @Override public FlagEvaluationDetails getObjectDetails(String key, Value defaultValue, - EvaluationContext ctx) { + EvaluationContext ctx) { return getObjectDetails(key, defaultValue, ctx, FlagEvaluationOptions.builder().build()); } @Override public FlagEvaluationDetails getObjectDetails(String key, Value defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + FlagEvaluationOptions options) { return this.evaluateFlag(FlagValueType.OBJECT, key, defaultValue, ctx, options); } diff --git a/src/main/java/dev/openfeature/sdk/Structure.java b/src/main/java/dev/openfeature/sdk/Structure.java index 02e36629e..f2fdc53e7 100644 --- a/src/main/java/dev/openfeature/sdk/Structure.java +++ b/src/main/java/dev/openfeature/sdk/Structure.java @@ -5,8 +5,6 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; -import java.util.Map.Entry; -import java.util.function.Function; import java.util.stream.Collectors; import static dev.openfeature.sdk.Value.objectToValue; @@ -46,6 +44,14 @@ public interface Structure { */ Map asMap(); + /** + * Get all values, as a map of Values. + * + * @return all attributes on the structure into a Map + */ + Map asUnmodifiableMap(); + + /** * Get all values, with as a map of Object. * @@ -95,7 +101,7 @@ default Object convertValue(Value value) { if (value.isStructure()) { Structure s = value.asStructure(); - return s.asMap() + return s.asUnmodifiableMap() .entrySet() .stream() .collect(HashMap::new, @@ -107,41 +113,6 @@ default Object convertValue(Value value) { throw new ValueNotConvertableError(); } - /** - * Recursively merges the base map with the overriding map. - * - * @param Structure type - * @param newStructure function to create the right structure - * @param base base map to merge - * @param overriding overriding map to merge - * @return resulting merged map - */ - default Map merge(Function, Structure> newStructure, - Map base, - Map overriding) { - - if (base.isEmpty()) { - return overriding; - } - if (overriding.isEmpty()) { - return base; - } - - final Map merged = new HashMap<>(base); - for (Entry overridingEntry : overriding.entrySet()) { - String key = overridingEntry.getKey(); - if (overridingEntry.getValue().isStructure() && merged.containsKey(key) && merged.get(key).isStructure()) { - Structure mergedValue = merged.get(key).asStructure(); - Structure overridingValue = overridingEntry.getValue().asStructure(); - Map newMap = this.merge(newStructure, mergedValue.asMap(), overridingValue.asMap()); - merged.put(key, new Value(newStructure.apply(newMap))); - } else { - merged.put(key, overridingEntry.getValue()); - } - } - return merged; - } - /** * Transform an object map to a {@link Structure} type. * diff --git a/src/main/java/dev/openfeature/sdk/Value.java b/src/main/java/dev/openfeature/sdk/Value.java index f0fdc8d45..7464ce5af 100644 --- a/src/main/java/dev/openfeature/sdk/Value.java +++ b/src/main/java/dev/openfeature/sdk/Value.java @@ -274,7 +274,7 @@ protected Value clone() { return new Value(copy); } if (this.isStructure()) { - return new Value(new ImmutableStructure(this.asStructure().asMap())); + return new Value(new ImmutableStructure(this.asStructure().asUnmodifiableMap())); } if (this.isInstant()) { Instant copy = Instant.ofEpochMilli(this.asInstant().toEpochMilli()); From f1cee1ca4c772aabb6740ee593b2ebb6cb2a2309 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 24 Oct 2024 08:48:06 -0400 Subject: [PATCH 007/745] chore(main): release 1.12.2 (#1162) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 37 +++++++++++++++++++++++++++++++++++ README.md | 8 ++++---- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 44 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index d2ffbd878..c6516de7a 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"1.12.1"} \ No newline at end of file +{".":"1.12.2"} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 099d21e91..6bfa9ddb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,42 @@ # Changelog +## [1.12.2](https://github.com/open-feature/java-sdk/compare/v1.12.1...v1.12.2) (2024-10-24) + + +### 🐛 Bug Fixes + +* **deps:** update junit5 monorepo ([#1171](https://github.com/open-feature/java-sdk/issues/1171)) ([02eed7a](https://github.com/open-feature/java-sdk/commit/02eed7a32c250483348d04925fe6840420b968cb)) + + +### 🧹 Chore + +* blocking set-provider in test ([d6d284b](https://github.com/open-feature/java-sdk/commit/d6d284b6a3e615ad90505bd183b098b084037616)) +* **deps:** update actions/cache digest to 6849a64 ([#1174](https://github.com/open-feature/java-sdk/issues/1174)) ([cedad9c](https://github.com/open-feature/java-sdk/commit/cedad9c2c6b6fd5c4b56b30ee5cd471fe4410a40)) +* **deps:** update actions/checkout digest to 11bd719 ([#1183](https://github.com/open-feature/java-sdk/issues/1183)) ([74958fd](https://github.com/open-feature/java-sdk/commit/74958fd261b0154d156d684e0e01360b8f3ba589)) +* **deps:** update actions/checkout digest to 163217d ([#1168](https://github.com/open-feature/java-sdk/issues/1168)) ([3f1cfed](https://github.com/open-feature/java-sdk/commit/3f1cfed913537c245284ff59d058982d1ebc8ce3)) +* **deps:** update actions/setup-java digest to 8df1039 ([#1172](https://github.com/open-feature/java-sdk/issues/1172)) ([a432760](https://github.com/open-feature/java-sdk/commit/a432760fc936b6a1c4ab2ed779c8ab49e6fe1eff)) +* **deps:** update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.8.6.5 ([#1173](https://github.com/open-feature/java-sdk/issues/1173)) ([b08e8d5](https://github.com/open-feature/java-sdk/commit/b08e8d5537942e8ae8c822f0466f6e18459d2d8d)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.15.5 ([#1165](https://github.com/open-feature/java-sdk/issues/1165)) ([2d3be26](https://github.com/open-feature/java-sdk/commit/2d3be2617b78d200162ce816e829abda80e130a2)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.15.7 ([#1179](https://github.com/open-feature/java-sdk/issues/1179)) ([0db0a50](https://github.com/open-feature/java-sdk/commit/0db0a50cf40d62e9880ca68f577c43fe86497532)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.15.5 ([#1166](https://github.com/open-feature/java-sdk/issues/1166)) ([51a3410](https://github.com/open-feature/java-sdk/commit/51a3410d8e8c85bb0b142e6a64b889795742de86)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.15.7 ([#1180](https://github.com/open-feature/java-sdk/issues/1180)) ([36620f8](https://github.com/open-feature/java-sdk/commit/36620f84081bb38cc542330ea44e84f6f5754093)) +* **deps:** update dependency org.codehaus.mojo:exec-maven-plugin to v3.5.0 ([#1175](https://github.com/open-feature/java-sdk/issues/1175)) ([c8c70e2](https://github.com/open-feature/java-sdk/commit/c8c70e23e807681d271ddcb3dc6879dd80cb1c02)) +* **deps:** update github/codeql-action digest to 0a30541 ([#1170](https://github.com/open-feature/java-sdk/issues/1170)) ([59139a2](https://github.com/open-feature/java-sdk/commit/59139a21867e99e65c9460fba35403efe0aa6f50)) +* **deps:** update github/codeql-action digest to 467d7e6 ([#1181](https://github.com/open-feature/java-sdk/issues/1181)) ([7a1eb9b](https://github.com/open-feature/java-sdk/commit/7a1eb9b9e94db003e2ada37ecb32cf912eef8766)) +* **deps:** update github/codeql-action digest to af56b04 ([#1167](https://github.com/open-feature/java-sdk/issues/1167)) ([432ec43](https://github.com/open-feature/java-sdk/commit/432ec438efdbe54e2300dd78db9fff1ce73fd725)) +* **deps:** update github/codeql-action digest to b35b023 ([#1176](https://github.com/open-feature/java-sdk/issues/1176)) ([9fb469f](https://github.com/open-feature/java-sdk/commit/9fb469f8e8f45afcf55edadcef4d73753d80e0e0)) +* **deps:** update github/codeql-action digest to b7cdb7f ([#1177](https://github.com/open-feature/java-sdk/issues/1177)) ([a085896](https://github.com/open-feature/java-sdk/commit/a08589664c6464df5443eccdb1b2e9eba84313eb)) +* **deps:** update github/codeql-action digest to c470063 ([#1163](https://github.com/open-feature/java-sdk/issues/1163)) ([4e39b55](https://github.com/open-feature/java-sdk/commit/4e39b55bda516bb07ffd7452169dc77b1c0e340f)) +* fix another flaky test ([473a057](https://github.com/open-feature/java-sdk/commit/473a05784cd25dfafdd8f55894b06c8503fb19af)) +* fix flaky test ([457da96](https://github.com/open-feature/java-sdk/commit/457da96e7ba328f572e086c614b6700e9fd1c8c8)) +* flaky test ([#1169](https://github.com/open-feature/java-sdk/issues/1169)) ([d6d284b](https://github.com/open-feature/java-sdk/commit/d6d284b6a3e615ad90505bd183b098b084037616)) +* improve benchmark realism; add more context ([#1182](https://github.com/open-feature/java-sdk/issues/1182)) ([0009e23](https://github.com/open-feature/java-sdk/commit/0009e23c7b38dff78afc7addede41fed16937976)) + + +### 🚀 Performance + +* reduce hashmap allocations ([#1178](https://github.com/open-feature/java-sdk/issues/1178)) ([fd7659a](https://github.com/open-feature/java-sdk/commit/fd7659a46fa7a8c4a04a09217abe7ab228779c7e)) + ## [1.12.1](https://github.com/open-feature/java-sdk/compare/v1.12.0...v1.12.1) (2024-10-15) diff --git a/README.md b/README.md index 636e96763..c710de664 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.12.1 + 1.12.2 ``` @@ -84,7 +84,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:1.12.1' + implementation 'dev.openfeature:sdk:1.12.2' } ``` diff --git a/pom.xml b/pom.xml index 2085ff726..ab36113fc 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ dev.openfeature sdk - 1.12.1 + 1.12.2 UTF-8 diff --git a/version.txt b/version.txt index f8f4f03b3..6b89d58f8 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.12.1 +1.12.2 From d0309eaa6616ef9e9caf8e605895ac82c8f4d780 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:15:09 +0000 Subject: [PATCH 008/745] chore(deps): update github/codeql-action digest to b91f43b (#1184) 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 1a8ee2e80..7916e1efd 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@467d7e6d9e138cb28eeebd638e6f0dbab1fd435e + uses: github/codeql-action/init@b91f43b4e4187262226c0523fe759b127320f62a with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@467d7e6d9e138cb28eeebd638e6f0dbab1fd435e + uses: github/codeql-action/analyze@b91f43b4e4187262226c0523fe759b127320f62a diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index ebd6739fc..231ed66dc 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@467d7e6d9e138cb28eeebd638e6f0dbab1fd435e + uses: github/codeql-action/init@b91f43b4e4187262226c0523fe759b127320f62a with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@467d7e6d9e138cb28eeebd638e6f0dbab1fd435e + uses: github/codeql-action/autobuild@b91f43b4e4187262226c0523fe759b127320f62a - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@467d7e6d9e138cb28eeebd638e6f0dbab1fd435e + uses: github/codeql-action/analyze@b91f43b4e4187262226c0523fe759b127320f62a From 4e3a329c406cc72a268f05766290633c67a9aae0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 25 Oct 2024 22:18:48 +0000 Subject: [PATCH 009/745] chore(deps): update github/codeql-action digest to 3aa7135 (#1186) 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 7916e1efd..e55080dab 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@b91f43b4e4187262226c0523fe759b127320f62a + uses: github/codeql-action/init@3aa71356c75a8edd8430d54dff2982203a28be45 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b91f43b4e4187262226c0523fe759b127320f62a + uses: github/codeql-action/analyze@3aa71356c75a8edd8430d54dff2982203a28be45 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 231ed66dc..872a8f841 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@b91f43b4e4187262226c0523fe759b127320f62a + uses: github/codeql-action/init@3aa71356c75a8edd8430d54dff2982203a28be45 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@b91f43b4e4187262226c0523fe759b127320f62a + uses: github/codeql-action/autobuild@3aa71356c75a8edd8430d54dff2982203a28be45 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b91f43b4e4187262226c0523fe759b127320f62a + uses: github/codeql-action/analyze@3aa71356c75a8edd8430d54dff2982203a28be45 From 5c7c28706e4614061b042080820b9efd04afc342 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 26 Oct 2024 01:56:27 +0000 Subject: [PATCH 010/745] chore(deps): update dependency org.apache.maven.plugins:maven-dependency-plugin to v3.8.1 (#1187) 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 ab36113fc..86f2d9f74 100644 --- a/pom.xml +++ b/pom.xml @@ -225,7 +225,7 @@ maven-dependency-plugin - 3.8.0 + 3.8.1 verify From 89c7f85da436b9f16193948183a1ca54eea6ceef Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 26 Oct 2024 03:41:50 +0000 Subject: [PATCH 011/745] chore(deps): update dependency org.apache.maven.plugins:maven-checkstyle-plugin to v3.6.0 (#1188) 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 86f2d9f74..03d25f7b7 100644 --- a/pom.xml +++ b/pom.xml @@ -407,7 +407,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.5.0 + 3.6.0 checkstyle.xml UTF-8 From d5082cd5f6907b6e7649813dbbea99cdeab20728 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 22:40:51 +0000 Subject: [PATCH 012/745] chore(deps): update dependency org.apache.maven.plugins:maven-pmd-plugin to v3.26.0 (#1189) 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 03d25f7b7..91a09df83 100644 --- a/pom.xml +++ b/pom.xml @@ -359,7 +359,7 @@ org.apache.maven.plugins maven-pmd-plugin - 3.25.0 + 3.26.0 run-pmd From f3163dfbd4b3997a0335699a2472373a846cf710 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 02:15:51 +0000 Subject: [PATCH 013/745] chore(deps): update github/codeql-action digest to 6a38de6 (#1190) 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 e55080dab..303cc69cb 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@3aa71356c75a8edd8430d54dff2982203a28be45 + uses: github/codeql-action/init@6a38de687243566b5f047bc89dac4492eb016f80 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3aa71356c75a8edd8430d54dff2982203a28be45 + uses: github/codeql-action/analyze@6a38de687243566b5f047bc89dac4492eb016f80 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 872a8f841..fd40a3b52 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@3aa71356c75a8edd8430d54dff2982203a28be45 + uses: github/codeql-action/init@6a38de687243566b5f047bc89dac4492eb016f80 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@3aa71356c75a8edd8430d54dff2982203a28be45 + uses: github/codeql-action/autobuild@6a38de687243566b5f047bc89dac4492eb016f80 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3aa71356c75a8edd8430d54dff2982203a28be45 + uses: github/codeql-action/analyze@6a38de687243566b5f047bc89dac4492eb016f80 From f99de6fa55bea093418ecc85ea79e9e30ce03d6b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 30 Oct 2024 01:45:47 +0000 Subject: [PATCH 014/745] chore(deps): update github/codeql-action digest to 9f93f47 (#1191) 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 303cc69cb..94ddef26e 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@6a38de687243566b5f047bc89dac4492eb016f80 + uses: github/codeql-action/init@9f93f47966f6365f7dd2b0eb0b06e74e4e64afaf with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6a38de687243566b5f047bc89dac4492eb016f80 + uses: github/codeql-action/analyze@9f93f47966f6365f7dd2b0eb0b06e74e4e64afaf diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index fd40a3b52..1039d41be 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@6a38de687243566b5f047bc89dac4492eb016f80 + uses: github/codeql-action/init@9f93f47966f6365f7dd2b0eb0b06e74e4e64afaf with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@6a38de687243566b5f047bc89dac4492eb016f80 + uses: github/codeql-action/autobuild@9f93f47966f6365f7dd2b0eb0b06e74e4e64afaf - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6a38de687243566b5f047bc89dac4492eb016f80 + uses: github/codeql-action/analyze@9f93f47966f6365f7dd2b0eb0b06e74e4e64afaf From 86219446337e9c73a41b8517b1e26fa044d3bbaa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 31 Oct 2024 20:31:28 +0000 Subject: [PATCH 015/745] chore(deps): update github/codeql-action digest to 48c3e26 (#1193) 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 94ddef26e..ae9079d97 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@9f93f47966f6365f7dd2b0eb0b06e74e4e64afaf + uses: github/codeql-action/init@48c3e2675613624ea7978e5d132169f97bc3b578 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9f93f47966f6365f7dd2b0eb0b06e74e4e64afaf + uses: github/codeql-action/analyze@48c3e2675613624ea7978e5d132169f97bc3b578 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 1039d41be..ef32b1b89 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@9f93f47966f6365f7dd2b0eb0b06e74e4e64afaf + uses: github/codeql-action/init@48c3e2675613624ea7978e5d132169f97bc3b578 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@9f93f47966f6365f7dd2b0eb0b06e74e4e64afaf + uses: github/codeql-action/autobuild@48c3e2675613624ea7978e5d132169f97bc3b578 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9f93f47966f6365f7dd2b0eb0b06e74e4e64afaf + uses: github/codeql-action/analyze@48c3e2675613624ea7978e5d132169f97bc3b578 From 2dba3a737dac6fefcbb1f56b292cacdca62735b5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 23:08:42 +0000 Subject: [PATCH 016/745] chore(deps): update github/codeql-action digest to cbe1897 (#1194) 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 ae9079d97..38897fb7a 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@48c3e2675613624ea7978e5d132169f97bc3b578 + uses: github/codeql-action/init@cbe18979603527f12c7871a6eb04833ecf1548c7 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@48c3e2675613624ea7978e5d132169f97bc3b578 + uses: github/codeql-action/analyze@cbe18979603527f12c7871a6eb04833ecf1548c7 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index ef32b1b89..a473ce1fc 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@48c3e2675613624ea7978e5d132169f97bc3b578 + uses: github/codeql-action/init@cbe18979603527f12c7871a6eb04833ecf1548c7 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@48c3e2675613624ea7978e5d132169f97bc3b578 + uses: github/codeql-action/autobuild@cbe18979603527f12c7871a6eb04833ecf1548c7 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@48c3e2675613624ea7978e5d132169f97bc3b578 + uses: github/codeql-action/analyze@cbe18979603527f12c7871a6eb04833ecf1548c7 From 309f28b520a8f629a500c359b1f522ba687bcc6b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 2 Nov 2024 00:57:59 +0000 Subject: [PATCH 017/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.15.8 (#1195) 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 91a09df83..0b920cb15 100644 --- a/pom.xml +++ b/pom.xml @@ -164,7 +164,7 @@ net.bytebuddy byte-buddy - 1.15.7 + 1.15.8 test From 30eb2ce082ae2854025be084da98fb856dbcd17c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 2 Nov 2024 03:05:33 +0000 Subject: [PATCH 018/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.15.8 (#1196) 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 0b920cb15..c54f382a1 100644 --- a/pom.xml +++ b/pom.xml @@ -171,7 +171,7 @@ net.bytebuddy byte-buddy-agent - 1.15.7 + 1.15.8 test From 54a234519f36ea803ec8574f27c94a9f754bf822 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 2 Nov 2024 21:30:23 +0000 Subject: [PATCH 019/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.15.9 (#1197) 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 c54f382a1..0a898a2eb 100644 --- a/pom.xml +++ b/pom.xml @@ -164,7 +164,7 @@ net.bytebuddy byte-buddy - 1.15.8 + 1.15.9 test From e32a712615f3b1be9cff61f1337d5b00c365c8f5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 3 Nov 2024 02:15:10 +0000 Subject: [PATCH 020/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.15.9 (#1198) 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 0a898a2eb..92ce652cc 100644 --- a/pom.xml +++ b/pom.xml @@ -171,7 +171,7 @@ net.bytebuddy byte-buddy-agent - 1.15.8 + 1.15.9 test From 08da9a34395a3e96dc2172f0f0533a4905cff204 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 3 Nov 2024 05:20:51 +0000 Subject: [PATCH 021/745] chore(deps): update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.5.2 (#1199) 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 92ce652cc..78fec5194 100644 --- a/pom.xml +++ b/pom.xml @@ -275,7 +275,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.5.1 + 3.5.2 ${surefireArgLine} From a2a57ab8f1161b5de3a112bbbdc421985baf304b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 3 Nov 2024 07:13:45 +0000 Subject: [PATCH 022/745] chore(deps): update dependency org.apache.maven.plugins:maven-javadoc-plugin to v3.11.1 (#1201) 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 78fec5194..90a2d4deb 100644 --- a/pom.xml +++ b/pom.xml @@ -477,7 +477,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.10.1 + 3.11.1 true all,-missing From d2cb092b09966bc2d5a7548e35b71ab2e56e0dee Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 3 Nov 2024 09:11:03 +0000 Subject: [PATCH 023/745] chore(deps): update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.2 (#1200) 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 90a2d4deb..dee985e07 100644 --- a/pom.xml +++ b/pom.xml @@ -260,7 +260,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.5.1 + 3.5.2 ${surefireArgLine} From d95905917730dcb8724fe166682ca773a536eb9b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 04:58:15 +0000 Subject: [PATCH 024/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.15.10 (#1202) 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 dee985e07..c9ee53479 100644 --- a/pom.xml +++ b/pom.xml @@ -164,7 +164,7 @@ net.bytebuddy byte-buddy - 1.15.9 + 1.15.10 test From 2bb2ed39928e0e15d369741df8b877c751e8d122 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 08:19:14 +0000 Subject: [PATCH 025/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.15.10 (#1203) 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 c9ee53479..b4715c881 100644 --- a/pom.xml +++ b/pom.xml @@ -171,7 +171,7 @@ net.bytebuddy byte-buddy-agent - 1.15.9 + 1.15.10 test From 3a9fd60fd4a9595a729995a59a0c4ef9625444bc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Nov 2024 04:42:35 +0000 Subject: [PATCH 026/745] chore(deps): update github/codeql-action digest to 5ac2ddd (#1204) 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 38897fb7a..1ab953e23 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@cbe18979603527f12c7871a6eb04833ecf1548c7 + uses: github/codeql-action/init@5ac2ddd6fc78e6c0d2af5b110b19381f38bd84df with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@cbe18979603527f12c7871a6eb04833ecf1548c7 + uses: github/codeql-action/analyze@5ac2ddd6fc78e6c0d2af5b110b19381f38bd84df diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index a473ce1fc..e61e346a4 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@cbe18979603527f12c7871a6eb04833ecf1548c7 + uses: github/codeql-action/init@5ac2ddd6fc78e6c0d2af5b110b19381f38bd84df with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@cbe18979603527f12c7871a6eb04833ecf1548c7 + uses: github/codeql-action/autobuild@5ac2ddd6fc78e6c0d2af5b110b19381f38bd84df - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@cbe18979603527f12c7871a6eb04833ecf1548c7 + uses: github/codeql-action/analyze@5ac2ddd6fc78e6c0d2af5b110b19381f38bd84df From eb4f6255615a77c65a79002f1233d1efe5eccd37 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Nov 2024 21:14:36 +0000 Subject: [PATCH 027/745] chore(deps): update github/codeql-action digest to 3ef4c08 (#1205) 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 1ab953e23..5f09aa1ce 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@5ac2ddd6fc78e6c0d2af5b110b19381f38bd84df + uses: github/codeql-action/init@3ef4c0845750690942ece9abe29a853edce0f43c with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5ac2ddd6fc78e6c0d2af5b110b19381f38bd84df + uses: github/codeql-action/analyze@3ef4c0845750690942ece9abe29a853edce0f43c diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index e61e346a4..907a79f51 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@5ac2ddd6fc78e6c0d2af5b110b19381f38bd84df + uses: github/codeql-action/init@3ef4c0845750690942ece9abe29a853edce0f43c with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@5ac2ddd6fc78e6c0d2af5b110b19381f38bd84df + uses: github/codeql-action/autobuild@3ef4c0845750690942ece9abe29a853edce0f43c - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5ac2ddd6fc78e6c0d2af5b110b19381f38bd84df + uses: github/codeql-action/analyze@3ef4c0845750690942ece9abe29a853edce0f43c From 446e2987e9b80175dff0ea72de9f58ba8e0dd323 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Nov 2024 22:08:50 +0000 Subject: [PATCH 028/745] chore(deps): update actions/checkout digest to 3b9b8c8 (#1206) 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 +- .github/workflows/static-code-scanning.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index d3d0569e5..d50490afc 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + - uses: actions/checkout@3b9b8c884f6b4bb4d5be2779c26374abadae0871 - name: Set up JDK 8 uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b with: diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 5f09aa1ce..222ce6c5b 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out the code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + uses: actions/checkout@3b9b8c884f6b4bb4d5be2779c26374abadae0871 - name: Set up JDK 8 uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9b1ac3408..1cf4fb370 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,7 +28,7 @@ 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@11bd71901bbe5b1630ceea73d27597364c9af683 + uses: actions/checkout@3b9b8c884f6b4bb4d5be2779c26374abadae0871 - name: Set up JDK 8 if: ${{ steps.release.outputs.release_created }} uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 907a79f51..458b5e467 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + uses: actions/checkout@3b9b8c884f6b4bb4d5be2779c26374abadae0871 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL From 21dbd3fc4c29acbb6b74cdb6b82bc5bb4dd5523e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 9 Nov 2024 00:41:31 +0000 Subject: [PATCH 029/745] chore(deps): update github/codeql-action digest to acb9cb1 (#1207) 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 222ce6c5b..30bca078e 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@3ef4c0845750690942ece9abe29a853edce0f43c + uses: github/codeql-action/init@acb9cb18eec7e3a113ef83cff0be91e75cfd9526 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3ef4c0845750690942ece9abe29a853edce0f43c + uses: github/codeql-action/analyze@acb9cb18eec7e3a113ef83cff0be91e75cfd9526 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 458b5e467..2f75a890d 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@3ef4c0845750690942ece9abe29a853edce0f43c + uses: github/codeql-action/init@acb9cb18eec7e3a113ef83cff0be91e75cfd9526 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@3ef4c0845750690942ece9abe29a853edce0f43c + uses: github/codeql-action/autobuild@acb9cb18eec7e3a113ef83cff0be91e75cfd9526 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3ef4c0845750690942ece9abe29a853edce0f43c + uses: github/codeql-action/analyze@acb9cb18eec7e3a113ef83cff0be91e75cfd9526 From a3ced47e5dc23badae4f008e5cf4e97c588fdfd4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 9 Nov 2024 03:31:56 +0000 Subject: [PATCH 030/745] chore(deps): update dependency org.simplify4u:slf4j2-mock to v2.4.0 (#1208) 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 b4715c881..c5b38bd2f 100644 --- a/pom.xml +++ b/pom.xml @@ -128,7 +128,7 @@ org.simplify4u slf4j2-mock - 2.3.0 + 2.4.0 test From 1c21d2444b31f61d6d83dfd8f6982f7ad71f708b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 21:47:01 +0000 Subject: [PATCH 031/745] chore(deps): update github/codeql-action digest to 4dc1519 (#1209) 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 30bca078e..7d6ef354f 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@acb9cb18eec7e3a113ef83cff0be91e75cfd9526 + uses: github/codeql-action/init@4dc1519e3cb370190074f4511ecb01f49430cb2b with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@acb9cb18eec7e3a113ef83cff0be91e75cfd9526 + uses: github/codeql-action/analyze@4dc1519e3cb370190074f4511ecb01f49430cb2b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 2f75a890d..b4ce6e06d 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@acb9cb18eec7e3a113ef83cff0be91e75cfd9526 + uses: github/codeql-action/init@4dc1519e3cb370190074f4511ecb01f49430cb2b with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@acb9cb18eec7e3a113ef83cff0be91e75cfd9526 + uses: github/codeql-action/autobuild@4dc1519e3cb370190074f4511ecb01f49430cb2b - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@acb9cb18eec7e3a113ef83cff0be91e75cfd9526 + uses: github/codeql-action/analyze@4dc1519e3cb370190074f4511ecb01f49430cb2b From a94bd37cff0c6d7b9f535335709d69b79db2c91e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:51:48 +0000 Subject: [PATCH 032/745] chore(deps): update github/codeql-action digest to 5cb4249 (#1210) 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 7d6ef354f..7d1afd0e1 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@4dc1519e3cb370190074f4511ecb01f49430cb2b + uses: github/codeql-action/init@5cb4249dc7848e27a64daec41f25f109ccf2a515 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4dc1519e3cb370190074f4511ecb01f49430cb2b + uses: github/codeql-action/analyze@5cb4249dc7848e27a64daec41f25f109ccf2a515 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index b4ce6e06d..4e4868dd6 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@4dc1519e3cb370190074f4511ecb01f49430cb2b + uses: github/codeql-action/init@5cb4249dc7848e27a64daec41f25f109ccf2a515 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@4dc1519e3cb370190074f4511ecb01f49430cb2b + uses: github/codeql-action/autobuild@5cb4249dc7848e27a64daec41f25f109ccf2a515 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4dc1519e3cb370190074f4511ecb01f49430cb2b + uses: github/codeql-action/analyze@5cb4249dc7848e27a64daec41f25f109ccf2a515 From 1df54411b758c67afaf47f103e357cb551e0efca Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 02:52:28 +0000 Subject: [PATCH 033/745] chore(deps): update github/codeql-action digest to 024283f (#1211) 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 7d1afd0e1..c48c6f448 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@5cb4249dc7848e27a64daec41f25f109ccf2a515 + uses: github/codeql-action/init@024283fcc9914a2f29343fa25558256c1799501f with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5cb4249dc7848e27a64daec41f25f109ccf2a515 + uses: github/codeql-action/analyze@024283fcc9914a2f29343fa25558256c1799501f diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 4e4868dd6..f8467b275 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@5cb4249dc7848e27a64daec41f25f109ccf2a515 + uses: github/codeql-action/init@024283fcc9914a2f29343fa25558256c1799501f with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@5cb4249dc7848e27a64daec41f25f109ccf2a515 + uses: github/codeql-action/autobuild@024283fcc9914a2f29343fa25558256c1799501f - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5cb4249dc7848e27a64daec41f25f109ccf2a515 + uses: github/codeql-action/analyze@024283fcc9914a2f29343fa25558256c1799501f From d5228f5ccfa55753178425c55a02af1833168513 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 10:56:56 +0000 Subject: [PATCH 034/745] chore(deps): update amannn/action-semantic-pull-request digest to 40166f0 (#1212) 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 88b02783e..bce134066 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@80c0371c57c5142ed6c844270bba1864bac8a4c6 + - uses: amannn/action-semantic-pull-request@40166f00814508ec3201fc8595b393d451c8cd80 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 92c87913ac417b8b3651290a4df828bdf5d501b9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 13:34:11 +0000 Subject: [PATCH 035/745] chore(deps): update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.8.6.6 (#1213) 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 c5b38bd2f..741fd8b4b 100644 --- a/pom.xml +++ b/pom.xml @@ -374,7 +374,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.8.6.5 + 4.8.6.6 spotbugs-exclusions.xml From 9f37927eaa60e53d1c7db192ca8e6e117f7f0017 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 00:23:20 +0000 Subject: [PATCH 036/745] chore(deps): update github/codeql-action digest to 6e3a010 (#1214) 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 c48c6f448..69e5113f6 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@024283fcc9914a2f29343fa25558256c1799501f + uses: github/codeql-action/init@6e3a010dfe7e41114c548b680d885bbd55b2834e with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@024283fcc9914a2f29343fa25558256c1799501f + uses: github/codeql-action/analyze@6e3a010dfe7e41114c548b680d885bbd55b2834e diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index f8467b275..4e6c8800e 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@024283fcc9914a2f29343fa25558256c1799501f + uses: github/codeql-action/init@6e3a010dfe7e41114c548b680d885bbd55b2834e with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@024283fcc9914a2f29343fa25558256c1799501f + uses: github/codeql-action/autobuild@6e3a010dfe7e41114c548b680d885bbd55b2834e - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@024283fcc9914a2f29343fa25558256c1799501f + uses: github/codeql-action/analyze@6e3a010dfe7e41114c548b680d885bbd55b2834e From 273efc62a7bb2e3fe962036d82818eb1da43b197 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 18:24:10 +0000 Subject: [PATCH 037/745] chore(deps): update actions/checkout digest to cbb7224 (#1216) 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 +- .github/workflows/static-code-scanning.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index d50490afc..b9aa805a9 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@3b9b8c884f6b4bb4d5be2779c26374abadae0871 + - uses: actions/checkout@cbb722410c2e876e24abbe8de2cc27693e501dcb - name: Set up JDK 8 uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b with: diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 69e5113f6..c47c24896 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out the code - uses: actions/checkout@3b9b8c884f6b4bb4d5be2779c26374abadae0871 + uses: actions/checkout@cbb722410c2e876e24abbe8de2cc27693e501dcb - name: Set up JDK 8 uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1cf4fb370..251ae637e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,7 +28,7 @@ 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@3b9b8c884f6b4bb4d5be2779c26374abadae0871 + uses: actions/checkout@cbb722410c2e876e24abbe8de2cc27693e501dcb - name: Set up JDK 8 if: ${{ steps.release.outputs.release_created }} uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 4e6c8800e..75180af5c 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@3b9b8c884f6b4bb4d5be2779c26374abadae0871 + uses: actions/checkout@cbb722410c2e876e24abbe8de2cc27693e501dcb # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL From 6d3bb694204107f21552b48c5f6f056fa37e6cc0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 21:40:29 +0000 Subject: [PATCH 038/745] chore(deps): update github/codeql-action digest to a1695c5 (#1215) 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 c47c24896..860e1dd40 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@6e3a010dfe7e41114c548b680d885bbd55b2834e + uses: github/codeql-action/init@a1695c562bbfa68dc5ab58c9b5e9f616b52bf5be with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6e3a010dfe7e41114c548b680d885bbd55b2834e + uses: github/codeql-action/analyze@a1695c562bbfa68dc5ab58c9b5e9f616b52bf5be diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 75180af5c..cb57dcea1 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@6e3a010dfe7e41114c548b680d885bbd55b2834e + uses: github/codeql-action/init@a1695c562bbfa68dc5ab58c9b5e9f616b52bf5be with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@6e3a010dfe7e41114c548b680d885bbd55b2834e + uses: github/codeql-action/autobuild@a1695c562bbfa68dc5ab58c9b5e9f616b52bf5be - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6e3a010dfe7e41114c548b680d885bbd55b2834e + uses: github/codeql-action/analyze@a1695c562bbfa68dc5ab58c9b5e9f616b52bf5be From 7aa77b8614401c56e8387d55382e4be115a7d1ef Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 01:13:12 +0000 Subject: [PATCH 039/745] chore(deps): update codecov/codecov-action action to v5 (#1217) 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 b9aa805a9..74a900649 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -49,7 +49,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4.6.0 + uses: codecov/codecov-action@v5.0.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 860e1dd40..a2e9c0373 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -36,7 +36,7 @@ jobs: run: mvn --batch-mode --update-snapshots --activate-profiles e2e verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4.6.0 + uses: codecov/codecov-action@v5.0.0 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From 1b4947f108c15a4777bb35bafb631a40c7e20e77 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 18:10:46 +0000 Subject: [PATCH 040/745] chore(deps): update codecov/codecov-action action to v5.0.2 (#1218) 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 74a900649..38183f2f3 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -49,7 +49,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.0.0 + uses: codecov/codecov-action@v5.0.2 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 a2e9c0373..b72afed04 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -36,7 +36,7 @@ jobs: run: mvn --batch-mode --update-snapshots --activate-profiles e2e verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.0.0 + uses: codecov/codecov-action@v5.0.2 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From 9cadc71d9d8a2a88f9c716c27eb939f423b95fa0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 16 Nov 2024 00:02:00 +0000 Subject: [PATCH 041/745] fix(deps): update dependency org.projectlombok:lombok to v1.18.36 (#1219) 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 741fd8b4b..8524afb60 100644 --- a/pom.xml +++ b/pom.xml @@ -45,7 +45,7 @@ org.projectlombok lombok - 1.18.34 + 1.18.36 provided From 45d065652004ecc0703af3b9c6fbfd2b45e69056 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 01:32:36 +0000 Subject: [PATCH 042/745] chore(deps): update github/codeql-action digest to e782c3a (#1220) 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 b72afed04..001eb56d0 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@a1695c562bbfa68dc5ab58c9b5e9f616b52bf5be + uses: github/codeql-action/init@e782c3a145d9946aba8fa390e406acbe4e4c05c5 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@a1695c562bbfa68dc5ab58c9b5e9f616b52bf5be + uses: github/codeql-action/analyze@e782c3a145d9946aba8fa390e406acbe4e4c05c5 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index cb57dcea1..7c3657a5e 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@a1695c562bbfa68dc5ab58c9b5e9f616b52bf5be + uses: github/codeql-action/init@e782c3a145d9946aba8fa390e406acbe4e4c05c5 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@a1695c562bbfa68dc5ab58c9b5e9f616b52bf5be + uses: github/codeql-action/autobuild@e782c3a145d9946aba8fa390e406acbe4e4c05c5 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@a1695c562bbfa68dc5ab58c9b5e9f616b52bf5be + uses: github/codeql-action/analyze@e782c3a145d9946aba8fa390e406acbe4e4c05c5 From 37f0f06467b10541755e723ff26144b716a26464 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 06:19:31 +0000 Subject: [PATCH 043/745] chore(deps): update github/codeql-action digest to cba5fb5 (#1221) 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 001eb56d0..ecfcc9776 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@e782c3a145d9946aba8fa390e406acbe4e4c05c5 + uses: github/codeql-action/init@cba5fb58d4f85affaf03eb9da32f5b6c9d76838b with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e782c3a145d9946aba8fa390e406acbe4e4c05c5 + uses: github/codeql-action/analyze@cba5fb58d4f85affaf03eb9da32f5b6c9d76838b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 7c3657a5e..0105e534a 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@e782c3a145d9946aba8fa390e406acbe4e4c05c5 + uses: github/codeql-action/init@cba5fb58d4f85affaf03eb9da32f5b6c9d76838b with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@e782c3a145d9946aba8fa390e406acbe4e4c05c5 + uses: github/codeql-action/autobuild@cba5fb58d4f85affaf03eb9da32f5b6c9d76838b - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e782c3a145d9946aba8fa390e406acbe4e4c05c5 + uses: github/codeql-action/analyze@cba5fb58d4f85affaf03eb9da32f5b6c9d76838b From bbc934c6d91af39b9ff384ebd58756d48b00415a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 21:43:05 +0000 Subject: [PATCH 044/745] chore(deps): update github/codeql-action digest to a6c8729 (#1222) 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 ecfcc9776..75f354ab4 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@cba5fb58d4f85affaf03eb9da32f5b6c9d76838b + uses: github/codeql-action/init@a6c8729a5d7573eb8d440e52a9645ce4db61d97c with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@cba5fb58d4f85affaf03eb9da32f5b6c9d76838b + uses: github/codeql-action/analyze@a6c8729a5d7573eb8d440e52a9645ce4db61d97c diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 0105e534a..bd74e23f6 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@cba5fb58d4f85affaf03eb9da32f5b6c9d76838b + uses: github/codeql-action/init@a6c8729a5d7573eb8d440e52a9645ce4db61d97c with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@cba5fb58d4f85affaf03eb9da32f5b6c9d76838b + uses: github/codeql-action/autobuild@a6c8729a5d7573eb8d440e52a9645ce4db61d97c - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@cba5fb58d4f85affaf03eb9da32f5b6c9d76838b + uses: github/codeql-action/analyze@a6c8729a5d7573eb8d440e52a9645ce4db61d97c From e91194ae16c1d68033a750050af18de68a618f61 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 01:33:05 +0000 Subject: [PATCH 045/745] chore(deps): update codecov/codecov-action action to v5.0.3 (#1223) 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 38183f2f3..a72010925 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -49,7 +49,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.0.2 + uses: codecov/codecov-action@v5.0.3 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 75f354ab4..b4241f502 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -36,7 +36,7 @@ jobs: run: mvn --batch-mode --update-snapshots --activate-profiles e2e verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.0.2 + uses: codecov/codecov-action@v5.0.3 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From 19ed5c7c97dc286a85faae1c4906508f97191497 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 09:22:54 +0000 Subject: [PATCH 046/745] chore(deps): update codecov/codecov-action action to v5.0.4 (#1224) 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 a72010925..c891dae48 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -49,7 +49,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.0.3 + uses: codecov/codecov-action@v5.0.4 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 b4241f502..d9004a0ac 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -36,7 +36,7 @@ jobs: run: mvn --batch-mode --update-snapshots --activate-profiles e2e verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.0.3 + uses: codecov/codecov-action@v5.0.4 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From 32276234257f82de98bcb01094c7219611e2c707 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 20:34:21 +0000 Subject: [PATCH 047/745] chore(deps): update github/codeql-action digest to f8e782a (#1225) 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 d9004a0ac..77611dbe5 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@a6c8729a5d7573eb8d440e52a9645ce4db61d97c + uses: github/codeql-action/init@f8e782af5670be7b12c0acb5b25c1c5703b931b9 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@a6c8729a5d7573eb8d440e52a9645ce4db61d97c + uses: github/codeql-action/analyze@f8e782af5670be7b12c0acb5b25c1c5703b931b9 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index bd74e23f6..7ae0ca66e 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@a6c8729a5d7573eb8d440e52a9645ce4db61d97c + uses: github/codeql-action/init@f8e782af5670be7b12c0acb5b25c1c5703b931b9 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@a6c8729a5d7573eb8d440e52a9645ce4db61d97c + uses: github/codeql-action/autobuild@f8e782af5670be7b12c0acb5b25c1c5703b931b9 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@a6c8729a5d7573eb8d440e52a9645ce4db61d97c + uses: github/codeql-action/analyze@f8e782af5670be7b12c0acb5b25c1c5703b931b9 From 13811dcf254b604ec73b4df184d432f1dc404398 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 22:34:42 +0000 Subject: [PATCH 048/745] chore(deps): update codecov/codecov-action action to v5.0.6 (#1226) 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 c891dae48..08980580a 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -49,7 +49,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.0.4 + uses: codecov/codecov-action@v5.0.6 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 77611dbe5..45923e522 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -36,7 +36,7 @@ jobs: run: mvn --batch-mode --update-snapshots --activate-profiles e2e verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.0.4 + uses: codecov/codecov-action@v5.0.6 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From 234062cf338036b3b942b83c00b31191fb626432 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 21 Nov 2024 08:03:20 +0000 Subject: [PATCH 049/745] chore(deps): update codecov/codecov-action action to v5.0.7 (#1227) 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 08980580a..d31c6130c 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -49,7 +49,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.0.6 + uses: codecov/codecov-action@v5.0.7 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 45923e522..ec7896fc0 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -36,7 +36,7 @@ jobs: run: mvn --batch-mode --update-snapshots --activate-profiles e2e verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.0.6 + uses: codecov/codecov-action@v5.0.7 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From a0723ec2f886aa834662f2e54bcce5f052262dac Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 22 Nov 2024 16:44:33 +0000 Subject: [PATCH 050/745] chore(deps): update github/codeql-action digest to 3d3d628 (#1229) 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 ec7896fc0..46bab8fba 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@f8e782af5670be7b12c0acb5b25c1c5703b931b9 + uses: github/codeql-action/init@3d3d628990a5f99229dd9fa1821cc5a4f31b613b with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f8e782af5670be7b12c0acb5b25c1c5703b931b9 + uses: github/codeql-action/analyze@3d3d628990a5f99229dd9fa1821cc5a4f31b613b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 7ae0ca66e..5bac449d5 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@f8e782af5670be7b12c0acb5b25c1c5703b931b9 + uses: github/codeql-action/init@3d3d628990a5f99229dd9fa1821cc5a4f31b613b with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@f8e782af5670be7b12c0acb5b25c1c5703b931b9 + uses: github/codeql-action/autobuild@3d3d628990a5f99229dd9fa1821cc5a4f31b613b - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f8e782af5670be7b12c0acb5b25c1c5703b931b9 + uses: github/codeql-action/analyze@3d3d628990a5f99229dd9fa1821cc5a4f31b613b From 764d6650e659aa93c1da66db348a2eb3641ae92f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 30 Nov 2024 01:23:12 +0000 Subject: [PATCH 051/745] chore(deps): update dependency org.cyclonedx:cyclonedx-maven-plugin to v2.9.1 (#1230) 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 8524afb60..d9e4bc723 100644 --- a/pom.xml +++ b/pom.xml @@ -200,7 +200,7 @@ org.cyclonedx cyclonedx-maven-plugin - 2.9.0 + 2.9.1 library 1.3 From 4bbaf517536386f53bd92ceaf62eb08fe4859e80 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 20:25:33 +0000 Subject: [PATCH 052/745] chore(deps): update github/codeql-action digest to af49565 (#1231) 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 46bab8fba..6c355eabe 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@3d3d628990a5f99229dd9fa1821cc5a4f31b613b + uses: github/codeql-action/init@af49565b852879ee08c297788e61c43f3b415aa4 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3d3d628990a5f99229dd9fa1821cc5a4f31b613b + uses: github/codeql-action/analyze@af49565b852879ee08c297788e61c43f3b415aa4 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 5bac449d5..04d134f73 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@3d3d628990a5f99229dd9fa1821cc5a4f31b613b + uses: github/codeql-action/init@af49565b852879ee08c297788e61c43f3b415aa4 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@3d3d628990a5f99229dd9fa1821cc5a4f31b613b + uses: github/codeql-action/autobuild@af49565b852879ee08c297788e61c43f3b415aa4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3d3d628990a5f99229dd9fa1821cc5a4f31b613b + uses: github/codeql-action/analyze@af49565b852879ee08c297788e61c43f3b415aa4 From b3549a1b4aa2bc27c38f66e3a0657b62d8ffc1b4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Dec 2024 16:31:38 +0000 Subject: [PATCH 053/745] chore(deps): update github/codeql-action digest to ef2fd42 (#1232) 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 6c355eabe..7ec07c94f 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@af49565b852879ee08c297788e61c43f3b415aa4 + uses: github/codeql-action/init@ef2fd42bcf7c6e45d4094283d6fdfedffcd69c87 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@af49565b852879ee08c297788e61c43f3b415aa4 + uses: github/codeql-action/analyze@ef2fd42bcf7c6e45d4094283d6fdfedffcd69c87 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 04d134f73..c28252fd0 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@af49565b852879ee08c297788e61c43f3b415aa4 + uses: github/codeql-action/init@ef2fd42bcf7c6e45d4094283d6fdfedffcd69c87 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@af49565b852879ee08c297788e61c43f3b415aa4 + uses: github/codeql-action/autobuild@ef2fd42bcf7c6e45d4094283d6fdfedffcd69c87 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@af49565b852879ee08c297788e61c43f3b415aa4 + uses: github/codeql-action/analyze@ef2fd42bcf7c6e45d4094283d6fdfedffcd69c87 From 5b460ead7e5f21eb7c86e9ae78740a2e26957420 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Dec 2024 22:13:25 +0000 Subject: [PATCH 054/745] chore(deps): update github/codeql-action digest to f1c289a (#1233) 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 7ec07c94f..5f9b6b8d9 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@ef2fd42bcf7c6e45d4094283d6fdfedffcd69c87 + uses: github/codeql-action/init@f1c289a551a329049623e4400b20e4bd4d48ed2f with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ef2fd42bcf7c6e45d4094283d6fdfedffcd69c87 + uses: github/codeql-action/analyze@f1c289a551a329049623e4400b20e4bd4d48ed2f diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index c28252fd0..3357e7fd9 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@ef2fd42bcf7c6e45d4094283d6fdfedffcd69c87 + uses: github/codeql-action/init@f1c289a551a329049623e4400b20e4bd4d48ed2f with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@ef2fd42bcf7c6e45d4094283d6fdfedffcd69c87 + uses: github/codeql-action/autobuild@f1c289a551a329049623e4400b20e4bd4d48ed2f - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ef2fd42bcf7c6e45d4094283d6fdfedffcd69c87 + uses: github/codeql-action/analyze@f1c289a551a329049623e4400b20e4bd4d48ed2f From bb3272d36479bde2594fe0bb64cea21d30299931 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2024 03:31:19 +0000 Subject: [PATCH 055/745] chore(deps): update github/codeql-action digest to 978ed82 (#1234) 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 5f9b6b8d9..5395d2828 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@f1c289a551a329049623e4400b20e4bd4d48ed2f + uses: github/codeql-action/init@978ed829bdde7389737ac17d6b144aeed5f9bdad with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f1c289a551a329049623e4400b20e4bd4d48ed2f + uses: github/codeql-action/analyze@978ed829bdde7389737ac17d6b144aeed5f9bdad diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 3357e7fd9..e32de60f9 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@f1c289a551a329049623e4400b20e4bd4d48ed2f + uses: github/codeql-action/init@978ed829bdde7389737ac17d6b144aeed5f9bdad with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@f1c289a551a329049623e4400b20e4bd4d48ed2f + uses: github/codeql-action/autobuild@978ed829bdde7389737ac17d6b144aeed5f9bdad - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f1c289a551a329049623e4400b20e4bd4d48ed2f + uses: github/codeql-action/analyze@978ed829bdde7389737ac17d6b144aeed5f9bdad From 409fd042f3921948ef0dabd58d0ef7a4c380b5fb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2024 17:02:17 +0000 Subject: [PATCH 056/745] chore(deps): update github/codeql-action digest to 3096afe (#1235) 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 5395d2828..2ffa85408 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@978ed829bdde7389737ac17d6b144aeed5f9bdad + uses: github/codeql-action/init@3096afedf9873361b2b2f65e1445b13272c83eb8 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@978ed829bdde7389737ac17d6b144aeed5f9bdad + uses: github/codeql-action/analyze@3096afedf9873361b2b2f65e1445b13272c83eb8 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index e32de60f9..84a67033a 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@978ed829bdde7389737ac17d6b144aeed5f9bdad + uses: github/codeql-action/init@3096afedf9873361b2b2f65e1445b13272c83eb8 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@978ed829bdde7389737ac17d6b144aeed5f9bdad + uses: github/codeql-action/autobuild@3096afedf9873361b2b2f65e1445b13272c83eb8 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@978ed829bdde7389737ac17d6b144aeed5f9bdad + uses: github/codeql-action/analyze@3096afedf9873361b2b2f65e1445b13272c83eb8 From 473be8659c296a7e1cd0cf926b91a851ed98eec5 Mon Sep 17 00:00:00 2001 From: warber <72415058+warber@users.noreply.github.com> Date: Thu, 5 Dec 2024 17:10:49 +0100 Subject: [PATCH 057/745] test: Update gherkin test sub module (#1236) Signed-off-by: Bernd Warmuth --- .gitmodules | 6 ++--- CONTRIBUTING.md | 2 +- pom.xml | 7 +++--- spec | 1 + ...nCucumberTest.java => EvaluationTest.java} | 11 ++++++--- .../e2e/{ => evaluation}/StepDefinitions.java | 24 +++++++++---------- test-harness | 1 - 7 files changed, 28 insertions(+), 24 deletions(-) create mode 160000 spec rename src/test/java/dev/openfeature/sdk/e2e/{RunCucumberTest.java => EvaluationTest.java} (62%) rename src/test/java/dev/openfeature/sdk/e2e/{ => evaluation}/StepDefinitions.java (90%) delete mode 160000 test-harness diff --git a/.gitmodules b/.gitmodules index 5893173a6..476d155da 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "test-harness"] - path = test-harness - url = https://github.com/open-feature/test-harness +[submodule "spec"] + path = spec + url = https://github.com/open-feature/spec/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2aafb314f..84c9645b9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,7 +23,7 @@ If you're adding tests to cover something in the spec, use the `@Specification` ## End-to-End Tests -The continuous integration runs a set of [gherkin e2e tests](https://github.com/open-feature/test-harness/blob/main/features/evaluation.feature) using `InMemoryProvider`. +The continuous integration runs a set of [gherkin e2e tests](https://github.com/open-feature/spec/blob/main/specification/assets/gherkin/evaluation.feature) using `InMemoryProvider`. to run alone: ``` diff --git a/pom.xml b/pom.xml index d9e4bc723..63fa4bd99 100644 --- a/pom.xml +++ b/pom.xml @@ -554,22 +554,21 @@ submodule update --init - test-harness + spec - copy-gherkin-tests + copy-evaluation-gherkin-tests validate exec - cp - test-harness/features/evaluation.feature + spec/specification/assets/gherkin/evaluation.feature src/test/resources/features/ diff --git a/spec b/spec new file mode 160000 index 000000000..d4a9a9109 --- /dev/null +++ b/spec @@ -0,0 +1 @@ +Subproject commit d4a9a910946eded57cf82d6fd4921785a5e64c2b diff --git a/src/test/java/dev/openfeature/sdk/e2e/RunCucumberTest.java b/src/test/java/dev/openfeature/sdk/e2e/EvaluationTest.java similarity index 62% rename from src/test/java/dev/openfeature/sdk/e2e/RunCucumberTest.java rename to src/test/java/dev/openfeature/sdk/e2e/EvaluationTest.java index 2c652338d..3e0f2ee89 100644 --- a/src/test/java/dev/openfeature/sdk/e2e/RunCucumberTest.java +++ b/src/test/java/dev/openfeature/sdk/e2e/EvaluationTest.java @@ -5,12 +5,17 @@ import org.junit.platform.suite.api.SelectClasspathResource; import org.junit.platform.suite.api.Suite; +import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME; import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME; @Suite @IncludeEngines("cucumber") -@SelectClasspathResource("features") +@SelectClasspathResource("features/evaluation.feature") @ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "pretty") -public class RunCucumberTest { - +@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "dev.openfeature.sdk.e2e.evaluation") +public class EvaluationTest { + } + + + diff --git a/src/test/java/dev/openfeature/sdk/e2e/StepDefinitions.java b/src/test/java/dev/openfeature/sdk/e2e/evaluation/StepDefinitions.java similarity index 90% rename from src/test/java/dev/openfeature/sdk/e2e/StepDefinitions.java rename to src/test/java/dev/openfeature/sdk/e2e/evaluation/StepDefinitions.java index 459fcefea..cf1905926 100644 --- a/src/test/java/dev/openfeature/sdk/e2e/StepDefinitions.java +++ b/src/test/java/dev/openfeature/sdk/e2e/evaluation/StepDefinitions.java @@ -1,4 +1,4 @@ -package dev.openfeature.sdk.e2e; +package dev.openfeature.sdk.e2e.evaluation; import dev.openfeature.sdk.Value; import dev.openfeature.sdk.EvaluationContext; @@ -52,7 +52,7 @@ public class StepDefinitions { @SneakyThrows @BeforeAll() - @Given("an openfeature client is registered with cache disabled") + @Given("a provider is registered") public static void setup() { Map> flags = buildFlags(); InMemoryProvider provider = new InMemoryProvider(flags); @@ -67,7 +67,7 @@ public static void setup() { // boolean value @When("a boolean flag with key {string} is evaluated with default value {string}") public void a_boolean_flag_with_key_boolean_flag_is_evaluated_with_default_value_false(String flagKey, - String defaultValue) { + String defaultValue) { this.booleanFlagValue = client.getBooleanValue(flagKey, Boolean.valueOf(defaultValue)); } @@ -117,7 +117,7 @@ public void an_object_flag_with_key_is_evaluated_with_a_null_default_value(Strin @Then("the resolved object value should be contain fields {string}, {string}, and {string}, with values {string}, {string} and {int}, respectively") public void the_resolved_object_value_should_be_contain_fields_and_with_values_and_respectively(String boolField, - String stringField, String numberField, String boolValue, String stringValue, int numberValue) { + String stringField, String numberField, String boolValue, String stringValue, int numberValue) { Structure structure = this.objectFlagValue.asStructure(); assertEquals(Boolean.valueOf(boolValue), structure.asMap().get(boolField).asBoolean()); @@ -132,7 +132,7 @@ public void the_resolved_object_value_should_be_contain_fields_and_with_values_a // boolean details @When("a boolean flag with key {string} is evaluated with details and default value {string}") public void a_boolean_flag_with_key_is_evaluated_with_details_and_default_value(String flagKey, - String defaultValue) { + String defaultValue) { this.booleanFlagDetails = client.getBooleanDetails(flagKey, Boolean.valueOf(defaultValue)); } @@ -148,13 +148,13 @@ public void the_resolved_boolean_value_should_be_the_variant_should_be_and_the_r // string details @When("a string flag with key {string} is evaluated with details and default value {string}") public void a_string_flag_with_key_is_evaluated_with_details_and_default_value(String flagKey, - String defaultValue) { + String defaultValue) { this.stringFlagDetails = client.getStringDetails(flagKey, defaultValue); } @Then("the resolved string details value should be {string}, the variant should be {string}, and the reason should be {string}") public void the_resolved_string_value_should_be_the_variant_should_be_and_the_reason_should_be(String expectedValue, - String expectedVariant, String expectedReason) { + String expectedVariant, String expectedReason) { assertEquals(expectedValue, this.stringFlagDetails.getValue()); assertEquals(expectedVariant, this.stringFlagDetails.getVariant()); assertEquals(expectedReason, this.stringFlagDetails.getReason()); @@ -168,7 +168,7 @@ public void an_integer_flag_with_key_is_evaluated_with_details_and_default_value @Then("the resolved integer details value should be {int}, the variant should be {string}, and the reason should be {string}") public void the_resolved_integer_value_should_be_the_variant_should_be_and_the_reason_should_be(int expectedValue, - String expectedVariant, String expectedReason) { + String expectedVariant, String expectedReason) { assertEquals(expectedValue, this.intFlagDetails.getValue()); assertEquals(expectedVariant, this.intFlagDetails.getVariant()); assertEquals(expectedReason, this.intFlagDetails.getReason()); @@ -182,7 +182,7 @@ public void a_float_flag_with_key_is_evaluated_with_details_and_default_value(St @Then("the resolved float details value should be {double}, the variant should be {string}, and the reason should be {string}") public void the_resolved_float_value_should_be_the_variant_should_be_and_the_reason_should_be(double expectedValue, - String expectedVariant, String expectedReason) { + String expectedVariant, String expectedReason) { assertEquals(expectedValue, this.doubleFlagDetails.getValue()); assertEquals(expectedVariant, this.doubleFlagDetails.getVariant()); assertEquals(expectedReason, this.doubleFlagDetails.getReason()); @@ -217,7 +217,7 @@ public void the_variant_should_be_and_the_reason_should_be(String expectedVarian @When("context contains keys {string}, {string}, {string}, {string} with values {string}, {string}, {int}, {string}") public void context_contains_keys_with_values(String field1, String field2, String field3, String field4, - String value1, String value2, Integer value3, String value4) { + String value1, String value2, Integer value3, String value4) { Map attributes = new HashMap<>(); attributes.put(field1, new Value(value1)); attributes.put(field2, new Value(value2)); @@ -253,7 +253,7 @@ public void the_resolved_flag_value_is_when_the_context_is_empty(String expected // not found @When("a non-existent string flag with key {string} is evaluated with details and a default value {string}") public void a_non_existent_string_flag_with_key_is_evaluated_with_details_and_a_default_value(String flagKey, - String defaultValue) { + String defaultValue) { notFoundFlagKey = flagKey; notFoundDefaultValue = defaultValue; notFoundDetails = client.getStringDetails(notFoundFlagKey, notFoundDefaultValue); @@ -273,7 +273,7 @@ public void the_reason_should_indicate_an_error_and_the_error_code_should_be_fla // type mismatch @When("a string flag with key {string} is evaluated as an integer, with details and a default value {int}") public void a_string_flag_with_key_is_evaluated_as_an_integer_with_details_and_a_default_value(String flagKey, - int defaultValue) { + int defaultValue) { typeErrorFlagKey = flagKey; typeErrorDefaultValue = defaultValue; typeErrorDetails = client.getIntegerDetails(typeErrorFlagKey, typeErrorDefaultValue); diff --git a/test-harness b/test-harness deleted file mode 160000 index 2d4c63c80..000000000 --- a/test-harness +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2d4c63c800aa3af172cf09176325d93124153cde From da725d89e03d499a37307cca47b2c51af5ac8782 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Dec 2024 23:08:11 +0000 Subject: [PATCH 058/745] chore(deps): update actions/cache digest to 1bd1e32 (#1237) 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 d31c6130c..496194427 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -32,7 +32,7 @@ jobs: server-password: ${{ secrets.OSSRH_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 2ffa85408..ef4801667 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -25,7 +25,7 @@ jobs: languages: java - name: Cache local Maven repository - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} From c5ad1b4d4f805a6ae070eabc6de38b37dd759c05 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 6 Dec 2024 01:03:17 +0000 Subject: [PATCH 059/745] chore(deps): update codecov/codecov-action action to v5.1.1 (#1238) 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 496194427..ad5c56386 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -49,7 +49,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.0.7 + uses: codecov/codecov-action@v5.1.1 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 ef4801667..d273f37c2 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -36,7 +36,7 @@ jobs: run: mvn --batch-mode --update-snapshots --activate-profiles e2e verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.0.7 + uses: codecov/codecov-action@v5.1.1 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From 64ad644bdbb6a4535da8ec7628e74d5f41f7ebec Mon Sep 17 00:00:00 2001 From: warber <72415058+warber@users.noreply.github.com> Date: Fri, 6 Dec 2024 16:19:36 +0100 Subject: [PATCH 060/745] feat: add tracking as per spec (#1228) feat: add tracking as per spec --------- Signed-off-by: Bernd Warmuth --- README.md | 33 ++- src/main/java/dev/openfeature/sdk/Client.java | 6 +- .../dev/openfeature/sdk/FeatureProvider.java | 10 + .../sdk/ImmutableTrackingEventDetails.java | 53 +++++ .../sdk/MutableTrackingEventDetails.java | 94 +++++++++ .../openfeature/sdk/OpenFeatureClient.java | 103 ++++++++-- .../java/dev/openfeature/sdk/Tracking.java | 42 ++++ .../openfeature/sdk/TrackingEventDetails.java | 7 + .../sdk/MutableTrackingEventDetailsTest.java | 51 +++++ .../openfeature/sdk/OpenFeatureAPITest.java | 20 ++ .../sdk/OpenFeatureClientTest.java | 4 +- .../dev/openfeature/sdk/TrackingSpecTest.java | 189 ++++++++++++++++++ 12 files changed, 576 insertions(+), 36 deletions(-) create mode 100644 src/main/java/dev/openfeature/sdk/ImmutableTrackingEventDetails.java create mode 100644 src/main/java/dev/openfeature/sdk/MutableTrackingEventDetails.java create mode 100644 src/main/java/dev/openfeature/sdk/Tracking.java create mode 100644 src/main/java/dev/openfeature/sdk/TrackingEventDetails.java create mode 100644 src/test/java/dev/openfeature/sdk/MutableTrackingEventDetailsTest.java create mode 100644 src/test/java/dev/openfeature/sdk/TrackingSpecTest.java diff --git a/README.md b/README.md index c710de664..a277600df 100644 --- a/README.md +++ b/README.md @@ -120,17 +120,18 @@ See [here](https://javadoc.io/doc/dev.openfeature/sdk/latest/) for the Javadocs. ## 🌟 Features -| Status | Features | Description | -| ------ |-----------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------| -| ✅ | [Providers](#providers) | Integrate with a commercial, open source, or in-house feature management tool. | -| ✅ | [Targeting](#targeting) | Contextually-aware flag evaluation using [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context). | -| ✅ | [Hooks](#hooks) | Add functionality to various stages of the flag evaluation life-cycle. | -| ✅ | [Logging](#logging) | Integrate with popular logging packages. | -| ✅ | [Domains](#domains) | Logically bind clients with providers. | -| ✅ | [Eventing](#eventing) | React to state changes in the provider or flag management system. | -| ✅ | [Shutdown](#shutdown) | Gracefully clean up a provider during application shutdown. | -| ✅ | [Transaction Context Propagation](#transaction-context-propagation) | Set a specific [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context) for a transaction (e.g. an HTTP request or a thread). | -| ✅ | [Extending](#extending) | Extend OpenFeature with custom providers and hooks. | +| Status | Features | Description | +| ------ |---------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------| +| ✅ | [Providers](#providers) | Integrate with a commercial, open source, or in-house feature management tool. | +| ✅ | [Targeting](#targeting) | Contextually-aware flag evaluation using [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context). | +| ✅ | [Hooks](#hooks) | Add functionality to various stages of the flag evaluation life-cycle. | +| ✅ | [Tracking](#tracking) | Associate user actions with feature flag evaluations. | +| ✅ | [Logging](#logging) | Integrate with popular logging packages. | +| ✅ | [Domains](#domains) | Logically bind clients with providers. | +| ✅ | [Eventing](#eventing) | React to state changes in the provider or flag management system. | +| ✅ | [Shutdown](#shutdown) | Gracefully clean up a provider during application shutdown. | +| ✅ | [Transaction Context Propagation](#transaction-context-propagation) | Set a specific [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context) for a transaction (e.g. an HTTP request or a thread). | +| ✅ | [Extending](#extending) | Extend OpenFeature with custom providers and hooks. | Implemented: ✅ | In-progress: ⚠️ | Not implemented yet: ❌ @@ -215,6 +216,16 @@ Once you've added a hook as a dependency, it can be registered at the global, cl FlagEvaluationOptions.builder().hook(new ExampleHook()).build()); ``` +### Tracking + +The [tracking API](https://openfeature.dev/specification/sections/tracking/) allows you to use OpenFeature abstractions to associate user actions with feature flag evaluations. +This is essential for robust experimentation powered by feature flags. Note that, unlike methods that handle feature flag evaluations, calling `track(...)` may throw an `IllegalArgumentException` if an empty string is passed as the `trackingEventName`. + +```java +OpenFeatureAPI api = OpenFeatureAPI.getInstance(); +api.getClient().track("visited-promo-page", new MutableTrackingEventDetails(99.77).add("currency", "USD")); +``` + ### Logging The Java SDK uses SLF4J. See the [SLF4J manual](https://slf4j.org/manual.html) for complete documentation. diff --git a/src/main/java/dev/openfeature/sdk/Client.java b/src/main/java/dev/openfeature/sdk/Client.java index 7b41b9b07..441d31e2b 100644 --- a/src/main/java/dev/openfeature/sdk/Client.java +++ b/src/main/java/dev/openfeature/sdk/Client.java @@ -5,17 +5,19 @@ /** * Interface used to resolve flags of varying types. */ -public interface Client extends Features, EventBus { +public interface Client extends Features, Tracking, EventBus { ClientMetadata getMetadata(); /** * Return an optional client-level evaluation context. + * * @return {@link EvaluationContext} */ EvaluationContext getEvaluationContext(); /** * Set the client-level evaluation context. + * * @param ctx Client level context. */ Client setEvaluationContext(EvaluationContext ctx); @@ -30,12 +32,14 @@ public interface Client extends Features, EventBus { /** * Fetch the hooks associated to this client. + * * @return A list of {@link Hook}s. */ List getHooks(); /** * Returns the current state of the associated provider. + * * @return the provider state */ ProviderState getProviderState(); diff --git a/src/main/java/dev/openfeature/sdk/FeatureProvider.java b/src/main/java/dev/openfeature/sdk/FeatureProvider.java index f73b6cdfa..706818e85 100644 --- a/src/main/java/dev/openfeature/sdk/FeatureProvider.java +++ b/src/main/java/dev/openfeature/sdk/FeatureProvider.java @@ -71,4 +71,14 @@ default ProviderState getState() { return ProviderState.READY; } + /** + * Feature provider implementations can opt in for to support Tracking by implementing this method. + * + * @param eventName The name of the tracking event + * @param context Evaluation context used in flag evaluation (Optional) + * @param details Data pertinent to a particular tracking event (Optional) + */ + default void track(String eventName, EvaluationContext context, TrackingEventDetails details) { + + } } diff --git a/src/main/java/dev/openfeature/sdk/ImmutableTrackingEventDetails.java b/src/main/java/dev/openfeature/sdk/ImmutableTrackingEventDetails.java new file mode 100644 index 000000000..b535bb7da --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/ImmutableTrackingEventDetails.java @@ -0,0 +1,53 @@ +package dev.openfeature.sdk; + +import dev.openfeature.sdk.internal.ExcludeFromGeneratedCoverageReport; +import lombok.experimental.Delegate; + +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; + + +/** + * ImmutableTrackingEventDetails represents data pertinent to a particular tracking event. + */ +public class ImmutableTrackingEventDetails implements TrackingEventDetails { + + @Delegate(excludes = DelegateExclusions.class) + private final ImmutableStructure structure; + + private final Number value; + + public ImmutableTrackingEventDetails() { + this.value = null; + this.structure = new ImmutableStructure(); + } + + public ImmutableTrackingEventDetails(final Number value) { + this.value = value; + this.structure = new ImmutableStructure(); + } + + public ImmutableTrackingEventDetails(final Number value, final Map attributes) { + this.value = value; + this.structure = new ImmutableStructure(attributes); + } + + /** + * Returns the optional tracking value. + */ + public Optional getValue() { + return Optional.ofNullable(value); + } + + + @SuppressWarnings("all") + private static class DelegateExclusions { + @ExcludeFromGeneratedCoverageReport + public Map merge(Function, Structure> newStructure, + Map base, + Map overriding) { + return null; + } + } +} diff --git a/src/main/java/dev/openfeature/sdk/MutableTrackingEventDetails.java b/src/main/java/dev/openfeature/sdk/MutableTrackingEventDetails.java new file mode 100644 index 000000000..9f0de8c3a --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/MutableTrackingEventDetails.java @@ -0,0 +1,94 @@ +package dev.openfeature.sdk; + +import dev.openfeature.sdk.internal.ExcludeFromGeneratedCoverageReport; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import lombok.experimental.Delegate; + +import java.time.Instant; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; + +/** + * MutableTrackingEventDetails represents data pertinent to a particular tracking event. + */ +@EqualsAndHashCode +@ToString +public class MutableTrackingEventDetails implements TrackingEventDetails { + + private final Number value; + @Delegate(excludes = MutableTrackingEventDetails.DelegateExclusions.class) + private final MutableStructure structure; + + public MutableTrackingEventDetails() { + this.value = null; + this.structure = new MutableStructure(); + } + + public MutableTrackingEventDetails(final Number value) { + this.value = value; + this.structure = new MutableStructure(); + } + + /** + * Returns the optional tracking value. + */ + public Optional getValue() { + return Optional.ofNullable(value); + } + + // override @Delegate methods so that we can use "add" methods and still return MutableTrackingEventDetails, + // not Structure + public MutableTrackingEventDetails add(String key, Boolean value) { + this.structure.add(key, value); + return this; + } + + public MutableTrackingEventDetails add(String key, String value) { + this.structure.add(key, value); + return this; + } + + public MutableTrackingEventDetails add(String key, Integer value) { + this.structure.add(key, value); + return this; + } + + public MutableTrackingEventDetails add(String key, Double value) { + this.structure.add(key, value); + return this; + } + + public MutableTrackingEventDetails add(String key, Instant value) { + this.structure.add(key, value); + return this; + } + + public MutableTrackingEventDetails add(String key, Structure value) { + this.structure.add(key, value); + return this; + } + + public MutableTrackingEventDetails add(String key, List value) { + this.structure.add(key, value); + return this; + } + + public MutableTrackingEventDetails add(String key, Value value) { + this.structure.add(key, value); + return this; + } + + + @SuppressWarnings("all") + private static class DelegateExclusions { + @ExcludeFromGeneratedCoverageReport + public Map merge(Function, Structure> newStructure, + Map base, + Map overriding) { + return null; + } + } +} diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index f56df15a0..ea566e652 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -1,13 +1,5 @@ package dev.openfeature.sdk; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.List; -import java.util.function.Consumer; - import dev.openfeature.sdk.exceptions.ExceptionUtils; import dev.openfeature.sdk.exceptions.FatalError; import dev.openfeature.sdk.exceptions.GeneralError; @@ -19,6 +11,15 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Consumer; + /** * OpenFeature Client implementation. * You should not instantiate this or reference this class. @@ -28,8 +29,8 @@ * @deprecated // TODO: eventually we will make this non-public. See issue #872 */ @Slf4j -@SuppressWarnings({ "PMD.DataflowAnomalyAnalysis", "PMD.BeanMembersShouldSerialize", "PMD.UnusedLocalVariable", - "unchecked", "rawtypes" }) +@SuppressWarnings({"PMD.DataflowAnomalyAnalysis", "PMD.BeanMembersShouldSerialize", "PMD.UnusedLocalVariable", + "unchecked", "rawtypes"}) @Deprecated() // TODO: eventually we will make this non-public. See issue #872 public class OpenFeatureClient implements Client { @@ -67,11 +68,56 @@ public OpenFeatureClient( this.hookSupport = new HookSupport(); } + /** + * {@inheritDoc} + */ @Override public ProviderState getProviderState() { return openfeatureApi.getFeatureProviderStateManager(domain).getState(); } + /** + * {@inheritDoc} + */ + @Override + public void track(String trackingEventName) { + validateTrackingEventName(trackingEventName); + invokeTrack(trackingEventName, null, null); + } + + + /** + * {@inheritDoc} + */ + @Override + public void track(String trackingEventName, EvaluationContext context) { + validateTrackingEventName(trackingEventName); + Objects.requireNonNull(context); + invokeTrack(trackingEventName, context, null); + } + + /** + * {@inheritDoc} + */ + @Override + public void track(String trackingEventName, TrackingEventDetails details) { + validateTrackingEventName(trackingEventName); + Objects.requireNonNull(details); + invokeTrack(trackingEventName, null, details); + } + + /** + * {@inheritDoc} + */ + @Override + public void track(String trackingEventName, EvaluationContext context, TrackingEventDetails details) { + validateTrackingEventName(trackingEventName); + Objects.requireNonNull(context); + Objects.requireNonNull(details); + invokeTrack(trackingEventName, mergeEvaluationContext(context), details); + } + + /** * {@inheritDoc} */ @@ -115,7 +161,7 @@ public EvaluationContext getEvaluationContext() { } private FlagEvaluationDetails evaluateFlag(FlagValueType type, String key, T defaultValue, - EvaluationContext ctx, FlagEvaluationOptions options) { + EvaluationContext ctx, FlagEvaluationOptions options) { FlagEvaluationOptions flagOptions = ObjectUtils.defaultIfNull(options, () -> FlagEvaluationOptions.builder().build()); Map hints = Collections.unmodifiableMap(flagOptions.getHookHints()); @@ -183,6 +229,19 @@ private static void enrichDetailsWithErrorDefaults(T defaultValue, FlagEvalu details.setReason(Reason.ERROR.toString()); } + private static void validateTrackingEventName(String str) { + Objects.requireNonNull(str); + if (str.isEmpty()) { + throw new IllegalArgumentException("trackingEventName cannot be empty"); + } + } + + private void invokeTrack(String trackingEventName, EvaluationContext context, TrackingEventDetails details) { + openfeatureApi.getFeatureProviderStateManager(domain) + .getProvider() + .track(trackingEventName, mergeEvaluationContext(context), details); + } + /** * Merge invocation contexts with API, transaction and client contexts. * Does not merge before context. @@ -244,7 +303,7 @@ public Boolean getBooleanValue(String key, Boolean defaultValue, EvaluationConte @Override public Boolean getBooleanValue(String key, Boolean defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + FlagEvaluationOptions options) { return getBooleanDetails(key, defaultValue, ctx, options).getValue(); } @@ -260,7 +319,7 @@ public FlagEvaluationDetails getBooleanDetails(String key, Boolean defa @Override public FlagEvaluationDetails getBooleanDetails(String key, Boolean defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + FlagEvaluationOptions options) { return this.evaluateFlag(FlagValueType.BOOLEAN, key, defaultValue, ctx, options); } @@ -276,7 +335,7 @@ public String getStringValue(String key, String defaultValue, EvaluationContext @Override public String getStringValue(String key, String defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + FlagEvaluationOptions options) { return getStringDetails(key, defaultValue, ctx, options).getValue(); } @@ -292,7 +351,7 @@ public FlagEvaluationDetails getStringDetails(String key, String default @Override public FlagEvaluationDetails getStringDetails(String key, String defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + FlagEvaluationOptions options) { return this.evaluateFlag(FlagValueType.STRING, key, defaultValue, ctx, options); } @@ -308,7 +367,7 @@ public Integer getIntegerValue(String key, Integer defaultValue, EvaluationConte @Override public Integer getIntegerValue(String key, Integer defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + FlagEvaluationOptions options) { return getIntegerDetails(key, defaultValue, ctx, options).getValue(); } @@ -324,7 +383,7 @@ public FlagEvaluationDetails getIntegerDetails(String key, Integer defa @Override public FlagEvaluationDetails getIntegerDetails(String key, Integer defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + FlagEvaluationOptions options) { return this.evaluateFlag(FlagValueType.INTEGER, key, defaultValue, ctx, options); } @@ -340,7 +399,7 @@ public Double getDoubleValue(String key, Double defaultValue, EvaluationContext @Override public Double getDoubleValue(String key, Double defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + FlagEvaluationOptions options) { return this.evaluateFlag(FlagValueType.DOUBLE, key, defaultValue, ctx, options).getValue(); } @@ -356,7 +415,7 @@ public FlagEvaluationDetails getDoubleDetails(String key, Double default @Override public FlagEvaluationDetails getDoubleDetails(String key, Double defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + FlagEvaluationOptions options) { return this.evaluateFlag(FlagValueType.DOUBLE, key, defaultValue, ctx, options); } @@ -372,7 +431,7 @@ public Value getObjectValue(String key, Value defaultValue, EvaluationContext ct @Override public Value getObjectValue(String key, Value defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + FlagEvaluationOptions options) { return getObjectDetails(key, defaultValue, ctx, options).getValue(); } @@ -383,13 +442,13 @@ public FlagEvaluationDetails getObjectDetails(String key, Value defaultVa @Override public FlagEvaluationDetails getObjectDetails(String key, Value defaultValue, - EvaluationContext ctx) { + EvaluationContext ctx) { return getObjectDetails(key, defaultValue, ctx, FlagEvaluationOptions.builder().build()); } @Override public FlagEvaluationDetails getObjectDetails(String key, Value defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + FlagEvaluationOptions options) { return this.evaluateFlag(FlagValueType.OBJECT, key, defaultValue, ctx, options); } diff --git a/src/main/java/dev/openfeature/sdk/Tracking.java b/src/main/java/dev/openfeature/sdk/Tracking.java new file mode 100644 index 000000000..ec9c8a8fe --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/Tracking.java @@ -0,0 +1,42 @@ +package dev.openfeature.sdk; + +/** + * Interface for Tracking events. + */ +public interface Tracking { + /** + * Performs tracking of a particular action or application state. + * + * @param trackingEventName Event name to track + * @throws IllegalArgumentException if {@code trackingEventName} is null + */ + void track(String trackingEventName); + + /** + * Performs tracking of a particular action or application state. + * + * @param trackingEventName Event name to track + * @param context Evaluation context used in flag evaluation + * @throws IllegalArgumentException if {@code trackingEventName} is null + */ + void track(String trackingEventName, EvaluationContext context); + + /** + * Performs tracking of a particular action or application state. + * + * @param trackingEventName Event name to track + * @param details Data pertinent to a particular tracking event + * @throws IllegalArgumentException if {@code trackingEventName} is null + */ + void track(String trackingEventName, TrackingEventDetails details); + + /** + * Performs tracking of a particular action or application state. + * + * @param trackingEventName Event name to track + * @param context Evaluation context used in flag evaluation + * @param details Data pertinent to a particular tracking event + * @throws IllegalArgumentException if {@code trackingEventName} is null + */ + void track(String trackingEventName, EvaluationContext context, TrackingEventDetails details); +} diff --git a/src/main/java/dev/openfeature/sdk/TrackingEventDetails.java b/src/main/java/dev/openfeature/sdk/TrackingEventDetails.java new file mode 100644 index 000000000..76b20fbbf --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/TrackingEventDetails.java @@ -0,0 +1,7 @@ +package dev.openfeature.sdk; + +/** + * Data pertinent to a particular tracking event. + */ +public interface TrackingEventDetails extends Structure { +} diff --git a/src/test/java/dev/openfeature/sdk/MutableTrackingEventDetailsTest.java b/src/test/java/dev/openfeature/sdk/MutableTrackingEventDetailsTest.java new file mode 100644 index 000000000..a169107f1 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/MutableTrackingEventDetailsTest.java @@ -0,0 +1,51 @@ +package dev.openfeature.sdk; + +import com.google.common.collect.Lists; +import org.junit.jupiter.api.Test; + +import java.time.Instant; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +class MutableTrackingEventDetailsTest { + + + @Test + void hasDefaultValue() { + MutableTrackingEventDetails track = new MutableTrackingEventDetails(); + assertFalse(track.getValue().isPresent()); + } + + @Test + void shouldUseCorrectValue() { + MutableTrackingEventDetails track = new MutableTrackingEventDetails(3); + assertThat(track.getValue()).hasValue(3); + } + + @Test + void shouldStoreAttributes() { + MutableTrackingEventDetails track = new MutableTrackingEventDetails(); + track.add("key0", true); + track.add("key1", 1); + track.add("key2", "2"); + track.add("key3", 1d); + track.add("key4", 4); + track.add("key5", Instant.parse("2023-12-03T10:15:30Z")); + track.add("key6", new MutableContext()); + track.add("key7", new Value(7)); + track.add("key8", Lists.newArrayList(new Value(8), new Value(9))); + + assertEquals(new Value(true), track.getValue("key0")); + assertEquals(new Value(1), track.getValue("key1")); + assertEquals(new Value("2"), track.getValue("key2")); + assertEquals(new Value(1d), track.getValue("key3")); + assertEquals(new Value(4), track.getValue("key4")); + assertEquals(new Value(Instant.parse("2023-12-03T10:15:30Z")), track.getValue("key5")); + assertEquals(new Value(new MutableContext()), track.getValue("key6")); + assertEquals(new Value(7), track.getValue("key7")); + assertArrayEquals(new Object[]{new Value(8), new Value(9)}, track.getValue("key8").asList().toArray()); + } +} \ No newline at end of file diff --git a/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java b/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java index 23c758e9f..026170a78 100644 --- a/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java +++ b/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java @@ -12,6 +12,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; class OpenFeatureAPITest { @@ -101,4 +104,21 @@ void getStateReturnsTheStateOfTheAppropriateProvider() throws Exception { assertThat(OpenFeatureAPI.getInstance().getClient(domain).getProviderState()) .isEqualTo(ProviderState.READY); } + + + @Test + void featureProviderTrackIsCalled() throws Exception { + FeatureProvider featureProvider = mock(FeatureProvider.class); + FeatureProviderTestUtils.setFeatureProvider(featureProvider); + + OpenFeatureAPI.getInstance() + .getClient() + .track("track-event", + new ImmutableContext(), + new MutableTrackingEventDetails(22.2f)); + + verify(featureProvider).initialize(any()); + verify(featureProvider).getMetadata(); + verify(featureProvider).track(any(), any(), any()); + } } diff --git a/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java b/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java index 69d38a486..3c82fd656 100644 --- a/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java +++ b/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java @@ -5,8 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; +import static org.mockito.Mockito.*; import java.util.HashMap; import java.util.concurrent.atomic.AtomicBoolean; @@ -79,6 +78,7 @@ void setEvaluationContextShouldAllowChaining() { assertEquals(client, result); } + @Test @DisplayName("Should not call evaluation methods when the provider has state FATAL") void shouldNotCallEvaluationMethodsWhenProviderIsInFatalErrorState() { diff --git a/src/test/java/dev/openfeature/sdk/TrackingSpecTest.java b/src/test/java/dev/openfeature/sdk/TrackingSpecTest.java new file mode 100644 index 000000000..6d195607b --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/TrackingSpecTest.java @@ -0,0 +1,189 @@ +package dev.openfeature.sdk; + +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 lombok.SneakyThrows; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.notNull; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.argThat; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +class TrackingSpecTest { + + private OpenFeatureAPI api; + private Client client; + + @BeforeEach + void getApiInstance() { + api = OpenFeatureAPI.getInstance(); + client = api.getClient(); + } + + + @Specification(number = "6.1.1.1", text = "The `client` MUST define a function for tracking the occurrence of " + + "a particular action or application state, with parameters `tracking event name` (string, required), " + + "`evaluation context` (optional) and `tracking event details` (optional), which returns nothing.") + @Specification(number = "6.1.2.1", text = "The `client` MUST define a function for tracking the occurrence of a " + + "particular action or application state, with parameters `tracking event name` (string, required) and " + + "`tracking event details` (optional), which returns nothing.") + @Test + @SneakyThrows + void trackMethodFulfillsSpec() { + + ImmutableContext ctx = new ImmutableContext(); + MutableTrackingEventDetails details = new MutableTrackingEventDetails(0.0f); + assertThatCode(() -> client.track("event")).doesNotThrowAnyException(); + assertThatCode(() -> client.track("event", ctx)).doesNotThrowAnyException(); + assertThatCode(() -> client.track("event", details)).doesNotThrowAnyException(); + assertThatCode(() -> client.track("event", ctx, details)).doesNotThrowAnyException(); + + assertThrows(NullPointerException.class, () -> client.track(null, ctx, details)); + assertThrows(NullPointerException.class, () -> client.track("event", null, details)); + assertThrows(NullPointerException.class, () -> client.track("event", ctx, null)); + assertThrows(NullPointerException.class, () -> client.track(null, null, null)); + assertThrows(NullPointerException.class, () -> client.track(null, ctx)); + assertThrows(NullPointerException.class, () -> client.track(null, details)); + assertThrows(NullPointerException.class, () -> client.track("event", (EvaluationContext) null)); + assertThrows(NullPointerException.class, () -> client.track("event", (TrackingEventDetails) null)); + + assertThrows(IllegalArgumentException.class, () -> client.track("")); + assertThrows(IllegalArgumentException.class, () -> client.track("", ctx)); + assertThrows(IllegalArgumentException.class, () -> client.track("", ctx, details)); + + + Class clientClass = OpenFeatureClient.class; + assertEquals( + void.class, + clientClass.getMethod("track", String.class).getReturnType(), + "The method should return void."); + assertEquals( + void.class, + clientClass.getMethod("track", String.class, EvaluationContext.class).getReturnType(), + "The method should return void."); + + assertEquals( + void.class, + clientClass.getMethod("track", String.class, EvaluationContext.class, TrackingEventDetails.class).getReturnType(), + "The method should return void."); + + + } + + @Specification(number = "6.1.3", text = "The evaluation context passed to the provider's track function " + + "MUST be merged in the order: API (global; lowest precedence) -> transaction -> client -> " + + "invocation (highest precedence), with duplicate values being overwritten.") + @Test + void contextsGetMerged() { + + api.setTransactionContextPropagator(new ThreadLocalTransactionContextPropagator()); + + Map apiAttr = new HashMap<>(); + apiAttr.put("my-key", new Value("hey")); + apiAttr.put("my-api-key", new Value("333")); + EvaluationContext apiCtx = new ImmutableContext(apiAttr); + api.setEvaluationContext(apiCtx); + + Map txAttr = new HashMap<>(); + txAttr.put("my-key", new Value("overwritten")); + txAttr.put("my-tx-key", new Value("444")); + EvaluationContext txCtx = new ImmutableContext(txAttr); + api.setTransactionContext(txCtx); + + Map clAttr = new HashMap<>(); + clAttr.put("my-key", new Value("overwritten-again")); + clAttr.put("my-cl-key", new Value("555")); + EvaluationContext clCtx = new ImmutableContext(clAttr); + client.setEvaluationContext(clCtx); + + FeatureProvider provider = ProviderFixture.createMockedProvider(); + FeatureProviderTestUtils.setFeatureProvider(provider); + + client.track("event", new MutableContext().add("my-key", "final"), new MutableTrackingEventDetails(0.0f)); + + Map expectedMap = Maps.newHashMap(); + expectedMap.put("my-key", new Value("final")); + expectedMap.put("my-api-key", new Value("333")); + expectedMap.put("my-tx-key", new Value("444")); + expectedMap.put("my-cl-key", new Value("555")); + verify(provider).track(eq("event"), argThat(ctx -> ctx.asMap().equals(expectedMap)), notNull()); + } + + @Specification(number = "6.1.4", text = "If the client's `track` function is called and the associated provider " + + "does not implement tracking, the client's `track` function MUST no-op.") + @Test + void noopProvider() { + FeatureProvider provider = spy(FeatureProvider.class); + api.setProvider(provider); + client.track("event"); + verify(provider).track(any(), any(), any()); + } + + @Specification(number = "6.2.1", text = "The `tracking event details` structure MUST define an optional numeric " + + "`value`, associating a scalar quality with an `tracking event`.") + @Specification(number = "6.2.2", text = "The `tracking event details` MUST support the inclusion of custom " + + "fields, having keys of type `string`, and values of type `boolean | string | number | structure`.") + @Test + void eventDetails() { + assertFalse(new MutableTrackingEventDetails().getValue().isPresent()); + assertFalse(new ImmutableTrackingEventDetails().getValue().isPresent()); + assertThat(new ImmutableTrackingEventDetails(2).getValue()).hasValue(2); + assertThat(new MutableTrackingEventDetails(9.87f).getValue()).hasValue(9.87f); + + + // using mutable tracking event details + Map expectedMap = Maps.newHashMap(); + expectedMap.put("my-str", new Value("str")); + expectedMap.put("my-num", new Value(1)); + expectedMap.put("my-bool", new Value(true)); + expectedMap.put("my-struct", new Value(new MutableTrackingEventDetails())); + + MutableTrackingEventDetails details = new MutableTrackingEventDetails() + .add("my-str", new Value("str")) + .add("my-num", new Value(1)) + .add("my-bool", new Value(true)) + .add("my-struct", new Value(new MutableTrackingEventDetails())); + + assertEquals(expectedMap, details.asMap()); + assertThatCode(() -> OpenFeatureAPI.getInstance().getClient(). + track( + "tracking-event-name", + new ImmutableContext(), + new MutableTrackingEventDetails())) + .doesNotThrowAnyException(); + + + // using immutable tracking event details + ImmutableMap expectedImmutable = ImmutableMap.of("my-str", new Value("str"), + "my-num", new Value(1), + "my-bool", new Value(true), + "my-struct", new Value(new ImmutableStructure()) + ); + + ImmutableTrackingEventDetails immutableDetails = new ImmutableTrackingEventDetails(2, expectedMap); + assertEquals(expectedImmutable, immutableDetails.asMap()); + assertThatCode(() -> OpenFeatureAPI.getInstance().getClient(). + track( + "tracking-event-name", + new ImmutableContext(), + new ImmutableTrackingEventDetails())) + .doesNotThrowAnyException(); + + + } + +} From baaa78b7ec34a3e508fda3ed8c3ea5382f1e18ea Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 6 Dec 2024 21:55:48 +0000 Subject: [PATCH 061/745] chore(deps): update github/codeql-action digest to 6f9e628 (#1239) 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 d273f37c2..1eaeaf487 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@3096afedf9873361b2b2f65e1445b13272c83eb8 + uses: github/codeql-action/init@6f9e628e6f9a18c785dd746325ba455111df1b67 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3096afedf9873361b2b2f65e1445b13272c83eb8 + uses: github/codeql-action/analyze@6f9e628e6f9a18c785dd746325ba455111df1b67 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 84a67033a..41ea5f52b 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@3096afedf9873361b2b2f65e1445b13272c83eb8 + uses: github/codeql-action/init@6f9e628e6f9a18c785dd746325ba455111df1b67 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@3096afedf9873361b2b2f65e1445b13272c83eb8 + uses: github/codeql-action/autobuild@6f9e628e6f9a18c785dd746325ba455111df1b67 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3096afedf9873361b2b2f65e1445b13272c83eb8 + uses: github/codeql-action/analyze@6f9e628e6f9a18c785dd746325ba455111df1b67 From c87c6e7a760e84a5e8d9a6d935ef35611d1de8ab Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 7 Dec 2024 16:29:04 +0000 Subject: [PATCH 062/745] chore(deps): update dependency org.apache.maven.plugins:maven-javadoc-plugin to v3.11.2 (#1240) 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 63fa4bd99..071f27c0a 100644 --- a/pom.xml +++ b/pom.xml @@ -477,7 +477,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.11.1 + 3.11.2 true all,-missing From cacacc2615d7c7b59af8935222d7c0c944e40479 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 08:48:34 -0500 Subject: [PATCH 063/745] chore(main): release 1.13.0 (#1185) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 68 +++++++++++++++++++++++++++++++++++ README.md | 8 ++--- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 75 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index c6516de7a..12295c5d8 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"1.12.2"} \ No newline at end of file +{".":"1.13.0"} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bfa9ddb8..d91800bc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,73 @@ # Changelog +## [1.13.0](https://github.com/open-feature/java-sdk/compare/v1.12.2...v1.13.0) (2024-12-07) + + +### 🐛 Bug Fixes + +* **deps:** update dependency org.projectlombok:lombok to v1.18.36 ([#1219](https://github.com/open-feature/java-sdk/issues/1219)) ([9cadc71](https://github.com/open-feature/java-sdk/commit/9cadc71d9d8a2a88f9c716c27eb939f423b95fa0)) + + +### ✨ New Features + +* add tracking as per spec ([#1228](https://github.com/open-feature/java-sdk/issues/1228)) ([64ad644](https://github.com/open-feature/java-sdk/commit/64ad644bdbb6a4535da8ec7628e74d5f41f7ebec)) + + +### 🧹 Chore + +* **deps:** update actions/cache digest to 1bd1e32 ([#1237](https://github.com/open-feature/java-sdk/issues/1237)) ([da725d8](https://github.com/open-feature/java-sdk/commit/da725d89e03d499a37307cca47b2c51af5ac8782)) +* **deps:** update actions/checkout digest to 3b9b8c8 ([#1206](https://github.com/open-feature/java-sdk/issues/1206)) ([446e298](https://github.com/open-feature/java-sdk/commit/446e2987e9b80175dff0ea72de9f58ba8e0dd323)) +* **deps:** update actions/checkout digest to cbb7224 ([#1216](https://github.com/open-feature/java-sdk/issues/1216)) ([273efc6](https://github.com/open-feature/java-sdk/commit/273efc62a7bb2e3fe962036d82818eb1da43b197)) +* **deps:** update amannn/action-semantic-pull-request digest to 40166f0 ([#1212](https://github.com/open-feature/java-sdk/issues/1212)) ([d5228f5](https://github.com/open-feature/java-sdk/commit/d5228f5ccfa55753178425c55a02af1833168513)) +* **deps:** update codecov/codecov-action action to v5 ([#1217](https://github.com/open-feature/java-sdk/issues/1217)) ([7aa77b8](https://github.com/open-feature/java-sdk/commit/7aa77b8614401c56e8387d55382e4be115a7d1ef)) +* **deps:** update codecov/codecov-action action to v5.0.2 ([#1218](https://github.com/open-feature/java-sdk/issues/1218)) ([1b4947f](https://github.com/open-feature/java-sdk/commit/1b4947f108c15a4777bb35bafb631a40c7e20e77)) +* **deps:** update codecov/codecov-action action to v5.0.3 ([#1223](https://github.com/open-feature/java-sdk/issues/1223)) ([e91194a](https://github.com/open-feature/java-sdk/commit/e91194ae16c1d68033a750050af18de68a618f61)) +* **deps:** update codecov/codecov-action action to v5.0.4 ([#1224](https://github.com/open-feature/java-sdk/issues/1224)) ([19ed5c7](https://github.com/open-feature/java-sdk/commit/19ed5c7c97dc286a85faae1c4906508f97191497)) +* **deps:** update codecov/codecov-action action to v5.0.6 ([#1226](https://github.com/open-feature/java-sdk/issues/1226)) ([13811dc](https://github.com/open-feature/java-sdk/commit/13811dcf254b604ec73b4df184d432f1dc404398)) +* **deps:** update codecov/codecov-action action to v5.0.7 ([#1227](https://github.com/open-feature/java-sdk/issues/1227)) ([234062c](https://github.com/open-feature/java-sdk/commit/234062cf338036b3b942b83c00b31191fb626432)) +* **deps:** update codecov/codecov-action action to v5.1.1 ([#1238](https://github.com/open-feature/java-sdk/issues/1238)) ([c5ad1b4](https://github.com/open-feature/java-sdk/commit/c5ad1b4d4f805a6ae070eabc6de38b37dd759c05)) +* **deps:** update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.8.6.6 ([#1213](https://github.com/open-feature/java-sdk/issues/1213)) ([92c8791](https://github.com/open-feature/java-sdk/commit/92c87913ac417b8b3651290a4df828bdf5d501b9)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.15.10 ([#1202](https://github.com/open-feature/java-sdk/issues/1202)) ([d959059](https://github.com/open-feature/java-sdk/commit/d95905917730dcb8724fe166682ca773a536eb9b)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.15.8 ([#1195](https://github.com/open-feature/java-sdk/issues/1195)) ([309f28b](https://github.com/open-feature/java-sdk/commit/309f28b520a8f629a500c359b1f522ba687bcc6b)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.15.9 ([#1197](https://github.com/open-feature/java-sdk/issues/1197)) ([54a2345](https://github.com/open-feature/java-sdk/commit/54a234519f36ea803ec8574f27c94a9f754bf822)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.15.10 ([#1203](https://github.com/open-feature/java-sdk/issues/1203)) ([2bb2ed3](https://github.com/open-feature/java-sdk/commit/2bb2ed39928e0e15d369741df8b877c751e8d122)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.15.8 ([#1196](https://github.com/open-feature/java-sdk/issues/1196)) ([30eb2ce](https://github.com/open-feature/java-sdk/commit/30eb2ce082ae2854025be084da98fb856dbcd17c)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.15.9 ([#1198](https://github.com/open-feature/java-sdk/issues/1198)) ([e32a712](https://github.com/open-feature/java-sdk/commit/e32a712615f3b1be9cff61f1337d5b00c365c8f5)) +* **deps:** update dependency org.apache.maven.plugins:maven-checkstyle-plugin to v3.6.0 ([#1188](https://github.com/open-feature/java-sdk/issues/1188)) ([89c7f85](https://github.com/open-feature/java-sdk/commit/89c7f85da436b9f16193948183a1ca54eea6ceef)) +* **deps:** update dependency org.apache.maven.plugins:maven-dependency-plugin to v3.8.1 ([#1187](https://github.com/open-feature/java-sdk/issues/1187)) ([5c7c287](https://github.com/open-feature/java-sdk/commit/5c7c28706e4614061b042080820b9efd04afc342)) +* **deps:** update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.5.2 ([#1199](https://github.com/open-feature/java-sdk/issues/1199)) ([08da9a3](https://github.com/open-feature/java-sdk/commit/08da9a34395a3e96dc2172f0f0533a4905cff204)) +* **deps:** update dependency org.apache.maven.plugins:maven-javadoc-plugin to v3.11.1 ([#1201](https://github.com/open-feature/java-sdk/issues/1201)) ([a2a57ab](https://github.com/open-feature/java-sdk/commit/a2a57ab8f1161b5de3a112bbbdc421985baf304b)) +* **deps:** update dependency org.apache.maven.plugins:maven-javadoc-plugin to v3.11.2 ([#1240](https://github.com/open-feature/java-sdk/issues/1240)) ([c87c6e7](https://github.com/open-feature/java-sdk/commit/c87c6e7a760e84a5e8d9a6d935ef35611d1de8ab)) +* **deps:** update dependency org.apache.maven.plugins:maven-pmd-plugin to v3.26.0 ([#1189](https://github.com/open-feature/java-sdk/issues/1189)) ([d5082cd](https://github.com/open-feature/java-sdk/commit/d5082cd5f6907b6e7649813dbbea99cdeab20728)) +* **deps:** update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.2 ([#1200](https://github.com/open-feature/java-sdk/issues/1200)) ([d2cb092](https://github.com/open-feature/java-sdk/commit/d2cb092b09966bc2d5a7548e35b71ab2e56e0dee)) +* **deps:** update dependency org.cyclonedx:cyclonedx-maven-plugin to v2.9.1 ([#1230](https://github.com/open-feature/java-sdk/issues/1230)) ([764d665](https://github.com/open-feature/java-sdk/commit/764d6650e659aa93c1da66db348a2eb3641ae92f)) +* **deps:** update dependency org.simplify4u:slf4j2-mock to v2.4.0 ([#1208](https://github.com/open-feature/java-sdk/issues/1208)) ([a3ced47](https://github.com/open-feature/java-sdk/commit/a3ced47e5dc23badae4f008e5cf4e97c588fdfd4)) +* **deps:** update github/codeql-action digest to 024283f ([#1211](https://github.com/open-feature/java-sdk/issues/1211)) ([1df5441](https://github.com/open-feature/java-sdk/commit/1df54411b758c67afaf47f103e357cb551e0efca)) +* **deps:** update github/codeql-action digest to 3096afe ([#1235](https://github.com/open-feature/java-sdk/issues/1235)) ([409fd04](https://github.com/open-feature/java-sdk/commit/409fd042f3921948ef0dabd58d0ef7a4c380b5fb)) +* **deps:** update github/codeql-action digest to 3aa7135 ([#1186](https://github.com/open-feature/java-sdk/issues/1186)) ([4e3a329](https://github.com/open-feature/java-sdk/commit/4e3a329c406cc72a268f05766290633c67a9aae0)) +* **deps:** update github/codeql-action digest to 3d3d628 ([#1229](https://github.com/open-feature/java-sdk/issues/1229)) ([a0723ec](https://github.com/open-feature/java-sdk/commit/a0723ec2f886aa834662f2e54bcce5f052262dac)) +* **deps:** update github/codeql-action digest to 3ef4c08 ([#1205](https://github.com/open-feature/java-sdk/issues/1205)) ([eb4f625](https://github.com/open-feature/java-sdk/commit/eb4f6255615a77c65a79002f1233d1efe5eccd37)) +* **deps:** update github/codeql-action digest to 48c3e26 ([#1193](https://github.com/open-feature/java-sdk/issues/1193)) ([8621944](https://github.com/open-feature/java-sdk/commit/86219446337e9c73a41b8517b1e26fa044d3bbaa)) +* **deps:** update github/codeql-action digest to 4dc1519 ([#1209](https://github.com/open-feature/java-sdk/issues/1209)) ([1c21d24](https://github.com/open-feature/java-sdk/commit/1c21d2444b31f61d6d83dfd8f6982f7ad71f708b)) +* **deps:** update github/codeql-action digest to 5ac2ddd ([#1204](https://github.com/open-feature/java-sdk/issues/1204)) ([3a9fd60](https://github.com/open-feature/java-sdk/commit/3a9fd60fd4a9595a729995a59a0c4ef9625444bc)) +* **deps:** update github/codeql-action digest to 5cb4249 ([#1210](https://github.com/open-feature/java-sdk/issues/1210)) ([a94bd37](https://github.com/open-feature/java-sdk/commit/a94bd37cff0c6d7b9f535335709d69b79db2c91e)) +* **deps:** update github/codeql-action digest to 6a38de6 ([#1190](https://github.com/open-feature/java-sdk/issues/1190)) ([f3163df](https://github.com/open-feature/java-sdk/commit/f3163dfbd4b3997a0335699a2472373a846cf710)) +* **deps:** update github/codeql-action digest to 6e3a010 ([#1214](https://github.com/open-feature/java-sdk/issues/1214)) ([9f37927](https://github.com/open-feature/java-sdk/commit/9f37927eaa60e53d1c7db192ca8e6e117f7f0017)) +* **deps:** update github/codeql-action digest to 6f9e628 ([#1239](https://github.com/open-feature/java-sdk/issues/1239)) ([baaa78b](https://github.com/open-feature/java-sdk/commit/baaa78b7ec34a3e508fda3ed8c3ea5382f1e18ea)) +* **deps:** update github/codeql-action digest to 978ed82 ([#1234](https://github.com/open-feature/java-sdk/issues/1234)) ([bb3272d](https://github.com/open-feature/java-sdk/commit/bb3272d36479bde2594fe0bb64cea21d30299931)) +* **deps:** update github/codeql-action digest to 9f93f47 ([#1191](https://github.com/open-feature/java-sdk/issues/1191)) ([f99de6f](https://github.com/open-feature/java-sdk/commit/f99de6fa55bea093418ecc85ea79e9e30ce03d6b)) +* **deps:** update github/codeql-action digest to a1695c5 ([#1215](https://github.com/open-feature/java-sdk/issues/1215)) ([6d3bb69](https://github.com/open-feature/java-sdk/commit/6d3bb694204107f21552b48c5f6f056fa37e6cc0)) +* **deps:** update github/codeql-action digest to a6c8729 ([#1222](https://github.com/open-feature/java-sdk/issues/1222)) ([bbc934c](https://github.com/open-feature/java-sdk/commit/bbc934c6d91af39b9ff384ebd58756d48b00415a)) +* **deps:** update github/codeql-action digest to acb9cb1 ([#1207](https://github.com/open-feature/java-sdk/issues/1207)) ([21dbd3f](https://github.com/open-feature/java-sdk/commit/21dbd3fc4c29acbb6b74cdb6b82bc5bb4dd5523e)) +* **deps:** update github/codeql-action digest to af49565 ([#1231](https://github.com/open-feature/java-sdk/issues/1231)) ([4bbaf51](https://github.com/open-feature/java-sdk/commit/4bbaf517536386f53bd92ceaf62eb08fe4859e80)) +* **deps:** update github/codeql-action digest to b91f43b ([#1184](https://github.com/open-feature/java-sdk/issues/1184)) ([d0309ea](https://github.com/open-feature/java-sdk/commit/d0309eaa6616ef9e9caf8e605895ac82c8f4d780)) +* **deps:** update github/codeql-action digest to cba5fb5 ([#1221](https://github.com/open-feature/java-sdk/issues/1221)) ([37f0f06](https://github.com/open-feature/java-sdk/commit/37f0f06467b10541755e723ff26144b716a26464)) +* **deps:** update github/codeql-action digest to cbe1897 ([#1194](https://github.com/open-feature/java-sdk/issues/1194)) ([2dba3a7](https://github.com/open-feature/java-sdk/commit/2dba3a737dac6fefcbb1f56b292cacdca62735b5)) +* **deps:** update github/codeql-action digest to e782c3a ([#1220](https://github.com/open-feature/java-sdk/issues/1220)) ([45d0656](https://github.com/open-feature/java-sdk/commit/45d065652004ecc0703af3b9c6fbfd2b45e69056)) +* **deps:** update github/codeql-action digest to ef2fd42 ([#1232](https://github.com/open-feature/java-sdk/issues/1232)) ([b3549a1](https://github.com/open-feature/java-sdk/commit/b3549a1b4aa2bc27c38f66e3a0657b62d8ffc1b4)) +* **deps:** update github/codeql-action digest to f1c289a ([#1233](https://github.com/open-feature/java-sdk/issues/1233)) ([5b460ea](https://github.com/open-feature/java-sdk/commit/5b460ead7e5f21eb7c86e9ae78740a2e26957420)) +* **deps:** update github/codeql-action digest to f8e782a ([#1225](https://github.com/open-feature/java-sdk/issues/1225)) ([3227623](https://github.com/open-feature/java-sdk/commit/32276234257f82de98bcb01094c7219611e2c707)) + ## [1.12.2](https://github.com/open-feature/java-sdk/compare/v1.12.1...v1.12.2) (2024-10-24) diff --git a/README.md b/README.md index a277600df..e58ef9d8c 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.12.2 + 1.13.0 ``` @@ -84,7 +84,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:1.12.2' + implementation 'dev.openfeature:sdk:1.13.0' } ``` diff --git a/pom.xml b/pom.xml index 071f27c0a..5c44206f3 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ dev.openfeature sdk - 1.12.2 + 1.13.0 UTF-8 diff --git a/version.txt b/version.txt index 6b89d58f8..feaae22ba 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.12.2 +1.13.0 From b0abfd02cf9e97f7409df3296818ac990b429058 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 10 Dec 2024 01:20:08 +0000 Subject: [PATCH 064/745] chore(deps): update github/codeql-action digest to 8975792 (#1241) 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 1eaeaf487..82c179781 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@6f9e628e6f9a18c785dd746325ba455111df1b67 + uses: github/codeql-action/init@89757925c7adddb19b7a2f28e3e1b27da88b7304 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6f9e628e6f9a18c785dd746325ba455111df1b67 + uses: github/codeql-action/analyze@89757925c7adddb19b7a2f28e3e1b27da88b7304 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 41ea5f52b..71cf81d57 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@6f9e628e6f9a18c785dd746325ba455111df1b67 + uses: github/codeql-action/init@89757925c7adddb19b7a2f28e3e1b27da88b7304 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@6f9e628e6f9a18c785dd746325ba455111df1b67 + uses: github/codeql-action/autobuild@89757925c7adddb19b7a2f28e3e1b27da88b7304 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6f9e628e6f9a18c785dd746325ba455111df1b67 + uses: github/codeql-action/analyze@89757925c7adddb19b7a2f28e3e1b27da88b7304 From 884f8fbf77c41e070526da0f73e136d4c3e41a4d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 11 Dec 2024 01:28:12 +0000 Subject: [PATCH 065/745] chore(deps): update github/codeql-action digest to 4d64ab6 (#1243) 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 82c179781..92f2dd65b 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@89757925c7adddb19b7a2f28e3e1b27da88b7304 + uses: github/codeql-action/init@4d64ab66ada6f86ef77ffc21047dd6ffabd004d4 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@89757925c7adddb19b7a2f28e3e1b27da88b7304 + uses: github/codeql-action/analyze@4d64ab66ada6f86ef77ffc21047dd6ffabd004d4 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 71cf81d57..ac3559de2 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@89757925c7adddb19b7a2f28e3e1b27da88b7304 + uses: github/codeql-action/init@4d64ab66ada6f86ef77ffc21047dd6ffabd004d4 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@89757925c7adddb19b7a2f28e3e1b27da88b7304 + uses: github/codeql-action/autobuild@4d64ab66ada6f86ef77ffc21047dd6ffabd004d4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@89757925c7adddb19b7a2f28e3e1b27da88b7304 + uses: github/codeql-action/analyze@4d64ab66ada6f86ef77ffc21047dd6ffabd004d4 From fd1c1702c6d4067c432c1522143266ddf470d18d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 11 Dec 2024 22:04:18 +0000 Subject: [PATCH 066/745] chore(deps): update github/codeql-action digest to 78d0136 (#1245) 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 92f2dd65b..53fc7bd3b 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@4d64ab66ada6f86ef77ffc21047dd6ffabd004d4 + uses: github/codeql-action/init@78d0136ff775bdfbff08f0d165181940f8bcf007 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4d64ab66ada6f86ef77ffc21047dd6ffabd004d4 + uses: github/codeql-action/analyze@78d0136ff775bdfbff08f0d165181940f8bcf007 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index ac3559de2..8f1a82f66 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@4d64ab66ada6f86ef77ffc21047dd6ffabd004d4 + uses: github/codeql-action/init@78d0136ff775bdfbff08f0d165181940f8bcf007 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@4d64ab66ada6f86ef77ffc21047dd6ffabd004d4 + uses: github/codeql-action/autobuild@78d0136ff775bdfbff08f0d165181940f8bcf007 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4d64ab66ada6f86ef77ffc21047dd6ffabd004d4 + uses: github/codeql-action/analyze@78d0136ff775bdfbff08f0d165181940f8bcf007 From 9acc8612a5fa7ea086da476195154a007cb55b7e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 12 Dec 2024 00:54:52 +0000 Subject: [PATCH 067/745] chore(deps): update actions/setup-java digest to 7136edc (#1244) 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 ad5c56386..4f9d6f2c1 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -22,7 +22,7 @@ jobs: steps: - uses: actions/checkout@cbb722410c2e876e24abbe8de2cc27693e501dcb - name: Set up JDK 8 - uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b + uses: actions/setup-java@7136edc5e8145b3c0b6bae8f4e62706c74e76538 with: java-version: '8' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 53fc7bd3b..5fb908777 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -13,7 +13,7 @@ jobs: uses: actions/checkout@cbb722410c2e876e24abbe8de2cc27693e501dcb - name: Set up JDK 8 - uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b + uses: actions/setup-java@7136edc5e8145b3c0b6bae8f4e62706c74e76538 with: java-version: '8' distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 251ae637e..60699590e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: uses: actions/checkout@cbb722410c2e876e24abbe8de2cc27693e501dcb - name: Set up JDK 8 if: ${{ steps.release.outputs.release_created }} - uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b + uses: actions/setup-java@7136edc5e8145b3c0b6bae8f4e62706c74e76538 with: java-version: '8' distribution: 'temurin' From 86e18c5d28a9f5fdd7234274720ba7ddcb529268 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 13 Dec 2024 01:31:22 +0000 Subject: [PATCH 068/745] chore(deps): update actions/setup-java digest to 7a6d8a8 (#1248) 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 4f9d6f2c1..3aeb23717 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -22,7 +22,7 @@ jobs: steps: - uses: actions/checkout@cbb722410c2e876e24abbe8de2cc27693e501dcb - name: Set up JDK 8 - uses: actions/setup-java@7136edc5e8145b3c0b6bae8f4e62706c74e76538 + uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b with: java-version: '8' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 5fb908777..cce826840 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -13,7 +13,7 @@ jobs: uses: actions/checkout@cbb722410c2e876e24abbe8de2cc27693e501dcb - name: Set up JDK 8 - uses: actions/setup-java@7136edc5e8145b3c0b6bae8f4e62706c74e76538 + uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b with: java-version: '8' distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 60699590e..2b1eb9e7f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: uses: actions/checkout@cbb722410c2e876e24abbe8de2cc27693e501dcb - name: Set up JDK 8 if: ${{ steps.release.outputs.release_created }} - uses: actions/setup-java@7136edc5e8145b3c0b6bae8f4e62706c74e76538 + uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b with: java-version: '8' distribution: 'temurin' From 4440cda6a5b42a903ba11835a975bf6247de845f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 15 Dec 2024 12:48:35 +0000 Subject: [PATCH 069/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.15.11 (#1249) 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 5c44206f3..243062e88 100644 --- a/pom.xml +++ b/pom.xml @@ -164,7 +164,7 @@ net.bytebuddy byte-buddy - 1.15.10 + 1.15.11 test From 6d169f55e235a071033a9bf1138484f09a5e472d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 15 Dec 2024 15:06:36 +0000 Subject: [PATCH 070/745] chore(deps): update github/codeql-action digest to dd75594 (#1247) 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 cce826840..43c8bac52 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@78d0136ff775bdfbff08f0d165181940f8bcf007 + uses: github/codeql-action/init@dd7559424621a6dd0b32ababe9e4b271a87f78d2 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@78d0136ff775bdfbff08f0d165181940f8bcf007 + uses: github/codeql-action/analyze@dd7559424621a6dd0b32ababe9e4b271a87f78d2 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 8f1a82f66..e6eb92def 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@78d0136ff775bdfbff08f0d165181940f8bcf007 + uses: github/codeql-action/init@dd7559424621a6dd0b32ababe9e4b271a87f78d2 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@78d0136ff775bdfbff08f0d165181940f8bcf007 + uses: github/codeql-action/autobuild@dd7559424621a6dd0b32ababe9e4b271a87f78d2 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@78d0136ff775bdfbff08f0d165181940f8bcf007 + uses: github/codeql-action/analyze@dd7559424621a6dd0b32ababe9e4b271a87f78d2 From 6772d3f3943fb3b7f7522c80b732aa058fd03bb9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 15 Dec 2024 18:15:18 +0000 Subject: [PATCH 071/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.15.11 (#1250) 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 243062e88..78432e712 100644 --- a/pom.xml +++ b/pom.xml @@ -171,7 +171,7 @@ net.bytebuddy byte-buddy-agent - 1.15.10 + 1.15.11 test From 834f72071806680353f42c750b04e36956736a9e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 18:39:04 +0000 Subject: [PATCH 072/745] fix(deps): update junit5 monorepo (#1251) 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 78432e712..cd500fcee 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ UTF-8 1.8 ${maven.compiler.source} - 5.11.3 + 5.11.4 **/e2e/*.java ${project.groupId}.${project.artifactId} @@ -109,7 +109,7 @@ org.junit.platform junit-platform-suite - 1.11.3 + 1.11.4 test @@ -187,7 +187,7 @@ org.junit junit-bom - 5.11.3 + 5.11.4 pom import From 482a5aef1005b2ebe2fdb9ee43243b6c2aeeadc8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 22:56:34 +0000 Subject: [PATCH 073/745] chore(deps): update github/codeql-action digest to 9d59969 (#1252) 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 43c8bac52..bfbfd1983 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@dd7559424621a6dd0b32ababe9e4b271a87f78d2 + uses: github/codeql-action/init@9d599696ef6f3546b15e3d9dfe46db6dfa487b9a with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@dd7559424621a6dd0b32ababe9e4b271a87f78d2 + uses: github/codeql-action/analyze@9d599696ef6f3546b15e3d9dfe46db6dfa487b9a diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index e6eb92def..52e884864 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@dd7559424621a6dd0b32ababe9e4b271a87f78d2 + uses: github/codeql-action/init@9d599696ef6f3546b15e3d9dfe46db6dfa487b9a with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@dd7559424621a6dd0b32ababe9e4b271a87f78d2 + uses: github/codeql-action/autobuild@9d599696ef6f3546b15e3d9dfe46db6dfa487b9a - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@dd7559424621a6dd0b32ababe9e4b271a87f78d2 + uses: github/codeql-action/analyze@9d599696ef6f3546b15e3d9dfe46db6dfa487b9a From f39c4b5af5e341bfec230d4cecd2037fc5430400 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2024 06:20:23 +0000 Subject: [PATCH 074/745] chore(deps): update dependency com.google.guava:guava to v33.4.0-jre (#1253) 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 cd500fcee..a8a0ff423 100644 --- a/pom.xml +++ b/pom.xml @@ -135,7 +135,7 @@ com.google.guava guava - 33.3.1-jre + 33.4.0-jre test From 6a7987455ef7e46d40b835c7d8dbda29322e3b2d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Dec 2024 03:34:59 +0000 Subject: [PATCH 075/745] chore(deps): update github/codeql-action digest to 562042d (#1254) 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 bfbfd1983..62339017d 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@9d599696ef6f3546b15e3d9dfe46db6dfa487b9a + uses: github/codeql-action/init@562042d742d834fa44c4fd29c197a62d76568c60 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9d599696ef6f3546b15e3d9dfe46db6dfa487b9a + uses: github/codeql-action/analyze@562042d742d834fa44c4fd29c197a62d76568c60 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 52e884864..81b662074 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@9d599696ef6f3546b15e3d9dfe46db6dfa487b9a + uses: github/codeql-action/init@562042d742d834fa44c4fd29c197a62d76568c60 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@9d599696ef6f3546b15e3d9dfe46db6dfa487b9a + uses: github/codeql-action/autobuild@562042d742d834fa44c4fd29c197a62d76568c60 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9d599696ef6f3546b15e3d9dfe46db6dfa487b9a + uses: github/codeql-action/analyze@562042d742d834fa44c4fd29c197a62d76568c60 From d274cdac3780286a0b45865864b12c3e4cff9f4b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 02:15:10 +0000 Subject: [PATCH 076/745] chore(deps): update codecov/codecov-action action to v5.1.2 (#1255) 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 3aeb23717..92993ff5e 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -49,7 +49,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.1.1 + uses: codecov/codecov-action@v5.1.2 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 62339017d..cc345fc29 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -36,7 +36,7 @@ jobs: run: mvn --batch-mode --update-snapshots --activate-profiles e2e verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.1.1 + uses: codecov/codecov-action@v5.1.2 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From 992c00396cb2fca6a6a7dc63d727b063a79386b6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 04:03:19 +0000 Subject: [PATCH 077/745] chore(deps): update github/codeql-action digest to 64cc90b (#1256) 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 cc345fc29..9659aaf63 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@562042d742d834fa44c4fd29c197a62d76568c60 + uses: github/codeql-action/init@64cc90bcd4b0a6919309f7882f920e60de2aef1c with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@562042d742d834fa44c4fd29c197a62d76568c60 + uses: github/codeql-action/analyze@64cc90bcd4b0a6919309f7882f920e60de2aef1c diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 81b662074..0351ac450 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@562042d742d834fa44c4fd29c197a62d76568c60 + uses: github/codeql-action/init@64cc90bcd4b0a6919309f7882f920e60de2aef1c with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@562042d742d834fa44c4fd29c197a62d76568c60 + uses: github/codeql-action/autobuild@64cc90bcd4b0a6919309f7882f920e60de2aef1c - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@562042d742d834fa44c4fd29c197a62d76568c60 + uses: github/codeql-action/analyze@64cc90bcd4b0a6919309f7882f920e60de2aef1c From 6d60c962fbac48a13d86271b361fb0cfd91a5342 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 22:28:15 +0000 Subject: [PATCH 078/745] chore(deps): update github/codeql-action digest to d01b25e (#1257) 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 9659aaf63..6700b6fec 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@64cc90bcd4b0a6919309f7882f920e60de2aef1c + uses: github/codeql-action/init@d01b25e645295d11d0fbb084a8c5e7546b1e508b with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@64cc90bcd4b0a6919309f7882f920e60de2aef1c + uses: github/codeql-action/analyze@d01b25e645295d11d0fbb084a8c5e7546b1e508b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 0351ac450..da1577a8a 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@64cc90bcd4b0a6919309f7882f920e60de2aef1c + uses: github/codeql-action/init@d01b25e645295d11d0fbb084a8c5e7546b1e508b with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@64cc90bcd4b0a6919309f7882f920e60de2aef1c + uses: github/codeql-action/autobuild@d01b25e645295d11d0fbb084a8c5e7546b1e508b - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@64cc90bcd4b0a6919309f7882f920e60de2aef1c + uses: github/codeql-action/analyze@d01b25e645295d11d0fbb084a8c5e7546b1e508b From c62ade3878dabf9194536d551f3316ba5c0ce5e1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 20 Dec 2024 01:39:52 +0000 Subject: [PATCH 079/745] chore(deps): update dependency org.assertj:assertj-core to v3.27.0 (#1258) 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 a8a0ff423..6f6e14f6a 100644 --- a/pom.xml +++ b/pom.xml @@ -74,7 +74,7 @@ org.assertj assertj-core - 3.26.3 + 3.27.0 test From fc6f35e581cacb0ad149c58a5943ec1429ce25ca Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 21 Dec 2024 00:46:09 +0000 Subject: [PATCH 080/745] chore(deps): update github/codeql-action digest to 7876007 (#1260) 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 6700b6fec..30e172bbb 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@d01b25e645295d11d0fbb084a8c5e7546b1e508b + uses: github/codeql-action/init@78760076e3f08852c2c3aeb5334f70d074e28c59 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@d01b25e645295d11d0fbb084a8c5e7546b1e508b + uses: github/codeql-action/analyze@78760076e3f08852c2c3aeb5334f70d074e28c59 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index da1577a8a..7891a8bb7 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@d01b25e645295d11d0fbb084a8c5e7546b1e508b + uses: github/codeql-action/init@78760076e3f08852c2c3aeb5334f70d074e28c59 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@d01b25e645295d11d0fbb084a8c5e7546b1e508b + uses: github/codeql-action/autobuild@78760076e3f08852c2c3aeb5334f70d074e28c59 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@d01b25e645295d11d0fbb084a8c5e7546b1e508b + uses: github/codeql-action/analyze@78760076e3f08852c2c3aeb5334f70d074e28c59 From f1817d8fef585f957de1cfb9222b03cb591ed2e9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 23:06:59 +0000 Subject: [PATCH 081/745] chore(deps): update github/codeql-action digest to 5b6e617 (#1263) 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 30e172bbb..4fa803aa3 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@78760076e3f08852c2c3aeb5334f70d074e28c59 + uses: github/codeql-action/init@5b6e617dc0241b2d60c2bccea90c56b67eceb797 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@78760076e3f08852c2c3aeb5334f70d074e28c59 + uses: github/codeql-action/analyze@5b6e617dc0241b2d60c2bccea90c56b67eceb797 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 7891a8bb7..f03229c2d 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@78760076e3f08852c2c3aeb5334f70d074e28c59 + uses: github/codeql-action/init@5b6e617dc0241b2d60c2bccea90c56b67eceb797 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@78760076e3f08852c2c3aeb5334f70d074e28c59 + uses: github/codeql-action/autobuild@5b6e617dc0241b2d60c2bccea90c56b67eceb797 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@78760076e3f08852c2c3aeb5334f70d074e28c59 + uses: github/codeql-action/analyze@5b6e617dc0241b2d60c2bccea90c56b67eceb797 From 64ec68bcf5c8151802ce299f252bbb97dd9e0bd4 Mon Sep 17 00:00:00 2001 From: Simon Schrottner Date: Fri, 3 Jan 2025 19:06:22 +0100 Subject: [PATCH 082/745] build: change checkstyle to google code format, plus adding spotless (#1264) Signed-off-by: Simon Schrottner --- .editorconfig | 72 + CONTRIBUTING.md | 32 + checkstyle.xml | 259 +++- pom.xml | 1190 +++++++++-------- .../openfeature/sdk/AbstractStructure.java | 13 +- .../dev/openfeature/sdk/BaseEvaluation.java | 6 + .../java/dev/openfeature/sdk/BooleanHook.java | 2 +- .../java/dev/openfeature/sdk/DoubleHook.java | 4 +- .../java/dev/openfeature/sdk/ErrorCode.java | 8 +- .../openfeature/sdk/EvaluationContext.java | 16 +- .../java/dev/openfeature/sdk/EventBus.java | 26 +- .../dev/openfeature/sdk/EventDetails.java | 4 +- .../dev/openfeature/sdk/EventProvider.java | 1 - .../dev/openfeature/sdk/EventSupport.java | 63 +- .../dev/openfeature/sdk/FeatureProvider.java | 4 +- .../sdk/FeatureProviderStateManager.java | 4 +- .../java/dev/openfeature/sdk/Features.java | 27 +- .../sdk/FlagEvaluationDetails.java | 6 +- .../sdk/FlagEvaluationOptions.java | 2 +- .../dev/openfeature/sdk/FlagValueType.java | 6 +- src/main/java/dev/openfeature/sdk/Hook.java | 11 +- .../java/dev/openfeature/sdk/HookContext.java | 30 +- .../java/dev/openfeature/sdk/HookSupport.java | 48 +- .../dev/openfeature/sdk/ImmutableContext.java | 9 +- .../openfeature/sdk/ImmutableMetadata.java | 7 +- .../openfeature/sdk/ImmutableStructure.java | 11 +- .../sdk/ImmutableTrackingEventDetails.java | 12 +- .../java/dev/openfeature/sdk/IntegerHook.java | 2 +- .../dev/openfeature/sdk/MutableContext.java | 9 +- .../dev/openfeature/sdk/MutableStructure.java | 5 +- .../sdk/MutableTrackingEventDetails.java | 16 +- .../dev/openfeature/sdk/NoOpProvider.java | 5 +- .../sdk/NoOpTransactionContextPropagator.java | 5 +- .../dev/openfeature/sdk/OpenFeatureAPI.java | 47 +- .../openfeature/sdk/OpenFeatureClient.java | 129 +- .../openfeature/sdk/ProviderEvaluation.java | 1 + .../dev/openfeature/sdk/ProviderEvent.java | 5 +- .../openfeature/sdk/ProviderEventDetails.java | 4 +- .../openfeature/sdk/ProviderRepository.java | 82 +- .../dev/openfeature/sdk/ProviderState.java | 8 +- src/main/java/dev/openfeature/sdk/Reason.java | 9 +- .../java/dev/openfeature/sdk/StringHook.java | 2 +- .../java/dev/openfeature/sdk/Structure.java | 32 +- .../openfeature/sdk/TrackingEventDetails.java | 3 +- src/main/java/dev/openfeature/sdk/Value.java | 122 +- .../sdk/exceptions/ExceptionUtils.java | 3 +- .../sdk/exceptions/FatalError.java | 3 +- .../sdk/exceptions/FlagNotFoundError.java | 2 +- .../sdk/exceptions/GeneralError.java | 1 + .../sdk/exceptions/InvalidContextError.java | 4 +- .../sdk/exceptions/ParseError.java | 4 +- .../sdk/exceptions/ProviderNotReadyError.java | 4 +- .../exceptions/TargetingKeyMissingError.java | 4 +- .../sdk/exceptions/TypeMismatchError.java | 4 +- .../exceptions/ValueNotConvertableError.java | 1 + .../sdk/hooks/logging/LoggingHook.java | 16 +- .../sdk/internal/AutoCloseableLock.java | 2 +- .../AutoCloseableReentrantReadWriteLock.java | 4 +- .../ExcludeFromGeneratedCoverageReport.java | 7 +- .../openfeature/sdk/internal/ObjectUtils.java | 21 +- .../openfeature/sdk/internal/TriConsumer.java | 4 +- .../providers/memory/ContextEvaluator.java | 1 + .../sdk/providers/memory/Flag.java | 4 +- .../providers/memory/InMemoryProvider.java | 67 +- .../openfeature/sdk/AlwaysBrokenProvider.java | 3 +- .../sdk/AlwaysBrokenWithDetailsProvider.java | 3 +- .../sdk/ClientProviderMappingTest.java | 4 +- .../sdk/DeveloperExperienceTest.java | 39 +- .../openfeature/sdk/DoSomethingProvider.java | 6 +- .../dev/openfeature/sdk/EvalContextTest.java | 123 +- .../openfeature/sdk/EventProviderTest.java | 33 +- .../java/dev/openfeature/sdk/EventsTest.java | 266 ++-- .../sdk/FeatureProviderStateManagerTest.java | 67 +- .../sdk/FlagEvaluationDetailsTest.java | 18 +- .../sdk/FlagEvaluationSpecTest.java | 588 +++++--- .../dev/openfeature/sdk/FlagMetadataTest.java | 9 +- .../dev/openfeature/sdk/HookContextTest.java | 36 +- .../dev/openfeature/sdk/HookSpecTest.java | 358 +++-- .../dev/openfeature/sdk/HookSupportTest.java | 39 +- .../openfeature/sdk/ImmutableContextTest.java | 54 +- .../sdk/ImmutableStructureTest.java | 63 +- .../sdk/InitializeBehaviorSpecTest.java | 59 +- .../java/dev/openfeature/sdk/LockingTest.java | 28 +- .../dev/openfeature/sdk/MetadataTest.java | 14 +- .../openfeature/sdk/MutableContextTest.java | 52 +- .../sdk/MutableTrackingEventDetailsTest.java | 16 +- .../dev/openfeature/sdk/NoOpProviderTest.java | 15 +- .../NoOpTransactionContextPropagatorTest.java | 7 +- .../sdk/NotImplementedException.java | 2 +- .../openfeature/sdk/OpenFeatureAPITest.java | 32 +- .../sdk/OpenFeatureClientTest.java | 26 +- .../sdk/ProviderEvaluationTest.java | 9 +- .../sdk/ProviderRepositoryTest.java | 149 ++- .../dev/openfeature/sdk/ProviderSpecTest.java | 112 +- .../sdk/ShutdownBehaviorSpecTest.java | 61 +- .../dev/openfeature/sdk/Specification.java | 1 + .../dev/openfeature/sdk/StructureTest.java | 28 +- ...LocalTransactionContextPropagatorTest.java | 9 +- .../dev/openfeature/sdk/TrackingSpecTest.java | 111 +- .../java/dev/openfeature/sdk/ValueTest.java | 49 +- .../sdk/benchmark/AllocationBenchmark.java | 24 +- .../sdk/benchmark/AllocationProfiler.java | 27 +- .../openfeature/sdk/e2e/EvaluationTest.java | 13 +- .../sdk/e2e/evaluation/StepDefinitions.java | 115 +- .../sdk/exceptions/ExceptionUtilsTest.java | 12 +- .../sdk/fixtures/HookFixtures.java | 5 +- .../sdk/fixtures/ProviderFixture.java | 17 +- .../sdk/hooks/logging/LoggingHookTest.java | 26 +- .../sdk/internal/ObjectUtilsTest.java | 14 +- .../sdk/internal/TriConsumerTest.java | 3 +- .../memory/InMemoryProviderTest.java | 56 +- .../testutils/FeatureProviderTestUtils.java | 18 +- .../sdk/testutils/TestEventsProvider.java | 16 +- .../sdk/testutils/TestFlagsUtils.java | 114 +- .../testutils/stubbing/ConditionStubber.java | 11 +- 115 files changed, 3267 insertions(+), 2208 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..5bffb8ae0 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,72 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +tab_width = 4 +trim_trailing_whitespace = true + +ij_continuation_indent_size = 8 + +[*.md] +max_line_length = off +trim_trailing_whitespace = false + +# Following the rules of the Google Java Style Guide. +# See https://google.github.io/styleguide/javaguide.html +[*.java] +max_line_length = 120 + +ij_java_do_not_wrap_after_single_annotation_in_parameter = true +ij_java_insert_inner_class_imports = false +ij_java_class_count_to_use_import_on_demand = 999 +ij_java_names_count_to_use_import_on_demand = 999 +ij_java_packages_to_use_import_on_demand = unset +ij_java_imports_layout = $*,|,* +ij_java_doc_align_param_comments = true +ij_java_doc_align_exception_comments = true +ij_java_doc_add_p_tag_on_empty_lines = false +ij_java_doc_do_not_wrap_if_one_line = true +ij_java_doc_keep_empty_parameter_tag = false +ij_java_doc_keep_empty_throws_tag = false +ij_java_doc_keep_empty_return_tag = false +ij_java_doc_preserve_line_breaks = true +ij_java_doc_indent_on_continuation = true +ij_java_keep_control_statement_in_one_line = false +ij_java_keep_blank_lines_in_code = 1 +ij_java_align_multiline_parameters = false +ij_java_align_multiline_resources = false +ij_java_align_multiline_for = true +ij_java_space_before_array_initializer_left_brace = true +ij_java_call_parameters_wrap = normal +ij_java_method_parameters_wrap = normal +ij_java_extends_list_wrap = normal +ij_java_throws_keyword_wrap = normal +ij_java_method_call_chain_wrap = normal +ij_java_binary_operation_wrap = normal +ij_java_binary_operation_sign_on_next_line = true +ij_java_ternary_operation_wrap = normal +ij_java_ternary_operation_signs_on_next_line = true +ij_java_keep_simple_methods_in_one_line = true +ij_java_keep_simple_lambdas_in_one_line = true +ij_java_keep_simple_classes_in_one_line = true +ij_java_for_statement_wrap = normal +ij_java_array_initializer_wrap = normal +ij_java_wrap_comments = true +ij_java_if_brace_force = always +ij_java_do_while_brace_force = always +ij_java_while_brace_force = always +ij_java_for_brace_force = always +ij_java_space_after_closing_angle_bracket_in_type_argument = false + +[{*.json,*.json5}] +indent_size = 2 +tab_width = 2 +ij_smart_tabs = false + +[*.yaml] +indent_size = 2 +tab_width = 2 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 84c9645b9..71b881b87 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,6 +21,38 @@ If you think we might be out of date with the spec, you can check that by invoki If you're adding tests to cover something in the spec, use the `@Specification` annotation like you see throughout the test suites. +## Code Styles + +### Overview +Our project follows strict code formatting standards to maintain consistency and readability across the codebase. We use [Spotless](https://github.com/diffplug/spotless) integrated with the [Palantir Java Format](https://github.com/palantir/palantir-java-format) for code formatting. + +**Spotless** ensures that all code complies with the formatting rules automatically, reducing style-related issues during code reviews. + +### How to Format Your Code +1. **Before Committing Changes:** + Run the Spotless plugin to format your code. This will apply the Palantir Java Format style: + ```bash + mvn spotless:apply + ``` + +2. **Verify Formatting:** + To check if your code adheres to the style guidelines without making changes: + ```bash + mvn spotless:check + ``` + + - If this command fails, your code does not follow the required formatting. Use `mvn spotless:apply` to fix it. + +### CI/CD Integration +Our Continuous Integration (CI) pipeline automatically checks code formatting using the Spotless plugin. Any code that does not pass the `spotless:check` step will cause the build to fail. + +### Best Practices +- Regularly run `mvn spotless:apply` during your work to ensure your code remains aligned with the standards. +- Configure your IDE (e.g., IntelliJ IDEA or Eclipse) to follow the Palantir Java format guidelines to reduce discrepancies during development. + +### Support +If you encounter issues with code formatting, please raise a GitHub issue or contact the maintainers. + ## End-to-End Tests The continuous integration runs a set of [gherkin e2e tests](https://github.com/open-feature/spec/blob/main/specification/assets/gherkin/evaluation.feature) using `InMemoryProvider`. diff --git a/checkstyle.xml b/checkstyle.xml index 2cf598c37..c5cb2999f 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -1,7 +1,7 @@ + "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN" + "https://checkstyle.org/dtds/configuration_1_3.dtd"> - + + - + @@ -34,9 +35,16 @@ + + - + @@ -52,7 +60,7 @@ - + @@ -69,48 +77,68 @@ + value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/> + value="Consider using special escape sequence instead of octal value or Unicode escaped value."/> + - - + + value="LITERAL_DO, LITERAL_ELSE, LITERAL_FOR, LITERAL_IF, LITERAL_WHILE"/> - + + + value="ANNOTATION_DEF, CLASS_DEF, CTOR_DEF, ENUM_CONSTANT_DEF, ENUM_DEF, + INTERFACE_DEF, LITERAL_CATCH, + LITERAL_DO, LITERAL_ELSE, LITERAL_FOR, LITERAL_IF, + LITERAL_WHILE, METHOD_DEF, + OBJBLOCK, STATIC_INIT, RECORD_DEF, COMPACT_CTOR_DEF"/> + + + value=" LITERAL_DEFAULT"/> + + + + + + value="CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, STATIC_INIT, + INSTANCE_INIT, ANNOTATION_DEF, ENUM_DEF, INTERFACE_DEF, RECORD_DEF, + COMPACT_CTOR_DEF"/> + + + + + + + + @@ -118,18 +146,35 @@ + + + value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, + BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, DO_WHILE, EQUAL, GE, GT, LAND, + LCURLY, LE, LITERAL_DO, LITERAL_ELSE, + LITERAL_FOR, LITERAL_IF, + LITERAL_WHILE, LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN, + NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, RCURLY, SL, SLIST, SL_ASSIGN, SR, + SR_ASSIGN, STAR, STAR_ASSIGN, LITERAL_ASSERT, + TYPE_EXTENSION_AND"/> + value="WhitespaceAround: ''{0}'' is not followed by whitespace. Empty blocks + may only be represented as '{}' when not part of a multi-block statement (4.1.3)"/> + value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/> + + + + + + + + @@ -140,8 +185,9 @@ + value="PACKAGE_DEF, IMPORT, STATIC_IMPORT, CLASS_DEF, INTERFACE_DEF, ENUM_DEF, + STATIC_INIT, INSTANCE_INIT, METHOD_DEF, CTOR_DEF, VARIABLE_DEF, RECORD_DEF, + COMPACT_CTOR_DEF"/> @@ -155,13 +201,13 @@ - + - + @@ -174,22 +220,23 @@ + value="Package name ''{0}'' must match pattern ''{1}''."/> - + + value="Type name ''{0}'' must match pattern ''{1}''."/> + value="Member name ''{0}'' must match pattern ''{1}''."/> + value="Parameter name ''{0}'' must match pattern ''{1}''."/> @@ -199,38 +246,53 @@ + value="Catch parameter name ''{0}'' must match pattern ''{1}''."/> + value="Local variable name ''{0}'' must match pattern ''{1}''."/> + + + + + value="Class type name ''{0}'' must match pattern ''{1}''."/> + + + + + + + + + value="Method type name ''{0}'' must match pattern ''{1}''."/> + value="Interface type name ''{0}'' must match pattern ''{1}''."/> + value="GenericWhitespace ''{0}'' is followed by whitespace."/> + value="GenericWhitespace ''{0}'' is preceded with whitespace."/> + value="GenericWhitespace ''{0}'' should followed by whitespace."/> + value="GenericWhitespace ''{0}'' is not preceded with whitespace."/> @@ -240,44 +302,62 @@ + + + + + + value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, ANNOTATION_DEF, ANNOTATION_FIELD_DEF, + PARAMETER_DEF, VARIABLE_DEF, METHOD_DEF, PATTERN_VARIABLE_DEF, RECORD_DEF, + RECORD_COMPONENT_DEF"/> + + + + + + + + + value="COMMA, SEMI, POST_INC, POST_DEC, DOT, + LABELED_STAT, METHOD_REF"/> + value="ANNOTATION, ANNOTATION_FIELD_DEF, CTOR_DEF, DOT, ENUM_CONSTANT_DEF, + EXPR, LITERAL_DO, LITERAL_FOR, LITERAL_IF, LITERAL_NEW, + LITERAL_WHILE, METHOD_CALL, + METHOD_DEF, QUESTION, RESOURCE_SPECIFICATION, SUPER_CTOR_CALL"/> + value="BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR, + LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR, METHOD_REF, + TYPE_EXTENSION_AND "/> - + value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, + RECORD_DEF, COMPACT_CTOR_DEF"/> @@ -289,46 +369,83 @@ + value="^@return the *|^This method returns |^A [{]@code [a-zA-Z0-9]+[}]( is a )"/> - + + + + value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/> - + + - + + + + + - - + + value="Method name ''{0}'' must match pattern ''{1}''."/> - - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index 6f6e14f6a..e7fe58c67 100644 --- a/pom.xml +++ b/pom.xml @@ -1,590 +1,640 @@ - 4.0.0 - - dev.openfeature - sdk - 1.13.0 - - - UTF-8 - 1.8 - ${maven.compiler.source} - 5.11.4 - - **/e2e/*.java - ${project.groupId}.${project.artifactId} - - - OpenFeature Java SDK - This is the Java implementation of OpenFeature, a vendor-agnostic abstraction library for evaluating feature flags. - https://openfeature.dev - - - abrahms - Justin Abrahms - eBay - https://justin.abrah.ms/ - - - - - Apache License 2.0 - https://www.apache.org/licenses/LICENSE-2.0 - - - - - scm:git:https://github.com/open-feature/java-sdk.git - scm:git:https://github.com/open-feature/java-sdk.git - https://github.com/open-feature/java-sdk - - - - - - org.projectlombok - lombok - 1.18.36 - provided - - - - - com.github.spotbugs - spotbugs - 4.8.6 - provided - - - - org.slf4j - slf4j-api - 2.0.16 - - - - - org.mockito - mockito-core - 4.11.0 - test - - - - org.assertj - assertj-core - 3.27.0 - test - - - - org.junit.jupiter - junit-jupiter - ${junit.jupiter.version} - test - - - - org.junit.jupiter - junit-jupiter-engine - ${junit.jupiter.version} - test - - - - org.junit.jupiter - junit-jupiter-api - ${junit.jupiter.version} - test - - - - org.junit.jupiter - junit-jupiter-params - ${junit.jupiter.version} - test - - - - org.junit.platform - junit-platform-suite - 1.11.4 - test - - - - io.cucumber - cucumber-java - test - - - - io.cucumber - cucumber-junit-platform-engine - test - - - - org.simplify4u - slf4j2-mock - 2.4.0 - test - - - - com.google.guava - guava - 33.4.0-jre - test - - - - org.awaitility - awaitility - 4.2.2 - test - - - - org.openjdk.jmh - jmh-core - 1.37 - test - - - - - + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + dev.openfeature + sdk + 1.13.0 + + + UTF-8 + 1.8 + ${maven.compiler.source} + 5.11.4 + + **/e2e/*.java + ${project.groupId}.${project.artifactId} + + + OpenFeature Java SDK + This is the Java implementation of OpenFeature, a vendor-agnostic abstraction library for evaluating + feature flags. + + https://openfeature.dev + + + abrahms + Justin Abrahms + eBay + https://justin.abrah.ms/ + + + + + Apache License 2.0 + https://www.apache.org/licenses/LICENSE-2.0 + + + + + scm:git:https://github.com/open-feature/java-sdk.git + scm:git:https://github.com/open-feature/java-sdk.git + https://github.com/open-feature/java-sdk + + - - - - - net.bytebuddy - byte-buddy - 1.15.11 - test - - - - net.bytebuddy - byte-buddy-agent - 1.15.11 - test - - - - - io.cucumber - cucumber-bom - 7.20.1 - pom - import - - - - org.junit - junit-bom - 5.11.4 - pom - import - + + org.projectlombok + lombok + 1.18.36 + provided + - - - - - - - org.cyclonedx - cyclonedx-maven-plugin - 2.9.1 - - library - 1.3 - true - true - true - true - true - false - false - all - - - - package - - makeAggregateBom - - - - - - - maven-dependency-plugin - 3.8.1 - - - verify - - analyze - - - - - true - - com.github.spotbugs:* - org.junit* - org.simplify4u:slf4j2-mock* - - - com.google.guava* - io.cucumber* - org.junit* - com.google.code.findbugs* - com.github.spotbugs* - org.simplify4u:slf4j-mock-common:* - - - - - - maven-compiler-plugin - 3.13.0 - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.5.2 - - - ${surefireArgLine} - - - - ${testExclusions} - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - 3.5.2 - - - ${surefireArgLine} - - - - - - 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 - maven-jar-plugin - 3.4.2 - - - - ${module-name} - - - - - - - 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 - + provided + + + + org.slf4j + slf4j-api + 2.0.16 + + + + + org.mockito + mockito-core + 4.11.0 + test + + + + org.assertj + assertj-core + 3.27.0 + test + + + + org.junit.jupiter + junit-jupiter + ${junit.jupiter.version} + test + + + + org.junit.jupiter + junit-jupiter-engine + ${junit.jupiter.version} + test + + + + org.junit.jupiter + junit-jupiter-api + ${junit.jupiter.version} + test + + + + org.junit.jupiter + junit-jupiter-params + ${junit.jupiter.version} + test + + + + org.junit.platform + junit-platform-suite + 1.11.4 + test + + + + io.cucumber + cucumber-java + test + + + + io.cucumber + cucumber-junit-platform-engine + test + + + + org.simplify4u + slf4j2-mock + 2.4.0 + test + + + + com.google.guava + guava + 33.4.0-jre + test + + + + org.awaitility + awaitility + 4.2.2 + test + + + + org.openjdk.jmh + jmh-core + 1.37 + test + + + + + - - com.puppycrawl.tools - checkstyle - 8.45.1 - + + + + + + net.bytebuddy + byte-buddy + 1.15.11 + test + + + + net.bytebuddy + byte-buddy-agent + 1.15.11 + test + + + + + io.cucumber + cucumber-bom + 7.20.1 + pom + import + + + + org.junit + junit-bom + 5.11.4 + pom + import + + - - - validate - validate - - check - - - - - - - - - - - deploy - - true - - + + - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.7.0 - true - - ossrh - https://s01.oss.sonatype.org/ - true - - - - - - - org.apache.maven.plugins - maven-source-plugin - 3.3.1 - - - attach-sources - - jar-no-fork - - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.11.2 - - true - all,-missing - - - - attach-javadocs - - jar - - - - - - - - - org.apache.maven.plugins - maven-gpg-plugin - 3.2.7 - - - sign-artifacts - install - - sign - - - - - + + org.cyclonedx + cyclonedx-maven-plugin + 2.9.1 + + library + 1.3 + true + true + true + true + true + false + false + all + + + + package + + makeAggregateBom + + + + - - - + + maven-dependency-plugin + 3.8.1 + + + verify + + analyze + + + + + true + + com.github.spotbugs:* + org.junit* + org.simplify4u:slf4j2-mock* + + + com.google.guava* + io.cucumber* + org.junit* + com.google.code.findbugs* + com.github.spotbugs* + org.simplify4u:slf4j-mock-common:* + + + - - benchmark - - - - pw.krejci - jmh-maven-plugin - 0.2.2 - - - - - - - e2e - - - - - - - - - org.codehaus.mojo - exec-maven-plugin - 3.5.0 - - - update-test-harness-submodule - validate - - exec - + + maven-compiler-plugin + 3.13.0 + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.5.2 + + + ${surefireArgLine} + + + + ${testExclusions} + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 3.5.2 + + + ${surefireArgLine} + + + + + + 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 + maven-jar-plugin + 3.4.2 + + + + ${module-name} + + + + + + + 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 - - git - - submodule - update - --init - spec - + checkstyle.xml + UTF-8 + true + true + false - - - copy-evaluation-gherkin-tests - validate - - exec - + + + com.puppycrawl.tools + checkstyle + 9.3 + + + + + validate + validate + + check + + + + + + com.diffplug.spotless + spotless-maven-plugin + 2.30.0 - - cp - - spec/specification/assets/gherkin/evaluation.feature - src/test/resources/features/ - + + + + + + + + .gitattributes + .gitignore + + + + + + true + 4 + + + + + + + + + true + 4 + + + + + + + - - - + + + + check + + + + - - - - - - - ossrh - https://s01.oss.sonatype.org/content/repositories/snapshots - - + + + + + + deploy + + true + + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.7.0 + true + + ossrh + https://s01.oss.sonatype.org/ + true + + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.3.1 + + + attach-sources + + jar-no-fork + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.11.2 + + true + all,-missing + + + + + attach-javadocs + + jar + + + + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 3.2.7 + + + sign-artifacts + install + + sign + + + + + + + + + + + benchmark + + + + pw.krejci + jmh-maven-plugin + 0.2.2 + + + + + + + e2e + + + + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.5.0 + + + update-test-harness-submodule + validate + + exec + + + + git + + submodule + update + --init + spec + + + + + copy-evaluation-gherkin-tests + validate + + exec + + + + cp + + spec/specification/assets/gherkin/evaluation.feature + src/test/resources/features/ + + + + + + + + + + + + + ossrh + https://s01.oss.sonatype.org/content/repositories/snapshots + + diff --git a/src/main/java/dev/openfeature/sdk/AbstractStructure.java b/src/main/java/dev/openfeature/sdk/AbstractStructure.java index 86fdde41a..6c652114c 100644 --- a/src/main/java/dev/openfeature/sdk/AbstractStructure.java +++ b/src/main/java/dev/openfeature/sdk/AbstractStructure.java @@ -1,10 +1,10 @@ package dev.openfeature.sdk; +import java.util.Collections; import java.util.HashMap; import java.util.Map; -import java.util.Collections; -@SuppressWarnings({ "PMD.BeanMembersShouldSerialize", "checkstyle:MissingJavadocType" }) +@SuppressWarnings({"PMD.BeanMembersShouldSerialize", "checkstyle:MissingJavadocType"}) abstract class AbstractStructure implements Structure { protected final Map attributes; @@ -24,6 +24,7 @@ public boolean isEmpty() { /** * Returns an unmodifiable representation of the internal attribute map. + * * @return immutable map */ public Map asUnmodifiableMap() { @@ -37,14 +38,12 @@ public Map asUnmodifiableMap() { */ @Override public Map asObjectMap() { - return attributes - .entrySet() - .stream() + return attributes.entrySet().stream() // custom collector, workaround for Collectors.toMap in JDK8 // https://bugs.openjdk.org/browse/JDK-8148463 - .collect(HashMap::new, + .collect( + HashMap::new, (accumulated, entry) -> accumulated.put(entry.getKey(), convertValue(entry.getValue())), HashMap::putAll); } - } diff --git a/src/main/java/dev/openfeature/sdk/BaseEvaluation.java b/src/main/java/dev/openfeature/sdk/BaseEvaluation.java index ed6e93510..d4209d9b2 100644 --- a/src/main/java/dev/openfeature/sdk/BaseEvaluation.java +++ b/src/main/java/dev/openfeature/sdk/BaseEvaluation.java @@ -2,29 +2,34 @@ /** * This is a common interface between the evaluation results that providers return and what is given to the end users. + * * @param The type of flag being evaluated. */ public interface BaseEvaluation { /** * Returns the resolved value of the evaluation. + * * @return {T} the resolve value */ T getValue(); /** * Returns an identifier for this value, if applicable. + * * @return {String} value identifier */ String getVariant(); /** * Describes how we came to the value that we're returning. + * * @return {Reason} */ String getReason(); /** * The error code, if applicable. Should only be set when the Reason is ERROR. + * * @return {ErrorCode} */ ErrorCode getErrorCode(); @@ -32,6 +37,7 @@ public interface BaseEvaluation { /** * The error message (usually from exception.getMessage()), if applicable. * Should only be set when the Reason is ERROR. + * * @return {String} */ String getErrorMessage(); diff --git a/src/main/java/dev/openfeature/sdk/BooleanHook.java b/src/main/java/dev/openfeature/sdk/BooleanHook.java index e9277766e..3c178ca5a 100644 --- a/src/main/java/dev/openfeature/sdk/BooleanHook.java +++ b/src/main/java/dev/openfeature/sdk/BooleanHook.java @@ -3,7 +3,7 @@ /** * 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 3ccf88b1b..70d17b37a 100644 --- a/src/main/java/dev/openfeature/sdk/DoubleHook.java +++ b/src/main/java/dev/openfeature/sdk/DoubleHook.java @@ -3,7 +3,7 @@ /** * 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 { @@ -12,4 +12,4 @@ public interface DoubleHook extends Hook { default boolean supportsFlagValueType(FlagValueType flagValueType) { return FlagValueType.DOUBLE == flagValueType; } -} \ No newline at end of file +} diff --git a/src/main/java/dev/openfeature/sdk/ErrorCode.java b/src/main/java/dev/openfeature/sdk/ErrorCode.java index 00451bdfb..cb5798f31 100644 --- a/src/main/java/dev/openfeature/sdk/ErrorCode.java +++ b/src/main/java/dev/openfeature/sdk/ErrorCode.java @@ -2,6 +2,12 @@ @SuppressWarnings("checkstyle:MissingJavadocType") public enum ErrorCode { - PROVIDER_NOT_READY, FLAG_NOT_FOUND, PARSE_ERROR, TYPE_MISMATCH, TARGETING_KEY_MISSING, INVALID_CONTEXT, GENERAL, + PROVIDER_NOT_READY, + FLAG_NOT_FOUND, + PARSE_ERROR, + TYPE_MISMATCH, + TARGETING_KEY_MISSING, + INVALID_CONTEXT, + GENERAL, PROVIDER_FATAL } diff --git a/src/main/java/dev/openfeature/sdk/EvaluationContext.java b/src/main/java/dev/openfeature/sdk/EvaluationContext.java index 5b2a33113..84760c0d9 100644 --- a/src/main/java/dev/openfeature/sdk/EvaluationContext.java +++ b/src/main/java/dev/openfeature/sdk/EvaluationContext.java @@ -28,12 +28,13 @@ public interface EvaluationContext extends Structure { * Recursively merges the overriding map into the base Value map. * The base map is mutated, the overriding map is not. * Null maps will cause no-op. - * + * * @param newStructure function to create the right structure(s) for Values - * @param base base map to merge - * @param overriding overriding map to merge + * @param base base map to merge + * @param overriding overriding map to merge */ - static void mergeMaps(Function, Structure> newStructure, + static void mergeMaps( + Function, Structure> newStructure, Map base, Map overriding) { @@ -46,12 +47,13 @@ static void mergeMaps(Function, Structure> newStructure, for (Entry overridingEntry : overriding.entrySet()) { String key = overridingEntry.getKey(); - if (overridingEntry.getValue().isStructure() && base.containsKey(key) && base.get(key).isStructure()) { + if (overridingEntry.getValue().isStructure() + && base.containsKey(key) + && base.get(key).isStructure()) { Structure mergedValue = base.get(key).asStructure(); Structure overridingValue = overridingEntry.getValue().asStructure(); Map newMap = mergedValue.asMap(); - mergeMaps(newStructure, newMap, - overridingValue.asUnmodifiableMap()); + mergeMaps(newStructure, newMap, overridingValue.asUnmodifiableMap()); base.put(key, new Value(newStructure.apply(newMap))); } else { base.put(key, overridingEntry.getValue()); diff --git a/src/main/java/dev/openfeature/sdk/EventBus.java b/src/main/java/dev/openfeature/sdk/EventBus.java index d635e9bac..16bd83405 100644 --- a/src/main/java/dev/openfeature/sdk/EventBus.java +++ b/src/main/java/dev/openfeature/sdk/EventBus.java @@ -6,38 +6,38 @@ * Interface for attaching event handlers. */ public interface EventBus { - + /** * Add a handler for the {@link ProviderEvent#PROVIDER_READY} event. * Shorthand for {@link #on(ProviderEvent, Consumer)} - * + * * @param handler behavior to add with this event * @return this */ T onProviderReady(Consumer handler); - + /** * Add a handler for the {@link ProviderEvent#PROVIDER_CONFIGURATION_CHANGED} event. * Shorthand for {@link #on(ProviderEvent, Consumer)} - * + * * @param handler behavior to add with this event * @return this */ T onProviderConfigurationChanged(Consumer handler); - + /** * Add a handler for the {@link ProviderEvent#PROVIDER_STALE} event. * Shorthand for {@link #on(ProviderEvent, Consumer)} - * + * * @param handler behavior to add with this event * @return this */ T onProviderError(Consumer handler); - + /** * Add a handler for the {@link ProviderEvent#PROVIDER_ERROR} event. * Shorthand for {@link #on(ProviderEvent, Consumer)} - * + * * @param handler behavior to add with this event * @return this */ @@ -45,18 +45,18 @@ public interface EventBus { /** * Add a handler for the specified {@link ProviderEvent}. - * - * @param event event type + * + * @param event event type * @param handler behavior to add with this event * @return this */ T on(ProviderEvent event, Consumer handler); - + /** * Remove the previously attached handler by reference. * If the handler doesn't exists, no-op. - * - * @param event event type + * + * @param event event type * @param handler to be removed * @return this */ diff --git a/src/main/java/dev/openfeature/sdk/EventDetails.java b/src/main/java/dev/openfeature/sdk/EventDetails.java index f2113eeae..e32e61013 100644 --- a/src/main/java/dev/openfeature/sdk/EventDetails.java +++ b/src/main/java/dev/openfeature/sdk/EventDetails.java @@ -17,9 +17,7 @@ static EventDetails fromProviderEventDetails(ProviderEventDetails providerEventD } static EventDetails fromProviderEventDetails( - ProviderEventDetails providerEventDetails, - String providerName, - String domain) { + ProviderEventDetails providerEventDetails, String providerName, String domain) { return builder() .domain(domain) .providerName(providerName) diff --git a/src/main/java/dev/openfeature/sdk/EventProvider.java b/src/main/java/dev/openfeature/sdk/EventProvider.java index 84893bece..e9cdae55b 100644 --- a/src/main/java/dev/openfeature/sdk/EventProvider.java +++ b/src/main/java/dev/openfeature/sdk/EventProvider.java @@ -2,7 +2,6 @@ import dev.openfeature.sdk.internal.TriConsumer; - /** * Abstract EventProvider. Providers must extend this class to support events. * Emit events with {@link #emit(ProviderEvent, ProviderEventDetails)}. Please diff --git a/src/main/java/dev/openfeature/sdk/EventSupport.java b/src/main/java/dev/openfeature/sdk/EventSupport.java index 085c8eb83..d3af45991 100644 --- a/src/main/java/dev/openfeature/sdk/EventSupport.java +++ b/src/main/java/dev/openfeature/sdk/EventSupport.java @@ -1,7 +1,5 @@ package dev.openfeature.sdk; -import lombok.extern.slf4j.Slf4j; - import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -13,6 +11,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; +import lombok.extern.slf4j.Slf4j; /** * Util class for storing and running handlers. @@ -35,74 +34,68 @@ class EventSupport { /** * Run all the event handlers associated with this domain. * If the domain is null, handlers attached to unnamed clients will run. - * + * * @param domain the domain to run event handlers for, or null * @param event the event type * @param eventDetails the event details */ public void runClientHandlers(String domain, ProviderEvent event, EventDetails eventDetails) { - domain = Optional.ofNullable(domain) - .orElse(defaultClientUuid); + domain = Optional.ofNullable(domain).orElse(defaultClientUuid); // run handlers if they exist Optional.ofNullable(handlerStores.get(domain)) .filter(store -> Optional.of(store).isPresent()) .map(store -> store.handlerMap.get(event)) - .ifPresent(handlers -> handlers - .forEach(handler -> runHandler(handler, eventDetails))); + .ifPresent(handlers -> handlers.forEach(handler -> runHandler(handler, eventDetails))); } /** * Run all the API (global) event handlers. - * + * * @param event the event type * @param eventDetails the event details */ public void runGlobalHandlers(ProviderEvent event, EventDetails eventDetails) { - globalHandlerStore.handlerMap.get(event) - .forEach(handler -> { - runHandler(handler, eventDetails); - }); + globalHandlerStore.handlerMap.get(event).forEach(handler -> { + runHandler(handler, eventDetails); + }); } /** * Add a handler for the specified domain, or all unnamed clients. - * - * @param domain the domain to add handlers for, or else unnamed - * @param event the event type - * @param handler the handler function to run + * + * @param domain the domain to add handlers for, or else unnamed + * @param event the event type + * @param handler the handler function to run */ public void addClientHandler(String domain, ProviderEvent event, Consumer handler) { - final String name = Optional.ofNullable(domain) - .orElse(defaultClientUuid); + final String name = Optional.ofNullable(domain).orElse(defaultClientUuid); // lazily create and cache a HandlerStore if it doesn't exist - HandlerStore store = Optional.ofNullable(this.handlerStores.get(name)) - .orElseGet(() -> { - HandlerStore newStore = new HandlerStore(); - this.handlerStores.put(name, newStore); - return newStore; - }); + HandlerStore store = Optional.ofNullable(this.handlerStores.get(name)).orElseGet(() -> { + HandlerStore newStore = new HandlerStore(); + this.handlerStores.put(name, newStore); + return newStore; + }); store.addHandler(event, handler); } /** * Remove a client event handler for the specified event type. - * - * @param domain the domain of the client handler to remove, or null to remove - * from unnamed clients - * @param event the event type - * @param handler the handler ref to be removed + * + * @param domain the domain of the client handler to remove, or null to remove + * from unnamed clients + * @param event the event type + * @param handler the handler ref to be removed */ public void removeClientHandler(String domain, ProviderEvent event, Consumer handler) { - domain = Optional.ofNullable(domain) - .orElse(defaultClientUuid); + domain = Optional.ofNullable(domain).orElse(defaultClientUuid); this.handlerStores.get(domain).removeHandler(event, handler); } /** * Add a global event handler of the specified event type. - * + * * @param event the event type * @param handler the handler to be added */ @@ -112,7 +105,7 @@ public void addGlobalHandler(ProviderEvent event, Consumer handler /** * Remove a global event handler for the specified event type. - * + * * @param event the event type * @param handler the handler ref to be removed */ @@ -122,7 +115,7 @@ public void removeGlobalHandler(ProviderEvent event, Consumer hand /** * Get all domain names for which we have event handlers registered. - * + * * @return set of domain names */ public Set getAllDomainNames() { @@ -131,7 +124,7 @@ public Set getAllDomainNames() { /** * Run the passed handler on the taskExecutor. - * + * * @param handler the handler to run * @param eventDetails the event details */ diff --git a/src/main/java/dev/openfeature/sdk/FeatureProvider.java b/src/main/java/dev/openfeature/sdk/FeatureProvider.java index 706818e85..4c630cb80 100644 --- a/src/main/java/dev/openfeature/sdk/FeatureProvider.java +++ b/src/main/java/dev/openfeature/sdk/FeatureProvider.java @@ -78,7 +78,5 @@ default ProviderState getState() { * @param context Evaluation context used in flag evaluation (Optional) * @param details Data pertinent to a particular tracking event (Optional) */ - default void track(String eventName, EvaluationContext context, TrackingEventDetails details) { - - } + default void track(String eventName, EvaluationContext context, TrackingEventDetails details) {} } diff --git a/src/main/java/dev/openfeature/sdk/FeatureProviderStateManager.java b/src/main/java/dev/openfeature/sdk/FeatureProviderStateManager.java index 973d46997..2c39ece6b 100644 --- a/src/main/java/dev/openfeature/sdk/FeatureProviderStateManager.java +++ b/src/main/java/dev/openfeature/sdk/FeatureProviderStateManager.java @@ -1,13 +1,13 @@ package dev.openfeature.sdk; import dev.openfeature.sdk.exceptions.OpenFeatureError; -import lombok.Getter; - import java.util.concurrent.atomic.AtomicBoolean; +import lombok.Getter; class FeatureProviderStateManager implements EventProviderListener { private final FeatureProvider delegate; private final AtomicBoolean isInitialized = new AtomicBoolean(); + @Getter private ProviderState state = ProviderState.NOT_READY; diff --git a/src/main/java/dev/openfeature/sdk/Features.java b/src/main/java/dev/openfeature/sdk/Features.java index ba25021a9..1f0b73d43 100644 --- a/src/main/java/dev/openfeature/sdk/Features.java +++ b/src/main/java/dev/openfeature/sdk/Features.java @@ -15,8 +15,8 @@ public interface Features { FlagEvaluationDetails getBooleanDetails(String key, Boolean defaultValue, EvaluationContext ctx); - FlagEvaluationDetails getBooleanDetails(String key, Boolean defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options); + FlagEvaluationDetails getBooleanDetails( + String key, Boolean defaultValue, EvaluationContext ctx, FlagEvaluationOptions options); String getStringValue(String key, String defaultValue); @@ -28,8 +28,8 @@ FlagEvaluationDetails getBooleanDetails(String key, Boolean defaultValu FlagEvaluationDetails getStringDetails(String key, String defaultValue, EvaluationContext ctx); - FlagEvaluationDetails getStringDetails(String key, String defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options); + FlagEvaluationDetails getStringDetails( + String key, String defaultValue, EvaluationContext ctx, FlagEvaluationOptions options); Integer getIntegerValue(String key, Integer defaultValue); @@ -41,8 +41,8 @@ FlagEvaluationDetails getStringDetails(String key, String defaultValue, FlagEvaluationDetails getIntegerDetails(String key, Integer defaultValue, EvaluationContext ctx); - FlagEvaluationDetails getIntegerDetails(String key, Integer defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options); + FlagEvaluationDetails getIntegerDetails( + String key, Integer defaultValue, EvaluationContext ctx, FlagEvaluationOptions options); Double getDoubleValue(String key, Double defaultValue); @@ -54,22 +54,19 @@ FlagEvaluationDetails getIntegerDetails(String key, Integer defaultValu FlagEvaluationDetails getDoubleDetails(String key, Double defaultValue, EvaluationContext ctx); - FlagEvaluationDetails getDoubleDetails(String key, Double defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options); + FlagEvaluationDetails getDoubleDetails( + String key, Double defaultValue, EvaluationContext ctx, FlagEvaluationOptions options); Value getObjectValue(String key, Value defaultValue); Value getObjectValue(String key, Value defaultValue, EvaluationContext ctx); - Value getObjectValue(String key, Value defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options); + Value getObjectValue(String key, Value defaultValue, EvaluationContext ctx, FlagEvaluationOptions options); FlagEvaluationDetails getObjectDetails(String key, Value defaultValue); - FlagEvaluationDetails getObjectDetails(String key, Value defaultValue, - EvaluationContext ctx); + FlagEvaluationDetails getObjectDetails(String key, Value defaultValue, EvaluationContext ctx); - FlagEvaluationDetails getObjectDetails(String key, Value defaultValue, - EvaluationContext ctx, - FlagEvaluationOptions options); + FlagEvaluationDetails getObjectDetails( + String key, Value defaultValue, EvaluationContext ctx, FlagEvaluationOptions options); } diff --git a/src/main/java/dev/openfeature/sdk/FlagEvaluationDetails.java b/src/main/java/dev/openfeature/sdk/FlagEvaluationDetails.java index 4562ea1e5..f1697e309 100644 --- a/src/main/java/dev/openfeature/sdk/FlagEvaluationDetails.java +++ b/src/main/java/dev/openfeature/sdk/FlagEvaluationDetails.java @@ -1,7 +1,6 @@ package dev.openfeature.sdk; import java.util.Optional; - import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -25,6 +24,7 @@ public class FlagEvaluationDetails implements BaseEvaluation { private String reason; private ErrorCode errorCode; private String errorMessage; + @Builder.Default private ImmutableMetadata flagMetadata = ImmutableMetadata.builder().build(); @@ -44,8 +44,8 @@ public static FlagEvaluationDetails from(ProviderEvaluation providerEv .reason(providerEval.getReason()) .errorMessage(providerEval.getErrorMessage()) .errorCode(providerEval.getErrorCode()) - .flagMetadata( - Optional.ofNullable(providerEval.getFlagMetadata()).orElse(ImmutableMetadata.builder().build())) + .flagMetadata(Optional.ofNullable(providerEval.getFlagMetadata()) + .orElse(ImmutableMetadata.builder().build())) .build(); } } diff --git a/src/main/java/dev/openfeature/sdk/FlagEvaluationOptions.java b/src/main/java/dev/openfeature/sdk/FlagEvaluationOptions.java index 5fa1a93f1..01ecb9b2e 100644 --- a/src/main/java/dev/openfeature/sdk/FlagEvaluationOptions.java +++ b/src/main/java/dev/openfeature/sdk/FlagEvaluationOptions.java @@ -3,7 +3,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; - import lombok.Builder; import lombok.Singular; @@ -13,6 +12,7 @@ public class FlagEvaluationOptions { @Singular List hooks; + @Builder.Default Map hookHints = new HashMap<>(); } diff --git a/src/main/java/dev/openfeature/sdk/FlagValueType.java b/src/main/java/dev/openfeature/sdk/FlagValueType.java index 11d43afb3..a8938d454 100644 --- a/src/main/java/dev/openfeature/sdk/FlagValueType.java +++ b/src/main/java/dev/openfeature/sdk/FlagValueType.java @@ -2,5 +2,9 @@ @SuppressWarnings("checkstyle:MissingJavadocType") public enum FlagValueType { - STRING, INTEGER, DOUBLE, OBJECT, BOOLEAN; + STRING, + INTEGER, + DOUBLE, + OBJECT, + BOOLEAN; } diff --git a/src/main/java/dev/openfeature/sdk/Hook.java b/src/main/java/dev/openfeature/sdk/Hook.java index 3856af266..9ca7e6b93 100644 --- a/src/main/java/dev/openfeature/sdk/Hook.java +++ b/src/main/java/dev/openfeature/sdk/Hook.java @@ -16,7 +16,7 @@ public interface Hook { * @param ctx Information about the particular flag evaluation * @param hints An immutable mapping of data for users to communicate to the hooks. * @return An optional {@link EvaluationContext}. If returned, it will be merged with the EvaluationContext - * instances from other hooks, the client and API. + * instances from other hooks, the client and API. */ default Optional before(HookContext ctx, Map hints) { return Optional.empty(); @@ -29,8 +29,7 @@ default Optional before(HookContext ctx, Map ctx, FlagEvaluationDetails details, Map hints) { - } + default void after(HookContext ctx, FlagEvaluationDetails details, Map hints) {} /** * Run when evaluation encounters an error. This will always run. Errors thrown will be swallowed. @@ -39,8 +38,7 @@ default void after(HookContext ctx, FlagEvaluationDetails details, Map ctx, Exception error, Map hints) { - } + default void error(HookContext ctx, Exception error, Map hints) {} /** * Run after flag evaluation, including any error processing. This will always run. Errors will be swallowed. @@ -48,8 +46,7 @@ default void error(HookContext ctx, Exception error, Map hint * @param ctx Information about the particular flag evaluation * @param hints An immutable mapping of data for users to communicate to the hooks. */ - default void finallyAfter(HookContext ctx, Map hints) { - } + default void finallyAfter(HookContext ctx, Map hints) {} default boolean supportsFlagValueType(FlagValueType flagValueType) { return true; diff --git a/src/main/java/dev/openfeature/sdk/HookContext.java b/src/main/java/dev/openfeature/sdk/HookContext.java index 5c9091b89..e14eeb643 100644 --- a/src/main/java/dev/openfeature/sdk/HookContext.java +++ b/src/main/java/dev/openfeature/sdk/HookContext.java @@ -10,28 +10,40 @@ * * @param the type for the flag being evaluated */ -@Value @Builder @With +@Value +@Builder +@With public class HookContext { @NonNull String flagKey; + @NonNull FlagValueType type; + @NonNull T defaultValue; + @NonNull EvaluationContext ctx; + ClientMetadata clientMetadata; Metadata providerMetadata; /** * Builds a {@link HookContext} instances from request data. - * @param key feature flag key - * @param type flag value type - * @param clientMetadata info on which client is calling + * + * @param key feature flag key + * @param type flag value type + * @param clientMetadata info on which client is calling * @param providerMetadata info on the provider - * @param ctx Evaluation Context for the request - * @param defaultValue Fallback value - * @param type that the flag is evaluating against + * @param ctx Evaluation Context for the request + * @param defaultValue Fallback value + * @param type that the flag is evaluating against * @return resulting context for hook */ - public static HookContext from(String key, FlagValueType type, ClientMetadata clientMetadata, - Metadata providerMetadata, EvaluationContext ctx, T defaultValue) { + public static HookContext from( + String key, + FlagValueType type, + ClientMetadata clientMetadata, + Metadata providerMetadata, + EvaluationContext ctx, + T defaultValue) { return HookContext.builder() .flagKey(key) .type(type) diff --git a/src/main/java/dev/openfeature/sdk/HookSupport.java b/src/main/java/dev/openfeature/sdk/HookSupport.java index f0216b255..95c8ff17d 100644 --- a/src/main/java/dev/openfeature/sdk/HookSupport.java +++ b/src/main/java/dev/openfeature/sdk/HookSupport.java @@ -6,39 +6,44 @@ import java.util.Map; import java.util.Optional; import java.util.function.Consumer; - import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @Slf4j @RequiredArgsConstructor -@SuppressWarnings({ "unchecked", "rawtypes" }) +@SuppressWarnings({"unchecked", "rawtypes"}) class HookSupport { - public EvaluationContext beforeHooks(FlagValueType flagValueType, HookContext hookCtx, List hooks, - Map hints) { + public EvaluationContext beforeHooks( + FlagValueType flagValueType, HookContext hookCtx, List hooks, Map hints) { return callBeforeHooks(flagValueType, hookCtx, hooks, hints); } - public void afterHooks(FlagValueType flagValueType, HookContext hookContext, FlagEvaluationDetails details, - List hooks, Map 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 afterAllHooks(FlagValueType flagValueType, HookContext hookCtx, List hooks, - Map hints) { + public void afterAllHooks( + FlagValueType flagValueType, HookContext hookCtx, List hooks, Map hints) { executeHooks(flagValueType, hooks, "finally", hook -> hook.finallyAfter(hookCtx, hints)); } - public void errorHooks(FlagValueType flagValueType, HookContext hookCtx, Exception e, List hooks, + 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( - FlagValueType flagValueType, List hooks, - String hookMethod, - Consumer> hookCode) { + FlagValueType flagValueType, List hooks, String hookMethod, Consumer> hookCode) { if (hooks != null) { for (Hook hook : hooks) { if (hook.supportsFlagValueType(flagValueType)) { @@ -53,15 +58,16 @@ private void executeChecked(Hook hook, Consumer> hookCode, String try { hookCode.accept(hook); } catch (Exception exception) { - log.error("Unhandled exception when running {} hook {} (only 'after' hooks should throw)", hookMethod, - hook.getClass(), 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) { + private void executeHooksUnchecked(FlagValueType flagValueType, List hooks, Consumer> hookCode) { if (hooks != null) { for (Hook hook : hooks) { if (hook.supportsFlagValueType(flagValueType)) { @@ -71,16 +77,16 @@ private void executeHooksUnchecked( } } - private EvaluationContext callBeforeHooks(FlagValueType flagValueType, HookContext hookCtx, - List hooks, Map hints) { + private EvaluationContext callBeforeHooks( + FlagValueType flagValueType, HookContext hookCtx, List hooks, Map hints) { // These traverse backwards from normal. List reversedHooks = new ArrayList<>(hooks); Collections.reverse(reversedHooks); EvaluationContext context = hookCtx.getCtx(); for (Hook hook : reversedHooks) { if (hook.supportsFlagValueType(flagValueType)) { - Optional optional = Optional.ofNullable(hook.before(hookCtx, hints)) - .orElse(Optional.empty()); + Optional optional = + Optional.ofNullable(hook.before(hookCtx, hints)).orElse(Optional.empty()); if (optional.isPresent()) { context = context.merge(optional.get()); } diff --git a/src/main/java/dev/openfeature/sdk/ImmutableContext.java b/src/main/java/dev/openfeature/sdk/ImmutableContext.java index d0dae6051..23a452e08 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableContext.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableContext.java @@ -1,10 +1,9 @@ package dev.openfeature.sdk; +import dev.openfeature.sdk.internal.ExcludeFromGeneratedCoverageReport; 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; @@ -88,15 +87,15 @@ public EvaluationContext merge(EvaluationContext overridingContext) { } Map attributes = this.asMap(); - EvaluationContext.mergeMaps(ImmutableStructure::new, attributes, - overridingContext.asUnmodifiableMap()); + EvaluationContext.mergeMaps(ImmutableStructure::new, attributes, overridingContext.asUnmodifiableMap()); return new ImmutableContext(attributes); } @SuppressWarnings("all") private static class DelegateExclusions { @ExcludeFromGeneratedCoverageReport - public Map merge(Function, Structure> newStructure, + public Map merge( + Function, Structure> newStructure, Map base, Map overriding) { return null; diff --git a/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java b/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java index 75f898470..c2b6f5838 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java @@ -1,10 +1,9 @@ package dev.openfeature.sdk; -import lombok.EqualsAndHashCode; -import lombok.extern.slf4j.Slf4j; - import java.util.HashMap; import java.util.Map; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; /** * Immutable Flag Metadata representation. Implementation is backed by a {@link Map} and immutability is provided @@ -98,7 +97,6 @@ public T getValue(final String key, final Class type) { } } - /** * Obtain a builder for {@link ImmutableMetadata}. */ @@ -188,6 +186,5 @@ public ImmutableMetadataBuilder addBoolean(final String key, final Boolean value public ImmutableMetadata build() { return new ImmutableMetadata(this.metadata); } - } } diff --git a/src/main/java/dev/openfeature/sdk/ImmutableStructure.java b/src/main/java/dev/openfeature/sdk/ImmutableStructure.java index 06c2551ff..c47a49eb3 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableStructure.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableStructure.java @@ -6,7 +6,6 @@ import java.util.Map.Entry; import java.util.Optional; import java.util.Set; - import lombok.EqualsAndHashCode; import lombok.ToString; @@ -20,7 +19,7 @@ */ @ToString @EqualsAndHashCode -@SuppressWarnings({ "PMD.BeanMembersShouldSerialize", "checkstyle:MissingJavadocType" }) +@SuppressWarnings({"PMD.BeanMembersShouldSerialize", "checkstyle:MissingJavadocType"}) public final class ImmutableStructure extends AbstractStructure { /** @@ -72,13 +71,15 @@ 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)); + 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)); } return copy; } - } diff --git a/src/main/java/dev/openfeature/sdk/ImmutableTrackingEventDetails.java b/src/main/java/dev/openfeature/sdk/ImmutableTrackingEventDetails.java index b535bb7da..6a4998745 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableTrackingEventDetails.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableTrackingEventDetails.java @@ -1,12 +1,10 @@ package dev.openfeature.sdk; import dev.openfeature.sdk.internal.ExcludeFromGeneratedCoverageReport; -import lombok.experimental.Delegate; - import java.util.Map; import java.util.Optional; import java.util.function.Function; - +import lombok.experimental.Delegate; /** * ImmutableTrackingEventDetails represents data pertinent to a particular tracking event. @@ -40,13 +38,13 @@ public Optional getValue() { return Optional.ofNullable(value); } - @SuppressWarnings("all") private static class DelegateExclusions { @ExcludeFromGeneratedCoverageReport - public Map merge(Function, Structure> newStructure, - Map base, - Map overriding) { + public Map merge( + Function, Structure> newStructure, + Map base, + Map overriding) { return null; } } diff --git a/src/main/java/dev/openfeature/sdk/IntegerHook.java b/src/main/java/dev/openfeature/sdk/IntegerHook.java index ada05c78d..971c2b3d6 100644 --- a/src/main/java/dev/openfeature/sdk/IntegerHook.java +++ b/src/main/java/dev/openfeature/sdk/IntegerHook.java @@ -3,7 +3,7 @@ /** * 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 IntegerHook extends Hook { diff --git a/src/main/java/dev/openfeature/sdk/MutableContext.java b/src/main/java/dev/openfeature/sdk/MutableContext.java index ffab28af2..7fda58065 100644 --- a/src/main/java/dev/openfeature/sdk/MutableContext.java +++ b/src/main/java/dev/openfeature/sdk/MutableContext.java @@ -1,11 +1,11 @@ package dev.openfeature.sdk; +import dev.openfeature.sdk.internal.ExcludeFromGeneratedCoverageReport; import java.time.Instant; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Function; -import dev.openfeature.sdk.internal.ExcludeFromGeneratedCoverageReport; import lombok.EqualsAndHashCode; import lombok.ToString; import lombok.experimental.Delegate; @@ -96,7 +96,6 @@ public MutableContext setTargetingKey(String targetingKey) { return this; } - /** * Retrieve targetingKey from the context. */ @@ -122,8 +121,7 @@ public EvaluationContext merge(EvaluationContext overridingContext) { } Map attributes = this.asMap(); - EvaluationContext.mergeMaps( - MutableStructure::new, attributes, overridingContext.asUnmodifiableMap()); + EvaluationContext.mergeMaps(MutableStructure::new, attributes, overridingContext.asUnmodifiableMap()); return new MutableContext(attributes); } @@ -134,7 +132,8 @@ public EvaluationContext merge(EvaluationContext overridingContext) { private static class DelegateExclusions { @ExcludeFromGeneratedCoverageReport - public Map merge(Function, Structure> newStructure, + public Map merge( + Function, Structure> newStructure, Map base, Map overriding) { diff --git a/src/main/java/dev/openfeature/sdk/MutableStructure.java b/src/main/java/dev/openfeature/sdk/MutableStructure.java index 1246aa5ef..a06e2f2d3 100644 --- a/src/main/java/dev/openfeature/sdk/MutableStructure.java +++ b/src/main/java/dev/openfeature/sdk/MutableStructure.java @@ -5,14 +5,13 @@ import java.util.List; import java.util.Map; import java.util.Set; - import lombok.EqualsAndHashCode; import lombok.ToString; /** - * {@link MutableStructure} represents a potentially nested object type which is used to represent + * {@link MutableStructure} represents a potentially nested object type which is used to represent * structured data. - * The MutableStructure is a Structure implementation which is not threadsafe, and whose attributes can + * The MutableStructure is a Structure implementation which is not threadsafe, and whose attributes can * be modified after instantiation. */ @ToString diff --git a/src/main/java/dev/openfeature/sdk/MutableTrackingEventDetails.java b/src/main/java/dev/openfeature/sdk/MutableTrackingEventDetails.java index 9f0de8c3a..5ab8aa4a3 100644 --- a/src/main/java/dev/openfeature/sdk/MutableTrackingEventDetails.java +++ b/src/main/java/dev/openfeature/sdk/MutableTrackingEventDetails.java @@ -1,15 +1,14 @@ package dev.openfeature.sdk; import dev.openfeature.sdk.internal.ExcludeFromGeneratedCoverageReport; -import lombok.EqualsAndHashCode; -import lombok.ToString; -import lombok.experimental.Delegate; - import java.time.Instant; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.Function; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import lombok.experimental.Delegate; /** * MutableTrackingEventDetails represents data pertinent to a particular tracking event. @@ -19,6 +18,7 @@ public class MutableTrackingEventDetails implements TrackingEventDetails { private final Number value; + @Delegate(excludes = MutableTrackingEventDetails.DelegateExclusions.class) private final MutableStructure structure; @@ -81,13 +81,13 @@ public MutableTrackingEventDetails add(String key, Value value) { return this; } - @SuppressWarnings("all") private static class DelegateExclusions { @ExcludeFromGeneratedCoverageReport - public Map merge(Function, Structure> newStructure, - Map base, - Map overriding) { + public Map merge( + Function, Structure> newStructure, + Map base, + Map overriding) { return null; } } diff --git a/src/main/java/dev/openfeature/sdk/NoOpProvider.java b/src/main/java/dev/openfeature/sdk/NoOpProvider.java index 2ad59c8bf..e427b9701 100644 --- a/src/main/java/dev/openfeature/sdk/NoOpProvider.java +++ b/src/main/java/dev/openfeature/sdk/NoOpProvider.java @@ -7,6 +7,7 @@ */ public class NoOpProvider implements FeatureProvider { public static final String PASSED_IN_DEFAULT = "Passed in default"; + @Getter private final String name = "No-op Provider"; @@ -58,8 +59,8 @@ public ProviderEvaluation getDoubleEvaluation(String key, Double default } @Override - public ProviderEvaluation getObjectEvaluation(String key, Value defaultValue, - EvaluationContext invocationContext) { + public ProviderEvaluation getObjectEvaluation( + String key, Value defaultValue, EvaluationContext invocationContext) { return ProviderEvaluation.builder() .value(defaultValue) .variant(PASSED_IN_DEFAULT) diff --git a/src/main/java/dev/openfeature/sdk/NoOpTransactionContextPropagator.java b/src/main/java/dev/openfeature/sdk/NoOpTransactionContextPropagator.java index a31b39b4c..f0949b79c 100644 --- a/src/main/java/dev/openfeature/sdk/NoOpTransactionContextPropagator.java +++ b/src/main/java/dev/openfeature/sdk/NoOpTransactionContextPropagator.java @@ -7,6 +7,7 @@ public class NoOpTransactionContextPropagator implements TransactionContextPropa /** * {@inheritDoc} + * * @return empty immutable context */ @Override @@ -18,7 +19,5 @@ public EvaluationContext getTransactionContext() { * {@inheritDoc} */ @Override - public void setTransactionContext(EvaluationContext evaluationContext) { - - } + public void setTransactionContext(EvaluationContext evaluationContext) {} } diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java b/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java index ad528568a..9175a7cd7 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java @@ -3,10 +3,13 @@ import dev.openfeature.sdk.exceptions.OpenFeatureError; import dev.openfeature.sdk.internal.AutoCloseableLock; import dev.openfeature.sdk.internal.AutoCloseableReentrantReadWriteLock; -import lombok.extern.slf4j.Slf4j; - -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.Set; import java.util.function.Consumer; +import lombok.extern.slf4j.Slf4j; /** * A global singleton which holds base configuration for the OpenFeature @@ -102,11 +105,7 @@ public Client getClient(String domain) { * @return a new client instance */ public Client getClient(String domain, String version) { - return new OpenFeatureClient( - this, - domain, - version - ); + return new OpenFeatureClient(this, domain, version); } /** @@ -196,7 +195,8 @@ public void setProvider(FeatureProvider provider) { */ public void setProvider(String domain, FeatureProvider provider) { try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) { - providerRepository.setProvider(domain, + providerRepository.setProvider( + domain, provider, this::attachEventProvider, this::emitReady, @@ -229,7 +229,8 @@ public void setProviderAndWait(FeatureProvider provider) throws OpenFeatureError */ public void setProviderAndWait(String domain, FeatureProvider provider) throws OpenFeatureError { try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) { - providerRepository.setProvider(domain, + providerRepository.setProvider( + domain, provider, this::attachEventProvider, this::emitReady, @@ -248,7 +249,10 @@ private void attachEventProvider(FeatureProvider provider) { } private void emitReady(FeatureProvider provider) { - runHandlersForProvider(provider, ProviderEvent.PROVIDER_READY, ProviderEventDetails.builder().build()); + runHandlersForProvider( + provider, + ProviderEvent.PROVIDER_READY, + ProviderEventDetails.builder().build()); } private void detachEventProvider(FeatureProvider provider) { @@ -258,7 +262,9 @@ private void detachEventProvider(FeatureProvider provider) { } private void emitError(FeatureProvider provider, OpenFeatureError exception) { - runHandlersForProvider(provider, ProviderEvent.PROVIDER_ERROR, + runHandlersForProvider( + provider, + ProviderEvent.PROVIDER_ERROR, ProviderEventDetails.builder().message(exception.getMessage()).build()); } @@ -394,8 +400,10 @@ void addHandler(String domain, ProviderEvent event, Consumer handl try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) { // if the provider is in the state associated with event, run immediately if (Optional.ofNullable(this.providerRepository.getProviderState(domain)) - .orElse(ProviderState.READY).matchesEvent(event)) { - eventSupport.runHandler(handler, EventDetails.builder().domain(domain).build()); + .orElse(ProviderState.READY) + .matchesEvent(event)) { + eventSupport.runHandler( + handler, EventDetails.builder().domain(domain).build()); } eventSupport.addClientHandler(domain, event, handler); } @@ -415,8 +423,7 @@ FeatureProviderStateManager getFeatureProviderStateManager(String domain) { private void runHandlersForProvider(FeatureProvider provider, ProviderEvent event, ProviderEventDetails details) { try (AutoCloseableLock __ = lock.readLockAutoCloseable()) { - List domainsForProvider = providerRepository - .getDomainsForProvider(provider); + List domainsForProvider = providerRepository.getDomainsForProvider(provider); final String providerName = Optional.ofNullable(provider.getMetadata()) .map(metadata -> metadata.getName()) @@ -427,8 +434,8 @@ private void runHandlersForProvider(FeatureProvider provider, ProviderEvent even // run the handlers associated with domains for this provider domainsForProvider.forEach(domain -> { - eventSupport.runClientHandlers(domain, event, - EventDetails.fromProviderEventDetails(details, providerName, domain)); + eventSupport.runClientHandlers( + domain, event, EventDetails.fromProviderEventDetails(details, providerName, domain)); }); if (providerRepository.isDefaultProvider(provider)) { @@ -437,8 +444,8 @@ private void runHandlersForProvider(FeatureProvider provider, ProviderEvent even Set boundDomains = providerRepository.getAllBoundDomains(); allDomainNames.removeAll(boundDomains); allDomainNames.forEach(domain -> { - eventSupport.runClientHandlers(domain, event, - EventDetails.fromProviderEventDetails(details, providerName, domain)); + eventSupport.runClientHandlers( + domain, event, EventDetails.fromProviderEventDetails(details, providerName, domain)); }); } } diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index ea566e652..60f987b77 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -8,9 +8,6 @@ import dev.openfeature.sdk.internal.AutoCloseableLock; import dev.openfeature.sdk.internal.AutoCloseableReentrantReadWriteLock; import dev.openfeature.sdk.internal.ObjectUtils; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -19,6 +16,8 @@ import java.util.Map; import java.util.Objects; import java.util.function.Consumer; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; /** * OpenFeature Client implementation. @@ -29,16 +28,24 @@ * @deprecated // TODO: eventually we will make this non-public. See issue #872 */ @Slf4j -@SuppressWarnings({"PMD.DataflowAnomalyAnalysis", "PMD.BeanMembersShouldSerialize", "PMD.UnusedLocalVariable", - "unchecked", "rawtypes"}) +@SuppressWarnings({ + "PMD.DataflowAnomalyAnalysis", + "PMD.BeanMembersShouldSerialize", + "PMD.UnusedLocalVariable", + "unchecked", + "rawtypes" +}) @Deprecated() // TODO: eventually we will make this non-public. See issue #872 public class OpenFeatureClient implements Client { private final OpenFeatureAPI openfeatureApi; + @Getter private final String domain; + @Getter private final String version; + private final List clientHooks; private final HookSupport hookSupport; AutoCloseableReentrantReadWriteLock hooksLock = new AutoCloseableReentrantReadWriteLock(); @@ -53,14 +60,11 @@ public class OpenFeatureClient implements Client { * providers (used by observability tools). * @param version Version of the client (used by observability tools). * @deprecated Do not use this constructor. It's for internal use only. - * Clients created using it will not run event handlers. - * Use the OpenFeatureAPI's getClient factory method instead. + * Clients created using it will not run event handlers. + * Use the OpenFeatureAPI's getClient factory method instead. */ @Deprecated() // TODO: eventually we will make this non-public. See issue #872 - public OpenFeatureClient( - OpenFeatureAPI openFeatureAPI, - String domain, - String version) { + public OpenFeatureClient(OpenFeatureAPI openFeatureAPI, String domain, String version) { this.openfeatureApi = openFeatureAPI; this.domain = domain; this.version = version; @@ -85,7 +89,6 @@ public void track(String trackingEventName) { invokeTrack(trackingEventName, null, null); } - /** * {@inheritDoc} */ @@ -117,7 +120,6 @@ public void track(String trackingEventName, EvaluationContext context, TrackingE invokeTrack(trackingEventName, mergeEvaluationContext(context), details); } - /** * {@inheritDoc} */ @@ -160,10 +162,10 @@ public EvaluationContext getEvaluationContext() { } } - private FlagEvaluationDetails evaluateFlag(FlagValueType type, String key, T defaultValue, - EvaluationContext ctx, FlagEvaluationOptions options) { - FlagEvaluationOptions flagOptions = ObjectUtils.defaultIfNull(options, - () -> FlagEvaluationOptions.builder().build()); + private FlagEvaluationDetails evaluateFlag( + FlagValueType type, String key, T defaultValue, EvaluationContext ctx, FlagEvaluationOptions options) { + FlagEvaluationOptions flagOptions = ObjectUtils.defaultIfNull( + options, () -> FlagEvaluationOptions.builder().build()); Map hints = Collections.unmodifiableMap(flagOptions.getHookHints()); FlagEvaluationDetails details = null; @@ -183,23 +185,31 @@ private FlagEvaluationDetails evaluateFlag(FlagValueType type, String key throw new FatalError("provider is in an irrecoverable error state"); } - mergedHooks = ObjectUtils.merge(provider.getProviderHooks(), flagOptions.getHooks(), clientHooks, - openfeatureApi.getHooks()); + mergedHooks = ObjectUtils.merge( + provider.getProviderHooks(), flagOptions.getHooks(), clientHooks, openfeatureApi.getHooks()); - EvaluationContext mergedCtx = hookSupport.beforeHooks(type, HookContext.from(key, type, this.getMetadata(), - provider.getMetadata(), mergeEvaluationContext(ctx), defaultValue), mergedHooks, hints); + EvaluationContext mergedCtx = hookSupport.beforeHooks( + type, + HookContext.from( + key, + type, + this.getMetadata(), + provider.getMetadata(), + mergeEvaluationContext(ctx), + defaultValue), + mergedHooks, + hints); - afterHookContext = HookContext.from(key, type, this.getMetadata(), - provider.getMetadata(), mergedCtx, defaultValue); + afterHookContext = + HookContext.from(key, type, this.getMetadata(), provider.getMetadata(), mergedCtx, defaultValue); - ProviderEvaluation providerEval = (ProviderEvaluation) createProviderEvaluation(type, key, - defaultValue, provider, mergedCtx); + ProviderEvaluation providerEval = + (ProviderEvaluation) createProviderEvaluation(type, key, defaultValue, provider, mergedCtx); details = FlagEvaluationDetails.from(providerEval, key); if (details.getErrorCode() != null) { - OpenFeatureError error = ExceptionUtils.instantiateErrorByErrorCode( - details.getErrorCode(), - details.getErrorMessage()); + OpenFeatureError error = + ExceptionUtils.instantiateErrorByErrorCode(details.getErrorCode(), details.getErrorMessage()); enrichDetailsWithErrorDefaults(defaultValue, details); hookSupport.errorHooks(type, afterHookContext, error, mergedHooks, hints); } else { @@ -237,7 +247,8 @@ private static void validateTrackingEventName(String str) { } private void invokeTrack(String trackingEventName, EvaluationContext context, TrackingEventDetails details) { - openfeatureApi.getFeatureProviderStateManager(domain) + openfeatureApi + .getFeatureProviderStateManager(domain) .getProvider() .track(trackingEventName, mergeEvaluationContext(context), details); } @@ -262,8 +273,7 @@ private EvaluationContext mergeContextMaps(EvaluationContext... contexts) { Map merged = new HashMap<>(); for (EvaluationContext evaluationContext : contexts) { if (evaluationContext != null && !evaluationContext.isEmpty()) { - EvaluationContext.mergeMaps(ImmutableStructure::new, merged, - evaluationContext.asUnmodifiableMap()); + EvaluationContext.mergeMaps(ImmutableStructure::new, merged, evaluationContext.asUnmodifiableMap()); } } return new ImmutableContext(merged); @@ -302,8 +312,8 @@ public Boolean getBooleanValue(String key, Boolean defaultValue, EvaluationConte } @Override - public Boolean getBooleanValue(String key, Boolean defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + public Boolean getBooleanValue( + String key, Boolean defaultValue, EvaluationContext ctx, FlagEvaluationOptions options) { return getBooleanDetails(key, defaultValue, ctx, options).getValue(); } @@ -314,12 +324,13 @@ public FlagEvaluationDetails getBooleanDetails(String key, Boolean defa @Override public FlagEvaluationDetails getBooleanDetails(String key, Boolean defaultValue, EvaluationContext ctx) { - return getBooleanDetails(key, defaultValue, ctx, FlagEvaluationOptions.builder().build()); + return getBooleanDetails( + key, defaultValue, ctx, FlagEvaluationOptions.builder().build()); } @Override - public FlagEvaluationDetails getBooleanDetails(String key, Boolean defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + public FlagEvaluationDetails getBooleanDetails( + String key, Boolean defaultValue, EvaluationContext ctx, FlagEvaluationOptions options) { return this.evaluateFlag(FlagValueType.BOOLEAN, key, defaultValue, ctx, options); } @@ -334,8 +345,8 @@ public String getStringValue(String key, String defaultValue, EvaluationContext } @Override - public String getStringValue(String key, String defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + public String getStringValue( + String key, String defaultValue, EvaluationContext ctx, FlagEvaluationOptions options) { return getStringDetails(key, defaultValue, ctx, options).getValue(); } @@ -346,12 +357,13 @@ public FlagEvaluationDetails getStringDetails(String key, String default @Override public FlagEvaluationDetails getStringDetails(String key, String defaultValue, EvaluationContext ctx) { - return getStringDetails(key, defaultValue, ctx, FlagEvaluationOptions.builder().build()); + return getStringDetails( + key, defaultValue, ctx, FlagEvaluationOptions.builder().build()); } @Override - public FlagEvaluationDetails getStringDetails(String key, String defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + public FlagEvaluationDetails getStringDetails( + String key, String defaultValue, EvaluationContext ctx, FlagEvaluationOptions options) { return this.evaluateFlag(FlagValueType.STRING, key, defaultValue, ctx, options); } @@ -366,8 +378,8 @@ public Integer getIntegerValue(String key, Integer defaultValue, EvaluationConte } @Override - public Integer getIntegerValue(String key, Integer defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + public Integer getIntegerValue( + String key, Integer defaultValue, EvaluationContext ctx, FlagEvaluationOptions options) { return getIntegerDetails(key, defaultValue, ctx, options).getValue(); } @@ -378,12 +390,13 @@ public FlagEvaluationDetails getIntegerDetails(String key, Integer defa @Override public FlagEvaluationDetails getIntegerDetails(String key, Integer defaultValue, EvaluationContext ctx) { - return getIntegerDetails(key, defaultValue, ctx, FlagEvaluationOptions.builder().build()); + return getIntegerDetails( + key, defaultValue, ctx, FlagEvaluationOptions.builder().build()); } @Override - public FlagEvaluationDetails getIntegerDetails(String key, Integer defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + public FlagEvaluationDetails getIntegerDetails( + String key, Integer defaultValue, EvaluationContext ctx, FlagEvaluationOptions options) { return this.evaluateFlag(FlagValueType.INTEGER, key, defaultValue, ctx, options); } @@ -398,9 +411,10 @@ public Double getDoubleValue(String key, Double defaultValue, EvaluationContext } @Override - public Double getDoubleValue(String key, Double defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { - return this.evaluateFlag(FlagValueType.DOUBLE, key, defaultValue, ctx, options).getValue(); + public Double getDoubleValue( + String key, Double defaultValue, EvaluationContext ctx, FlagEvaluationOptions options) { + return this.evaluateFlag(FlagValueType.DOUBLE, key, defaultValue, ctx, options) + .getValue(); } @Override @@ -414,8 +428,8 @@ public FlagEvaluationDetails getDoubleDetails(String key, Double default } @Override - public FlagEvaluationDetails getDoubleDetails(String key, Double defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + public FlagEvaluationDetails getDoubleDetails( + String key, Double defaultValue, EvaluationContext ctx, FlagEvaluationOptions options) { return this.evaluateFlag(FlagValueType.DOUBLE, key, defaultValue, ctx, options); } @@ -430,8 +444,7 @@ public Value getObjectValue(String key, Value defaultValue, EvaluationContext ct } @Override - public Value getObjectValue(String key, Value defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + public Value getObjectValue(String key, Value defaultValue, EvaluationContext ctx, FlagEvaluationOptions options) { return getObjectDetails(key, defaultValue, ctx, options).getValue(); } @@ -441,14 +454,14 @@ public FlagEvaluationDetails getObjectDetails(String key, Value defaultVa } @Override - public FlagEvaluationDetails getObjectDetails(String key, Value defaultValue, - EvaluationContext ctx) { - return getObjectDetails(key, defaultValue, ctx, FlagEvaluationOptions.builder().build()); + public FlagEvaluationDetails getObjectDetails(String key, Value defaultValue, EvaluationContext ctx) { + return getObjectDetails( + key, defaultValue, ctx, FlagEvaluationOptions.builder().build()); } @Override - public FlagEvaluationDetails getObjectDetails(String key, Value defaultValue, EvaluationContext ctx, - FlagEvaluationOptions options) { + public FlagEvaluationDetails getObjectDetails( + String key, Value defaultValue, EvaluationContext ctx, FlagEvaluationOptions options) { return this.evaluateFlag(FlagValueType.OBJECT, key, defaultValue, ctx, options); } diff --git a/src/main/java/dev/openfeature/sdk/ProviderEvaluation.java b/src/main/java/dev/openfeature/sdk/ProviderEvaluation.java index 004f5cfd7..39fddf24c 100644 --- a/src/main/java/dev/openfeature/sdk/ProviderEvaluation.java +++ b/src/main/java/dev/openfeature/sdk/ProviderEvaluation.java @@ -20,6 +20,7 @@ public class ProviderEvaluation implements BaseEvaluation { private String reason; ErrorCode errorCode; private String errorMessage; + @Builder.Default private ImmutableMetadata flagMetadata = ImmutableMetadata.builder().build(); } diff --git a/src/main/java/dev/openfeature/sdk/ProviderEvent.java b/src/main/java/dev/openfeature/sdk/ProviderEvent.java index dcefd606a..47ac8c952 100644 --- a/src/main/java/dev/openfeature/sdk/ProviderEvent.java +++ b/src/main/java/dev/openfeature/sdk/ProviderEvent.java @@ -4,5 +4,8 @@ * Provider event types. */ public enum ProviderEvent { - PROVIDER_READY, PROVIDER_CONFIGURATION_CHANGED, PROVIDER_ERROR, PROVIDER_STALE; + PROVIDER_READY, + PROVIDER_CONFIGURATION_CHANGED, + PROVIDER_ERROR, + PROVIDER_STALE; } diff --git a/src/main/java/dev/openfeature/sdk/ProviderEventDetails.java b/src/main/java/dev/openfeature/sdk/ProviderEventDetails.java index d927e4291..f202574d7 100644 --- a/src/main/java/dev/openfeature/sdk/ProviderEventDetails.java +++ b/src/main/java/dev/openfeature/sdk/ProviderEventDetails.java @@ -1,14 +1,14 @@ package dev.openfeature.sdk; import java.util.List; - import lombok.Data; import lombok.experimental.SuperBuilder; /** * The details of a particular event. */ -@Data @SuperBuilder(toBuilder = true) +@Data +@SuperBuilder(toBuilder = true) public class ProviderEventDetails { private List flagsChanged; private String message; diff --git a/src/main/java/dev/openfeature/sdk/ProviderRepository.java b/src/main/java/dev/openfeature/sdk/ProviderRepository.java index d3a5c1acc..bec866820 100644 --- a/src/main/java/dev/openfeature/sdk/ProviderRepository.java +++ b/src/main/java/dev/openfeature/sdk/ProviderRepository.java @@ -2,8 +2,6 @@ import dev.openfeature.sdk.exceptions.GeneralError; import dev.openfeature.sdk.exceptions.OpenFeatureError; -import lombok.extern.slf4j.Slf4j; - import java.util.List; import java.util.Map; import java.util.Optional; @@ -16,14 +14,14 @@ import java.util.function.Consumer; import java.util.stream.Collectors; import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; @Slf4j class ProviderRepository { private final Map stateManagers = new ConcurrentHashMap<>(); - private final AtomicReference defaultStateManger = new AtomicReference<>( - new FeatureProviderStateManager(new NoOpProvider()) - ); + private final AtomicReference defaultStateManger = + new AtomicReference<>(new FeatureProviderStateManager(new NoOpProvider())); private final ExecutorService taskExecutor = Executors.newCachedThreadPool(runnable -> { final Thread thread = new Thread(runnable); thread.setDaemon(true); @@ -96,7 +94,8 @@ public ProviderState getProviderState(String domain) { public List getDomainsForProvider(FeatureProvider provider) { return stateManagers.entrySet().stream() .filter(entry -> entry.getValue().hasSameProvider(provider)) - .map(Map.Entry::getKey).collect(Collectors.toList()); + .map(Map.Entry::getKey) + .collect(Collectors.toList()); } public Set getAllBoundDomains() { @@ -110,12 +109,13 @@ public boolean isDefaultProvider(FeatureProvider provider) { /** * Set the default provider. */ - public void setProvider(FeatureProvider provider, - Consumer afterSet, - Consumer afterInit, - Consumer afterShutdown, - BiConsumer afterError, - boolean waitForInit) { + public void setProvider( + FeatureProvider provider, + Consumer afterSet, + Consumer afterInit, + Consumer afterShutdown, + BiConsumer afterError, + boolean waitForInit) { if (provider == null) { throw new IllegalArgumentException("Provider cannot be null"); } @@ -130,13 +130,14 @@ public void setProvider(FeatureProvider provider, * @param waitForInit When true, wait for initialization to finish, then returns. * Otherwise, initialization happens in the background. */ - public void setProvider(String domain, - FeatureProvider provider, - Consumer afterSet, - Consumer afterInit, - Consumer afterShutdown, - BiConsumer afterError, - boolean waitForInit) { + public void setProvider( + String domain, + FeatureProvider provider, + Consumer afterSet, + Consumer afterInit, + Consumer afterShutdown, + BiConsumer afterError, + boolean waitForInit) { if (provider == null) { throw new IllegalArgumentException("Provider cannot be null"); } @@ -146,13 +147,14 @@ public void setProvider(String domain, prepareAndInitializeProvider(domain, provider, afterSet, afterInit, afterShutdown, afterError, waitForInit); } - private void prepareAndInitializeProvider(String domain, - FeatureProvider newProvider, - Consumer afterSet, - Consumer afterInit, - Consumer afterShutdown, - BiConsumer afterError, - boolean waitForInit) { + private void prepareAndInitializeProvider( + String domain, + FeatureProvider newProvider, + Consumer afterSet, + Consumer afterInit, + Consumer afterShutdown, + BiConsumer afterError, + boolean waitForInit) { final FeatureProviderStateManager newStateManager; final FeatureProviderStateManager oldStateManager; @@ -195,11 +197,12 @@ private FeatureProviderStateManager getExistingStateManagerForProvider(FeaturePr return null; } - private void initializeProvider(FeatureProviderStateManager newManager, - Consumer afterInit, - Consumer afterShutdown, - BiConsumer afterError, - FeatureProviderStateManager oldManager) { + private void initializeProvider( + FeatureProviderStateManager newManager, + Consumer afterInit, + Consumer afterShutdown, + BiConsumer afterError, + FeatureProviderStateManager oldManager) { try { if (ProviderState.NOT_READY.equals(newManager.getState())) { newManager.initialize(OpenFeatureAPI.getInstance().getEvaluationContext()); @@ -210,15 +213,13 @@ private void initializeProvider(FeatureProviderStateManager newManager, log.error( "Exception when initializing feature provider {}", newManager.getProvider().getClass().getName(), - e - ); + e); afterError.accept(newManager.getProvider(), e); } catch (Exception e) { log.error( "Exception when initializing feature provider {}", newManager.getProvider().getClass().getName(), - e - ); + e); afterError.accept(newManager.getProvider(), new GeneralError(e)); } } @@ -238,7 +239,8 @@ private void shutDownOld(FeatureProviderStateManager oldManager, Consumer { diff --git a/src/main/java/dev/openfeature/sdk/Structure.java b/src/main/java/dev/openfeature/sdk/Structure.java index f2fdc53e7..bfb744998 100644 --- a/src/main/java/dev/openfeature/sdk/Structure.java +++ b/src/main/java/dev/openfeature/sdk/Structure.java @@ -1,23 +1,23 @@ package dev.openfeature.sdk; -import dev.openfeature.sdk.exceptions.ValueNotConvertableError; +import static dev.openfeature.sdk.Value.objectToValue; +import dev.openfeature.sdk.exceptions.ValueNotConvertableError; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import static dev.openfeature.sdk.Value.objectToValue; - /** - * {@link Structure} represents a potentially nested object type which is used to represent + * {@link Structure} represents a potentially nested object type which is used to represent * structured data. */ @SuppressWarnings("PMD.BeanMembersShouldSerialize") public interface Structure { - + /** * Boolean indicating if this structure is empty. + * * @return boolean for emptiness */ boolean isEmpty(); @@ -51,7 +51,6 @@ public interface Structure { */ Map asUnmodifiableMap(); - /** * Get all values, with as a map of Object. * @@ -93,20 +92,15 @@ default Object convertValue(Value value) { } if (value.isList()) { - return value.asList() - .stream() - .map(this::convertValue) - .collect(Collectors.toList()); + return value.asList().stream().map(this::convertValue).collect(Collectors.toList()); } if (value.isStructure()) { Structure s = value.asStructure(); - return s.asUnmodifiableMap() - .entrySet() - .stream() - .collect(HashMap::new, - (accumulated, entry) -> accumulated.put(entry.getKey(), - convertValue(entry.getValue())), + return s.asUnmodifiableMap().entrySet().stream() + .collect( + HashMap::new, + (accumulated, entry) -> accumulated.put(entry.getKey(), convertValue(entry.getValue())), HashMap::putAll); } @@ -121,9 +115,9 @@ default Object convertValue(Value value) { */ static Structure mapToStructure(Map map) { return new MutableStructure(map.entrySet().stream() - .collect(HashMap::new, - (accumulated, entry) -> accumulated.put(entry.getKey(), - objectToValue(entry.getValue())), + .collect( + HashMap::new, + (accumulated, entry) -> accumulated.put(entry.getKey(), objectToValue(entry.getValue())), HashMap::putAll)); } } diff --git a/src/main/java/dev/openfeature/sdk/TrackingEventDetails.java b/src/main/java/dev/openfeature/sdk/TrackingEventDetails.java index 76b20fbbf..15b0208c0 100644 --- a/src/main/java/dev/openfeature/sdk/TrackingEventDetails.java +++ b/src/main/java/dev/openfeature/sdk/TrackingEventDetails.java @@ -3,5 +3,4 @@ /** * Data pertinent to a particular tracking event. */ -public interface TrackingEventDetails extends Structure { -} +public interface TrackingEventDetails extends Structure {} diff --git a/src/main/java/dev/openfeature/sdk/Value.java b/src/main/java/dev/openfeature/sdk/Value.java index 7464ce5af..05e538e50 100644 --- a/src/main/java/dev/openfeature/sdk/Value.java +++ b/src/main/java/dev/openfeature/sdk/Value.java @@ -1,17 +1,16 @@ package dev.openfeature.sdk; +import static dev.openfeature.sdk.Structure.mapToStructure; + +import dev.openfeature.sdk.exceptions.TypeMismatchError; import java.time.Instant; import java.util.List; import java.util.Map; import java.util.stream.Collectors; - -import dev.openfeature.sdk.exceptions.TypeMismatchError; import lombok.EqualsAndHashCode; import lombok.SneakyThrows; import lombok.ToString; -import static dev.openfeature.sdk.Structure.mapToStructure; - /** * Values serve as a generic return type for structure data from providers. * Providers may deal in JSON, protobuf, XML or some other data-interchange format. @@ -37,33 +36,34 @@ public Value() { /** * Construct a new Value with an Object. + * * @param value to be wrapped. * @throws InstantiationException if value is not a valid type - * (boolean, string, int, double, list, structure, instant) + * (boolean, string, int, double, list, structure, instant) */ public Value(Object value) throws InstantiationException { this.innerObject = value; if (!this.isNull() - && !this.isBoolean() - && !this.isString() - && !this.isNumber() - && !this.isStructure() - && !this.isList() - && !this.isInstant()) { + && !this.isBoolean() + && !this.isString() + && !this.isNumber() + && !this.isStructure() + && !this.isList() + && !this.isInstant()) { throw new InstantiationException("Invalid value type: " + value.getClass()); } } public Value(Value value) { - this.innerObject = value.innerObject; + this.innerObject = value.innerObject; } public Value(Boolean value) { - this.innerObject = value; + this.innerObject = value; } public Value(String value) { - this.innerObject = value; + this.innerObject = value; } public Value(Integer value) { @@ -71,69 +71,69 @@ public Value(Integer value) { } public Value(Double value) { - this.innerObject = value; + this.innerObject = value; } public Value(Structure value) { - this.innerObject = value; + this.innerObject = value; } public Value(List value) { - this.innerObject = value; + this.innerObject = value; } public Value(Instant value) { this.innerObject = value; } - /** + /** * Check if this Value represents null. - * + * * @return boolean */ public boolean isNull() { return this.innerObject == null; } - /** + /** * Check if this Value represents a Boolean. - * + * * @return boolean */ public boolean isBoolean() { return this.innerObject instanceof Boolean; } - /** + /** * Check if this Value represents a String. - * + * * @return boolean */ public boolean isString() { return this.innerObject instanceof String; } - /** + /** * Check if this Value represents a numeric value. - * + * * @return boolean */ public boolean isNumber() { return this.innerObject instanceof Number; } - /** + /** * Check if this Value represents a Structure. - * + * * @return boolean */ public boolean isStructure() { return this.innerObject instanceof Structure; } - - /** + + /** * Check if this Value represents a List of Values. - * + * * @return boolean */ public boolean isList() { @@ -155,87 +155,88 @@ public boolean isList() { return true; } - /** + /** * Check if this Value represents an Instant. - * + * * @return boolean */ public boolean isInstant() { return this.innerObject instanceof Instant; } - - /** + + /** * Retrieve the underlying Boolean value, or null. - * + * * @return Boolean */ - @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "NP_BOOLEAN_RETURN_NULL", - justification = "This is not a plain true/false method. It's understood it can return null.") + @edu.umd.cs.findbugs.annotations.SuppressFBWarnings( + value = "NP_BOOLEAN_RETURN_NULL", + justification = "This is not a plain true/false method. It's understood it can return null.") public Boolean asBoolean() { if (this.isBoolean()) { - return (Boolean)this.innerObject; + return (Boolean) this.innerObject; } return null; } - - /** + + /** * Retrieve the underlying object. - * + * * @return Object */ public Object asObject() { return this.innerObject; } - /** + /** * Retrieve the underlying String value, or null. - * + * * @return String */ public String asString() { if (this.isString()) { - return (String)this.innerObject; + return (String) this.innerObject; } return null; } - /** + /** * Retrieve the underlying numeric value as an Integer, or null. * If the value is not an integer, it will be rounded using Math.round(). - * + * * @return Integer */ public Integer asInteger() { if (this.isNumber() && !this.isNull()) { - return ((Number)this.innerObject).intValue(); + return ((Number) this.innerObject).intValue(); } return null; } - - /** + + /** * Retrieve the underlying numeric value as a Double, or null. - * + * * @return Double */ public Double asDouble() { if (this.isNumber() && !isNull()) { - return ((Number)this.innerObject).doubleValue(); + return ((Number) this.innerObject).doubleValue(); } return null; } - /** + /** * Retrieve the underlying Structure value, or null. - * + * * @return Structure */ public Structure asStructure() { if (this.isStructure()) { - return (Structure)this.innerObject; + return (Structure) this.innerObject; } return null; } - + /** * Retrieve the underlying List value, or null. * @@ -249,14 +250,14 @@ public List asList() { return null; } - /** + /** * Retrieve the underlying Instant value, or null. - * + * * @return Instant */ public Instant asInstant() { if (this.isInstant()) { - return (Instant)this.innerObject; + return (Instant) this.innerObject; } return null; } @@ -305,9 +306,8 @@ public static Value objectToValue(Object object) { } else if (object instanceof Structure) { return new Value((Structure) object); } else if (object instanceof List) { - return new Value(((List) object).stream() - .map(o -> objectToValue(o)) - .collect(Collectors.toList())); + return new Value( + ((List) object).stream().map(o -> objectToValue(o)).collect(Collectors.toList())); } else if (object instanceof Instant) { return new Value((Instant) object); } else if (object instanceof Map) { diff --git a/src/main/java/dev/openfeature/sdk/exceptions/ExceptionUtils.java b/src/main/java/dev/openfeature/sdk/exceptions/ExceptionUtils.java index 28c7cd716..f44dcea24 100644 --- a/src/main/java/dev/openfeature/sdk/exceptions/ExceptionUtils.java +++ b/src/main/java/dev/openfeature/sdk/exceptions/ExceptionUtils.java @@ -9,7 +9,8 @@ public class ExceptionUtils { /** * Creates an Error for the specific error code. - * @param errorCode the ErrorCode to use + * + * @param errorCode the ErrorCode to use * @param errorMessage the error message to include in the returned error * @return the specific OpenFeatureError for the errorCode */ diff --git a/src/main/java/dev/openfeature/sdk/exceptions/FatalError.java b/src/main/java/dev/openfeature/sdk/exceptions/FatalError.java index d50d1a42c..93d11dc83 100644 --- a/src/main/java/dev/openfeature/sdk/exceptions/FatalError.java +++ b/src/main/java/dev/openfeature/sdk/exceptions/FatalError.java @@ -8,6 +8,7 @@ @StandardException public class FatalError extends OpenFeatureError { private static final long serialVersionUID = 1L; + @Getter private final ErrorCode errorCode = ErrorCode.PROVIDER_FATAL; -} \ No newline at end of file +} diff --git a/src/main/java/dev/openfeature/sdk/exceptions/FlagNotFoundError.java b/src/main/java/dev/openfeature/sdk/exceptions/FlagNotFoundError.java index 7c88ebb44..e60ce416d 100644 --- a/src/main/java/dev/openfeature/sdk/exceptions/FlagNotFoundError.java +++ b/src/main/java/dev/openfeature/sdk/exceptions/FlagNotFoundError.java @@ -8,7 +8,7 @@ @StandardException public class FlagNotFoundError extends OpenFeatureErrorWithoutStacktrace { private static final long serialVersionUID = 1L; + @Getter private final ErrorCode errorCode = ErrorCode.FLAG_NOT_FOUND; - } diff --git a/src/main/java/dev/openfeature/sdk/exceptions/GeneralError.java b/src/main/java/dev/openfeature/sdk/exceptions/GeneralError.java index d7256c3f4..e89bd1cbc 100644 --- a/src/main/java/dev/openfeature/sdk/exceptions/GeneralError.java +++ b/src/main/java/dev/openfeature/sdk/exceptions/GeneralError.java @@ -8,6 +8,7 @@ @StandardException public class GeneralError extends OpenFeatureError { private static final long serialVersionUID = 1L; + @Getter private final ErrorCode errorCode = ErrorCode.GENERAL; } diff --git a/src/main/java/dev/openfeature/sdk/exceptions/InvalidContextError.java b/src/main/java/dev/openfeature/sdk/exceptions/InvalidContextError.java index e70c3efe2..34e5505ef 100644 --- a/src/main/java/dev/openfeature/sdk/exceptions/InvalidContextError.java +++ b/src/main/java/dev/openfeature/sdk/exceptions/InvalidContextError.java @@ -11,6 +11,6 @@ public class InvalidContextError extends OpenFeatureError { private static final long serialVersionUID = 1L; - @Getter private final ErrorCode errorCode = ErrorCode.INVALID_CONTEXT; - + @Getter + private final ErrorCode errorCode = ErrorCode.INVALID_CONTEXT; } diff --git a/src/main/java/dev/openfeature/sdk/exceptions/ParseError.java b/src/main/java/dev/openfeature/sdk/exceptions/ParseError.java index ac8fca877..dd2b6438c 100644 --- a/src/main/java/dev/openfeature/sdk/exceptions/ParseError.java +++ b/src/main/java/dev/openfeature/sdk/exceptions/ParseError.java @@ -11,6 +11,6 @@ public class ParseError extends OpenFeatureError { private static final long serialVersionUID = 1L; - @Getter private final ErrorCode errorCode = ErrorCode.PARSE_ERROR; - + @Getter + private final ErrorCode errorCode = ErrorCode.PARSE_ERROR; } diff --git a/src/main/java/dev/openfeature/sdk/exceptions/ProviderNotReadyError.java b/src/main/java/dev/openfeature/sdk/exceptions/ProviderNotReadyError.java index 0416eae26..5498b6f11 100644 --- a/src/main/java/dev/openfeature/sdk/exceptions/ProviderNotReadyError.java +++ b/src/main/java/dev/openfeature/sdk/exceptions/ProviderNotReadyError.java @@ -8,5 +8,7 @@ @StandardException public class ProviderNotReadyError extends OpenFeatureErrorWithoutStacktrace { private static final long serialVersionUID = 1L; - @Getter private final ErrorCode errorCode = ErrorCode.PROVIDER_NOT_READY; + + @Getter + private final ErrorCode errorCode = ErrorCode.PROVIDER_NOT_READY; } diff --git a/src/main/java/dev/openfeature/sdk/exceptions/TargetingKeyMissingError.java b/src/main/java/dev/openfeature/sdk/exceptions/TargetingKeyMissingError.java index 12437dc7e..05924ec72 100644 --- a/src/main/java/dev/openfeature/sdk/exceptions/TargetingKeyMissingError.java +++ b/src/main/java/dev/openfeature/sdk/exceptions/TargetingKeyMissingError.java @@ -11,6 +11,6 @@ public class TargetingKeyMissingError extends OpenFeatureError { private static final long serialVersionUID = 1L; - @Getter private final ErrorCode errorCode = ErrorCode.TARGETING_KEY_MISSING; - + @Getter + private final ErrorCode errorCode = ErrorCode.TARGETING_KEY_MISSING; } diff --git a/src/main/java/dev/openfeature/sdk/exceptions/TypeMismatchError.java b/src/main/java/dev/openfeature/sdk/exceptions/TypeMismatchError.java index 9d88922c7..13bf48bbf 100644 --- a/src/main/java/dev/openfeature/sdk/exceptions/TypeMismatchError.java +++ b/src/main/java/dev/openfeature/sdk/exceptions/TypeMismatchError.java @@ -12,6 +12,6 @@ public class TypeMismatchError extends OpenFeatureError { private static final long serialVersionUID = 1L; - @Getter private final ErrorCode errorCode = ErrorCode.TYPE_MISMATCH; - + @Getter + private final ErrorCode errorCode = ErrorCode.TYPE_MISMATCH; } diff --git a/src/main/java/dev/openfeature/sdk/exceptions/ValueNotConvertableError.java b/src/main/java/dev/openfeature/sdk/exceptions/ValueNotConvertableError.java index a681b5efa..13d46c8b7 100644 --- a/src/main/java/dev/openfeature/sdk/exceptions/ValueNotConvertableError.java +++ b/src/main/java/dev/openfeature/sdk/exceptions/ValueNotConvertableError.java @@ -10,6 +10,7 @@ @StandardException public class ValueNotConvertableError extends OpenFeatureError { private static final long serialVersionUID = 1L; + @Getter private final ErrorCode errorCode = ErrorCode.GENERAL; } diff --git a/src/main/java/dev/openfeature/sdk/hooks/logging/LoggingHook.java b/src/main/java/dev/openfeature/sdk/hooks/logging/LoggingHook.java index 716168f06..7465aa779 100644 --- a/src/main/java/dev/openfeature/sdk/hooks/logging/LoggingHook.java +++ b/src/main/java/dev/openfeature/sdk/hooks/logging/LoggingHook.java @@ -17,8 +17,9 @@ * Flag evaluation data is logged at debug and error in before/after stages and error stages, respectively. */ @Slf4j -@edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "RV_RETURN_VALUE_IGNORED", - justification = "we can ignore return values of chainables (builders) here") +@edu.umd.cs.findbugs.annotations.SuppressFBWarnings( + value = "RV_RETURN_VALUE_IGNORED", + justification = "we can ignore return values of chainables (builders) here") public class LoggingHook implements Hook { static final String DOMAIN_KEY = "domain"; @@ -43,6 +44,7 @@ public LoggingHook() { /** * Construct a new LoggingHook. + * * @param includeEvaluationContext include a serialized evaluation context in the log message (defaults to false) */ public LoggingHook(boolean includeEvaluationContext) { @@ -59,8 +61,8 @@ public Optional before(HookContext hookContext, Map hookContext, FlagEvaluationDetails details, - Map hints) { + public void after( + HookContext hookContext, FlagEvaluationDetails details, Map hints) { LoggingEventBuilder builder = log.atDebug() .addKeyValue(REASON_KEY, details.getReason()) .addKeyValue(VARIANT_KEY, details.getVariant()) @@ -71,8 +73,7 @@ public void after(HookContext hookContext, FlagEvaluationDetails @Override public void error(HookContext hookContext, Exception error, Map hints) { - LoggingEventBuilder builder = log.atError() - .addKeyValue(ERROR_MESSAGE_KEY, error.getMessage()); + LoggingEventBuilder builder = log.atError().addKeyValue(ERROR_MESSAGE_KEY, error.getMessage()); addCommonProps(builder, hookContext); ErrorCode errorCode = error instanceof OpenFeatureError ? ((OpenFeatureError) error).getErrorCode() : null; builder.addKeyValue(ERROR_CODE_KEY, errorCode); @@ -81,7 +82,8 @@ public void error(HookContext hookContext, Exception error, Map hookContext) { builder.addKeyValue(DOMAIN_KEY, hookContext.getClientMetadata().getDomain()) - .addKeyValue(PROVIDER_NAME_KEY, hookContext.getProviderMetadata().getName()) + .addKeyValue( + PROVIDER_NAME_KEY, hookContext.getProviderMetadata().getName()) .addKeyValue(FLAG_KEY_KEY, hookContext.getFlagKey()) .addKeyValue(DEFAULT_VALUE_KEY, hookContext.getDefaultValue()); diff --git a/src/main/java/dev/openfeature/sdk/internal/AutoCloseableLock.java b/src/main/java/dev/openfeature/sdk/internal/AutoCloseableLock.java index bf2f30426..2569aaf30 100644 --- a/src/main/java/dev/openfeature/sdk/internal/AutoCloseableLock.java +++ b/src/main/java/dev/openfeature/sdk/internal/AutoCloseableLock.java @@ -2,7 +2,7 @@ @SuppressWarnings("checkstyle:MissingJavadocType") public interface AutoCloseableLock extends AutoCloseable { - + /** * Override the exception in AutoClosable. */ diff --git a/src/main/java/dev/openfeature/sdk/internal/AutoCloseableReentrantReadWriteLock.java b/src/main/java/dev/openfeature/sdk/internal/AutoCloseableReentrantReadWriteLock.java index 92827ef68..1e94e3aed 100644 --- a/src/main/java/dev/openfeature/sdk/internal/AutoCloseableReentrantReadWriteLock.java +++ b/src/main/java/dev/openfeature/sdk/internal/AutoCloseableReentrantReadWriteLock.java @@ -10,6 +10,7 @@ public class AutoCloseableReentrantReadWriteLock extends ReentrantReadWriteLock /** * Get the single write lock as an AutoCloseableLock. + * * @return unlock method ref */ public AutoCloseableLock writeLockAutoCloseable() { @@ -19,10 +20,11 @@ public AutoCloseableLock writeLockAutoCloseable() { /** * Get the multi read lock as an AutoCloseableLock. + * * @return unlock method ref */ public AutoCloseableLock readLockAutoCloseable() { this.readLock().lock(); return this.readLock()::unlock; } -} \ No newline at end of file +} diff --git a/src/main/java/dev/openfeature/sdk/internal/ExcludeFromGeneratedCoverageReport.java b/src/main/java/dev/openfeature/sdk/internal/ExcludeFromGeneratedCoverageReport.java index e25f12607..f91fb815b 100644 --- a/src/main/java/dev/openfeature/sdk/internal/ExcludeFromGeneratedCoverageReport.java +++ b/src/main/java/dev/openfeature/sdk/internal/ExcludeFromGeneratedCoverageReport.java @@ -1,14 +1,13 @@ package dev.openfeature.sdk.internal; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; -import java.lang.annotation.Target; import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.ElementType; +import java.lang.annotation.Target; /** * JaCoCo ignores coverage of methods annotated with any annotation with "generated" in the name. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) -public @interface ExcludeFromGeneratedCoverageReport { -} \ No newline at end of file +public @interface ExcludeFromGeneratedCoverageReport {} diff --git a/src/main/java/dev/openfeature/sdk/internal/ObjectUtils.java b/src/main/java/dev/openfeature/sdk/internal/ObjectUtils.java index 9e5dcf613..b367820c2 100644 --- a/src/main/java/dev/openfeature/sdk/internal/ObjectUtils.java +++ b/src/main/java/dev/openfeature/sdk/internal/ObjectUtils.java @@ -4,7 +4,6 @@ import java.util.List; import java.util.Map; import java.util.function.Supplier; - import lombok.experimental.UtilityClass; @SuppressWarnings("checkstyle:MissingJavadocType") @@ -13,9 +12,10 @@ public class ObjectUtils { /** * If the source param is null, return the default value. - * @param source maybe null object + * + * @param source maybe null object * @param defaultValue thing to use if source is null - * @param list type + * @param list type * @return resulting object */ public static List defaultIfNull(List source, Supplier> defaultValue) { @@ -27,10 +27,11 @@ public static List defaultIfNull(List source, Supplier> defaul /** * If the source param is null, return the default value. - * @param source maybe null object + * + * @param source maybe null object * @param defaultValue thing to use if source is null - * @param map key type - * @param map value type + * @param map key type + * @param map value type * @return resulting map */ public static Map defaultIfNull(Map source, Supplier> defaultValue) { @@ -42,9 +43,10 @@ public static Map defaultIfNull(Map source, Supplier type + * @param type * @return resulting object */ public static T defaultIfNull(T source, Supplier defaultValue) { @@ -56,8 +58,9 @@ public static T defaultIfNull(T source, Supplier defaultValue) { /** * Concatenate a bunch of lists. + * * @param sources bunch of lists. - * @param list type + * @param list type * @return resulting object */ @SafeVarargs diff --git a/src/main/java/dev/openfeature/sdk/internal/TriConsumer.java b/src/main/java/dev/openfeature/sdk/internal/TriConsumer.java index 723f4aeb4..831307800 100644 --- a/src/main/java/dev/openfeature/sdk/internal/TriConsumer.java +++ b/src/main/java/dev/openfeature/sdk/internal/TriConsumer.java @@ -4,7 +4,7 @@ /** * Like {@link java.util.function.BiConsumer} but with 3 params. - * + * * @see java.util.function.BiConsumer */ @FunctionalInterface @@ -35,4 +35,4 @@ default TriConsumer andThen(TriConsumer after) { after.accept(t, u, v); }; } -} \ No newline at end of file +} diff --git a/src/main/java/dev/openfeature/sdk/providers/memory/ContextEvaluator.java b/src/main/java/dev/openfeature/sdk/providers/memory/ContextEvaluator.java index 02fa323c2..715868be6 100644 --- a/src/main/java/dev/openfeature/sdk/providers/memory/ContextEvaluator.java +++ b/src/main/java/dev/openfeature/sdk/providers/memory/ContextEvaluator.java @@ -4,6 +4,7 @@ /** * Context evaluator - use for resolving flag according to evaluation context, for handling targeting. + * * @param expected value type */ public interface ContextEvaluator { 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 8cfe85c93..61778d85b 100644 --- a/src/main/java/dev/openfeature/sdk/providers/memory/Flag.java +++ b/src/main/java/dev/openfeature/sdk/providers/memory/Flag.java @@ -1,12 +1,11 @@ package dev.openfeature.sdk.providers.memory; +import java.util.Map; import lombok.Builder; import lombok.Getter; import lombok.Singular; import lombok.ToString; -import java.util.Map; - /** * Flag representation for the in-memory provider. */ @@ -16,6 +15,7 @@ public class Flag { @Singular private Map variants; + private String defaultVariant; private ContextEvaluator contextEvaluator; } 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 2bea3e4ef..d3fdb985c 100644 --- a/src/main/java/dev/openfeature/sdk/providers/memory/InMemoryProvider.java +++ b/src/main/java/dev/openfeature/sdk/providers/memory/InMemoryProvider.java @@ -1,17 +1,28 @@ package dev.openfeature.sdk.providers.memory; -import dev.openfeature.sdk.*; -import dev.openfeature.sdk.exceptions.*; -import lombok.Getter; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; - +import dev.openfeature.sdk.EvaluationContext; +import dev.openfeature.sdk.EventProvider; +import dev.openfeature.sdk.Metadata; +import dev.openfeature.sdk.ProviderEvaluation; +import dev.openfeature.sdk.ProviderEventDetails; +import dev.openfeature.sdk.ProviderState; +import dev.openfeature.sdk.Reason; +import dev.openfeature.sdk.Value; +import dev.openfeature.sdk.exceptions.FatalError; +import dev.openfeature.sdk.exceptions.FlagNotFoundError; +import dev.openfeature.sdk.exceptions.GeneralError; +import dev.openfeature.sdk.exceptions.OpenFeatureError; +import dev.openfeature.sdk.exceptions.ProviderNotReadyError; +import dev.openfeature.sdk.exceptions.TypeMismatchError; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import lombok.Getter; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; /** * In-memory provider. @@ -38,6 +49,7 @@ public InMemoryProvider(Map> flags) { /** * Initializes the provider. + * * @param evaluationContext evaluation context * @throws Exception on error */ @@ -60,9 +72,9 @@ public void updateFlags(Map> newFlags) { this.flags.putAll(newFlags); ProviderEventDetails details = ProviderEventDetails.builder() - .flagsChanged(new ArrayList<>(flagsChanged)) - .message("flags changed") - .build(); + .flagsChanged(new ArrayList<>(flagsChanged)) + .message("flags changed") + .build(); emitProviderConfigurationChanged(details); } @@ -76,46 +88,45 @@ public void updateFlags(Map> newFlags) { public void updateFlag(String flagKey, Flag newFlag) { this.flags.put(flagKey, newFlag); ProviderEventDetails details = ProviderEventDetails.builder() - .flagsChanged(Collections.singletonList(flagKey)) - .message("flag added/updated") - .build(); + .flagsChanged(Collections.singletonList(flagKey)) + .message("flag added/updated") + .build(); emitProviderConfigurationChanged(details); } @Override - public ProviderEvaluation getBooleanEvaluation(String key, Boolean defaultValue, - EvaluationContext evaluationContext) { + public ProviderEvaluation getBooleanEvaluation( + String key, Boolean defaultValue, EvaluationContext evaluationContext) { return getEvaluation(key, evaluationContext, Boolean.class); } @Override - public ProviderEvaluation getStringEvaluation(String key, String defaultValue, - EvaluationContext evaluationContext) { + public ProviderEvaluation getStringEvaluation( + String key, String defaultValue, EvaluationContext evaluationContext) { return getEvaluation(key, evaluationContext, String.class); } @Override - public ProviderEvaluation getIntegerEvaluation(String key, Integer defaultValue, - EvaluationContext evaluationContext) { + public ProviderEvaluation getIntegerEvaluation( + String key, Integer defaultValue, EvaluationContext evaluationContext) { return getEvaluation(key, evaluationContext, Integer.class); } @Override - public ProviderEvaluation getDoubleEvaluation(String key, Double defaultValue, - EvaluationContext evaluationContext) { + public ProviderEvaluation getDoubleEvaluation( + String key, Double defaultValue, EvaluationContext evaluationContext) { return getEvaluation(key, evaluationContext, Double.class); } @SneakyThrows @Override - public ProviderEvaluation getObjectEvaluation(String key, Value defaultValue, - EvaluationContext evaluationContext) { + public ProviderEvaluation getObjectEvaluation( + String key, Value defaultValue, EvaluationContext evaluationContext) { return getEvaluation(key, evaluationContext, Value.class); } private ProviderEvaluation getEvaluation( - String key, EvaluationContext evaluationContext, Class expectedType - ) throws OpenFeatureError { + String key, EvaluationContext evaluationContext, Class expectedType) throws OpenFeatureError { if (!ProviderState.READY.equals(state)) { if (ProviderState.NOT_READY.equals(state)) { throw new ProviderNotReadyError("provider not yet initialized"); @@ -138,9 +149,9 @@ private ProviderEvaluation getEvaluation( value = (T) flag.getVariants().get(flag.getDefaultVariant()); } return ProviderEvaluation.builder() - .value(value) - .variant(flag.getDefaultVariant()) - .reason(Reason.STATIC.toString()) - .build(); + .value(value) + .variant(flag.getDefaultVariant()) + .reason(Reason.STATIC.toString()) + .build(); } } diff --git a/src/test/java/dev/openfeature/sdk/AlwaysBrokenProvider.java b/src/test/java/dev/openfeature/sdk/AlwaysBrokenProvider.java index 841d738e5..2f214d8ac 100644 --- a/src/test/java/dev/openfeature/sdk/AlwaysBrokenProvider.java +++ b/src/test/java/dev/openfeature/sdk/AlwaysBrokenProvider.java @@ -32,7 +32,8 @@ public ProviderEvaluation getDoubleEvaluation(String key, Double default } @Override - public ProviderEvaluation getObjectEvaluation(String key, Value defaultValue, EvaluationContext invocationContext) { + public ProviderEvaluation getObjectEvaluation( + String key, Value defaultValue, EvaluationContext invocationContext) { throw new FlagNotFoundError(TestConstants.BROKEN_MESSAGE); } } diff --git a/src/test/java/dev/openfeature/sdk/AlwaysBrokenWithDetailsProvider.java b/src/test/java/dev/openfeature/sdk/AlwaysBrokenWithDetailsProvider.java index b3ead41bd..8f304eaac 100644 --- a/src/test/java/dev/openfeature/sdk/AlwaysBrokenWithDetailsProvider.java +++ b/src/test/java/dev/openfeature/sdk/AlwaysBrokenWithDetailsProvider.java @@ -44,7 +44,8 @@ public ProviderEvaluation getDoubleEvaluation(String key, Double default } @Override - public ProviderEvaluation getObjectEvaluation(String key, Value defaultValue, EvaluationContext invocationContext) { + public ProviderEvaluation getObjectEvaluation( + String key, Value defaultValue, EvaluationContext invocationContext) { return ProviderEvaluation.builder() .errorMessage(TestConstants.BROKEN_MESSAGE) .errorCode(ErrorCode.FLAG_NOT_FOUND) diff --git a/src/test/java/dev/openfeature/sdk/ClientProviderMappingTest.java b/src/test/java/dev/openfeature/sdk/ClientProviderMappingTest.java index 8f022a384..cd7e8b295 100644 --- a/src/test/java/dev/openfeature/sdk/ClientProviderMappingTest.java +++ b/src/test/java/dev/openfeature/sdk/ClientProviderMappingTest.java @@ -1,10 +1,10 @@ package dev.openfeature.sdk; +import static org.junit.jupiter.api.Assertions.*; + import dev.openfeature.sdk.testutils.FeatureProviderTestUtils; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - class ClientProviderMappingTest { @Test diff --git a/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java b/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java index 4502699b1..c39c5ba31 100644 --- a/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java +++ b/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java @@ -1,13 +1,5 @@ package dev.openfeature.sdk; -import dev.openfeature.sdk.fixtures.HookFixtures; -import dev.openfeature.sdk.testutils.FeatureProviderTestUtils; -import dev.openfeature.sdk.testutils.TestEventsProvider; -import lombok.SneakyThrows; -import org.junit.jupiter.api.Test; - -import java.util.*; - import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -15,6 +7,17 @@ import static org.mockito.Mockito.times; 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; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import lombok.SneakyThrows; +import org.junit.jupiter.api.Test; + class DeveloperExperienceTest implements HookFixtures { transient String flagKey = "mykey"; @@ -49,7 +52,10 @@ void evalHooks() { api.setProviderAndWait(new TestEventsProvider()); Client client = api.getClient(); client.addHooks(clientHook); - Boolean retval = client.getBooleanValue(flagKey, false, null, + Boolean retval = client.getBooleanValue( + flagKey, + false, + null, FlagEvaluationOptions.builder().hook(evalHook).build()); verify(clientHook, times(1)).finallyAfter(any(), any()); verify(evalHook, times(1)).finallyAfter(any(), any()); @@ -132,7 +138,10 @@ void setProviderAndWaitShouldPutTheProviderInReadyState() { assertThat(client.getProviderState()).isEqualTo(ProviderState.READY); } - @Specification(number = "5.3.5", text = "If the provider emits an event, the value of the client's provider status MUST be updated accordingly.") + @Specification( + number = "5.3.5", + text = + "If the provider emits an event, the value of the client's provider status MUST be updated accordingly.") @Test void shouldPutTheProviderInStateErrorAfterEmittingErrorEvent() { String domain = "domain"; @@ -145,7 +154,10 @@ void shouldPutTheProviderInStateErrorAfterEmittingErrorEvent() { assertThat(client.getProviderState()).isEqualTo(ProviderState.ERROR); } - @Specification(number = "5.3.5", text = "If the provider emits an event, the value of the client's provider status MUST be updated accordingly.") + @Specification( + number = "5.3.5", + text = + "If the provider emits an event, the value of the client's provider status MUST be updated accordingly.") @Test void shouldPutTheProviderInStateStaleAfterEmittingStaleEvent() { String domain = "domain"; @@ -158,7 +170,10 @@ void shouldPutTheProviderInStateStaleAfterEmittingStaleEvent() { assertThat(client.getProviderState()).isEqualTo(ProviderState.STALE); } - @Specification(number = "5.3.5", text = "If the provider emits an event, the value of the client's provider status MUST be updated accordingly.") + @Specification( + number = "5.3.5", + text = + "If the provider emits an event, the value of the client's provider status MUST be updated accordingly.") @Test void shouldPutTheProviderInStateReadyAfterEmittingReadyEvent() { String domain = "domain"; diff --git a/src/test/java/dev/openfeature/sdk/DoSomethingProvider.java b/src/test/java/dev/openfeature/sdk/DoSomethingProvider.java index 322934469..0477a725b 100644 --- a/src/test/java/dev/openfeature/sdk/DoSomethingProvider.java +++ b/src/test/java/dev/openfeature/sdk/DoSomethingProvider.java @@ -4,7 +4,8 @@ class DoSomethingProvider implements FeatureProvider { static final String name = "Something"; // Flag evaluation metadata - static final ImmutableMetadata DEFAULT_METADATA = ImmutableMetadata.builder().build(); + static final ImmutableMetadata DEFAULT_METADATA = + ImmutableMetadata.builder().build(); private ImmutableMetadata flagMetadata; public DoSomethingProvider() { @@ -53,7 +54,8 @@ public ProviderEvaluation getDoubleEvaluation(String key, Double default } @Override - public ProviderEvaluation getObjectEvaluation(String key, Value defaultValue, EvaluationContext invocationContext) { + public ProviderEvaluation getObjectEvaluation( + String key, Value defaultValue, EvaluationContext invocationContext) { return ProviderEvaluation.builder() .value(null) .flagMetadata(flagMetadata) diff --git a/src/test/java/dev/openfeature/sdk/EvalContextTest.java b/src/test/java/dev/openfeature/sdk/EvalContextTest.java index c7f3aa44d..0f910b00e 100644 --- a/src/test/java/dev/openfeature/sdk/EvalContextTest.java +++ b/src/test/java/dev/openfeature/sdk/EvalContextTest.java @@ -1,6 +1,7 @@ package dev.openfeature.sdk; -import org.junit.jupiter.api.Test; +import static dev.openfeature.sdk.EvaluationContext.TARGETING_KEY; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.time.Instant; import java.time.temporal.ChronoUnit; @@ -8,23 +9,26 @@ import java.util.HashMap; import java.util.List; import java.util.Map; - -import static dev.openfeature.sdk.EvaluationContext.TARGETING_KEY; -import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; public class EvalContextTest { - @Specification(number="3.1.1", - text="The `evaluation context` structure **MUST** define an optional `targeting key` field of " + - "type string, identifying the subject of the flag evaluation.") - @Test void requires_targeting_key() { + @Specification( + number = "3.1.1", + text = "The `evaluation context` structure **MUST** define an optional `targeting key` field of " + + "type string, identifying the subject of the flag evaluation.") + @Test + void requires_targeting_key() { EvaluationContext ec = new ImmutableContext("targeting-key", new HashMap<>()); assertEquals("targeting-key", ec.getTargetingKey()); } - @Specification(number="3.1.2", text= "The evaluation context MUST support the inclusion of " + - "custom fields, having keys of type `string`, and " + - "values of type `boolean | string | number | datetime | structure`.") - @Test void eval_context() { + @Specification( + number = "3.1.2", + text = "The evaluation context MUST support the inclusion of " + + "custom fields, having keys of type `string`, and " + + "values of type `boolean | string | number | datetime | structure`.") + @Test + void eval_context() { Map attributes = new HashMap<>(); Instant dt = Instant.now().truncatedTo(ChronoUnit.MILLIS); attributes.put("str", new Value("test")); @@ -42,16 +46,21 @@ public class EvalContextTest { assertEquals(dt, ec.getValue("dt").asInstant().truncatedTo(ChronoUnit.MILLIS)); } - @Specification(number="3.1.2", text="The evaluation context MUST support the inclusion of " + - "custom fields, having keys of type `string`, and " + - "values of type `boolean | string | number | datetime | structure`.") - @Test void eval_context_structure_array() { + @Specification( + number = "3.1.2", + text = "The evaluation context MUST support the inclusion of " + + "custom fields, having keys of type `string`, and " + + "values of type `boolean | string | number | datetime | structure`.") + @Test + void eval_context_structure_array() { Map attributes = new HashMap<>(); attributes.put("obj", new Value(new MutableStructure().add("val1", 1).add("val2", "2"))); - List values = new ArrayList(){{ - add(new Value("one")); - add(new Value("two")); - }}; + List values = new ArrayList() { + { + add(new Value("one")); + add(new Value("two")); + } + }; attributes.put("arr", new Value(values)); EvaluationContext ec = new ImmutableContext(attributes); @@ -64,11 +73,16 @@ public class EvalContextTest { assertEquals("two", arr.get(1).asString()); } - @Specification(number="3.1.3", text="The evaluation context MUST support fetching the custom fields by key and also fetching all key value pairs.") - @Test void fetch_all() { - Map attributes = new HashMap<>(); + @Specification( + number = "3.1.3", + text = + "The evaluation context MUST support fetching the custom fields by key and also fetching all key value pairs.") + @Test + void fetch_all() { + Map attributes = new HashMap<>(); Instant dt = Instant.now(); - MutableStructure mutableStructure = new MutableStructure().add("val1", 1).add("val2", "2"); + MutableStructure mutableStructure = + new MutableStructure().add("val1", 1).add("val2", "2"); attributes.put("str", new Value("test")); attributes.put("str2", new Value("test2")); attributes.put("bool", new Value(true)); @@ -96,8 +110,9 @@ public class EvalContextTest { assertEquals("2", foundObj.getValue("val2").asString()); } - @Specification(number="3.1.4", text="The evaluation context fields MUST have an unique key.") - @Test void unique_key_across_types() { + @Specification(number = "3.1.4", text = "The evaluation context fields MUST have an unique key.") + @Test + void unique_key_across_types() { MutableContext ec = new MutableContext(); ec.add("key", "val"); ec.add("key", "val2"); @@ -107,8 +122,9 @@ public class EvalContextTest { assertEquals(3, ec.getValue("key").asInteger()); } - @Test void unique_key_across_types_immutableContext() { - HashMap attributes = new HashMap<>(); + @Test + void unique_key_across_types_immutableContext() { + HashMap attributes = new HashMap<>(); attributes.put("key", new Value("val")); attributes.put("key", new Value("val2")); attributes.put("key", new Value(3)); @@ -117,23 +133,23 @@ public class EvalContextTest { assertEquals(3, ec.getValue("key").asInteger()); } - @Test void can_chain_attribute_addition() { + @Test + void can_chain_attribute_addition() { MutableContext ec = new MutableContext(); - MutableContext out = ec.add("str", "test") - .add("int", 4) - .add("bool", false) - .add("str", new MutableStructure()); + MutableContext out = + ec.add("str", "test").add("int", 4).add("bool", false).add("str", new MutableStructure()); assertEquals(MutableContext.class, out.getClass()); } - @Test void can_add_key_with_null() { + @Test + void can_add_key_with_null() { MutableContext ec = new MutableContext() - .add("Boolean", (Boolean)null) - .add("String", (String)null) - .add("Double", (Double)null) - .add("Structure", (MutableStructure)null) - .add("List", (List)null) - .add("Instant", (Instant)null); + .add("Boolean", (Boolean) null) + .add("String", (String) null) + .add("Double", (Double) null) + .add("Structure", (MutableStructure) null) + .add("List", (List) null) + .add("Instant", (Instant) null); assertEquals(6, ec.asMap().size()); assertEquals(null, ec.getValue("Boolean").asBoolean()); assertEquals(null, ec.getValue("String").asString()); @@ -143,7 +159,8 @@ public class EvalContextTest { assertEquals(null, ec.getValue("Instant").asString()); } - @Test void Immutable_context_merge_targeting_key() { + @Test + void Immutable_context_merge_targeting_key() { String key1 = "key1"; EvaluationContext ctx1 = new ImmutableContext(key1, new HashMap<>()); EvaluationContext ctx2 = new ImmutableContext(new HashMap<>()); @@ -156,19 +173,21 @@ public class EvalContextTest { ctxMerged = ctx1.merge(ctx2); assertEquals(key2, ctxMerged.getTargetingKey()); - ctx2 = new ImmutableContext(" ",new HashMap<>()); + ctx2 = new ImmutableContext(" ", new HashMap<>()); ctxMerged = ctx1.merge(ctx2); assertEquals(key1, ctxMerged.getTargetingKey()); } - @Test void merge_null_returns_value() { + @Test + void merge_null_returns_value() { MutableContext ctx1 = new MutableContext("key"); ctx1.add("mything", "value"); EvaluationContext result = ctx1.merge(null); assertEquals(ctx1, result); } - @Test void merge_targeting_key() { + @Test + void merge_targeting_key() { String key1 = "key1"; MutableContext ctx1 = new MutableContext(key1); MutableContext ctx2 = new MutableContext(); @@ -186,14 +205,15 @@ public class EvalContextTest { assertEquals(key2, ctxMerged.getTargetingKey()); } - @Test void asObjectMap() { + @Test + void asObjectMap() { String key1 = "key1"; MutableContext ctx = new MutableContext(key1); ctx.add("stringItem", "stringValue"); ctx.add("boolItem", false); ctx.add("integerItem", 1); ctx.add("doubleItem", 1.2); - ctx.add("instantItem", Instant.ofEpochSecond(1663331342)); + ctx.add("instantItem", Instant.ofEpochSecond(1663331342)); List listItem = new ArrayList<>(); listItem.add(new Value("item1")); listItem.add(new Value("item2")); @@ -207,18 +227,17 @@ public class EvalContextTest { structureValue.put("structBoolItem", new Value(false)); structureValue.put("structIntegerItem", new Value(1)); structureValue.put("structDoubleItem", new Value(1.2)); - structureValue.put("structInstantItem", new Value(Instant.ofEpochSecond(1663331342))); + structureValue.put("structInstantItem", new Value(Instant.ofEpochSecond(1663331342))); Structure structure = new MutableStructure(structureValue); ctx.add("structureItem", structure); - Map want = new HashMap<>(); want.put(TARGETING_KEY, key1); want.put("stringItem", "stringValue"); want.put("boolItem", false); want.put("integerItem", 1); want.put("doubleItem", 1.2); - want.put("instantItem", Instant.ofEpochSecond(1663331342)); + want.put("instantItem", Instant.ofEpochSecond(1663331342)); List wantListItem = new ArrayList<>(); wantListItem.add("item1"); wantListItem.add("item2"); @@ -232,9 +251,9 @@ public class EvalContextTest { wantStructureValue.put("structBoolItem", false); wantStructureValue.put("structIntegerItem", 1); wantStructureValue.put("structDoubleItem", 1.2); - wantStructureValue.put("structInstantItem", Instant.ofEpochSecond(1663331342)); - want.put("structureItem",wantStructureValue); + wantStructureValue.put("structInstantItem", Instant.ofEpochSecond(1663331342)); + want.put("structureItem", wantStructureValue); - assertEquals(want,ctx.asObjectMap()); + assertEquals(want, ctx.asObjectMap()); } } diff --git a/src/test/java/dev/openfeature/sdk/EventProviderTest.java b/src/test/java/dev/openfeature/sdk/EventProviderTest.java index acf2ce6b3..d8af6e8d3 100644 --- a/src/test/java/dev/openfeature/sdk/EventProviderTest.java +++ b/src/test/java/dev/openfeature/sdk/EventProviderTest.java @@ -1,20 +1,15 @@ package dev.openfeature.sdk; -import dev.openfeature.sdk.exceptions.FatalError; -import dev.openfeature.sdk.exceptions.GeneralError; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + import dev.openfeature.sdk.internal.TriConsumer; import lombok.SneakyThrows; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import java.util.concurrent.atomic.AtomicBoolean; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - class EventProviderTest { private TestEventProvider eventProvider; @@ -71,7 +66,6 @@ void throwsWhenOnEmitDifferent() { assertThrows(IllegalStateException.class, () -> eventProvider.attach(onEmit2)); } - @Test @DisplayName("should not throw if second same onEmit attached") void doesNotThrowWhenOnEmitSame() { @@ -91,32 +85,29 @@ public Metadata getMetadata() { } @Override - public ProviderEvaluation getBooleanEvaluation(String key, Boolean defaultValue, - EvaluationContext ctx) { + public ProviderEvaluation getBooleanEvaluation( + String key, Boolean defaultValue, EvaluationContext ctx) { throw new UnsupportedOperationException("Unimplemented method 'getBooleanEvaluation'"); } @Override - public ProviderEvaluation getStringEvaluation(String key, String defaultValue, - EvaluationContext ctx) { + public ProviderEvaluation getStringEvaluation(String key, String defaultValue, EvaluationContext ctx) { throw new UnsupportedOperationException("Unimplemented method 'getStringEvaluation'"); } @Override - public ProviderEvaluation getIntegerEvaluation(String key, Integer defaultValue, - EvaluationContext ctx) { + public ProviderEvaluation getIntegerEvaluation( + String key, Integer defaultValue, EvaluationContext ctx) { throw new UnsupportedOperationException("Unimplemented method 'getIntegerEvaluation'"); } @Override - public ProviderEvaluation getDoubleEvaluation(String key, Double defaultValue, - EvaluationContext ctx) { + public ProviderEvaluation getDoubleEvaluation(String key, Double defaultValue, EvaluationContext ctx) { throw new UnsupportedOperationException("Unimplemented method 'getDoubleEvaluation'"); } @Override - public ProviderEvaluation getObjectEvaluation(String key, Value defaultValue, - EvaluationContext ctx) { + public ProviderEvaluation getObjectEvaluation(String key, Value defaultValue, EvaluationContext ctx) { throw new UnsupportedOperationException("Unimplemented method 'getObjectEvaluation'"); } @@ -130,4 +121,4 @@ public void attach(TriConsumer mockOnEmit() { return (TriConsumer) mock(TriConsumer.class); } -} \ No newline at end of file +} diff --git a/src/test/java/dev/openfeature/sdk/EventsTest.java b/src/test/java/dev/openfeature/sdk/EventsTest.java index 41bcf86c4..02a5953b9 100644 --- a/src/test/java/dev/openfeature/sdk/EventsTest.java +++ b/src/test/java/dev/openfeature/sdk/EventsTest.java @@ -1,23 +1,22 @@ package dev.openfeature.sdk; +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.argThat; +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.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.ArgumentMatcher; -import java.util.Arrays; -import java.util.List; -import java.util.function.Consumer; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.awaitility.Awaitility.await; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Mockito.*; - class EventsTest { private static final int TIMEOUT = 300; @@ -41,8 +40,10 @@ class Initialization { @Test @DisplayName("should fire initial READY event when provider init succeeds") - @Specification(number = "5.3.1", text = "If the provider's initialize function terminates normally," + - " PROVIDER_READY handlers MUST run.") + @Specification( + number = "5.3.1", + text = "If the provider's initialize function terminates normally," + + " PROVIDER_READY handlers MUST run.") void apiInitReady() { final Consumer handler = mockHandler(); final String name = "apiInitReady"; @@ -50,14 +51,15 @@ void apiInitReady() { TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); OpenFeatureAPI.getInstance().onProviderReady(handler); OpenFeatureAPI.getInstance().setProviderAndWait(name, provider); - verify(handler, timeout(TIMEOUT).atLeastOnce()) - .accept(any()); + verify(handler, timeout(TIMEOUT).atLeastOnce()).accept(any()); } @Test @DisplayName("should fire initial ERROR event when provider init errors") - @Specification(number = "5.3.2", text = "If the provider's initialize function terminates abnormally," + - " PROVIDER_ERROR handlers MUST run.") + @Specification( + number = "5.3.2", + text = "If the provider's initialize function terminates abnormally," + + " PROVIDER_ERROR handlers MUST run.") void apiInitError() { final Consumer handler = mockHandler(); final String name = "apiInitError"; @@ -78,9 +80,10 @@ class ProviderEvents { @Test @DisplayName("should propagate events") - @Specification(number = "5.1.2", text = "When a provider signals the occurrence of a particular event, " - + - "the associated client and API event handlers MUST run.") + @Specification( + number = "5.1.2", + text = "When a provider signals the occurrence of a particular event, " + + "the associated client and API event handlers MUST run.") void apiShouldPropagateEvents() { final Consumer handler = mockHandler(); final String name = "apiShouldPropagateEvents"; @@ -89,18 +92,24 @@ void apiShouldPropagateEvents() { OpenFeatureAPI.getInstance().setProviderAndWait(name, provider); OpenFeatureAPI.getInstance().onProviderConfigurationChanged(handler); - provider.mockEvent(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, EventDetails.builder().build()); + provider.mockEvent( + ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, + EventDetails.builder().build()); verify(handler, timeout(TIMEOUT)).accept(any()); } @Test @DisplayName("should support all event types") - @Specification(number = "5.1.1", text = "The provider MAY define a mechanism for signaling the occurrence " - + "of one of a set of events, including PROVIDER_READY, PROVIDER_ERROR, " - + "PROVIDER_CONFIGURATION_CHANGED and PROVIDER_STALE, with a provider event details payload.") - @Specification(number = "5.2.2", text = "The API MUST provide a function for associating handler functions" - + - " with a particular provider event type.") + @Specification( + number = "5.1.1", + text = + "The provider MAY define a mechanism for signaling the occurrence " + + "of one of a set of events, including PROVIDER_READY, PROVIDER_ERROR, " + + "PROVIDER_CONFIGURATION_CHANGED and PROVIDER_STALE, with a provider event details payload.") + @Specification( + number = "5.2.2", + text = "The API MUST provide a function for associating handler functions" + + " with a particular provider event type.") void apiShouldSupportAllEventTypes() { final String name = "apiShouldSupportAllEventTypes"; final Consumer handler1 = mockHandler(); @@ -117,7 +126,8 @@ void apiShouldSupportAllEventTypes() { OpenFeatureAPI.getInstance().onProviderError(handler4); Arrays.asList(ProviderEvent.values()).stream().forEach(eventType -> { - provider.mockEvent(eventType, ProviderEventDetails.builder().build()); + provider.mockEvent( + eventType, ProviderEventDetails.builder().build()); }); verify(handler1, timeout(TIMEOUT).atLeastOnce()).accept(any()); @@ -143,7 +153,10 @@ class ProviderEvents { @Test @DisplayName("should propagate events for default provider and anonymous client") - @Specification(number = "5.1.2", text = "When a provider signals the occurrence of a particular event, the associated client and API event handlers MUST run.") + @Specification( + number = "5.1.2", + text = + "When a provider signals the occurrence of a particular event, the associated client and API event handlers MUST run.") void shouldPropagateDefaultAndAnon() { final Consumer handler = mockHandler(); @@ -153,13 +166,17 @@ void shouldPropagateDefaultAndAnon() { Client client = OpenFeatureAPI.getInstance().getClient(); client.onProviderStale(handler); - provider.mockEvent(ProviderEvent.PROVIDER_STALE, EventDetails.builder().build()); + provider.mockEvent( + ProviderEvent.PROVIDER_STALE, EventDetails.builder().build()); verify(handler, timeout(TIMEOUT)).accept(any()); } @Test @DisplayName("should propagate events for default provider and named client") - @Specification(number = "5.1.2", text = "When a provider signals the occurrence of a particular event, the associated client and API event handlers MUST run.") + @Specification( + number = "5.1.2", + text = + "When a provider signals the occurrence of a particular event, the associated client and API event handlers MUST run.") void shouldPropagateDefaultAndNamed() { final Consumer handler = mockHandler(); final String name = "shouldPropagateDefaultAndNamed"; @@ -170,7 +187,8 @@ void shouldPropagateDefaultAndNamed() { Client client = OpenFeatureAPI.getInstance().getClient(name); client.onProviderStale(handler); - provider.mockEvent(ProviderEvent.PROVIDER_STALE, EventDetails.builder().build()); + provider.mockEvent( + ProviderEvent.PROVIDER_STALE, EventDetails.builder().build()); verify(handler, timeout(TIMEOUT)).accept(any()); } } @@ -186,7 +204,10 @@ class NamedProvider { class Initialization { @Test @DisplayName("should fire initial READY event when provider init succeeds after client retrieved") - @Specification(number = "5.3.1", text = "If the provider's initialize function terminates normally, PROVIDER_READY handlers MUST run.") + @Specification( + number = "5.3.1", + text = + "If the provider's initialize function terminates normally, PROVIDER_READY handlers MUST run.") void initReadyProviderBefore() { final Consumer handler = mockHandler(); final String name = "initReadyProviderBefore"; @@ -202,7 +223,10 @@ void initReadyProviderBefore() { @Test @DisplayName("should fire initial READY event when provider init succeeds before client retrieved") - @Specification(number = "5.3.1", text = "If the provider's initialize function terminates normally, PROVIDER_READY handlers MUST run.") + @Specification( + number = "5.3.1", + text = + "If the provider's initialize function terminates normally, PROVIDER_READY handlers MUST run.") void initReadyProviderAfter() { final Consumer handler = mockHandler(); final String name = "initReadyProviderAfter"; @@ -218,7 +242,10 @@ void initReadyProviderAfter() { @Test @DisplayName("should fire initial ERROR event when provider init errors after client retrieved") - @Specification(number = "5.3.2", text = "If the provider's initialize function terminates abnormally, PROVIDER_ERROR handlers MUST run.") + @Specification( + number = "5.3.2", + text = + "If the provider's initialize function terminates abnormally, PROVIDER_ERROR handlers MUST run.") void initErrorProviderAfter() { final Consumer handler = mockHandler(); final String name = "initErrorProviderAfter"; @@ -230,14 +257,16 @@ void initErrorProviderAfter() { // set provider after getting a client OpenFeatureAPI.getInstance().setProvider(name, provider); verify(handler, timeout(TIMEOUT)).accept(argThat(details -> { - return name.equals(details.getDomain()) - && errMessage.equals(details.getMessage()); + return name.equals(details.getDomain()) && errMessage.equals(details.getMessage()); })); } @Test @DisplayName("should fire initial ERROR event when provider init errors before client retrieved") - @Specification(number = "5.3.2", text = "If the provider's initialize function terminates abnormally, PROVIDER_ERROR handlers MUST run.") + @Specification( + number = "5.3.2", + text = + "If the provider's initialize function terminates abnormally, PROVIDER_ERROR handlers MUST run.") void initErrorProviderBefore() { final Consumer handler = mockHandler(); final String name = "initErrorProviderBefore"; @@ -249,8 +278,7 @@ void initErrorProviderBefore() { Client client = OpenFeatureAPI.getInstance().getClient(name); client.onProviderError(handler); verify(handler, timeout(TIMEOUT)).accept(argThat(details -> { - return name.equals(details.getDomain()) - && errMessage.equals(details.getMessage()); + return name.equals(details.getDomain()) && errMessage.equals(details.getMessage()); })); } } @@ -261,7 +289,10 @@ class ProviderEvents { @Test @DisplayName("should propagate events when provider set before client retrieved") - @Specification(number = "5.1.2", text = "When a provider signals the occurrence of a particular event, the associated client and API event handlers MUST run.") + @Specification( + number = "5.1.2", + text = + "When a provider signals the occurrence of a particular event, the associated client and API event handlers MUST run.") void shouldPropagateBefore() { final Consumer handler = mockHandler(); final String name = "shouldPropagateBefore"; @@ -272,13 +303,19 @@ void shouldPropagateBefore() { Client client = OpenFeatureAPI.getInstance().getClient(name); client.onProviderConfigurationChanged(handler); - provider.mockEvent(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, EventDetails.builder().build()); - verify(handler, timeout(TIMEOUT)).accept(argThat(details -> details.getDomain().equals(name))); + provider.mockEvent( + ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, + EventDetails.builder().build()); + verify(handler, timeout(TIMEOUT)) + .accept(argThat(details -> details.getDomain().equals(name))); } @Test @DisplayName("should propagate events when provider set after client retrieved") - @Specification(number = "5.1.2", text = "When a provider signals the occurrence of a particular event, the associated client and API event handlers MUST run.") + @Specification( + number = "5.1.2", + text = + "When a provider signals the occurrence of a particular event, the associated client and API event handlers MUST run.") void shouldPropagateAfter() { final Consumer handler = mockHandler(); @@ -290,18 +327,25 @@ void shouldPropagateAfter() { // set provider after getting a client OpenFeatureAPI.getInstance().setProviderAndWait(name, provider); - provider.mockEvent(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, EventDetails.builder().build()); - verify(handler, timeout(TIMEOUT)).accept(argThat(details -> details.getDomain().equals(name))); + provider.mockEvent( + ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, + EventDetails.builder().build()); + verify(handler, timeout(TIMEOUT)) + .accept(argThat(details -> details.getDomain().equals(name))); } @Test @DisplayName("should support all event types") - @Specification(number = "5.1.1", text = "The provider MAY define a mechanism for signaling the occurrence " - + "of one of a set of events, including PROVIDER_READY, PROVIDER_ERROR, " - + "PROVIDER_CONFIGURATION_CHANGED and PROVIDER_STALE, with a provider event details payload.") - @Specification(number = "5.2.1", text = "The client MUST provide a function for associating handler functions" - + - " with a particular provider event type.") + @Specification( + number = "5.1.1", + text = + "The provider MAY define a mechanism for signaling the occurrence " + + "of one of a set of events, including PROVIDER_READY, PROVIDER_ERROR, " + + "PROVIDER_CONFIGURATION_CHANGED and PROVIDER_STALE, with a provider event details payload.") + @Specification( + number = "5.2.1", + text = "The client MUST provide a function for associating handler functions" + + " with a particular provider event type.") void shouldSupportAllEventTypes() { final String name = "shouldSupportAllEventTypes"; final Consumer handler1 = mockHandler(); @@ -321,8 +365,8 @@ void shouldSupportAllEventTypes() { Arrays.asList(ProviderEvent.values()).stream().forEach(eventType -> { provider.mockEvent(eventType, ProviderEventDetails.builder().build()); }); - ArgumentMatcher nameMatches = (EventDetails details) -> details.getDomain() - .equals(name); + ArgumentMatcher nameMatches = + (EventDetails details) -> details.getDomain().equals(name); verify(handler1, timeout(TIMEOUT).atLeastOnce()).accept(argThat(nameMatches)); verify(handler2, timeout(TIMEOUT).atLeastOnce()).accept(argThat(nameMatches)); verify(handler3, timeout(TIMEOUT).atLeastOnce()).accept(argThat(nameMatches)); @@ -353,7 +397,9 @@ void shouldNotRunHandlers() { await().until(() -> provider1.isShutDown()); // fire old event - provider1.mockEvent(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, EventDetails.builder().build()); + provider1.mockEvent( + ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, + EventDetails.builder().build()); // a bit of waiting here, but we want to make sure these are indeed never // called. @@ -363,8 +409,10 @@ void shouldNotRunHandlers() { @Test @DisplayName("other client handlers should not run") - @Specification(number = "5.1.3", text = "When a provider signals the occurrence of a particular event, " + - "event handlers on clients which are not associated with that provider MUST NOT run.") + @Specification( + number = "5.1.3", + text = "When a provider signals the occurrence of a particular event, " + + "event handlers on clients which are not associated with that provider MUST NOT run.") void otherClientHandlersShouldNotRun() { final String name1 = "otherClientHandlersShouldNotRun1"; final String name2 = "otherClientHandlersShouldNotRun2"; @@ -382,7 +430,9 @@ void otherClientHandlersShouldNotRun() { client1.onProviderConfigurationChanged(handlerToRun); client2.onProviderConfigurationChanged(handlerNotToRun); - provider1.mockEvent(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, ProviderEventDetails.builder().build()); + provider1.mockEvent( + ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, + ProviderEventDetails.builder().build()); verify(handlerToRun, timeout(TIMEOUT)).accept(any()); verify(handlerNotToRun, never()).accept(any()); @@ -390,8 +440,10 @@ void otherClientHandlersShouldNotRun() { @Test @DisplayName("bound named client handlers should not run with default") - @Specification(number = "5.1.3", text = "When a provider signals the occurrence of a particular event, " + - "event handlers on clients which are not associated with that provider MUST NOT run.") + @Specification( + number = "5.1.3", + text = "When a provider signals the occurrence of a particular event, " + + "event handlers on clients which are not associated with that provider MUST NOT run.") void boundShouldNotRunWithDefault() { final String name = "boundShouldNotRunWithDefault"; final Consumer handlerNotToRun = mockHandler(); @@ -408,7 +460,9 @@ void boundShouldNotRunWithDefault() { await().until(() -> namedProvider.getState().equals(ProviderState.READY)); // fire event on default provider - defaultProvider.mockEvent(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, ProviderEventDetails.builder().build()); + defaultProvider.mockEvent( + ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, + ProviderEventDetails.builder().build()); verify(handlerNotToRun, after(TIMEOUT).never()).accept(any()); OpenFeatureAPI.getInstance().setProviderAndWait(new NoOpProvider()); @@ -416,8 +470,10 @@ void boundShouldNotRunWithDefault() { @Test @DisplayName("unbound named client handlers should run with default") - @Specification(number = "5.1.3", text = "When a provider signals the occurrence of a particular event, " + - "event handlers on clients which are not associated with that provider MUST NOT run.") + @Specification( + number = "5.1.3", + text = "When a provider signals the occurrence of a particular event, " + + "event handlers on clients which are not associated with that provider MUST NOT run.") void unboundShouldRunWithDefault() { final String name = "unboundShouldRunWithDefault"; final Consumer handlerToRun = mockHandler(); @@ -432,7 +488,9 @@ void unboundShouldRunWithDefault() { await().until(() -> defaultProvider.getState().equals(ProviderState.READY)); // fire event on default provider - defaultProvider.mockEvent(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, ProviderEventDetails.builder().build()); + defaultProvider.mockEvent( + ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, + ProviderEventDetails.builder().build()); verify(handlerToRun, timeout(TIMEOUT)).accept(any()); OpenFeatureAPI.getInstance().setProviderAndWait(new NoOpProvider()); @@ -440,7 +498,9 @@ void unboundShouldRunWithDefault() { @Test @DisplayName("subsequent handlers run if earlier throws") - @Specification(number = "5.2.5", text = "If a handler function terminates abnormally, other handler functions MUST run.") + @Specification( + number = "5.2.5", + text = "If a handler function terminates abnormally, other handler functions MUST run.") void handlersRunIfOneThrows() { final String name = "handlersRunIfOneThrows"; final Consumer errorHandler = mockHandler(); @@ -457,7 +517,9 @@ void handlersRunIfOneThrows() { client1.onProviderConfigurationChanged(nextHandler); client1.onProviderConfigurationChanged(lastHandler); - provider.mockEvent(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, ProviderEventDetails.builder().build()); + provider.mockEvent( + ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, + ProviderEventDetails.builder().build()); verify(errorHandler, timeout(TIMEOUT)).accept(any()); verify(nextHandler, timeout(TIMEOUT)).accept(any()); verify(lastHandler, timeout(TIMEOUT)).accept(any()); @@ -466,7 +528,9 @@ void handlersRunIfOneThrows() { @Test @DisplayName("should have all properties") @Specification(number = "5.2.4", text = "The handler function MUST accept a event details parameter.") - @Specification(number = "5.2.3", text = "The `event details` MUST contain the `provider name` associated with the event.") + @Specification( + number = "5.2.3", + text = "The `event details` MUST contain the `provider name` associated with the event.") void shouldHaveAllProperties() { final Consumer handler1 = mockHandler(); final Consumer handler2 = mockHandler(); @@ -481,7 +545,8 @@ void shouldHaveAllProperties() { client.onProviderConfigurationChanged(handler2); List flagsChanged = Arrays.asList("flag"); - ImmutableMetadata metadata = ImmutableMetadata.builder().addInteger("int", 1).build(); + ImmutableMetadata metadata = + ImmutableMetadata.builder().addInteger("int", 1).build(); String message = "a message"; ProviderEventDetails details = ProviderEventDetails.builder() .eventMetadata(metadata) @@ -492,25 +557,25 @@ void shouldHaveAllProperties() { provider.mockEvent(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, details); // both global and client handler should have all the fields. - verify(handler1, timeout(TIMEOUT)) - .accept(argThat((EventDetails eventDetails) -> { - return metadata.equals(eventDetails.getEventMetadata()) - // TODO: issue for client name in events - && flagsChanged.equals(eventDetails.getFlagsChanged()) - && message.equals(eventDetails.getMessage()); - })); - verify(handler2, timeout(TIMEOUT)) - .accept(argThat((EventDetails eventDetails) -> { - return metadata.equals(eventDetails.getEventMetadata()) - && flagsChanged.equals(eventDetails.getFlagsChanged()) - && message.equals(eventDetails.getMessage()) - && name.equals(eventDetails.getDomain()); - })); + verify(handler1, timeout(TIMEOUT)).accept(argThat((EventDetails eventDetails) -> { + return metadata.equals(eventDetails.getEventMetadata()) + // TODO: issue for client name in events + && flagsChanged.equals(eventDetails.getFlagsChanged()) + && message.equals(eventDetails.getMessage()); + })); + verify(handler2, timeout(TIMEOUT)).accept(argThat((EventDetails eventDetails) -> { + return metadata.equals(eventDetails.getEventMetadata()) + && flagsChanged.equals(eventDetails.getFlagsChanged()) + && message.equals(eventDetails.getMessage()) + && name.equals(eventDetails.getDomain()); + })); } @Test @DisplayName("if the provider is ready handlers must run immediately") - @Specification(number = "5.3.3", text = "Handlers attached after the provider is already in the associated state, MUST run immediately.") + @Specification( + number = "5.3.3", + text = "Handlers attached after the provider is already in the associated state, MUST run immediately.") void matchingReadyEventsMustRunImmediately() { final String name = "matchingEventsMustRunImmediately"; final Consumer handler = mockHandler(); @@ -527,7 +592,9 @@ void matchingReadyEventsMustRunImmediately() { @Test @DisplayName("if the provider is ready handlers must run immediately") - @Specification(number = "5.3.3", text = "Handlers attached after the provider is already in the associated state, MUST run immediately.") + @Specification( + number = "5.3.3", + text = "Handlers attached after the provider is already in the associated state, MUST run immediately.") void matchingStaleEventsMustRunImmediately() { final String name = "matchingEventsMustRunImmediately"; final Consumer handler = mockHandler(); @@ -547,7 +614,9 @@ void matchingStaleEventsMustRunImmediately() { @Test @DisplayName("if the provider is ready handlers must run immediately") - @Specification(number = "5.3.3", text = "Handlers attached after the provider is already in the associated state, MUST run immediately.") + @Specification( + number = "5.3.3", + text = "Handlers attached after the provider is already in the associated state, MUST run immediately.") void matchingErrorEventsMustRunImmediately() { final String name = "matchingEventsMustRunImmediately"; final Consumer handler = mockHandler(); @@ -560,7 +629,6 @@ void matchingErrorEventsMustRunImmediately() { provider.emitProviderError(ProviderEventDetails.builder().build()); assertThat(client.getProviderState()).isEqualTo(ProviderState.ERROR); - // should run even thought handler was added after error client.onProviderError(handler); verify(handler, timeout(TIMEOUT)).accept(any()); @@ -580,8 +648,11 @@ void mustPersistAcrossChanges() { Client client = OpenFeatureAPI.getInstance().getClient(name); client.onProviderConfigurationChanged(handler); - provider1.mockEvent(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, ProviderEventDetails.builder().build()); - ArgumentMatcher nameMatches = (EventDetails details) -> details.getDomain().equals(name); + provider1.mockEvent( + ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, + ProviderEventDetails.builder().build()); + ArgumentMatcher nameMatches = + (EventDetails details) -> details.getDomain().equals(name); verify(handler, timeout(TIMEOUT).times(1)).accept(argThat(nameMatches)); @@ -590,13 +661,17 @@ void mustPersistAcrossChanges() { // verify that with the new provider under the same name, the handler is called // again. - provider2.mockEvent(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, ProviderEventDetails.builder().build()); + provider2.mockEvent( + ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, + ProviderEventDetails.builder().build()); verify(handler, timeout(TIMEOUT).times(2)).accept(argThat(nameMatches)); } @Nested class HandlerRemoval { - @Specification(number = "5.2.7", text = "The API and client MUST provide a function allowing the removal of event handlers.") + @Specification( + number = "5.2.7", + text = "The API and client MUST provide a function allowing the removal of event handlers.") @Test @DisplayName("should not run removed events") @SneakyThrows @@ -617,18 +692,21 @@ void removedEventsShouldNotRun() { client.removeHandler(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, handler2); // emit event - provider.mockEvent(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, ProviderEventDetails.builder().build()); - + provider.mockEvent( + ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, + ProviderEventDetails.builder().build()); + // both global and client handlers should not run. verify(handler1, after(TIMEOUT).never()).accept(any()); verify(handler2, never()).accept(any()); } } - @Specification(number = "5.1.4", text = "PROVIDER_ERROR events SHOULD populate the provider event details's error message field.") + @Specification( + number = "5.1.4", + text = "PROVIDER_ERROR events SHOULD populate the provider event details's error message field.") @Test - void thisIsAProviderRequirement() { - } + void thisIsAProviderRequirement() {} @SuppressWarnings("unchecked") private static Consumer mockHandler() { diff --git a/src/test/java/dev/openfeature/sdk/FeatureProviderStateManagerTest.java b/src/test/java/dev/openfeature/sdk/FeatureProviderStateManagerTest.java index 9d05524f1..ff3f3a3f8 100644 --- a/src/test/java/dev/openfeature/sdk/FeatureProviderStateManagerTest.java +++ b/src/test/java/dev/openfeature/sdk/FeatureProviderStateManagerTest.java @@ -1,17 +1,16 @@ package dev.openfeature.sdk; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + import dev.openfeature.sdk.exceptions.FatalError; import dev.openfeature.sdk.exceptions.GeneralError; +import java.util.concurrent.atomic.AtomicInteger; +import javax.annotation.Nullable; import lombok.SneakyThrows; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import javax.annotation.Nullable; -import java.util.concurrent.atomic.AtomicInteger; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; - class FeatureProviderStateManagerTest { private FeatureProviderStateManager wrapper; @@ -48,7 +47,10 @@ void shouldSetStateToNotReadyAfterConstruction() { @SneakyThrows @Test - @Specification(number = "1.7.3", text = "The client's provider status accessor MUST indicate READY if the initialize function of the associated provider terminates normally.") + @Specification( + number = "1.7.3", + text = + "The client's provider status accessor MUST indicate READY if the initialize function of the associated provider terminates normally.") void shouldSetStateToReadyAfterInit() { assertThat(wrapper.getState()).isEqualTo(ProviderState.NOT_READY); wrapper.initialize(null); @@ -65,7 +67,10 @@ void shouldSetStateToNotReadyAfterShutdown() { assertThat(wrapper.getState()).isEqualTo(ProviderState.NOT_READY); } - @Specification(number = "1.7.4", text = "The client's provider status accessor MUST indicate ERROR if the initialize function of the associated provider terminates abnormally.") + @Specification( + number = "1.7.4", + text = + "The client's provider status accessor MUST indicate ERROR if the initialize function of the associated provider terminates abnormally.") @Test void shouldSetStateToErrorAfterErrorOnInit() { testDelegate.throwOnInit = new Exception(); @@ -74,7 +79,10 @@ void shouldSetStateToErrorAfterErrorOnInit() { assertThat(wrapper.getState()).isEqualTo(ProviderState.ERROR); } - @Specification(number = "1.7.4", text = "The client's provider status accessor MUST indicate ERROR if the initialize function of the associated provider terminates abnormally.") + @Specification( + number = "1.7.4", + text = + "The client's provider status accessor MUST indicate ERROR if the initialize function of the associated provider terminates abnormally.") @Test void shouldSetStateToErrorAfterOpenFeatureErrorOnInit() { testDelegate.throwOnInit = new GeneralError(); @@ -83,7 +91,10 @@ void shouldSetStateToErrorAfterOpenFeatureErrorOnInit() { assertThat(wrapper.getState()).isEqualTo(ProviderState.ERROR); } - @Specification(number = "1.7.5", text = "The client's provider status accessor MUST indicate FATAL if the initialize function of the associated provider terminates abnormally and indicates error code PROVIDER_FATAL.") + @Specification( + number = "1.7.5", + text = + "The client's provider status accessor MUST indicate FATAL if the initialize function of the associated provider terminates abnormally and indicates error code PROVIDER_FATAL.") @Test void shouldSetStateToErrorAfterFatalErrorOnInit() { testDelegate.throwOnInit = new FatalError(); @@ -92,7 +103,10 @@ void shouldSetStateToErrorAfterFatalErrorOnInit() { assertThat(wrapper.getState()).isEqualTo(ProviderState.FATAL); } - @Specification(number = "5.3.5", text = "If the provider emits an event, the value of the client's provider status MUST be updated accordingly.") + @Specification( + number = "5.3.5", + text = + "If the provider emits an event, the value of the client's provider status MUST be updated accordingly.") @Test void shouldSetTheStateToReadyWhenAReadyEventIsEmitted() { assertThat(wrapper.getState()).isEqualTo(ProviderState.NOT_READY); @@ -100,7 +114,10 @@ void shouldSetTheStateToReadyWhenAReadyEventIsEmitted() { assertThat(wrapper.getState()).isEqualTo(ProviderState.READY); } - @Specification(number = "5.3.5", text = "If the provider emits an event, the value of the client's provider status MUST be updated accordingly.") + @Specification( + number = "5.3.5", + text = + "If the provider emits an event, the value of the client's provider status MUST be updated accordingly.") @Test void shouldSetTheStateToStaleWhenAStaleEventIsEmitted() { assertThat(wrapper.getState()).isEqualTo(ProviderState.NOT_READY); @@ -108,25 +125,31 @@ void shouldSetTheStateToStaleWhenAStaleEventIsEmitted() { assertThat(wrapper.getState()).isEqualTo(ProviderState.STALE); } - @Specification(number = "5.3.5", text = "If the provider emits an event, the value of the client's provider status MUST be updated accordingly.") + @Specification( + number = "5.3.5", + text = + "If the provider emits an event, the value of the client's provider status MUST be updated accordingly.") @Test void shouldSetTheStateToErrorWhenAnErrorEventIsEmitted() { assertThat(wrapper.getState()).isEqualTo(ProviderState.NOT_READY); wrapper.onEmit( ProviderEvent.PROVIDER_ERROR, - ProviderEventDetails.builder().errorCode(ErrorCode.GENERAL).build() - ); + ProviderEventDetails.builder().errorCode(ErrorCode.GENERAL).build()); assertThat(wrapper.getState()).isEqualTo(ProviderState.ERROR); } - @Specification(number = "5.3.5", text = "If the provider emits an event, the value of the client's provider status MUST be updated accordingly.") + @Specification( + number = "5.3.5", + text = + "If the provider emits an event, the value of the client's provider status MUST be updated accordingly.") @Test void shouldSetTheStateToFatalWhenAFatalErrorEventIsEmitted() { assertThat(wrapper.getState()).isEqualTo(ProviderState.NOT_READY); wrapper.onEmit( ProviderEvent.PROVIDER_ERROR, - ProviderEventDetails.builder().errorCode(ErrorCode.PROVIDER_FATAL).build() - ); + ProviderEventDetails.builder() + .errorCode(ErrorCode.PROVIDER_FATAL) + .build()); assertThat(wrapper.getState()).isEqualTo(ProviderState.FATAL); } @@ -141,7 +164,8 @@ public Metadata getMetadata() { } @Override - public ProviderEvaluation getBooleanEvaluation(String key, Boolean defaultValue, EvaluationContext ctx) { + public ProviderEvaluation getBooleanEvaluation( + String key, Boolean defaultValue, EvaluationContext ctx) { return null; } @@ -151,7 +175,8 @@ public ProviderEvaluation getStringEvaluation(String key, String default } @Override - public ProviderEvaluation getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx) { + public ProviderEvaluation getIntegerEvaluation( + String key, Integer defaultValue, EvaluationContext ctx) { return null; } @@ -178,4 +203,4 @@ public void shutdown() { shutdownCalled.incrementAndGet(); } } -} \ No newline at end of file +} diff --git a/src/test/java/dev/openfeature/sdk/FlagEvaluationDetailsTest.java b/src/test/java/dev/openfeature/sdk/FlagEvaluationDetailsTest.java index dfa77274e..345a7effc 100644 --- a/src/test/java/dev/openfeature/sdk/FlagEvaluationDetailsTest.java +++ b/src/test/java/dev/openfeature/sdk/FlagEvaluationDetailsTest.java @@ -29,13 +29,7 @@ public void sevenArgConstructor() { ImmutableMetadata metadata = ImmutableMetadata.builder().build(); FlagEvaluationDetails details = new FlagEvaluationDetails<>( - flagKey, - value, - variant, - reason.toString(), - errorCode, - errorMessage, - metadata); + flagKey, value, variant, reason.toString(), errorCode, errorMessage, metadata); assertEquals(flagKey, details.getFlagKey()); assertEquals(value, details.getValue()); @@ -48,13 +42,14 @@ public void sevenArgConstructor() { @Test @DisplayName("should be able to compare 2 FlagEvaluationDetails") - public void compareFlagEvaluationDetails(){ + public void compareFlagEvaluationDetails() { FlagEvaluationDetails fed1 = FlagEvaluationDetails.builder() .reason(Reason.ERROR.toString()) .value(false) .errorCode(ErrorCode.GENERAL) .errorMessage("error XXX") - .flagMetadata(ImmutableMetadata.builder().addString("metadata","1").build()) + .flagMetadata( + ImmutableMetadata.builder().addString("metadata", "1").build()) .build(); FlagEvaluationDetails fed2 = FlagEvaluationDetails.builder() @@ -62,9 +57,10 @@ public void compareFlagEvaluationDetails(){ .value(false) .errorCode(ErrorCode.GENERAL) .errorMessage("error XXX") - .flagMetadata(ImmutableMetadata.builder().addString("metadata","1").build()) + .flagMetadata( + ImmutableMetadata.builder().addString("metadata", "1").build()) .build(); - assertEquals(fed1,fed2); + assertEquals(fed1, fed2); } } diff --git a/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java b/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java index a2316a59c..2ad88d328 100644 --- a/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java @@ -1,10 +1,20 @@ package dev.openfeature.sdk; +import static dev.openfeature.sdk.DoSomethingProvider.DEFAULT_METADATA; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.*; + import dev.openfeature.sdk.exceptions.GeneralError; import dev.openfeature.sdk.fixtures.HookFixtures; -import dev.openfeature.sdk.providers.memory.InMemoryProvider; import dev.openfeature.sdk.testutils.FeatureProviderTestUtils; import dev.openfeature.sdk.testutils.TestEventsProvider; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; import lombok.SneakyThrows; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -13,18 +23,6 @@ import org.simplify4u.slf4jmock.LoggerMock; import org.slf4j.Logger; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -import static dev.openfeature.sdk.DoSomethingProvider.DEFAULT_METADATA; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Mockito.*; - class FlagEvaluationSpecTest implements HookFixtures { private Logger logger; @@ -48,34 +46,49 @@ void getApiInstance() { api = OpenFeatureAPI.getInstance(); } - @AfterEach void reset_ctx() { + @AfterEach + void reset_ctx() { api.setEvaluationContext(null); } - @BeforeEach void set_logger() { + @BeforeEach + void set_logger() { logger = Mockito.mock(Logger.class); LoggerMock.setMock(OpenFeatureClient.class, logger); } - @AfterEach void reset_logs() { + @AfterEach + 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() { + @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="The API MUST define a provider mutator, a function to set the default provider, which accepts an API-conformant provider implementation.") - @Test void provider() { + @Specification( + number = "1.1.2.1", + text = + "The API MUST define a provider mutator, a function to set the default provider, which accepts an API-conformant provider implementation.") + @Test + void provider() { FeatureProvider mockProvider = mock(FeatureProvider.class); FeatureProviderTestUtils.setFeatureProvider(mockProvider); assertThat(api.getProvider()).isEqualTo(mockProvider); } @SneakyThrows - @Specification(number="1.1.8", text="The API SHOULD provide functions to set a provider and wait for the initialize function to return or throw.") - @Test void providerAndWait() { + @Specification( + number = "1.1.8", + text = + "The API SHOULD provide functions to set a provider and wait for the initialize function to return or throw.") + @Test + void providerAndWait() { FeatureProvider provider = new TestEventsProvider(500); OpenFeatureAPI.getInstance().setProviderAndWait(provider); Client client = api.getClient(); @@ -89,8 +102,12 @@ void getApiInstance() { } @SneakyThrows - @Specification(number="1.1.8", text="The API SHOULD provide functions to set a provider and wait for the initialize function to return or throw.") - @Test void providerAndWaitError() { + @Specification( + number = "1.1.8", + text = + "The API SHOULD provide functions to set a provider and wait for the initialize function to return or throw.") + @Test + void providerAndWaitError() { FeatureProvider provider1 = new TestEventsProvider(500, true, "fake error"); assertThrows(GeneralError.class, () -> api.setProviderAndWait(provider1)); @@ -99,8 +116,12 @@ void getApiInstance() { assertThrows(GeneralError.class, () -> api.setProviderAndWait(providerName, provider2)); } - @Specification(number="2.4.5", text="The provider SHOULD indicate an error if flag resolution is attempted before the provider is ready.") - @Test void shouldReturnNotReadyIfNotInitialized() { + @Specification( + number = "2.4.5", + text = + "The provider SHOULD indicate an error if flag resolution is attempted before the provider is ready.") + @Test + void shouldReturnNotReadyIfNotInitialized() { FeatureProvider provider = new TestEventsProvider(100); String providerName = "shouldReturnNotReadyIfNotInitialized"; OpenFeatureAPI.getInstance().setProvider(providerName, provider); @@ -110,14 +131,21 @@ void getApiInstance() { assertEquals(Reason.ERROR.toString(), details.getReason()); } - @Specification(number="1.1.5", text="The API MUST provide a function for retrieving the metadata field of the configured provider.") - @Test void provider_metadata() { + @Specification( + number = "1.1.5", + text = "The API MUST provide a function for retrieving the metadata field of the configured provider.") + @Test + void provider_metadata() { FeatureProviderTestUtils.setFeatureProvider(new DoSomethingProvider()); assertThat(api.getProviderMetadata().getName()).isEqualTo(DoSomethingProvider.name); } - @Specification(number="1.1.4", text="The API MUST provide a function to add hooks which accepts one or more API-conformant hooks, and appends them to the collection of any previously added hooks. When new hooks are added, previously added hooks are not removed.") - @Test void hook_addition() { + @Specification( + number = "1.1.4", + text = + "The API MUST provide a function to add hooks which accepts one or more API-conformant hooks, and appends them to the collection of any previously added hooks. When new hooks are added, previously added hooks are not removed.") + @Test + void hook_addition() { Hook h1 = mock(Hook.class); Hook h2 = mock(Hook.class); api.addHooks(h1); @@ -130,8 +158,12 @@ void getApiInstance() { assertEquals(h2, api.getHooks().get(1)); } - @Specification(number="1.1.6", text="The API MUST provide a function for creating a client which accepts the following options: - domain (optional): A logical string identifier for binding clients to provider.") - @Test void domainName() { + @Specification( + number = "1.1.6", + text = + "The API MUST provide a function for creating a client which accepts the following options: - domain (optional): A logical string identifier for binding clients to provider.") + @Test + void domainName() { assertNull(api.getClient().getMetadata().getDomain()); String domain = "Sir Calls-a-lot"; @@ -139,8 +171,12 @@ void getApiInstance() { assertEquals(domain, clientForDomain.getMetadata().getDomain()); } - @Specification(number="1.2.1", text="The client MUST provide a method to add hooks which accepts one or more API-conformant hooks, and appends them to the collection of any previously added hooks. When new hooks are added, previously added hooks are not removed.") - @Test void hookRegistration() { + @Specification( + number = "1.2.1", + text = + "The client MUST provide a method to add hooks which accepts one or more API-conformant hooks, and appends them to the collection of any previously added hooks. When new hooks are added, previously added hooks are not removed.") + @Test + void hookRegistration() { Client c = _client(); Hook m1 = mock(Hook.class); Hook m2 = mock(Hook.class); @@ -152,9 +188,16 @@ void getApiInstance() { assertTrue(hooks.contains(m2)); } - @Specification(number="1.3.1.1", text="The client MUST provide methods for typed flag evaluation, including boolean, numeric, string, and structure, with parameters flag key (string, required), default value (boolean | number | string | structure, required), evaluation context (optional), and evaluation options (optional), which returns the flag value.") - @Specification(number="1.3.3.1", text="The client SHOULD provide functions for floating-point numbers and integers, consistent with language idioms.") - @Test void value_flags() { + @Specification( + number = "1.3.1.1", + text = + "The client MUST provide methods for typed flag evaluation, including boolean, numeric, string, and structure, with parameters flag key (string, required), default value (boolean | number | string | structure, required), evaluation context (optional), and evaluation options (optional), which returns the flag value.") + @Specification( + number = "1.3.3.1", + text = + "The client SHOULD provide functions for floating-point numbers and integers, consistent with language idioms.") + @Test + void value_flags() { FeatureProviderTestUtils.setFeatureProvider(new DoSomethingProvider()); Client c = api.getClient(); @@ -162,32 +205,80 @@ void getApiInstance() { assertEquals(true, c.getBooleanValue(key, false)); assertEquals(true, c.getBooleanValue(key, false, new ImmutableContext())); - assertEquals(true, c.getBooleanValue(key, false, new ImmutableContext(), FlagEvaluationOptions.builder().build())); + assertEquals( + true, + c.getBooleanValue( + key, + false, + new ImmutableContext(), + FlagEvaluationOptions.builder().build())); assertEquals("gnirts-ym", c.getStringValue(key, "my-string")); assertEquals("gnirts-ym", c.getStringValue(key, "my-string", new ImmutableContext())); - assertEquals("gnirts-ym", c.getStringValue(key, "my-string", new ImmutableContext(), FlagEvaluationOptions.builder().build())); + assertEquals( + "gnirts-ym", + c.getStringValue( + key, + "my-string", + new ImmutableContext(), + FlagEvaluationOptions.builder().build())); assertEquals(400, c.getIntegerValue(key, 4)); assertEquals(400, c.getIntegerValue(key, 4, new ImmutableContext())); - assertEquals(400, c.getIntegerValue(key, 4, new ImmutableContext(), FlagEvaluationOptions.builder().build())); + assertEquals( + 400, + c.getIntegerValue( + key, + 4, + new ImmutableContext(), + FlagEvaluationOptions.builder().build())); assertEquals(40.0, c.getDoubleValue(key, .4)); assertEquals(40.0, c.getDoubleValue(key, .4, new ImmutableContext())); - assertEquals(40.0, c.getDoubleValue(key, .4, new ImmutableContext(), FlagEvaluationOptions.builder().build())); + assertEquals( + 40.0, + c.getDoubleValue( + key, + .4, + new ImmutableContext(), + FlagEvaluationOptions.builder().build())); assertEquals(null, c.getObjectValue(key, new Value())); assertEquals(null, c.getObjectValue(key, new Value(), new ImmutableContext())); - assertEquals(null, c.getObjectValue(key, new Value(), new ImmutableContext(), FlagEvaluationOptions.builder().build())); + assertEquals( + null, + c.getObjectValue( + key, + new Value(), + new ImmutableContext(), + FlagEvaluationOptions.builder().build())); } - @Specification(number="1.4.1.1", text="The client MUST provide methods for detailed flag value evaluation with parameters flag key (string, required), default value (boolean | number | string | structure, required), evaluation context (optional), and evaluation options (optional), which returns an evaluation details structure.") - @Specification(number="1.4.3", text="The evaluation details structure's value field MUST contain the evaluated flag value.") - @Specification(number="1.4.4.1", text="The evaluation details structure SHOULD accept a generic argument (or use an equivalent language feature) which indicates the type of the wrapped value field.") - @Specification(number="1.4.5", text="The evaluation details structure's flag key field MUST contain the flag key argument passed to the detailed flag evaluation method.") - @Specification(number="1.4.6", text="In cases of normal execution, the evaluation details structure's variant field MUST contain the value of the variant field in the flag resolution structure returned by the configured provider, if the field is set.") - @Specification(number="1.4.7", text="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() { + @Specification( + number = "1.4.1.1", + text = + "The client MUST provide methods for detailed flag value evaluation with parameters flag key (string, required), default value (boolean | number | string | structure, required), evaluation context (optional), and evaluation options (optional), which returns an evaluation details structure.") + @Specification( + number = "1.4.3", + text = "The evaluation details structure's value field MUST contain the evaluated flag value.") + @Specification( + number = "1.4.4.1", + text = + "The evaluation details structure SHOULD accept a generic argument (or use an equivalent language feature) which indicates the type of the wrapped value field.") + @Specification( + number = "1.4.5", + text = + "The evaluation details structure's flag key field MUST contain the flag key argument passed to the detailed flag evaluation method.") + @Specification( + number = "1.4.6", + text = + "In cases of normal execution, the evaluation details structure's variant field MUST contain the value of the variant field in the flag resolution structure returned by the configured provider, if the field is set.") + @Specification( + number = "1.4.7", + text = + "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()); Client c = api.getClient(); String key = "key"; @@ -200,7 +291,13 @@ void getApiInstance() { .build(); assertEquals(bd, c.getBooleanDetails(key, true)); assertEquals(bd, c.getBooleanDetails(key, true, new ImmutableContext())); - assertEquals(bd, c.getBooleanDetails(key, true, new ImmutableContext(), FlagEvaluationOptions.builder().build())); + assertEquals( + bd, + c.getBooleanDetails( + key, + true, + new ImmutableContext(), + FlagEvaluationOptions.builder().build())); FlagEvaluationDetails sd = FlagEvaluationDetails.builder() .flagKey(key) @@ -210,7 +307,13 @@ void getApiInstance() { .build(); assertEquals(sd, c.getStringDetails(key, "test")); assertEquals(sd, c.getStringDetails(key, "test", new ImmutableContext())); - assertEquals(sd, c.getStringDetails(key, "test", new ImmutableContext(), FlagEvaluationOptions.builder().build())); + assertEquals( + sd, + c.getStringDetails( + key, + "test", + new ImmutableContext(), + FlagEvaluationOptions.builder().build())); FlagEvaluationDetails id = FlagEvaluationDetails.builder() .flagKey(key) @@ -219,7 +322,13 @@ void getApiInstance() { .build(); assertEquals(id, c.getIntegerDetails(key, 4)); assertEquals(id, c.getIntegerDetails(key, 4, new ImmutableContext())); - assertEquals(id, c.getIntegerDetails(key, 4, new ImmutableContext(), FlagEvaluationOptions.builder().build())); + assertEquals( + id, + c.getIntegerDetails( + key, + 4, + new ImmutableContext(), + FlagEvaluationOptions.builder().build())); FlagEvaluationDetails dd = FlagEvaluationDetails.builder() .flagKey(key) @@ -228,30 +337,55 @@ void getApiInstance() { .build(); assertEquals(dd, c.getDoubleDetails(key, .4)); assertEquals(dd, c.getDoubleDetails(key, .4, new ImmutableContext())); - assertEquals(dd, c.getDoubleDetails(key, .4, new ImmutableContext(), FlagEvaluationOptions.builder().build())); + assertEquals( + dd, + c.getDoubleDetails( + key, + .4, + new ImmutableContext(), + FlagEvaluationOptions.builder().build())); // TODO: Structure detail tests. } - @Specification(number="1.5.1", text="The evaluation options structure's hooks field denotes an ordered collection of hooks that the client MUST execute for the respective flag evaluation, in addition to those already configured.") + @Specification( + number = "1.5.1", + text = + "The evaluation options structure's hooks field denotes an ordered collection of hooks that the client MUST execute for the respective flag evaluation, in addition to those already configured.") @SneakyThrows - @Test void hooks() { + @Test + void hooks() { Client c = _initializedClient(); Hook clientHook = mockBooleanHook(); Hook invocationHook = mockBooleanHook(); c.addHooks(clientHook); - c.getBooleanValue("key", false, null, FlagEvaluationOptions.builder() - .hook(invocationHook) - .build()); + c.getBooleanValue( + "key", + false, + null, + FlagEvaluationOptions.builder().hook(invocationHook).build()); verify(clientHook, times(1)).before(any(), any()); verify(invocationHook, times(1)).before(any(), any()); } - @Specification(number="1.4.8", text="In cases of abnormal execution, the `evaluation details` structure's `error code` field **MUST** contain an `error code`.") - @Specification(number="1.4.9", text="In cases of abnormal execution (network failure, unhandled error, etc) the `reason` field in the `evaluation details` SHOULD indicate an error.") - @Specification(number="1.4.10", text="Methods, functions, or operations on the client MUST NOT throw exceptions, or otherwise abnormally terminate. Flag evaluation calls must always return the `default value` in the event of abnormal execution. Exceptions include functions or methods for the purposes for configuration or setup.") - @Specification(number="1.4.13", 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() { + @Specification( + number = "1.4.8", + text = + "In cases of abnormal execution, the `evaluation details` structure's `error code` field **MUST** contain an `error code`.") + @Specification( + number = "1.4.9", + text = + "In cases of abnormal execution (network failure, unhandled error, etc) the `reason` field in the `evaluation details` SHOULD indicate an error.") + @Specification( + number = "1.4.10", + text = + "Methods, functions, or operations on the client MUST NOT throw exceptions, or otherwise abnormally terminate. Flag evaluation calls must always return the `default value` in the event of abnormal execution. Exceptions include functions or methods for the purposes for configuration or setup.") + @Specification( + number = "1.4.13", + 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() { FeatureProviderTestUtils.setFeatureProvider(new AlwaysBrokenProvider()); Client c = api.getClient(); boolean defaultValue = false; @@ -263,11 +397,24 @@ void getApiInstance() { assertEquals(defaultValue, details.getValue()); } - @Specification(number="1.4.8", text="In cases of abnormal execution, the `evaluation details` structure's `error code` field **MUST** contain an `error code`.") - @Specification(number="1.4.9", text="In cases of abnormal execution (network failure, unhandled error, etc) the `reason` field in the `evaluation details` SHOULD indicate an error.") - @Specification(number="1.4.10", text="Methods, functions, or operations on the client MUST NOT throw exceptions, or otherwise abnormally terminate. Flag evaluation calls must always return the `default value` in the event of abnormal execution. Exceptions include functions or methods for the purposes for configuration or setup.") - @Specification(number="1.4.13", 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() { + @Specification( + number = "1.4.8", + text = + "In cases of abnormal execution, the `evaluation details` structure's `error code` field **MUST** contain an `error code`.") + @Specification( + number = "1.4.9", + text = + "In cases of abnormal execution (network failure, unhandled error, etc) the `reason` field in the `evaluation details` SHOULD indicate an error.") + @Specification( + number = "1.4.10", + text = + "Methods, functions, or operations on the client MUST NOT throw exceptions, or otherwise abnormally terminate. Flag evaluation calls must always return the `default value` in the event of abnormal execution. Exceptions include functions or methods for the purposes for configuration or setup.") + @Specification( + number = "1.4.13", + 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()); Client c = api.getClient(); boolean defaultValue = false; @@ -279,21 +426,25 @@ void getApiInstance() { assertEquals(defaultValue, details.getValue()); } - @Specification(number="1.4.11", text="Methods, functions, or operations on the client SHOULD NOT write log messages.") - @Test void log_on_error() throws NotImplementedException { + @Specification( + number = "1.4.11", + text = "Methods, functions, or operations on the client SHOULD NOT write log messages.") + @Test + void log_on_error() throws NotImplementedException { FeatureProviderTestUtils.setFeatureProvider(new AlwaysBrokenProvider()); Client c = api.getClient(); FlagEvaluationDetails result = c.getBooleanDetails("test", false); assertEquals(Reason.ERROR.toString(), result.getReason()); - Mockito.verify(logger, never()).error( - any(String.class), - any(), - any()); + Mockito.verify(logger, never()).error(any(String.class), any(), any()); } - @Specification(number="1.2.2", text="The client interface MUST define a metadata member or accessor, containing an immutable domain field or accessor of type string, which corresponds to the domain value supplied during client creation. In previous drafts, this property was called name. For backwards compatibility, implementations should consider name an alias to domain.") - @Test void clientMetadata() { + @Specification( + number = "1.2.2", + text = + "The client interface MUST define a metadata member or accessor, containing an immutable domain field or accessor of type string, which corresponds to the domain value supplied during client creation. In previous drafts, this property was called name. For backwards compatibility, implementations should consider name an alias to domain.") + @Test + void clientMetadata() { Client c = _client(); assertNull(c.getMetadata().getName()); assertNull(c.getMetadata().getDomain()); @@ -306,27 +457,36 @@ void getApiInstance() { assertEquals(domainName, c2.getMetadata().getDomain()); } - @Specification(number="1.4.9", text="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() { + @Specification( + number = "1.4.9", + text = + "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()); Client c = api.getClient(); FlagEvaluationDetails result = c.getBooleanDetails("test", false); assertEquals(Reason.ERROR.toString(), result.getReason()); } - @Specification(number="1.4.14", text="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() { + @Specification( + number = "1.4.14", + text = + "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)); Client c = api.getClient(); FlagEvaluationDetails result = c.getBooleanDetails("test", false); assertNotNull(result.getFlagMetadata()); } - @Specification(number="3.2.2.1", text="The API MUST have a method for setting the global evaluation context.") - @Test void api_context() { + @Specification(number = "3.2.2.1", text = "The API MUST have a method for setting the global evaluation context.") + @Test + void api_context() { String contextKey = "some-key"; String contextValue = "some-value"; - DoSomethingProvider provider = spy( new DoSomethingProvider()); + DoSomethingProvider provider = spy(new DoSomethingProvider()); FeatureProviderTestUtils.setFeatureProvider(provider); Map attributes = new HashMap<>(); @@ -339,12 +499,20 @@ void getApiInstance() { client.getBooleanValue("any-flag", false); // assert that the value from the global context was passed to the provider - verify(provider).getBooleanEvaluation(any(), any(), argThat((arg) -> arg.getValue(contextKey).asString().equals(contextValue))); + verify(provider).getBooleanEvaluation(any(), any(), argThat((arg) -> arg.getValue(contextKey) + .asString() + .equals(contextValue))); } - @Specification(number="3.2.1.1", text="The API, Client and invocation MUST have a method for supplying evaluation context.") - @Specification(number="3.2.3", text="Evaluation context MUST be merged in the order: API (global; lowest precedence) -> transaction -> client -> invocation -> before hooks (highest precedence), with duplicate values being overwritten.") - @Test void multi_layer_context_merges_correctly() { + @Specification( + number = "3.2.1.1", + text = "The API, Client and invocation MUST have a method for supplying evaluation context.") + @Specification( + number = "3.2.3", + text = + "Evaluation context MUST be merged in the order: API (global; lowest precedence) -> transaction -> client -> invocation -> before hooks (highest precedence), with duplicate values being overwritten.") + @Test + void multi_layer_context_merges_correctly() { DoSomethingProvider provider = spy(new DoSomethingProvider()); FeatureProviderTestUtils.setFeatureProvider(provider); TransactionContextPropagator transactionContextPropagator = new ThreadLocalTransactionContextPropagator(); @@ -357,8 +525,10 @@ public Optional before(HookContext ctx, Map ctx, FlagEvaluationDetails details, Map hints) { + public void after( + HookContext ctx, FlagEvaluationDetails details, Map hints) { Hook.super.after(ctx, details, hints); } }); @@ -404,59 +574,133 @@ public void after(HookContext ctx, FlagEvaluationDetails detai invocationAttributes.put("invocation", new Value("4")); EvaluationContext invocationCtx = new ImmutableContext(invocationAttributes); - c.getBooleanValue("key", false, invocationCtx, FlagEvaluationOptions.builder().hook(hook).build()); + c.getBooleanValue( + "key", + false, + invocationCtx, + FlagEvaluationOptions.builder().hook(hook).build()); // assert the correct overrides in before hook - verify(hook).before(argThat((arg) -> { - EvaluationContext evaluationContext = arg.getCtx(); - return evaluationContext.getValue("api").asString().equals("1") && - evaluationContext.getValue("transaction").asString().equals("2") && - evaluationContext.getValue("client").asString().equals("3") && - evaluationContext.getValue("invocation").asString().equals("4") && - evaluationContext.getValue("common1").asString().equals("2") && - evaluationContext.getValue("common2").asString().equals("3") && - evaluationContext.getValue("common3").asString().equals("4") && - evaluationContext.getValue("common4").asString().equals("3") && - evaluationContext.getValue("common5").asString().equals("4") && - evaluationContext.getValue("common6").asString().equals("4"); - }), any()); + verify(hook) + .before( + argThat((arg) -> { + EvaluationContext evaluationContext = arg.getCtx(); + return evaluationContext.getValue("api").asString().equals("1") + && evaluationContext + .getValue("transaction") + .asString() + .equals("2") + && evaluationContext + .getValue("client") + .asString() + .equals("3") + && evaluationContext + .getValue("invocation") + .asString() + .equals("4") + && evaluationContext + .getValue("common1") + .asString() + .equals("2") + && evaluationContext + .getValue("common2") + .asString() + .equals("3") + && evaluationContext + .getValue("common3") + .asString() + .equals("4") + && evaluationContext + .getValue("common4") + .asString() + .equals("3") + && evaluationContext + .getValue("common5") + .asString() + .equals("4") + && evaluationContext + .getValue("common6") + .asString() + .equals("4"); + }), + any()); // assert the correct overrides in evaluation verify(provider).getBooleanEvaluation(any(), any(), argThat((arg) -> { - return arg.getValue("api").asString().equals("1") && - arg.getValue("transaction").asString().equals("2") && - arg.getValue("client").asString().equals("3") && - arg.getValue("invocation").asString().equals("4") && - arg.getValue("before").asString().equals("5") && - arg.getValue("common1").asString().equals("2") && - arg.getValue("common2").asString().equals("3") && - arg.getValue("common3").asString().equals("4") && - arg.getValue("common4").asString().equals("3") && - arg.getValue("common5").asString().equals("4") && - arg.getValue("common6").asString().equals("4") && - arg.getValue("common7").asString().equals("5"); + return arg.getValue("api").asString().equals("1") + && arg.getValue("transaction").asString().equals("2") + && arg.getValue("client").asString().equals("3") + && arg.getValue("invocation").asString().equals("4") + && arg.getValue("before").asString().equals("5") + && arg.getValue("common1").asString().equals("2") + && arg.getValue("common2").asString().equals("3") + && arg.getValue("common3").asString().equals("4") + && arg.getValue("common4").asString().equals("3") + && arg.getValue("common5").asString().equals("4") + && arg.getValue("common6").asString().equals("4") + && arg.getValue("common7").asString().equals("5"); })); // assert the correct overrides in after hook - verify(hook).after(argThat((arg) -> { - EvaluationContext evaluationContext = arg.getCtx(); - return evaluationContext.getValue("api").asString().equals("1") && - evaluationContext.getValue("transaction").asString().equals("2") && - evaluationContext.getValue("client").asString().equals("3") && - evaluationContext.getValue("invocation").asString().equals("4") && - evaluationContext.getValue("before").asString().equals("5") && - evaluationContext.getValue("common1").asString().equals("2") && - evaluationContext.getValue("common2").asString().equals("3") && - evaluationContext.getValue("common3").asString().equals("4") && - evaluationContext.getValue("common4").asString().equals("3") && - evaluationContext.getValue("common5").asString().equals("4") && - evaluationContext.getValue("common6").asString().equals("4") && - evaluationContext.getValue("common7").asString().equals("5"); - }), any(), any()); + verify(hook) + .after( + argThat((arg) -> { + EvaluationContext evaluationContext = arg.getCtx(); + return evaluationContext.getValue("api").asString().equals("1") + && evaluationContext + .getValue("transaction") + .asString() + .equals("2") + && evaluationContext + .getValue("client") + .asString() + .equals("3") + && evaluationContext + .getValue("invocation") + .asString() + .equals("4") + && evaluationContext + .getValue("before") + .asString() + .equals("5") + && evaluationContext + .getValue("common1") + .asString() + .equals("2") + && evaluationContext + .getValue("common2") + .asString() + .equals("3") + && evaluationContext + .getValue("common3") + .asString() + .equals("4") + && evaluationContext + .getValue("common4") + .asString() + .equals("3") + && evaluationContext + .getValue("common5") + .asString() + .equals("4") + && evaluationContext + .getValue("common6") + .asString() + .equals("4") + && evaluationContext + .getValue("common7") + .asString() + .equals("5"); + }), + any(), + any()); } - @Specification(number="3.3.1.1", text="The API SHOULD have a method for setting a transaction context propagator.") - @Test void setting_transaction_context_propagator() { + @Specification( + number = "3.3.1.1", + text = "The API SHOULD have a method for setting a transaction context propagator.") + @Test + void setting_transaction_context_propagator() { DoSomethingProvider provider = new DoSomethingProvider(); FeatureProviderTestUtils.setFeatureProvider(provider); @@ -465,8 +709,12 @@ public void after(HookContext ctx, FlagEvaluationDetails detai assertEquals(transactionContextPropagator, api.getTransactionContextPropagator()); } - @Specification(number="3.3.1.2.1", text="The API MUST have a method for setting the evaluation context of the transaction context propagator for the current transaction.") - @Test void setting_transaction_context() { + @Specification( + number = "3.3.1.2.1", + text = + "The API MUST have a method for setting the evaluation context of the transaction context propagator for the current transaction.") + @Test + void setting_transaction_context() { DoSomethingProvider provider = new DoSomethingProvider(); FeatureProviderTestUtils.setFeatureProvider(provider); @@ -481,9 +729,16 @@ public void after(HookContext ctx, FlagEvaluationDetails detai assertEquals(transactionContext, transactionContextPropagator.getTransactionContext()); } - @Specification(number="3.3.1.2.2", text="A transaction context propagator MUST have a method for setting the evaluation context of the current transaction.") - @Specification(number="3.3.1.2.3", text="A transaction context propagator MUST have a method for getting the evaluation context of the current transaction.") - @Test void transaction_context_propagator_setting_context() { + @Specification( + number = "3.3.1.2.2", + text = + "A transaction context propagator MUST have a method for setting the evaluation context of the current transaction.") + @Specification( + number = "3.3.1.2.3", + text = + "A transaction context propagator MUST have a method for getting the evaluation context of the current transaction.") + @Test + void transaction_context_propagator_setting_context() { TransactionContextPropagator transactionContextPropagator = new ThreadLocalTransactionContextPropagator(); Map attributes = new HashMap<>(); @@ -494,23 +749,46 @@ public void after(HookContext ctx, FlagEvaluationDetails detai assertEquals(transactionContext, transactionContextPropagator.getTransactionContext()); } - @Specification(number="1.3.4", text="The client SHOULD guarantee the returned value of any typed flag evaluation method is of the expected type. If the value returned by the underlying provider implementation does not match the expected type, it's to be considered abnormal execution, and the supplied default value should be returned.") - @Test void type_system_prevents_this() {} - - @Specification(number="1.1.7", text="The client creation function MUST NOT throw, or otherwise abnormally terminate.") - @Test void constructor_does_not_throw() {} - - @Specification(number="1.4.12", text="The client SHOULD provide asynchronous or non-blocking mechanisms for flag evaluation.") - @Test void one_thread_per_request_model() {} - - @Specification(number="1.4.14.1", text="Condition: Flag metadata MUST be immutable.") - @Test void compiler_enforced() {} - - @Specification(number="1.4.2.1", text="The client MUST provide methods for detailed flag value evaluation with parameters flag key (string, required), default value (boolean | number | string | structure, required), and evaluation options (optional), which returns an evaluation details structure.") - @Specification(number="1.3.2.1", text="The client MUST provide methods for typed flag evaluation, including boolean, numeric, string, and structure, with parameters flag key (string, required), default value (boolean | number | string | structure, required), and evaluation options (optional), which returns the flag value.") - @Specification(number="3.2.2.2", text="The Client and invocation MUST NOT have a method for supplying evaluation context.") - @Specification(number="3.2.4.1", text="When the global evaluation context is set, the on context changed handler MUST run.") - @Specification(number="3.3.2.1", text="The API MUST NOT have a method for setting a transaction context propagator.") - @Test void not_applicable_for_dynamic_context() {} - + @Specification( + number = "1.3.4", + text = + "The client SHOULD guarantee the returned value of any typed flag evaluation method is of the expected type. If the value returned by the underlying provider implementation does not match the expected type, it's to be considered abnormal execution, and the supplied default value should be returned.") + @Test + void type_system_prevents_this() {} + + @Specification( + number = "1.1.7", + text = "The client creation function MUST NOT throw, or otherwise abnormally terminate.") + @Test + void constructor_does_not_throw() {} + + @Specification( + number = "1.4.12", + text = "The client SHOULD provide asynchronous or non-blocking mechanisms for flag evaluation.") + @Test + void one_thread_per_request_model() {} + + @Specification(number = "1.4.14.1", text = "Condition: Flag metadata MUST be immutable.") + @Test + void compiler_enforced() {} + + @Specification( + number = "1.4.2.1", + text = + "The client MUST provide methods for detailed flag value evaluation with parameters flag key (string, required), default value (boolean | number | string | structure, required), and evaluation options (optional), which returns an evaluation details structure.") + @Specification( + number = "1.3.2.1", + text = + "The client MUST provide methods for typed flag evaluation, including boolean, numeric, string, and structure, with parameters flag key (string, required), default value (boolean | number | string | structure, required), and evaluation options (optional), which returns the flag value.") + @Specification( + number = "3.2.2.2", + text = "The Client and invocation MUST NOT have a method for supplying evaluation context.") + @Specification( + number = "3.2.4.1", + text = "When the global evaluation context is set, the on context changed handler MUST run.") + @Specification( + number = "3.3.2.1", + text = "The API MUST NOT have a method for setting a transaction context propagator.") + @Test + void not_applicable_for_dynamic_context() {} } diff --git a/src/test/java/dev/openfeature/sdk/FlagMetadataTest.java b/src/test/java/dev/openfeature/sdk/FlagMetadataTest.java index c300daa05..f8b9ba58e 100644 --- a/src/test/java/dev/openfeature/sdk/FlagMetadataTest.java +++ b/src/test/java/dev/openfeature/sdk/FlagMetadataTest.java @@ -1,10 +1,10 @@ package dev.openfeature.sdk; +import static org.assertj.core.api.Assertions.assertThat; + import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import static org.assertj.core.api.Assertions.assertThat; - class FlagMetadataTest { @Test @@ -44,9 +44,8 @@ public void builder_validation() { @DisplayName("Value type mismatch returns a null") public void value_type_validation() { // given - ImmutableMetadata flagMetadata = ImmutableMetadata.builder() - .addString("string", "string") - .build(); + ImmutableMetadata flagMetadata = + ImmutableMetadata.builder().addString("string", "string").build(); // then assertThat(flagMetadata.getBoolean("string")).isNull(); diff --git a/src/test/java/dev/openfeature/sdk/HookContextTest.java b/src/test/java/dev/openfeature/sdk/HookContextTest.java index 50cc66177..2196b8b1f 100644 --- a/src/test/java/dev/openfeature/sdk/HookContextTest.java +++ b/src/test/java/dev/openfeature/sdk/HookContextTest.java @@ -1,30 +1,32 @@ package dev.openfeature.sdk; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; +import org.junit.jupiter.api.Test; + class HookContextTest { - @Specification(number="4.2.2.2", text="Condition: The client metadata field in the hook context MUST be immutable.") - @Specification(number="4.2.2.3", text="Condition: The provider metadata field in the hook context MUST be immutable.") - @Test void metadata_field_is_type_metadata() { + @Specification( + number = "4.2.2.2", + text = "Condition: The client metadata field in the hook context MUST be immutable.") + @Specification( + number = "4.2.2.3", + text = "Condition: The provider metadata field in the hook context MUST be immutable.") + @Test + void metadata_field_is_type_metadata() { ClientMetadata clientMetadata = mock(ClientMetadata.class); Metadata meta = mock(Metadata.class); - HookContext hc = HookContext.from( - "key", - FlagValueType.BOOLEAN, - clientMetadata, - meta, - new ImmutableContext(), - false - ); + HookContext hc = + HookContext.from("key", FlagValueType.BOOLEAN, clientMetadata, meta, new ImmutableContext(), false); assertTrue(ClientMetadata.class.isAssignableFrom(hc.getClientMetadata().getClass())); assertTrue(Metadata.class.isAssignableFrom(hc.getProviderMetadata().getClass())); } - @Specification(number="4.3.3.1", text="The before stage MUST run before flag resolution occurs. It accepts a hook context (required) and hook hints (optional) as parameters. It has no return value.") - @Test void not_applicable_for_dynamic_context() {} - -} \ No newline at end of file + @Specification( + number = "4.3.3.1", + text = + "The before stage MUST run before flag resolution occurs. It accepts a hook context (required) and hook hints (optional) as parameters. It has no return value.") + @Test + void not_applicable_for_dynamic_context() {} +} diff --git a/src/test/java/dev/openfeature/sdk/HookSpecTest.java b/src/test/java/dev/openfeature/sdk/HookSpecTest.java index 4609c8d51..4a141c611 100644 --- a/src/test/java/dev/openfeature/sdk/HookSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSpecTest.java @@ -1,23 +1,28 @@ package dev.openfeature.sdk; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + 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; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; import lombok.SneakyThrows; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.mockito.InOrder; -import java.util.*; - -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.fail; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - class HookSpecTest implements HookFixtures { @AfterEach void emptyApiHooks() { @@ -25,7 +30,10 @@ void emptyApiHooks() { OpenFeatureAPI.getInstance().clearHooks(); } - @Specification(number = "4.1.3", text = "The flag key, flag type, and default value properties MUST be immutable. If the language does not support immutability, the hook MUST NOT modify these properties.") + @Specification( + number = "4.1.3", + text = + "The flag key, flag type, and default value properties MUST be immutable. If the language does not support immutability, the hook MUST NOT modify these properties.") @Test void immutableValues() { try { @@ -50,7 +58,10 @@ void immutableValues() { } } - @Specification(number = "4.1.1", text = "Hook context MUST provide: the flag key, flag value type, evaluation context, and the default value.") + @Specification( + number = "4.1.1", + text = + "Hook context MUST provide: the flag key, flag value type, evaluation context, and the default value.") @Test void nullish_properties_on_hookcontext() { // missing ctx @@ -112,10 +123,11 @@ void nullish_properties_on_hookcontext() { } catch (NullPointerException e) { fail("NPE after we provided all relevant info"); } - } - @Specification(number = "4.1.2", text = "The hook context SHOULD provide: access to the client metadata and the provider metadata fields.") + @Specification( + number = "4.1.2", + text = "The hook context SHOULD provide: access to the client metadata and the provider metadata fields.") @Test void optional_properties() { // don't specify @@ -145,7 +157,10 @@ void optional_properties() { .build(); } - @Specification(number = "4.3.2.1", text = "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.") + @Specification( + number = "4.3.2.1", + text = + "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(); @@ -153,7 +168,10 @@ void before_runs_ahead_of_evaluation() { Client client = api.getClient(); Hook evalHook = mockBooleanHook(); - client.getBooleanValue("key", false, new ImmutableContext(), + client.getBooleanValue( + "key", + false, + new ImmutableContext(), FlagEvaluationOptions.builder().hook(evalHook).build()); verify(evalHook, times(1)).before(any(), any()); @@ -161,8 +179,7 @@ void before_runs_ahead_of_evaluation() { @Test void feo_has_hook_list() { - FlagEvaluationOptions feo = FlagEvaluationOptions.builder() - .build(); + FlagEvaluationOptions feo = FlagEvaluationOptions.builder().build(); assertNotNull(feo.getHooks()); } @@ -175,7 +192,6 @@ void error_hook_run_during_non_finally_stage() { verify(h, times(0)).error(any(), any(), any()); } - @Test void error_hook_must_run_if_resolution_details_returns_an_error_code() { @@ -184,18 +200,20 @@ void error_hook_must_run_if_resolution_details_returns_an_error_code() { EvaluationContext invocationCtx = new ImmutableContext(); Hook hook = mockBooleanHook(); FeatureProvider provider = mock(FeatureProvider.class); - when(provider.getBooleanEvaluation(any(), any(), any())).thenReturn(ProviderEvaluation.builder() - .errorCode(ErrorCode.FLAG_NOT_FOUND) - .errorMessage(errorMessage) - .build()); + when(provider.getBooleanEvaluation(any(), any(), any())) + .thenReturn(ProviderEvaluation.builder() + .errorCode(ErrorCode.FLAG_NOT_FOUND) + .errorMessage(errorMessage) + .build()); OpenFeatureAPI api = OpenFeatureAPI.getInstance(); FeatureProviderTestUtils.setFeatureProvider("errorHookMustRun", provider); Client client = api.getClient("errorHookMustRun"); - client.getBooleanValue("key", false, invocationCtx, - FlagEvaluationOptions.builder() - .hook(hook) - .build()); + client.getBooleanValue( + "key", + false, + invocationCtx, + FlagEvaluationOptions.builder().hook(hook).build()); ArgumentCaptor captor = ArgumentCaptor.forClass(Exception.class); @@ -209,12 +227,25 @@ void error_hook_must_run_if_resolution_details_returns_an_error_code() { assertInstanceOf(FlagNotFoundError.class, exception); } - - @Specification(number = "4.3.6", text = "The after stage MUST run after flag resolution occurs. It accepts a hook context (required), flag evaluation details (required) and hook hints (optional). It has no return value.") - @Specification(number = "4.3.7", text = "The error hook MUST run when errors are encountered in the before stage, the after stage or during flag resolution. It accepts hook context (required), exception representing what went wrong (required), and hook hints (optional). It has no return value.") - @Specification(number = "4.3.8", text = "The finally hook MUST run after the before, after, and error stages. It accepts a hook context (required) and hook hints (optional). There is no return value.") - @Specification(number = "4.4.1", text = "The API, Client, Provider, and invocation MUST have a method for registering hooks.") - @Specification(number = "4.4.2", text = "Hooks MUST be evaluated in the following order: - before: API, Client, Invocation, Provider - after: Provider, Invocation, Client, API - error (if applicable): Provider, Invocation, Client, API - finally: Provider, Invocation, Client, API") + @Specification( + number = "4.3.6", + text = + "The after stage MUST run after flag resolution occurs. It accepts a hook context (required), flag evaluation details (required) and hook hints (optional). It has no return value.") + @Specification( + number = "4.3.7", + text = + "The error hook MUST run when errors are encountered in the before stage, the after stage or during flag resolution. It accepts hook context (required), exception representing what went wrong (required), and hook hints (optional). It has no return value.") + @Specification( + number = "4.3.8", + text = + "The finally hook MUST run after the before, after, and error stages. It accepts a hook context (required) and hook hints (optional). There is no return value.") + @Specification( + number = "4.4.1", + text = "The API, Client, Provider, and invocation MUST have a method for registering hooks.") + @Specification( + number = "4.4.2", + text = + "Hooks MUST be evaluated in the following order: - before: API, Client, Invocation, Provider - after: Provider, Invocation, Client, API - error (if applicable): Provider, Invocation, Client, API - finally: Provider, Invocation, Client, API") @Test void hook_eval_order() { List evalOrder = new ArrayList<>(); @@ -230,8 +261,10 @@ public Optional before(HookContext ctx, Map ctx, FlagEvaluationDetails details, Map hints) { + public void after( + HookContext ctx, + FlagEvaluationDetails details, + Map hints) { evalOrder.add("provider after"); } @@ -255,7 +288,8 @@ public Optional before(HookContext ctx, Map ctx, FlagEvaluationDetails details, Map hints) { + public void after( + HookContext ctx, FlagEvaluationDetails details, Map hints) { evalOrder.add("api after"); throw new RuntimeException(); // trigger error flows. } @@ -280,7 +314,8 @@ public Optional before(HookContext ctx, Map ctx, FlagEvaluationDetails details, Map hints) { + public void after( + HookContext ctx, FlagEvaluationDetails details, Map hints) { evalOrder.add("client after"); } @@ -295,41 +330,63 @@ public void finallyAfter(HookContext ctx, Map hints) { } }); - c.getBooleanValue("key", false, null, FlagEvaluationOptions - .builder() - .hook(new BooleanHook() { - @Override - public Optional before(HookContext ctx, Map hints) { - evalOrder.add("invocation before"); - return null; - } - - @Override - public void after(HookContext ctx, FlagEvaluationDetails details, Map hints) { - evalOrder.add("invocation after"); - } - - @Override - public void error(HookContext ctx, Exception error, Map hints) { - evalOrder.add("invocation error"); - } - - @Override - public void finallyAfter(HookContext ctx, Map hints) { - evalOrder.add("invocation finally"); - } - }) - .build()); + c.getBooleanValue( + "key", + false, + null, + FlagEvaluationOptions.builder() + .hook(new BooleanHook() { + @Override + public Optional before( + HookContext ctx, Map hints) { + evalOrder.add("invocation before"); + return null; + } + + @Override + public void after( + HookContext ctx, + FlagEvaluationDetails details, + Map hints) { + evalOrder.add("invocation after"); + } + + @Override + public void error(HookContext ctx, Exception error, Map hints) { + evalOrder.add("invocation error"); + } + + @Override + public void finallyAfter(HookContext ctx, Map hints) { + evalOrder.add("invocation finally"); + } + }) + .build()); List expectedOrder = Arrays.asList( - "api before", "client before", "invocation before", "provider before", - "provider after", "invocation after", "client after", "api after", - "provider error", "invocation error", "client error", "api error", - "provider finally", "invocation finally", "client finally", "api finally"); + "api before", + "client before", + "invocation before", + "provider before", + "provider after", + "invocation after", + "client after", + "api after", + "provider error", + "invocation error", + "client error", + "api error", + "provider finally", + "invocation finally", + "client finally", + "api finally"); assertEquals(expectedOrder, evalOrder); } - @Specification(number = "4.4.6", text = "If an error occurs during the evaluation of before or after hooks, any remaining hooks in the before or after stages MUST NOT be invoked.") + @Specification( + number = "4.4.6", + text = + "If an error occurs during the evaluation of before or after hooks, any remaining hooks in the before or after stages MUST NOT be invoked.") @Test void error_stops_before() { Hook h = mockBooleanHook(); @@ -340,15 +397,19 @@ void error_stops_before() { api.setProviderAndWait(new AlwaysBrokenProvider()); Client c = api.getClient(); - c.getBooleanDetails("key", false, null, FlagEvaluationOptions.builder() - .hook(h2) - .hook(h) - .build()); - verify(h, times(1)).before(any(), any()); - verify(h2, times(0)).before(any(), any()); + c.getBooleanDetails( + "key", + false, + null, + FlagEvaluationOptions.builder().hook(h2).hook(h).build()); + verify(h, times(1)).before(any(), any()); + verify(h2, times(0)).before(any(), any()); } - @Specification(number = "4.4.6", text = "If an error occurs during the evaluation of before or after hooks, any remaining hooks in the before or after stages MUST NOT be invoked.") + @Specification( + number = "4.4.6", + text = + "If an error occurs during the evaluation of before or after hooks, any remaining hooks in the before or after stages MUST NOT be invoked.") @SneakyThrows @Test void error_stops_after() { @@ -358,15 +419,19 @@ void error_stops_after() { Client c = getClient(TestEventsProvider.newInitializedTestEventsProvider()); - c.getBooleanDetails("key", false, null, FlagEvaluationOptions.builder() - .hook(h) - .hook(h2) - .build()); + c.getBooleanDetails( + "key", + false, + null, + FlagEvaluationOptions.builder().hook(h).hook(h2).build()); verify(h, times(1)).after(any(), any(), any()); verify(h2, times(0)).after(any(), any(), any()); } - @Specification(number = "4.2.1", text = "hook hints MUST be a structure supports definition of arbitrary properties, with keys of type string, and values of type boolean | string | number | datetime | structure..") + @Specification( + number = "4.2.1", + text = + "hook hints MUST be a structure supports definition of arbitrary properties, with keys of type string, and values of type boolean | string | number | datetime | structure..") @Specification(number = "4.5.2", text = "hook hints MUST be passed to each hook.") @Specification(number = "4.2.2.1", text = "Condition: Hook hints MUST be immutable.") @Specification(number = "4.5.3", text = "The hook MUST NOT alter the hook hints structure.") @@ -378,23 +443,28 @@ void hook_hints() { Hook mutatingHook = new BooleanHook() { @Override public Optional before(HookContext ctx, Map hints) { - assertThatCode(() -> hints.put(hintKey, "changed value")).isInstanceOf(UnsupportedOperationException.class); + assertThatCode(() -> hints.put(hintKey, "changed value")) + .isInstanceOf(UnsupportedOperationException.class); return Optional.empty(); } @Override - public void after(HookContext ctx, FlagEvaluationDetails details, Map hints) { - assertThatCode(() -> hints.put(hintKey, "changed value")).isInstanceOf(UnsupportedOperationException.class); + public void after( + HookContext ctx, FlagEvaluationDetails details, Map hints) { + assertThatCode(() -> hints.put(hintKey, "changed value")) + .isInstanceOf(UnsupportedOperationException.class); } @Override public void error(HookContext ctx, Exception error, Map hints) { - assertThatCode(() -> hints.put(hintKey, "changed value")).isInstanceOf(UnsupportedOperationException.class); + assertThatCode(() -> hints.put(hintKey, "changed value")) + .isInstanceOf(UnsupportedOperationException.class); } @Override public void finallyAfter(HookContext ctx, Map hints) { - assertThatCode(() -> hints.put(hintKey, "changed value")).isInstanceOf(UnsupportedOperationException.class); + assertThatCode(() -> hints.put(hintKey, "changed value")) + .isInstanceOf(UnsupportedOperationException.class); } }; @@ -402,13 +472,16 @@ public void finallyAfter(HookContext ctx, Map hints) { hh.put(hintKey, "My hint value"); hh = Collections.unmodifiableMap(hh); - client.getBooleanValue("key", false, new ImmutableContext(), FlagEvaluationOptions.builder() - .hook(mutatingHook) - .hookHints(hh) - .build()); + client.getBooleanValue( + "key", + false, + new ImmutableContext(), + FlagEvaluationOptions.builder().hook(mutatingHook).hookHints(hh).build()); } - @Specification(number = "4.5.1", text = "Flag evaluation options MAY contain hook hints, a map of data to be provided to hook invocations.") + @Specification( + number = "4.5.1", + text = "Flag evaluation options MAY contain hook hints, a map of data to be provided to hook invocations.") @Test void missing_hook_hints() { FlagEvaluationOptions feo = FlagEvaluationOptions.builder().build(); @@ -421,15 +494,16 @@ void flag_eval_hook_order() { Hook hook = mockBooleanHook(); FeatureProvider provider = mock(FeatureProvider.class); when(provider.getBooleanEvaluation(any(), any(), any())) - .thenReturn(ProviderEvaluation.builder() - .value(true) - .build()); + .thenReturn(ProviderEvaluation.builder().value(true).build()); InOrder order = inOrder(hook, provider); OpenFeatureAPI api = OpenFeatureAPI.getInstance(); FeatureProviderTestUtils.setFeatureProvider(provider); Client client = api.getClient(); - client.getBooleanValue("key", false, new ImmutableContext(), + client.getBooleanValue( + "key", + false, + new ImmutableContext(), FlagEvaluationOptions.builder().hook(hook).build()); order.verify(hook).before(any(), any()); @@ -438,27 +512,39 @@ void flag_eval_hook_order() { order.verify(hook).finallyAfter(any(), any()); } - @Specification(number = "4.4.5", text = "If an error occurs in the before or after hooks, the error hooks MUST be invoked.") - @Specification(number = "4.4.7", text = "If an error occurs in the before hooks, the default value MUST be returned.") + @Specification( + number = "4.4.5", + text = "If an error occurs in the before or after hooks, the error hooks MUST be invoked.") + @Specification( + number = "4.4.7", + text = "If an error occurs in the before hooks, the default value MUST be returned.") @Test void error_hooks__before() { Hook hook = mockBooleanHook(); doThrow(RuntimeException.class).when(hook).before(any(), any()); Client client = getClient(TestEventsProvider.newInitializedTestEventsProvider()); - Boolean value = client.getBooleanValue("key", false, new ImmutableContext(), + Boolean value = client.getBooleanValue( + "key", + false, + new ImmutableContext(), FlagEvaluationOptions.builder().hook(hook).build()); verify(hook, times(1)).before(any(), any()); verify(hook, times(1)).error(any(), any(), any()); assertEquals(false, value, "Falls through to the default."); } - @Specification(number = "4.4.5", text = "If an error occurs in the before or after hooks, the error hooks MUST be invoked.") + @Specification( + number = "4.4.5", + text = "If an error occurs in the before or after hooks, the error hooks MUST be invoked.") @Test void error_hooks__after() { Hook hook = mockBooleanHook(); doThrow(RuntimeException.class).when(hook).after(any(), any(), any()); Client client = getClient(TestEventsProvider.newInitializedTestEventsProvider()); - client.getBooleanValue("key", false, new ImmutableContext(), + client.getBooleanValue( + "key", + false, + new ImmutableContext(), FlagEvaluationOptions.builder().hook(hook).build()); verify(hook, times(1)).after(any(), any(), any()); verify(hook, times(1)).error(any(), any(), any()); @@ -472,11 +558,11 @@ void multi_hooks_early_out__before() { Client client = getClient(null); - client.getBooleanValue("key", false, new ImmutableContext(), - FlagEvaluationOptions.builder() - .hook(hook2) - .hook(hook) - .build()); + client.getBooleanValue( + "key", + false, + new ImmutableContext(), + FlagEvaluationOptions.builder().hook(hook2).hook(hook).build()); verify(hook, times(1)).before(any(), any()); verify(hook2, times(0)).before(any(), any()); @@ -486,7 +572,10 @@ void multi_hooks_early_out__before() { } @Specification(number = "4.1.4", text = "The evaluation context MUST be mutable only within the before hook.") - @Specification(number = "4.3.4", text = "Any `evaluation context` returned from a `before` hook MUST be passed to subsequent `before` hooks (via `HookContext`).") + @Specification( + number = "4.3.4", + text = + "Any `evaluation context` returned from a `before` hook MUST be passed to subsequent `before` hooks (via `HookContext`).") @Test void beforeContextUpdated() { String targetingKey = "test-key"; @@ -498,11 +587,11 @@ void beforeContextUpdated() { InOrder order = inOrder(hook, hook2); Client client = getClient(null); - client.getBooleanValue("key", false, ctx, - FlagEvaluationOptions.builder() - .hook(hook2) - .hook(hook) - .build()); + client.getBooleanValue( + "key", + false, + ctx, + FlagEvaluationOptions.builder().hook(hook2).hook(hook).build()); order.verify(hook).before(any(), any()); ArgumentCaptor> captor = ArgumentCaptor.forClass(HookContext.class); @@ -510,10 +599,12 @@ void beforeContextUpdated() { HookContext hc = captor.getValue(); assertEquals(hc.getCtx().getTargetingKey(), targetingKey); - } - @Specification(number = "4.3.5", text = "When before hooks have finished executing, any resulting evaluation context MUST be merged with the existing evaluation context.") + @Specification( + number = "4.3.5", + text = + "When before hooks have finished executing, any resulting evaluation context MUST be merged with the existing evaluation context.") @Test void mergeHappensCorrectly() { Map attributes = new HashMap<>(); @@ -521,7 +612,6 @@ void mergeHappensCorrectly() { attributes.put("another", new Value("exists")); EvaluationContext hookCtx = new ImmutableContext(attributes); - Map attributes1 = new HashMap<>(); attributes1.put("something", new Value("here")); attributes1.put("test", new Value("broken")); @@ -531,17 +621,17 @@ void mergeHappensCorrectly() { when(hook.before(any(), any())).thenReturn(Optional.of(hookCtx)); FeatureProvider provider = mock(FeatureProvider.class); - when(provider.getBooleanEvaluation(any(), any(), any())).thenReturn(ProviderEvaluation.builder() - .value(true) - .build()); + when(provider.getBooleanEvaluation(any(), any(), any())) + .thenReturn(ProviderEvaluation.builder().value(true).build()); OpenFeatureAPI api = OpenFeatureAPI.getInstance(); FeatureProviderTestUtils.setFeatureProvider(provider); Client client = api.getClient(); - client.getBooleanValue("key", false, invocationCtx, - FlagEvaluationOptions.builder() - .hook(hook) - .build()); + client.getBooleanValue( + "key", + false, + invocationCtx, + FlagEvaluationOptions.builder().hook(hook).build()); ArgumentCaptor captor = ArgumentCaptor.forClass(ImmutableContext.class); verify(provider).getBooleanEvaluation(any(), any(), captor.capture()); @@ -551,7 +641,10 @@ void mergeHappensCorrectly() { assertEquals("here", ec.getValue("something").asString()); } - @Specification(number = "4.4.3", text = "If a finally hook abnormally terminates, evaluation MUST proceed, including the execution of any remaining finally hooks.") + @Specification( + number = "4.4.3", + text = + "If a finally hook abnormally terminates, evaluation MUST proceed, including the execution of any remaining finally hooks.") @Test void first_finally_broken() { Hook hook = mockBooleanHook(); @@ -561,18 +654,21 @@ void first_finally_broken() { InOrder order = inOrder(hook, hook2); Client client = getClient(null); - client.getBooleanValue("key", false, new ImmutableContext(), - FlagEvaluationOptions.builder() - .hook(hook2) - .hook(hook) - .build()); + client.getBooleanValue( + "key", + false, + new ImmutableContext(), + FlagEvaluationOptions.builder().hook(hook2).hook(hook).build()); order.verify(hook).before(any(), any()); order.verify(hook2).finallyAfter(any(), any()); order.verify(hook).finallyAfter(any(), any()); } - @Specification(number = "4.4.4", text = "If an error hook abnormally terminates, evaluation MUST proceed, including the execution of any remaining error hooks.") + @Specification( + number = "4.4.4", + text = + "If an error hook abnormally terminates, evaluation MUST proceed, including the execution of any remaining error hooks.") @Test void first_error_broken() { Hook hook = mockBooleanHook(); @@ -582,11 +678,11 @@ void first_error_broken() { InOrder order = inOrder(hook, hook2); Client client = getClient(null); - client.getBooleanValue("key", false, new ImmutableContext(), - FlagEvaluationOptions.builder() - .hook(hook2) - .hook(hook) - .build()); + client.getBooleanValue( + "key", + false, + new ImmutableContext(), + FlagEvaluationOptions.builder().hook(hook2).hook(hook).build()); order.verify(hook).before(any(), any()); order.verify(hook2).error(any(), any(), any()); @@ -605,8 +701,7 @@ private Client getClient(FeatureProvider provider) { @Specification(number = "4.3.1", text = "Hooks MUST specify at least one stage.") @Test - void default_methods_so_impossible() { - } + void default_methods_so_impossible() {} @Specification(number = "4.3.9.1", text = "Instead of finally, finallyAfter SHOULD be used.") @SneakyThrows @@ -619,5 +714,4 @@ void doesnt_use_finally() { assertThatCode(() -> Hook.class.getMethod("finallyAfter", HookContext.class, Map.class)) .doesNotThrowAnyException(); } - } diff --git a/src/test/java/dev/openfeature/sdk/HookSupportTest.java b/src/test/java/dev/openfeature/sdk/HookSupportTest.java index bf6501dd5..73256ab5f 100644 --- a/src/test/java/dev/openfeature/sdk/HookSupportTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSupportTest.java @@ -5,19 +5,17 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import dev.openfeature.sdk.fixtures.HookFixtures; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Optional; - import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; -import dev.openfeature.sdk.fixtures.HookFixtures; - class HookSupportTest implements HookFixtures { @Test @DisplayName("should merge EvaluationContexts on before hooks correctly") @@ -25,14 +23,16 @@ void shouldMergeEvaluationContextsOnBeforeHooksCorrectly() { Map attributes = new HashMap<>(); attributes.put("baseKey", new Value("baseValue")); EvaluationContext baseContext = new ImmutableContext(attributes); - HookContext hookContext = new HookContext<>("flagKey", FlagValueType.STRING, "defaultValue", baseContext, () -> "client", () -> "provider"); + HookContext hookContext = new HookContext<>( + "flagKey", FlagValueType.STRING, "defaultValue", baseContext, () -> "client", () -> "provider"); Hook hook1 = mockStringHook(); Hook hook2 = mockStringHook(); when(hook1.before(any(), any())).thenReturn(Optional.of(evaluationContextWithValue("bla", "blubber"))); when(hook2.before(any(), any())).thenReturn(Optional.of(evaluationContextWithValue("foo", "bar"))); HookSupport hookSupport = new HookSupport(); - EvaluationContext result = hookSupport.beforeHooks(FlagValueType.STRING, hookContext, Arrays.asList(hook1, hook2), Collections.emptyMap()); + EvaluationContext result = hookSupport.beforeHooks( + FlagValueType.STRING, hookContext, Arrays.asList(hook1, hook2), Collections.emptyMap()); assertThat(result.getValue("bla").asString()).isEqualTo("blubber"); assertThat(result.getValue("foo").asString()).isEqualTo("bar"); @@ -47,12 +47,30 @@ void shouldAlwaysCallGenericHook(FlagValueType flagValueType) { HookSupport hookSupport = new HookSupport(); EvaluationContext baseContext = new ImmutableContext(); IllegalStateException expectedException = new IllegalStateException("All fine, just a test"); - HookContext hookContext = new HookContext<>("flagKey", flagValueType, createDefaultValue(flagValueType), baseContext, () -> "client", () -> "provider"); + HookContext hookContext = new HookContext<>( + "flagKey", + flagValueType, + createDefaultValue(flagValueType), + baseContext, + () -> "client", + () -> "provider"); - hookSupport.beforeHooks(flagValueType, hookContext, Collections.singletonList(genericHook), Collections.emptyMap()); - hookSupport.afterHooks(flagValueType, hookContext, FlagEvaluationDetails.builder().build(), Collections.singletonList(genericHook), Collections.emptyMap()); - hookSupport.afterAllHooks(flagValueType, hookContext, Collections.singletonList(genericHook), Collections.emptyMap()); - hookSupport.errorHooks(flagValueType, hookContext, expectedException, Collections.singletonList(genericHook), Collections.emptyMap()); + hookSupport.beforeHooks( + flagValueType, hookContext, Collections.singletonList(genericHook), Collections.emptyMap()); + hookSupport.afterHooks( + flagValueType, + hookContext, + FlagEvaluationDetails.builder().build(), + Collections.singletonList(genericHook), + Collections.emptyMap()); + hookSupport.afterAllHooks( + flagValueType, hookContext, Collections.singletonList(genericHook), Collections.emptyMap()); + hookSupport.errorHooks( + flagValueType, + hookContext, + expectedException, + Collections.singletonList(genericHook), + Collections.emptyMap()); verify(genericHook).before(any(), any()); verify(genericHook).after(any(), any(), any()); @@ -83,5 +101,4 @@ private EvaluationContext evaluationContextWithValue(String key, String value) { EvaluationContext baseContext = new ImmutableContext(attributes); return baseContext; } - } diff --git a/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java b/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java index 44a6f4790..e69a974b3 100644 --- a/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java +++ b/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java @@ -1,18 +1,16 @@ package dev.openfeature.sdk; -import java.util.Collections; -import java.util.Map; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import java.util.HashMap; - 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.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + class ImmutableContextTest { @DisplayName("attributes unable to allow mutation should not affect the immutable context") @Test @@ -23,7 +21,8 @@ void shouldNotAttemptToModifyAttributesForImmutableContext() { // should check the usage of Map.of() which is a more likely use case, but that API isn't available in Java 8 EvaluationContext ctx = new ImmutableContext("targeting key", Collections.unmodifiableMap(attributes)); attributes.put("key3", new Value("val3")); - assertArrayEquals(new Object[]{"key1", "key2", TARGETING_KEY}, ctx.keySet().toArray()); + assertArrayEquals( + new Object[] {"key1", "key2", TARGETING_KEY}, ctx.keySet().toArray()); } @DisplayName("attributes mutation should not affect the immutable context") @@ -34,7 +33,8 @@ void shouldCreateCopyOfAttributesForImmutableContext() { attributes.put("key2", new Value("val2")); EvaluationContext ctx = new ImmutableContext("targeting key", attributes); attributes.put("key3", new Value("val3")); - assertArrayEquals(new Object[]{"key1", "key2", TARGETING_KEY}, ctx.keySet().toArray()); + assertArrayEquals( + new Object[] {"key1", "key2", TARGETING_KEY}, ctx.keySet().toArray()); } @DisplayName("targeting key should be changed from the overriding context") @@ -60,6 +60,7 @@ void shouldRetainTargetingKeyWhenOverridingContextTargetingKeyValueIsEmpty() { EvaluationContext merge = ctx.merge(overriding); assertEquals("targeting_key", merge.getTargetingKey()); } + @DisplayName("missing targeting key should return null") @Test void missingTargetingKeyShould() { @@ -76,10 +77,12 @@ void mergeShouldReturnAllTheValuesFromTheContextWhenOverridingContextIsNull() { EvaluationContext ctx = new ImmutableContext("targeting_key", attributes); EvaluationContext merge = ctx.merge(null); assertEquals("targeting_key", merge.getTargetingKey()); - assertArrayEquals(new Object[]{"key1", "key2", TARGETING_KEY}, merge.keySet().toArray()); + assertArrayEquals( + new Object[] {"key1", "key2", TARGETING_KEY}, merge.keySet().toArray()); } - @DisplayName("Merge should retain subkeys from the existing context when the overriding context has the same targeting key") + @DisplayName( + "Merge should retain subkeys from the existing context when the overriding context has the same targeting key") @Test void mergeShouldRetainItsSubkeysWhenOverridingContextHasTheSameKey() { HashMap attributes = new HashMap<>(); @@ -92,21 +95,24 @@ void mergeShouldRetainItsSubkeysWhenOverridingContextHasTheSameKey() { attributes.put("key2", new Value("val2")); ovKey1Attributes.put("overriding_key1_1", new Value("overriding_val_1_1")); overridingAttributes.put("key1", new Value(new ImmutableStructure(ovKey1Attributes))); - + EvaluationContext ctx = new ImmutableContext("targeting_key", attributes); EvaluationContext overriding = new ImmutableContext("targeting_key", overridingAttributes); EvaluationContext merge = ctx.merge(overriding); assertEquals("targeting_key", merge.getTargetingKey()); - assertArrayEquals(new Object[]{"key1", "key2", TARGETING_KEY}, merge.keySet().toArray()); - + assertArrayEquals( + new Object[] {"key1", "key2", TARGETING_KEY}, merge.keySet().toArray()); + Value key1 = merge.getValue("key1"); assertTrue(key1.isStructure()); - + Structure value = key1.asStructure(); - assertArrayEquals(new Object[]{"key1_1","overriding_key1_1"}, value.keySet().toArray()); + assertArrayEquals( + new Object[] {"key1_1", "overriding_key1_1"}, value.keySet().toArray()); } - - @DisplayName("Merge should retain subkeys from the existing context when the overriding context doesn't have targeting key") + + @DisplayName( + "Merge should retain subkeys from the existing context when the overriding context doesn't have targeting key") @Test void mergeShouldRetainItsSubkeysWhenOverridingContextHasNoTargetingKey() { HashMap attributes = new HashMap<>(); @@ -115,16 +121,16 @@ void mergeShouldRetainItsSubkeysWhenOverridingContextHasNoTargetingKey() { key1Attributes.put("key1_1", new Value("val1_1")); attributes.put("key1", new Value(new ImmutableStructure(key1Attributes))); attributes.put("key2", new Value("val2")); - + EvaluationContext ctx = new ImmutableContext(attributes); EvaluationContext overriding = new ImmutableContext(); EvaluationContext merge = ctx.merge(overriding); - assertArrayEquals(new Object[]{"key1", "key2"}, merge.keySet().toArray()); - + assertArrayEquals(new Object[] {"key1", "key2"}, merge.keySet().toArray()); + Value key1 = merge.getValue("key1"); assertTrue(key1.isStructure()); - + Structure value = key1.asStructure(); - assertArrayEquals(new Object[]{"key1_1"}, value.keySet().toArray()); + assertArrayEquals(new Object[] {"key1_1"}, value.keySet().toArray()); } } diff --git a/src/test/java/dev/openfeature/sdk/ImmutableStructureTest.java b/src/test/java/dev/openfeature/sdk/ImmutableStructureTest.java index 491b5069f..dff95adca 100644 --- a/src/test/java/dev/openfeature/sdk/ImmutableStructureTest.java +++ b/src/test/java/dev/openfeature/sdk/ImmutableStructureTest.java @@ -1,6 +1,6 @@ package dev.openfeature.sdk; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; import java.time.Instant; import java.time.temporal.ChronoUnit; @@ -9,16 +9,17 @@ import java.util.List; import java.util.Map; import java.util.Set; - -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; class ImmutableStructureTest { - @Test void noArgShouldContainEmptyAttributes() { + @Test + void noArgShouldContainEmptyAttributes() { ImmutableStructure structure = new ImmutableStructure(); assertEquals(0, structure.asMap().keySet().size()); } - @Test void mapArgShouldContainNewMap() { + @Test + void mapArgShouldContainNewMap() { String KEY = "key"; Map map = new HashMap() { { @@ -30,7 +31,8 @@ class ImmutableStructureTest { assertNotSame(structure.asMap(), map); // should be a copy } - @Test void MutatingGetValueShouldNotChangeOriginalValue() { + @Test + void MutatingGetValueShouldNotChangeOriginalValue() { String KEY = "key"; List lists = new ArrayList<>(); lists.add(new Value(KEY)); @@ -47,7 +49,8 @@ class ImmutableStructureTest { assertNotSame(structure.asMap(), map); // should be a copy } - @Test void MutatingGetInstantValueShouldNotChangeOriginalValue() { + @Test + void MutatingGetInstantValueShouldNotChangeOriginalValue() { String KEY = "key"; Instant now = Instant.now().truncatedTo(ChronoUnit.MILLIS); Map map = new HashMap() { @@ -56,39 +59,60 @@ class ImmutableStructureTest { } }; ImmutableStructure structure = new ImmutableStructure(map); - //mutate the original value + // mutate the original value Instant tomorrow = now.plus(1, ChronoUnit.DAYS); - //mutate the getValue + // mutate the getValue structure.getValue(KEY).asInstant().plus(1, ChronoUnit.DAYS); assertNotEquals(tomorrow, structure.getValue(KEY).asInstant()); assertEquals(now, structure.getValue(KEY).asInstant()); } - @Test void MutatingGetStructureValueShouldNotChangeOriginalValue() { + @Test + void MutatingGetStructureValueShouldNotChangeOriginalValue() { String KEY = "key"; List lists = new ArrayList<>(); lists.add(new Value("dummy_list_1")); - MutableStructure mutableStructure = new MutableStructure().add("key1","val1").add("list", lists); + MutableStructure mutableStructure = + new MutableStructure().add("key1", "val1").add("list", lists); Map map = new HashMap() { { put(KEY, new Value(mutableStructure)); } }; ImmutableStructure structure = new ImmutableStructure(map); - //mutate the original structure + // mutate the original structure mutableStructure.add("key2", "val2"); - //mutate the return value + // mutate the return value structure.getValue(KEY).asStructure().asMap().put("key3", new Value("val3")); assertEquals(2, structure.getValue(KEY).asStructure().asMap().size()); - assertArrayEquals(new Object[]{"key1", "list"}, structure.getValue(KEY).asStructure().keySet().toArray()); + assertArrayEquals( + new Object[] {"key1", "list"}, + structure.getValue(KEY).asStructure().keySet().toArray()); assertTrue(structure.getValue(KEY).asStructure() instanceof ImmutableStructure); - //mutate list value + // mutate list value lists.add(new Value("dummy_list_2")); - //mutate the return list value + // mutate the return list value structure.getValue(KEY).asStructure().asMap().get("list").asList().add(new Value("dummy_list_3")); - assertEquals(1, structure.getValue(KEY).asStructure().asMap().get("list").asList().size()); - assertEquals("dummy_list_1", structure.getValue(KEY).asStructure().asMap().get("list").asList().get(0).asString()); + assertEquals( + 1, + structure + .getValue(KEY) + .asStructure() + .asMap() + .get("list") + .asList() + .size()); + assertEquals( + "dummy_list_1", + structure + .getValue(KEY) + .asStructure() + .asMap() + .get("list") + .asList() + .get(0) + .asString()); } @Test @@ -112,7 +136,8 @@ void GettingAMissingValueShouldReturnNull() { assertNull(value); } - @Test void objectMapTest() { + @Test + void objectMapTest() { Map attrs = new HashMap<>(); attrs.put("test", new Value(45)); ImmutableStructure structure = new ImmutableStructure(attrs); diff --git a/src/test/java/dev/openfeature/sdk/InitializeBehaviorSpecTest.java b/src/test/java/dev/openfeature/sdk/InitializeBehaviorSpecTest.java index 4d0599a7a..3353f5644 100644 --- a/src/test/java/dev/openfeature/sdk/InitializeBehaviorSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/InitializeBehaviorSpecTest.java @@ -1,10 +1,18 @@ package dev.openfeature.sdk; -import dev.openfeature.sdk.testutils.exception.TestException; -import org.junit.jupiter.api.*; - import static org.assertj.core.api.Assertions.assertThatCode; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.verify; + +import dev.openfeature.sdk.testutils.exception.TestException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; class InitializeBehaviorSpecTest { @@ -18,11 +26,13 @@ void setupTest() { @Nested class DefaultProvider { - @Specification(number = "1.1.2.2", text = "The `provider mutator` function MUST invoke the `initialize` " - + "function on the newly registered provider before using it to resolve flag values.") + @Specification( + number = "1.1.2.2", + text = "The `provider mutator` function MUST invoke the `initialize` " + + "function on the newly registered provider before using it to resolve flag values.") @Test @DisplayName("must call initialize function of the newly registered provider before using it for " - + "flag evaluation") + + "flag evaluation") void mustCallInitializeFunctionOfTheNewlyRegisteredProviderBeforeUsingItForFlagEvaluation() throws Exception { FeatureProvider featureProvider = mock(FeatureProvider.class); doReturn(ProviderState.NOT_READY).when(featureProvider).getState(); @@ -32,10 +42,12 @@ void mustCallInitializeFunctionOfTheNewlyRegisteredProviderBeforeUsingItForFlagE verify(featureProvider, timeout(1000)).initialize(any()); } - @Specification(number = "1.4.10", text = "Methods, functions, or operations on the client MUST NOT throw " - + "exceptions, or otherwise abnormally terminate. Flag evaluation calls must always return the " - + "`default value` in the event of abnormal execution. Exceptions include functions or methods for " - + "the purposes for configuration or setup.") + @Specification( + number = "1.4.10", + text = "Methods, functions, or operations on the client MUST NOT throw " + + "exceptions, or otherwise abnormally terminate. Flag evaluation calls must always return the " + + "`default value` in the event of abnormal execution. Exceptions include functions or methods for " + + "the purposes for configuration or setup.") @Test @DisplayName("should catch exception thrown by the provider on initialization") void shouldCatchExceptionThrownByTheProviderOnInitialization() throws Exception { @@ -44,7 +56,7 @@ void shouldCatchExceptionThrownByTheProviderOnInitialization() throws Exception doThrow(TestException.class).when(featureProvider).initialize(any()); assertThatCode(() -> OpenFeatureAPI.getInstance().setProvider(featureProvider)) - .doesNotThrowAnyException(); + .doesNotThrowAnyException(); verify(featureProvider, timeout(1000)).initialize(any()); } @@ -53,12 +65,15 @@ void shouldCatchExceptionThrownByTheProviderOnInitialization() throws Exception @Nested class ProviderForNamedClient { - @Specification(number = "1.1.2.2", text = "The `provider mutator` function MUST invoke the `initialize`" - + " function on the newly registered provider before using it to resolve flag values.") + @Specification( + number = "1.1.2.2", + text = "The `provider mutator` function MUST invoke the `initialize`" + + " function on the newly registered provider before using it to resolve flag values.") @Test @DisplayName("must call initialize function of the newly registered named provider before using it " - + "for flag evaluation") - void mustCallInitializeFunctionOfTheNewlyRegisteredNamedProviderBeforeUsingItForFlagEvaluation() throws Exception { + + "for flag evaluation") + void mustCallInitializeFunctionOfTheNewlyRegisteredNamedProviderBeforeUsingItForFlagEvaluation() + throws Exception { FeatureProvider featureProvider = mock(FeatureProvider.class); doReturn(ProviderState.NOT_READY).when(featureProvider).getState(); @@ -67,10 +82,12 @@ void mustCallInitializeFunctionOfTheNewlyRegisteredNamedProviderBeforeUsingItFor verify(featureProvider, timeout(1000)).initialize(any()); } - @Specification(number = "1.4.10", text = "Methods, functions, or operations on the client MUST NOT throw " - + "exceptions, or otherwise abnormally terminate. Flag evaluation calls must always return the " - + "`default value` in the event of abnormal execution. Exceptions include functions or methods for " - + "the purposes for configuration or setup.") + @Specification( + number = "1.4.10", + text = "Methods, functions, or operations on the client MUST NOT throw " + + "exceptions, or otherwise abnormally terminate. Flag evaluation calls must always return the " + + "`default value` in the event of abnormal execution. Exceptions include functions or methods for " + + "the purposes for configuration or setup.") @Test @DisplayName("should catch exception thrown by the named client provider on initialization") void shouldCatchExceptionThrownByTheNamedClientProviderOnInitialization() throws Exception { @@ -79,7 +96,7 @@ void shouldCatchExceptionThrownByTheNamedClientProviderOnInitialization() throws doThrow(TestException.class).when(featureProvider).initialize(any()); assertThatCode(() -> OpenFeatureAPI.getInstance().setProvider(DOMAIN_NAME, featureProvider)) - .doesNotThrowAnyException(); + .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/LockingTest.java index ddfa9c079..4b7af5530 100644 --- a/src/test/java/dev/openfeature/sdk/LockingTest.java +++ b/src/test/java/dev/openfeature/sdk/LockingTest.java @@ -5,26 +5,24 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import dev.openfeature.sdk.internal.AutoCloseableReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.function.Consumer; - import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Isolated; -import dev.openfeature.sdk.internal.AutoCloseableReentrantReadWriteLock; - @Isolated() class LockingTest { - + private static OpenFeatureAPI api; private OpenFeatureClient client; private AutoCloseableReentrantReadWriteLock apiLock; private AutoCloseableReentrantReadWriteLock clientContextLock; private AutoCloseableReentrantReadWriteLock clientHooksLock; - + @BeforeAll static void beforeAll() { api = OpenFeatureAPI.getInstance(); @@ -34,7 +32,7 @@ static void beforeAll() { @BeforeEach void beforeEach() { client = (OpenFeatureClient) api.getClient("LockingTest"); - + apiLock = setupLock(apiLock, mockInnerReadLock(), mockInnerWriteLock()); OpenFeatureAPI.lock = apiLock; @@ -93,8 +91,9 @@ void onProviderErrorShouldWriteLockAndUnlock() { @Nested class Client { - - // Note that the API lock is used for adding client handlers, they are all added (indirectly) on the API object. + + // Note that the API lock is used for adding client handlers, they are all added (indirectly) on the API + // object. @Test void onShouldApiWriteLockAndUnlock() { @@ -138,16 +137,13 @@ void onProviderErrorProviderReadyShouldApiWriteLockAndUnlock() { } } - @Test void addHooksShouldWriteLockAndUnlock() { - client.addHooks(new Hook() { - }); + client.addHooks(new Hook() {}); verify(clientHooksLock.writeLock()).lock(); verify(clientHooksLock.writeLock()).unlock(); - api.addHooks(new Hook() { - }); + api.addHooks(new Hook() {}); verify(apiLock.writeLock()).lock(); verify(apiLock.writeLock()).unlock(); } @@ -199,7 +195,6 @@ void getTransactionalContextPropagatorShouldReadLockAndUnlock() { verify(apiLock.readLock()).unlock(); } - @Test void clearHooksShouldWriteLockAndUnlock() { api.clearHooks(); @@ -221,7 +216,8 @@ private static ReentrantReadWriteLock.WriteLock mockInnerWriteLock() { return writeLockMock; } - private AutoCloseableReentrantReadWriteLock setupLock(AutoCloseableReentrantReadWriteLock lock, + private AutoCloseableReentrantReadWriteLock setupLock( + AutoCloseableReentrantReadWriteLock lock, AutoCloseableReentrantReadWriteLock.ReadLock readlock, AutoCloseableReentrantReadWriteLock.WriteLock writeLock) { lock = mock(AutoCloseableReentrantReadWriteLock.class); @@ -231,4 +227,4 @@ private AutoCloseableReentrantReadWriteLock setupLock(AutoCloseableReentrantRead when(lock.writeLock()).thenReturn(writeLock); return lock; } -} \ No newline at end of file +} diff --git a/src/test/java/dev/openfeature/sdk/MetadataTest.java b/src/test/java/dev/openfeature/sdk/MetadataTest.java index 944f45e36..f8ee0ceb7 100644 --- a/src/test/java/dev/openfeature/sdk/MetadataTest.java +++ b/src/test/java/dev/openfeature/sdk/MetadataTest.java @@ -1,12 +1,16 @@ package dev.openfeature.sdk; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.fail; +import org.junit.jupiter.api.Test; + class MetadataTest { - @Specification(number="4.2.2.2", text="Condition: The client metadata field in the hook context MUST be immutable.") - @Specification(number="4.2.2.3", text="Condition: The provider metadata field in the hook context MUST be immutable.") + @Specification( + number = "4.2.2.2", + text = "Condition: The client metadata field in the hook context MUST be immutable.") + @Specification( + number = "4.2.2.3", + text = "Condition: The provider metadata field in the hook context MUST be immutable.") @Test void metadata_is_immutable() { try { @@ -16,4 +20,4 @@ void metadata_is_immutable() { // Pass } } -} \ No newline at end of file +} diff --git a/src/test/java/dev/openfeature/sdk/MutableContextTest.java b/src/test/java/dev/openfeature/sdk/MutableContextTest.java index df21e6eca..953e3f636 100644 --- a/src/test/java/dev/openfeature/sdk/MutableContextTest.java +++ b/src/test/java/dev/openfeature/sdk/MutableContextTest.java @@ -1,17 +1,16 @@ package dev.openfeature.sdk; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - 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.assertTrue; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + class MutableContextTest { @DisplayName("attributes unable to allow mutation should not affect the Mutable context") @@ -23,7 +22,8 @@ void shouldNotAttemptToModifyAttributesForMutableContext() { // should check the usage of Map.of() which is a more likely use case, but that API isn't available in Java 8 EvaluationContext ctx = new MutableContext("targeting key", Collections.unmodifiableMap(attributes)); attributes.put("key3", new Value("val3")); - assertArrayEquals(new Object[]{"key1", "key2", TARGETING_KEY}, ctx.keySet().toArray()); + assertArrayEquals( + new Object[] {"key1", "key2", TARGETING_KEY}, ctx.keySet().toArray()); } @DisplayName("targeting key should be changed from the overriding context") @@ -49,6 +49,7 @@ void shouldRetainTargetingKeyWhenOverridingContextTargetingKeyValueIsEmpty() { EvaluationContext merge = ctx.merge(overriding); assertEquals("targeting_key", merge.getTargetingKey()); } + @DisplayName("missing targeting key should return null") @Test void missingTargetingKeyShould() { @@ -65,10 +66,12 @@ void mergeShouldReturnAllTheValuesFromTheContextWhenOverridingContextIsNull() { EvaluationContext ctx = new MutableContext("targeting_key", attributes); EvaluationContext merge = ctx.merge(null); assertEquals("targeting_key", merge.getTargetingKey()); - assertArrayEquals(new Object[]{"key1", "key2", TARGETING_KEY}, merge.keySet().toArray()); + assertArrayEquals( + new Object[] {"key1", "key2", TARGETING_KEY}, merge.keySet().toArray()); } - @DisplayName("Merge should retain subkeys from the existing context when the overriding context has the same targeting key") + @DisplayName( + "Merge should retain subkeys from the existing context when the overriding context has the same targeting key") @Test void mergeShouldRetainItsSubkeysWhenOverridingContextHasTheSameKey() { HashMap attributes = new HashMap<>(); @@ -81,21 +84,24 @@ void mergeShouldRetainItsSubkeysWhenOverridingContextHasTheSameKey() { attributes.put("key2", new Value("val2")); ovKey1Attributes.put("overriding_key1_1", new Value("overriding_val_1_1")); overridingAttributes.put("key1", new Value(new ImmutableStructure(ovKey1Attributes))); - + EvaluationContext ctx = new MutableContext("targeting_key", attributes); EvaluationContext overriding = new MutableContext("targeting_key", overridingAttributes); EvaluationContext merge = ctx.merge(overriding); assertEquals("targeting_key", merge.getTargetingKey()); - assertArrayEquals(new Object[]{"key1", "key2", TARGETING_KEY}, merge.keySet().toArray()); - + assertArrayEquals( + new Object[] {"key1", "key2", TARGETING_KEY}, merge.keySet().toArray()); + Value key1 = merge.getValue("key1"); assertTrue(key1.isStructure()); - + Structure value = key1.asStructure(); - assertArrayEquals(new Object[]{"key1_1","overriding_key1_1"}, value.keySet().toArray()); + assertArrayEquals( + new Object[] {"key1_1", "overriding_key1_1"}, value.keySet().toArray()); } - - @DisplayName("Merge should retain subkeys from the existing context when the overriding context doesn't have targeting key") + + @DisplayName( + "Merge should retain subkeys from the existing context when the overriding context doesn't have targeting key") @Test void mergeShouldRetainItsSubkeysWhenOverridingContextHasNoTargetingKey() { HashMap attributes = new HashMap<>(); @@ -104,17 +110,17 @@ void mergeShouldRetainItsSubkeysWhenOverridingContextHasNoTargetingKey() { key1Attributes.put("key1_1", new Value("val1_1")); attributes.put("key1", new Value(new ImmutableStructure(key1Attributes))); attributes.put("key2", new Value("val2")); - + EvaluationContext ctx = new MutableContext(attributes); EvaluationContext overriding = new MutableContext(); EvaluationContext merge = ctx.merge(overriding); - assertArrayEquals(new Object[]{"key1", "key2"}, merge.keySet().toArray()); - + assertArrayEquals(new Object[] {"key1", "key2"}, merge.keySet().toArray()); + Value key1 = merge.getValue("key1"); assertTrue(key1.isStructure()); - + Structure value = key1.asStructure(); - assertArrayEquals(new Object[]{"key1_1"}, value.keySet().toArray()); + assertArrayEquals(new Object[] {"key1_1"}, value.keySet().toArray()); } @DisplayName("Ensure mutations are chainable") @@ -129,6 +135,6 @@ void shouldAllowChainingOfMutations() { assertEquals("TARGETING_KEY", context.getTargetingKey()); assertEquals("val1", context.getValue("key1").asString()); assertEquals(2, context.getValue("key2").asInteger()); - assertEquals(3.0, context.getValue("key3").asDouble()); + assertEquals(3.0, context.getValue("key3").asDouble()); } } diff --git a/src/test/java/dev/openfeature/sdk/MutableTrackingEventDetailsTest.java b/src/test/java/dev/openfeature/sdk/MutableTrackingEventDetailsTest.java index a169107f1..04fe12ad2 100644 --- a/src/test/java/dev/openfeature/sdk/MutableTrackingEventDetailsTest.java +++ b/src/test/java/dev/openfeature/sdk/MutableTrackingEventDetailsTest.java @@ -1,17 +1,15 @@ package dev.openfeature.sdk; -import com.google.common.collect.Lists; -import org.junit.jupiter.api.Test; - -import java.time.Instant; - import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; -class MutableTrackingEventDetailsTest { +import com.google.common.collect.Lists; +import java.time.Instant; +import org.junit.jupiter.api.Test; +class MutableTrackingEventDetailsTest { @Test void hasDefaultValue() { @@ -46,6 +44,8 @@ void shouldStoreAttributes() { assertEquals(new Value(Instant.parse("2023-12-03T10:15:30Z")), track.getValue("key5")); assertEquals(new Value(new MutableContext()), track.getValue("key6")); assertEquals(new Value(7), track.getValue("key7")); - assertArrayEquals(new Object[]{new Value(8), new Value(9)}, track.getValue("key8").asList().toArray()); + assertArrayEquals( + new Object[] {new Value(8), new Value(9)}, + track.getValue("key8").asList().toArray()); } -} \ No newline at end of file +} diff --git a/src/test/java/dev/openfeature/sdk/NoOpProviderTest.java b/src/test/java/dev/openfeature/sdk/NoOpProviderTest.java index 2f34cd7d4..d0c7c6014 100644 --- a/src/test/java/dev/openfeature/sdk/NoOpProviderTest.java +++ b/src/test/java/dev/openfeature/sdk/NoOpProviderTest.java @@ -5,32 +5,37 @@ import org.junit.jupiter.api.Test; public class NoOpProviderTest { - @Test void bool() { + @Test + void bool() { NoOpProvider p = new NoOpProvider(); ProviderEvaluation eval = p.getBooleanEvaluation("key", true, null); assertEquals(true, eval.getValue()); } - @Test void str() { + @Test + void str() { NoOpProvider p = new NoOpProvider(); ProviderEvaluation eval = p.getStringEvaluation("key", "works", null); assertEquals("works", eval.getValue()); } - @Test void integer() { + @Test + void integer() { NoOpProvider p = new NoOpProvider(); ProviderEvaluation eval = p.getIntegerEvaluation("key", 4, null); assertEquals(4, eval.getValue()); } - @Test void noOpdouble() { + @Test + void noOpdouble() { NoOpProvider p = new NoOpProvider(); ProviderEvaluation eval = p.getDoubleEvaluation("key", 0.4, null); assertEquals(0.4, eval.getValue()); } - @Test void value() { + @Test + void value() { NoOpProvider p = new NoOpProvider(); Value s = new Value(); ProviderEvaluation eval = p.getObjectEvaluation("key", s, null); diff --git a/src/test/java/dev/openfeature/sdk/NoOpTransactionContextPropagatorTest.java b/src/test/java/dev/openfeature/sdk/NoOpTransactionContextPropagatorTest.java index 06b7e93c7..d824a5a1a 100644 --- a/src/test/java/dev/openfeature/sdk/NoOpTransactionContextPropagatorTest.java +++ b/src/test/java/dev/openfeature/sdk/NoOpTransactionContextPropagatorTest.java @@ -1,11 +1,10 @@ package dev.openfeature.sdk; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; import java.util.HashMap; import java.util.Map; - -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; class NoOpTransactionContextPropagatorTest { @@ -26,4 +25,4 @@ public void setTransactionContext() { EvaluationContext result = contextPropagator.getTransactionContext(); assertTrue(result.asMap().isEmpty()); } -} \ No newline at end of file +} diff --git a/src/test/java/dev/openfeature/sdk/NotImplementedException.java b/src/test/java/dev/openfeature/sdk/NotImplementedException.java index 09d7bcbbb..780c167b6 100644 --- a/src/test/java/dev/openfeature/sdk/NotImplementedException.java +++ b/src/test/java/dev/openfeature/sdk/NotImplementedException.java @@ -4,7 +4,7 @@ public class NotImplementedException extends RuntimeException { private static final long serialVersionUID = 1L; - public NotImplementedException(String message){ + public NotImplementedException(String message) { super(message); } } diff --git a/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java b/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java index 026170a78..63145ecb6 100644 --- a/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java +++ b/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java @@ -1,14 +1,5 @@ package dev.openfeature.sdk; -import dev.openfeature.sdk.providers.memory.InMemoryProvider; -import dev.openfeature.sdk.testutils.FeatureProviderTestUtils; -import dev.openfeature.sdk.testutils.TestEventsProvider; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.util.Collections; -import java.util.HashMap; - import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -16,6 +7,14 @@ import static org.mockito.Mockito.mock; 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; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + class OpenFeatureAPITest { private static final String DOMAIN_NAME = "my domain"; @@ -36,7 +35,10 @@ void namedProviderTest() { .isEqualTo(api.getProviderMetadata("namedProviderTest").getName()); } - @Specification(number = "1.1.3", text = "The API MUST provide a function to bind a given provider to one or more clients using a domain. If the domain already has a bound provider, it is overwritten with the new mapping.") + @Specification( + number = "1.1.3", + text = + "The API MUST provide a function to bind a given provider to one or more clients using a domain. If the domain already has a bound provider, it is overwritten with the new mapping.") @Test void namedProviderOverwrittenTest() { String domain = "namedProviderOverwrittenTest"; @@ -45,7 +47,10 @@ void namedProviderOverwrittenTest() { FeatureProviderTestUtils.setFeatureProvider(domain, provider1); FeatureProviderTestUtils.setFeatureProvider(domain, provider2); - assertThat(OpenFeatureAPI.getInstance().getProvider(domain).getMetadata().getName()) + assertThat(OpenFeatureAPI.getInstance() + .getProvider(domain) + .getMetadata() + .getName()) .isEqualTo(DoSomethingProvider.name); } @@ -105,7 +110,6 @@ void getStateReturnsTheStateOfTheAppropriateProvider() throws Exception { .isEqualTo(ProviderState.READY); } - @Test void featureProviderTrackIsCalled() throws Exception { FeatureProvider featureProvider = mock(FeatureProvider.class); @@ -113,9 +117,7 @@ void featureProviderTrackIsCalled() throws Exception { OpenFeatureAPI.getInstance() .getClient() - .track("track-event", - new ImmutableContext(), - new MutableTrackingEventDetails(22.2f)); + .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/OpenFeatureClientTest.java b/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java index 3c82fd656..50b5254c8 100644 --- a/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java +++ b/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java @@ -7,9 +7,11 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; +import dev.openfeature.sdk.exceptions.FatalError; +import dev.openfeature.sdk.fixtures.HookFixtures; +import dev.openfeature.sdk.testutils.TestEventsProvider; import java.util.HashMap; import java.util.concurrent.atomic.AtomicBoolean; - import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -18,10 +20,6 @@ import org.simplify4u.slf4jmock.LoggerMock; import org.slf4j.Logger; -import dev.openfeature.sdk.exceptions.FatalError; -import dev.openfeature.sdk.fixtures.HookFixtures; -import dev.openfeature.sdk.testutils.TestEventsProvider; - class OpenFeatureClientTest implements HookFixtures { private Logger logger; @@ -41,13 +39,15 @@ void reset_logs() { @DisplayName("should not throw exception if hook has different type argument than hookContext") void shouldNotThrowExceptionIfHookHasDifferentTypeArgumentThanHookContext() { OpenFeatureAPI api = OpenFeatureAPI.getInstance(); - api.setProviderAndWait("shouldNotThrowExceptionIfHookHasDifferentTypeArgumentThanHookContext", new DoSomethingProvider()); + api.setProviderAndWait( + "shouldNotThrowExceptionIfHookHasDifferentTypeArgumentThanHookContext", new DoSomethingProvider()); Client client = api.getClient("shouldNotThrowExceptionIfHookHasDifferentTypeArgumentThanHookContext"); client.addHooks(mockBooleanHook(), mockStringHook()); FlagEvaluationDetails actual = client.getBooleanDetails("feature key", Boolean.FALSE); assertThat(actual.getValue()).isTrue(); - // I dislike this, but given the mocking tools available, there's no way that I know of to say "no errors were logged" + // I dislike this, but given the mocking tools available, there's no way that I know of to say "no errors were + // logged" Mockito.verify(logger, never()).error(any()); Mockito.verify(logger, never()).error(anyString(), any(Throwable.class)); Mockito.verify(logger, never()).error(anyString(), any(Object.class)); @@ -78,7 +78,6 @@ void setEvaluationContextShouldAllowChaining() { assertEquals(client, result); } - @Test @DisplayName("Should not call evaluation methods when the provider has state FATAL") void shouldNotCallEvaluationMethodsWhenProviderIsInFatalErrorState() { @@ -86,7 +85,10 @@ void shouldNotCallEvaluationMethodsWhenProviderIsInFatalErrorState() { OpenFeatureAPI api = OpenFeatureAPI.getInstance(); Client client = api.getClient("shouldNotCallEvaluationMethodsWhenProviderIsInFatalErrorState"); - assertThrows(FatalError.class, () -> api.setProviderAndWait("shouldNotCallEvaluationMethodsWhenProviderIsInFatalErrorState", provider)); + assertThrows( + FatalError.class, + () -> api.setProviderAndWait( + "shouldNotCallEvaluationMethodsWhenProviderIsInFatalErrorState", provider)); FlagEvaluationDetails details = client.getBooleanDetails("key", true); assertThat(details.getErrorCode()).isEqualTo(ErrorCode.PROVIDER_FATAL); } @@ -126,7 +128,8 @@ public Metadata getMetadata() { } @Override - public ProviderEvaluation getBooleanEvaluation(String key, Boolean defaultValue, EvaluationContext ctx) { + public ProviderEvaluation getBooleanEvaluation( + String key, Boolean defaultValue, EvaluationContext ctx) { evaluationCalled.set(true); return null; } @@ -138,7 +141,8 @@ public ProviderEvaluation getStringEvaluation(String key, String default } @Override - public ProviderEvaluation getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx) { + public ProviderEvaluation getIntegerEvaluation( + String key, Integer defaultValue, EvaluationContext ctx) { evaluationCalled.set(true); return null; } diff --git a/src/test/java/dev/openfeature/sdk/ProviderEvaluationTest.java b/src/test/java/dev/openfeature/sdk/ProviderEvaluationTest.java index 16215dc1c..24762431e 100644 --- a/src/test/java/dev/openfeature/sdk/ProviderEvaluationTest.java +++ b/src/test/java/dev/openfeature/sdk/ProviderEvaluationTest.java @@ -27,13 +27,8 @@ public void sixArgConstructor() { String errorMessage = "message"; ImmutableMetadata metadata = ImmutableMetadata.builder().build(); - ProviderEvaluation details = new ProviderEvaluation<>( - value, - variant, - reason.toString(), - errorCode, - errorMessage, - metadata); + ProviderEvaluation details = + new ProviderEvaluation<>(value, variant, reason.toString(), errorCode, errorMessage, metadata); assertEquals(value, details.getValue()); assertEquals(variant, details.getVariant()); diff --git a/src/test/java/dev/openfeature/sdk/ProviderRepositoryTest.java b/src/test/java/dev/openfeature/sdk/ProviderRepositoryTest.java index 26a04d533..98652635d 100644 --- a/src/test/java/dev/openfeature/sdk/ProviderRepositoryTest.java +++ b/src/test/java/dev/openfeature/sdk/ProviderRepositoryTest.java @@ -1,12 +1,16 @@ package dev.openfeature.sdk; +import static dev.openfeature.sdk.fixtures.ProviderFixture.*; +import static dev.openfeature.sdk.testutils.stubbing.ConditionStubber.doDelayResponse; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.awaitility.Awaitility.await; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; + import dev.openfeature.sdk.exceptions.OpenFeatureError; import dev.openfeature.sdk.testutils.exception.TestException; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - import java.time.Duration; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -14,15 +18,10 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; - -import static dev.openfeature.sdk.fixtures.ProviderFixture.*; -import static dev.openfeature.sdk.testutils.stubbing.ConditionStubber.doDelayResponse; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.awaitility.Awaitility.await; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; class ProviderRepositoryTest { @@ -48,8 +47,9 @@ class DefaultProvider { @Test @DisplayName("should reject null as default provider") void shouldRejectNullAsDefaultProvider() { - assertThatCode(() -> providerRepository.setProvider(null, mockAfterSet(), mockAfterInit(), - mockAfterShutdown(), mockAfterError(), false)).isInstanceOf(IllegalArgumentException.class); + assertThatCode(() -> providerRepository.setProvider( + null, mockAfterSet(), mockAfterInit(), mockAfterShutdown(), mockAfterError(), false)) + .isInstanceOf(IllegalArgumentException.class); } @Test @@ -64,13 +64,17 @@ void shouldImmediatelyReturnWhenCallingTheProviderMutator() throws Exception { FeatureProvider featureProvider = createMockedProvider(); doDelayResponse(Duration.ofSeconds(10)).when(featureProvider).initialize(new ImmutableContext()); - await() - .alias("wait for provider mutator to return") + await().alias("wait for provider mutator to return") .pollDelay(Duration.ofMillis(1)) .atMost(Duration.ofSeconds(1)) .until(() -> { - providerRepository.setProvider(featureProvider, mockAfterSet(), mockAfterInit(), - mockAfterShutdown(), mockAfterError(), false); + providerRepository.setProvider( + featureProvider, + mockAfterSet(), + mockAfterInit(), + mockAfterShutdown(), + mockAfterError(), + false); verify(featureProvider, timeout(TIMEOUT)).initialize(any()); return true; }); @@ -85,8 +89,14 @@ class NamedProvider { @Test @DisplayName("should reject null as named provider") void shouldRejectNullAsNamedProvider() { - assertThatCode(() -> providerRepository.setProvider(DOMAIN_NAME, null, mockAfterSet(), mockAfterInit(), - mockAfterShutdown(), mockAfterError(), false)) + assertThatCode(() -> providerRepository.setProvider( + DOMAIN_NAME, + null, + mockAfterSet(), + mockAfterInit(), + mockAfterShutdown(), + mockAfterError(), + false)) .isInstanceOf(IllegalArgumentException.class); } @@ -94,8 +104,14 @@ void shouldRejectNullAsNamedProvider() { @DisplayName("should reject null as domain name") void shouldRejectNullAsDefaultProvider() { NoOpProvider provider = new NoOpProvider(); - assertThatCode(() -> providerRepository.setProvider(null, provider, mockAfterSet(), mockAfterInit(), - mockAfterShutdown(), mockAfterError(), false)) + assertThatCode(() -> providerRepository.setProvider( + null, + provider, + mockAfterSet(), + mockAfterInit(), + mockAfterShutdown(), + mockAfterError(), + false)) .isInstanceOf(IllegalArgumentException.class); } @@ -105,13 +121,18 @@ void shouldImmediatelyReturnWhenCallingTheDomainProviderMutator() throws Excepti FeatureProvider featureProvider = createMockedProvider(); doDelayResponse(Duration.ofSeconds(10)).when(featureProvider).initialize(any()); - await() - .alias("wait for provider mutator to return") + await().alias("wait for provider mutator to return") .pollDelay(Duration.ofMillis(1)) .atMost(Duration.ofSeconds(1)) .until(() -> { - providerRepository.setProvider("a domain", featureProvider, mockAfterSet(), - mockAfterInit(), mockAfterShutdown(), mockAfterError(), false); + providerRepository.setProvider( + "a domain", + featureProvider, + mockAfterSet(), + mockAfterInit(), + mockAfterShutdown(), + mockAfterError(), + false); verify(featureProvider, timeout(TIMEOUT)).initialize(any()); return true; }); @@ -131,13 +152,17 @@ void shouldImmediatelyReturnWhenCallingTheProviderMutator() throws Exception { FeatureProvider newProvider = createMockedProvider(); doDelayResponse(Duration.ofSeconds(10)).when(newProvider).initialize(any()); - await() - .alias("wait for provider mutator to return") + await().alias("wait for provider mutator to return") .pollDelay(Duration.ofMillis(1)) .atMost(Duration.ofSeconds(1)) .until(() -> { - providerRepository.setProvider(newProvider, mockAfterSet(), mockAfterInit(), - mockAfterShutdown(), mockAfterError(), false); + providerRepository.setProvider( + newProvider, + mockAfterSet(), + mockAfterInit(), + mockAfterShutdown(), + mockAfterError(), + false); verify(newProvider, timeout(TIMEOUT)).initialize(any()); return true; }); @@ -168,12 +193,16 @@ void shouldImmediatelyReturnWhenCallingTheProviderMutator() throws Exception { FeatureProvider newProvider = createMockedProvider(); doDelayResponse(Duration.ofSeconds(10)).when(newProvider).initialize(any()); - Future providerMutation = executorService - .submit(() -> providerRepository.setProvider(DOMAIN_NAME, newProvider, mockAfterSet(), - mockAfterInit(), mockAfterShutdown(), mockAfterError(), false)); + Future providerMutation = executorService.submit(() -> providerRepository.setProvider( + DOMAIN_NAME, + newProvider, + mockAfterSet(), + mockAfterInit(), + mockAfterShutdown(), + mockAfterError(), + false)); - await() - .alias("wait for provider mutator to return") + await().alias("wait for provider mutator to return") .pollDelay(Duration.ofMillis(1)) .atMost(Duration.ofSeconds(1)) .until(providerMutation::isDone); @@ -278,55 +307,47 @@ void shouldShutdownAllFeatureProvidersOnShutdown() { } private void setFeatureProvider(FeatureProvider provider) { - providerRepository.setProvider(provider, mockAfterSet(), mockAfterInit(), mockAfterShutdown(), - mockAfterError(), false); + providerRepository.setProvider( + provider, mockAfterSet(), mockAfterInit(), mockAfterShutdown(), mockAfterError(), false); waitForSettingProviderHasBeenCompleted(ProviderRepository::getProvider, provider); } - - private void setFeatureProvider(FeatureProvider provider, Consumer afterSet, - Consumer afterInit, Consumer afterShutdown, - BiConsumer afterError) { - providerRepository.setProvider(provider, afterSet, afterInit, afterShutdown, - afterError, false); + private void setFeatureProvider( + FeatureProvider provider, + Consumer afterSet, + Consumer afterInit, + Consumer afterShutdown, + BiConsumer afterError) { + providerRepository.setProvider(provider, afterSet, afterInit, afterShutdown, afterError, false); waitForSettingProviderHasBeenCompleted(ProviderRepository::getProvider, provider); } private void setFeatureProvider(String namedProvider, FeatureProvider provider) { - providerRepository.setProvider(namedProvider, provider, mockAfterSet(), mockAfterInit(), mockAfterShutdown(), - mockAfterError(), false); + providerRepository.setProvider( + namedProvider, provider, mockAfterSet(), mockAfterInit(), mockAfterShutdown(), mockAfterError(), false); waitForSettingProviderHasBeenCompleted(repository -> repository.getProvider(namedProvider), provider); } private void waitForSettingProviderHasBeenCompleted( - Function extractor, - FeatureProvider provider) { - await() - .pollDelay(Duration.ofMillis(1)) - .atMost(Duration.ofSeconds(5)) - .until(() -> { - return extractor.apply(providerRepository).equals(provider); - }); + Function extractor, FeatureProvider provider) { + await().pollDelay(Duration.ofMillis(1)).atMost(Duration.ofSeconds(5)).until(() -> { + return extractor.apply(providerRepository).equals(provider); + }); } private Consumer mockAfterSet() { - return fp -> { - }; + return fp -> {}; } private Consumer mockAfterInit() { - return fp -> { - }; + return fp -> {}; } private Consumer mockAfterShutdown() { - return fp -> { - }; + return fp -> {}; } private BiConsumer mockAfterError() { - return (fp, ex) -> { - }; + return (fp, ex) -> {}; } - } diff --git a/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java b/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java index a87cc5178..ec87acd70 100644 --- a/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java @@ -10,17 +10,31 @@ public class ProviderSpecTest { NoOpProvider p = new NoOpProvider(); - @Specification(number = "2.1.1", text = "The provider interface MUST define a metadata member or accessor, containing a name field or accessor of type string, which identifies the provider implementation.") + @Specification( + number = "2.1.1", + text = + "The provider interface MUST define a metadata member or accessor, containing a name field or accessor of type string, which identifies the provider implementation.") @Test void name_accessor() { assertNotNull(p.getName()); } - @Specification(number = "2.2.2.1", text = "The feature provider interface MUST define methods for typed " + - "flag resolution, including boolean, numeric, string, and structure.") - @Specification(number = "2.2.3", text = "In cases of normal execution, the `provider` MUST populate the `resolution details` structure's `value` field with the resolved flag value.") - @Specification(number = "2.2.1", text = "The `feature provider` interface MUST define methods to resolve flag values, with parameters `flag key` (string, required), `default value` (boolean | number | string | structure, required) and `evaluation context` (optional), which returns a `resolution details` structure.") - @Specification(number = "2.2.8.1", text = "The `resolution details` structure SHOULD accept a generic argument (or use an equivalent language feature) which indicates the type of the wrapped `value` field.") + @Specification( + number = "2.2.2.1", + text = "The feature provider interface MUST define methods for typed " + + "flag resolution, including boolean, numeric, string, and structure.") + @Specification( + number = "2.2.3", + text = + "In cases of normal execution, the `provider` MUST populate the `resolution details` structure's `value` field with the resolved flag value.") + @Specification( + number = "2.2.1", + text = + "The `feature provider` interface MUST define methods to resolve flag values, with parameters `flag key` (string, required), `default value` (boolean | number | string | structure, required) and `evaluation context` (optional), which returns a `resolution details` structure.") + @Specification( + number = "2.2.8.1", + text = + "The `resolution details` structure SHOULD accept a generic argument (or use an equivalent language feature) which indicates the type of the wrapped `value` field.") @Test void flag_value_set() { ProviderEvaluation int_result = p.getIntegerEvaluation("key", 4, new ImmutableContext()); @@ -37,31 +51,47 @@ void flag_value_set() { ProviderEvaluation object_result = p.getObjectEvaluation("key", new Value(), new ImmutableContext()); assertNotNull(object_result.getValue()); - } - @Specification(number = "2.2.5", text = "The `provider` SHOULD populate the `resolution details` structure's `reason` field with `\"STATIC\"`, `\"DEFAULT\",` `\"TARGETING_MATCH\"`, `\"SPLIT\"`, `\"CACHED\"`, `\"DISABLED\"`, `\"UNKNOWN\"`, `\"STALE\"`, `\"ERROR\"` or some other string indicating the semantic reason for the returned flag value.") + @Specification( + number = "2.2.5", + text = + "The `provider` SHOULD populate the `resolution details` structure's `reason` field with `\"STATIC\"`, `\"DEFAULT\",` `\"TARGETING_MATCH\"`, `\"SPLIT\"`, `\"CACHED\"`, `\"DISABLED\"`, `\"UNKNOWN\"`, `\"STALE\"`, `\"ERROR\"` or some other string indicating the semantic reason for the returned flag value.") @Test void has_reason() { ProviderEvaluation result = p.getBooleanEvaluation("key", false, new ImmutableContext()); assertEquals(Reason.DEFAULT.toString(), result.getReason()); } - @Specification(number = "2.2.6", text = "In cases of normal execution, the `provider` MUST NOT populate the `resolution details` structure's `error code` field, or otherwise must populate it with a null or falsy value.") + @Specification( + number = "2.2.6", + text = + "In cases of normal execution, the `provider` MUST NOT populate the `resolution details` structure's `error code` field, or otherwise must populate it with a null or falsy value.") @Test void no_error_code_by_default() { ProviderEvaluation result = p.getBooleanEvaluation("key", false, new ImmutableContext()); assertNull(result.getErrorCode()); } - @Specification(number = "2.2.7", text = "In cases of abnormal execution, the `provider` **MUST** indicate an error using the idioms of the implementation language, with an associated `error code` and optional associated `error message`.") - @Specification(number = "2.3.2", text = "In cases of normal execution, the `provider` MUST NOT populate the `resolution details` structure's `error message` field, or otherwise must populate it with a null or falsy value.") - @Specification(number = "2.3.3", text = "In cases of abnormal execution, the `resolution details` structure's `error message` field MAY contain a string containing additional detail about the nature of the error.") + @Specification( + number = "2.2.7", + text = + "In cases of abnormal execution, the `provider` **MUST** indicate an error using the idioms of the implementation language, with an associated `error code` and optional associated `error message`.") + @Specification( + number = "2.3.2", + text = + "In cases of normal execution, the `provider` MUST NOT populate the `resolution details` structure's `error message` field, or otherwise must populate it with a null or falsy value.") + @Specification( + number = "2.3.3", + text = + "In cases of abnormal execution, the `resolution details` structure's `error message` field MAY contain a string containing additional detail about the nature of the error.") @Test - void up_to_provider_implementation() { - } + void up_to_provider_implementation() {} - @Specification(number = "2.2.4", text = "In cases of normal execution, the `provider` SHOULD populate the `resolution details` structure's `variant` field with a string identifier corresponding to the returned flag value.") + @Specification( + number = "2.2.4", + text = + "In cases of normal execution, the `provider` SHOULD populate the `resolution details` structure's `variant` field with a string identifier corresponding to the returned flag value.") @Test void variant_set() { ProviderEvaluation int_result = p.getIntegerEvaluation("key", 4, new ImmutableContext()); @@ -77,7 +107,10 @@ void variant_set() { assertNotNull(boolean_result.getReason()); } - @Specification(number = "2.2.10", text = "`flag metadata` MUST be a structure supporting the definition of arbitrary properties, with keys of type `string`, and values of type `boolean | string | number`.") + @Specification( + number = "2.2.10", + text = + "`flag metadata` MUST be a structure supporting the definition of arbitrary properties, with keys of type `string`, and values of type `boolean | string | number`.") @Test void flag_metadata_structure() { ImmutableMetadata metadata = ImmutableMetadata.builder() @@ -97,30 +130,51 @@ void flag_metadata_structure() { assertEquals("str", metadata.getString("string")); } - @Specification(number = "2.3.1", text = "The provider interface MUST define a provider hook mechanism which can be optionally implemented in order to add hook instances to the evaluation life-cycle.") - @Specification(number = "4.4.1", text = "The API, Client, Provider, and invocation MUST have a method for registering hooks.") + @Specification( + number = "2.3.1", + text = + "The provider interface MUST define a provider hook mechanism which can be optionally implemented in order to add hook instances to the evaluation life-cycle.") + @Specification( + number = "4.4.1", + text = "The API, Client, Provider, and invocation MUST have a method for registering hooks.") @Test void provider_hooks() { assertEquals(0, p.getProviderHooks().size()); } - @Specification(number = "2.4.2", text = "The provider MAY define a status field/accessor which indicates the readiness of the provider, with possible values NOT_READY, READY, or ERROR.") + @Specification( + number = "2.4.2", + text = + "The provider MAY define a status field/accessor which indicates the readiness of the provider, with possible values NOT_READY, READY, or ERROR.") @Test void defines_status() { assertTrue(p.getState() instanceof ProviderState); } - @Specification(number = "2.4.3", text = "The provider MUST set its status field/accessor to READY if its initialize function terminates normally.") - @Specification(number = "2.4.4", text = "The provider MUST set its status field to ERROR if its initialize function terminates abnormally.") - @Specification(number = "2.2.9", text = "The provider SHOULD populate the resolution details structure's flag metadata field.") - @Specification(number = "2.4.1", text = "The provider MAY define an initialize function which accepts the global evaluation context as an argument and performs initialization logic relevant to the provider.") - @Specification(number = "2.5.1", text = "The provider MAY define a mechanism to gracefully shutdown and dispose of resources.") + @Specification( + number = "2.4.3", + text = + "The provider MUST set its status field/accessor to READY if its initialize function terminates normally.") + @Specification( + number = "2.4.4", + text = "The provider MUST set its status field to ERROR if its initialize function terminates abnormally.") + @Specification( + number = "2.2.9", + text = "The provider SHOULD populate the resolution details structure's flag metadata field.") + @Specification( + number = "2.4.1", + text = + "The provider MAY define an initialize function which accepts the global evaluation context as an argument and performs initialization logic relevant to the provider.") + @Specification( + number = "2.5.1", + text = "The provider MAY define a mechanism to gracefully shutdown and dispose of resources.") @Test - void provider_responsibility() { - } + void provider_responsibility() {} - @Specification(number = "2.6.1", text = "The provider MAY define an on context changed handler, which takes an argument for the previous context and the newly set context, in order to respond to an evaluation context change.") + @Specification( + number = "2.6.1", + text = + "The provider MAY define an on context changed handler, which takes an argument for the previous context and the newly set context, in order to respond to an evaluation context change.") @Test - void not_applicable_for_dynamic_context() { - } + void not_applicable_for_dynamic_context() {} } diff --git a/src/test/java/dev/openfeature/sdk/ShutdownBehaviorSpecTest.java b/src/test/java/dev/openfeature/sdk/ShutdownBehaviorSpecTest.java index bc2dc0ea9..e7caf9274 100644 --- a/src/test/java/dev/openfeature/sdk/ShutdownBehaviorSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/ShutdownBehaviorSpecTest.java @@ -1,18 +1,17 @@ package dev.openfeature.sdk; +import static dev.openfeature.sdk.testutils.FeatureProviderTestUtils.setFeatureProvider; +import static org.mockito.Mockito.*; + import dev.openfeature.sdk.fixtures.ProviderFixture; import dev.openfeature.sdk.testutils.exception.TestException; +import java.time.Duration; import org.awaitility.Awaitility; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import java.time.Duration; - -import static dev.openfeature.sdk.testutils.FeatureProviderTestUtils.setFeatureProvider; -import static org.mockito.Mockito.*; - class ShutdownBehaviorSpecTest { private String DOMAIN = "myDomain"; @@ -25,9 +24,13 @@ void resetFeatureProvider() { @Nested class DefaultProvider { - @Specification(number = "1.1.2.3", text = "The `provider mutator` function MUST invoke the `shutdown` function on the previously registered provider once it's no longer being used to resolve flag values.") + @Specification( + number = "1.1.2.3", + text = + "The `provider mutator` function MUST invoke the `shutdown` function on the previously registered provider once it's no longer being used to resolve flag values.") @Test - @DisplayName("must invoke shutdown method on previously registered provider once it should not be used for flag evaluation anymore") + @DisplayName( + "must invoke shutdown method on previously registered provider once it should not be used for flag evaluation anymore") void mustInvokeShutdownMethodOnPreviouslyRegisteredProviderOnceItShouldNotBeUsedForFlagEvaluationAnymore() { FeatureProvider featureProvider = ProviderFixture.createMockedProvider(); @@ -37,10 +40,12 @@ void mustInvokeShutdownMethodOnPreviouslyRegisteredProviderOnceItShouldNotBeUsed verify(featureProvider, timeout(1000)).shutdown(); } - @Specification(number = "1.4.10", text = "Methods, functions, or operations on the client MUST NOT throw " - + "exceptions, or otherwise abnormally terminate. Flag evaluation calls must always return the " - + "`default value` in the event of abnormal execution. Exceptions include functions or methods for " - + "the purposes for configuration or setup.") + @Specification( + number = "1.4.10", + text = "Methods, functions, or operations on the client MUST NOT throw " + + "exceptions, or otherwise abnormally terminate. Flag evaluation calls must always return the " + + "`default value` in the event of abnormal execution. Exceptions include functions or methods for " + + "the purposes for configuration or setup.") @Test @DisplayName("should catch exception thrown by the provider on shutdown") void shouldCatchExceptionThrownByTheProviderOnShutdown() { @@ -57,9 +62,13 @@ void shouldCatchExceptionThrownByTheProviderOnShutdown() { @Nested class NamedProvider { - @Specification(number = "1.1.2.3", text = "The `provider mutator` function MUST invoke the `shutdown` function on the previously registered provider once it's no longer being used to resolve flag values.") + @Specification( + number = "1.1.2.3", + text = + "The `provider mutator` function MUST invoke the `shutdown` function on the previously registered provider once it's no longer being used to resolve flag values.") @Test - @DisplayName("must invoke shutdown method on previously registered provider once it should not be used for flag evaluation anymore") + @DisplayName( + "must invoke shutdown method on previously registered provider once it should not be used for flag evaluation anymore") void mustInvokeShutdownMethodOnPreviouslyRegisteredProviderOnceItShouldNotBeUsedForFlagEvaluationAnymore() { FeatureProvider featureProvider = ProviderFixture.createMockedProvider(); @@ -69,10 +78,12 @@ void mustInvokeShutdownMethodOnPreviouslyRegisteredProviderOnceItShouldNotBeUsed verify(featureProvider, timeout(1000)).shutdown(); } - @Specification(number = "1.4.10", text = "Methods, functions, or operations on the client MUST NOT throw " - + "exceptions, or otherwise abnormally terminate. Flag evaluation calls must always return the " - + "`default value` in the event of abnormal execution. Exceptions include functions or methods for " - + "the purposes for configuration or setup.") + @Specification( + number = "1.4.10", + text = "Methods, functions, or operations on the client MUST NOT throw " + + "exceptions, or otherwise abnormally terminate. Flag evaluation calls must always return the " + + "`default value` in the event of abnormal execution. Exceptions include functions or methods for " + + "the purposes for configuration or setup.") @Test @DisplayName("should catch exception thrown by the named client provider on shutdown") void shouldCatchExceptionThrownByTheNamedClientProviderOnShutdown() { @@ -89,7 +100,9 @@ void shouldCatchExceptionThrownByTheNamedClientProviderOnShutdown() { @Nested class General { - @Specification(number = "1.6.1", text = "The API MUST define a mechanism to propagate a shutdown request to active providers.") + @Specification( + number = "1.6.1", + text = "The API MUST define a mechanism to propagate a shutdown request to active providers.") @Test @DisplayName("must shutdown all providers on shutting down api") void mustShutdownAllProvidersOnShuttingDownApi() { @@ -102,17 +115,13 @@ void mustShutdownAllProvidersOnShuttingDownApi() { synchronized (OpenFeatureAPI.class) { api.shutdown(); - Awaitility - .await() - .atMost(Duration.ofSeconds(1)) - .untilAsserted(() -> { - verify(defaultProvider).shutdown(); - verify(namedProvider).shutdown(); - }); + Awaitility.await().atMost(Duration.ofSeconds(1)).untilAsserted(() -> { + verify(defaultProvider).shutdown(); + verify(namedProvider).shutdown(); + }); } } - @Test @DisplayName("once shutdown is complete, api must be ready to use again") void apiIsReadyToUseAfterShutdown() { diff --git a/src/test/java/dev/openfeature/sdk/Specification.java b/src/test/java/dev/openfeature/sdk/Specification.java index 061e45ec5..c75e179c1 100644 --- a/src/test/java/dev/openfeature/sdk/Specification.java +++ b/src/test/java/dev/openfeature/sdk/Specification.java @@ -5,5 +5,6 @@ @Repeatable(Specifications.class) public @interface Specification { String number(); + String text(); } diff --git a/src/test/java/dev/openfeature/sdk/StructureTest.java b/src/test/java/dev/openfeature/sdk/StructureTest.java index 16747ee06..2a2406a54 100644 --- a/src/test/java/dev/openfeature/sdk/StructureTest.java +++ b/src/test/java/dev/openfeature/sdk/StructureTest.java @@ -1,7 +1,10 @@ package dev.openfeature.sdk; -import lombok.SneakyThrows; -import org.junit.jupiter.api.Test; +import static dev.openfeature.sdk.Structure.mapToStructure; +import static org.junit.jupiter.api.Assertions.assertEquals; +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.util.ArrayList; @@ -9,20 +12,18 @@ import java.util.HashMap; import java.util.List; import java.util.Map; - -import static dev.openfeature.sdk.Structure.mapToStructure; -import static org.junit.jupiter.api.Assertions.assertEquals; -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 lombok.SneakyThrows; +import org.junit.jupiter.api.Test; public class StructureTest { - @Test public void noArgShouldContainEmptyAttributes() { + @Test + public void noArgShouldContainEmptyAttributes() { MutableStructure structure = new MutableStructure(); assertEquals(0, structure.asMap().keySet().size()); } - @Test public void mapArgShouldContainNewMap() { + @Test + public void mapArgShouldContainNewMap() { String KEY = "key"; Map map = new HashMap() { { @@ -34,7 +35,8 @@ public class StructureTest { assertNotSame(structure.asMap(), map); // should be a copy } - @Test public void addAndGetAddAndReturnValues() { + @Test + public void addAndGetAddAndReturnValues() { String BOOL_KEY = "bool"; String STRING_KEY = "string"; String INT_KEY = "int"; @@ -104,7 +106,7 @@ void mapToStructureTest() { @Test void asObjectHandlesNullValue() { Map map = new HashMap<>(); - map.put("null", new Value((String)null)); + map.put("null", new Value((String) null)); ImmutableStructure structure = new ImmutableStructure(map); assertNull(structure.asObjectMap().get("null")); } @@ -112,6 +114,6 @@ void asObjectHandlesNullValue() { @Test void convertValueHandlesNullValue() { ImmutableStructure structure = new ImmutableStructure(); - assertNull(structure.convertValue(new Value((String)null))); + assertNull(structure.convertValue(new Value((String) null))); } } diff --git a/src/test/java/dev/openfeature/sdk/ThreadLocalTransactionContextPropagatorTest.java b/src/test/java/dev/openfeature/sdk/ThreadLocalTransactionContextPropagatorTest.java index 531205c16..2993f880b 100644 --- a/src/test/java/dev/openfeature/sdk/ThreadLocalTransactionContextPropagatorTest.java +++ b/src/test/java/dev/openfeature/sdk/ThreadLocalTransactionContextPropagatorTest.java @@ -1,12 +1,11 @@ package dev.openfeature.sdk; -import lombok.SneakyThrows; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; - -import static org.junit.jupiter.api.Assertions.*; +import lombok.SneakyThrows; +import org.junit.jupiter.api.Test; public class ThreadLocalTransactionContextPropagatorTest { @@ -54,4 +53,4 @@ public void setTransactionContextTwoThreads() { assertSame(secondContext, secondThreadContext); assertSame(firstContext, contextPropagator.getTransactionContext()); } -} \ No newline at end of file +} diff --git a/src/test/java/dev/openfeature/sdk/TrackingSpecTest.java b/src/test/java/dev/openfeature/sdk/TrackingSpecTest.java index 6d195607b..a8f6e30f3 100644 --- a/src/test/java/dev/openfeature/sdk/TrackingSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/TrackingSpecTest.java @@ -1,16 +1,5 @@ package dev.openfeature.sdk; -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 lombok.SneakyThrows; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.util.HashMap; -import java.util.Map; - import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -23,6 +12,16 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; +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; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + class TrackingSpecTest { private OpenFeatureAPI api; @@ -34,13 +33,16 @@ void getApiInstance() { client = api.getClient(); } - - @Specification(number = "6.1.1.1", text = "The `client` MUST define a function for tracking the occurrence of " + - "a particular action or application state, with parameters `tracking event name` (string, required), " + - "`evaluation context` (optional) and `tracking event details` (optional), which returns nothing.") - @Specification(number = "6.1.2.1", text = "The `client` MUST define a function for tracking the occurrence of a " + - "particular action or application state, with parameters `tracking event name` (string, required) and " + - "`tracking event details` (optional), which returns nothing.") + @Specification( + number = "6.1.1.1", + text = "The `client` MUST define a function for tracking the occurrence of " + + "a particular action or application state, with parameters `tracking event name` (string, required), " + + "`evaluation context` (optional) and `tracking event details` (optional), which returns nothing.") + @Specification( + number = "6.1.2.1", + text = "The `client` MUST define a function for tracking the occurrence of a " + + "particular action or application state, with parameters `tracking event name` (string, required) and " + + "`tracking event details` (optional), which returns nothing.") @Test @SneakyThrows void trackMethodFulfillsSpec() { @@ -65,7 +67,6 @@ void trackMethodFulfillsSpec() { assertThrows(IllegalArgumentException.class, () -> client.track("", ctx)); assertThrows(IllegalArgumentException.class, () -> client.track("", ctx, details)); - Class clientClass = OpenFeatureClient.class; assertEquals( void.class, @@ -73,20 +74,24 @@ void trackMethodFulfillsSpec() { "The method should return void."); assertEquals( void.class, - clientClass.getMethod("track", String.class, EvaluationContext.class).getReturnType(), + clientClass + .getMethod("track", String.class, EvaluationContext.class) + .getReturnType(), "The method should return void."); assertEquals( void.class, - clientClass.getMethod("track", String.class, EvaluationContext.class, TrackingEventDetails.class).getReturnType(), + clientClass + .getMethod("track", String.class, EvaluationContext.class, TrackingEventDetails.class) + .getReturnType(), "The method should return void."); - - } - @Specification(number = "6.1.3", text = "The evaluation context passed to the provider's track function " + - "MUST be merged in the order: API (global; lowest precedence) -> transaction -> client -> " + - "invocation (highest precedence), with duplicate values being overwritten.") + @Specification( + number = "6.1.3", + text = "The evaluation context passed to the provider's track function " + + "MUST be merged in the order: API (global; lowest precedence) -> transaction -> client -> " + + "invocation (highest precedence), with duplicate values being overwritten.") @Test void contextsGetMerged() { @@ -123,8 +128,10 @@ void contextsGetMerged() { verify(provider).track(eq("event"), argThat(ctx -> ctx.asMap().equals(expectedMap)), notNull()); } - @Specification(number = "6.1.4", text = "If the client's `track` function is called and the associated provider " + - "does not implement tracking, the client's `track` function MUST no-op.") + @Specification( + number = "6.1.4", + text = "If the client's `track` function is called and the associated provider " + + "does not implement tracking, the client's `track` function MUST no-op.") @Test void noopProvider() { FeatureProvider provider = spy(FeatureProvider.class); @@ -133,10 +140,15 @@ void noopProvider() { verify(provider).track(any(), any(), any()); } - @Specification(number = "6.2.1", text = "The `tracking event details` structure MUST define an optional numeric " + - "`value`, associating a scalar quality with an `tracking event`.") - @Specification(number = "6.2.2", text = "The `tracking event details` MUST support the inclusion of custom " + - "fields, having keys of type `string`, and values of type `boolean | string | number | structure`.") + @Specification( + number = "6.2.1", + text = "The `tracking event details` structure MUST define an optional numeric " + + "`value`, associating a scalar quality with an `tracking event`.") + @Specification( + number = "6.2.2", + text = + "The `tracking event details` MUST support the inclusion of custom " + + "fields, having keys of type `string`, and values of type `boolean | string | number | structure`.") @Test void eventDetails() { assertFalse(new MutableTrackingEventDetails().getValue().isPresent()); @@ -144,7 +156,6 @@ void eventDetails() { assertThat(new ImmutableTrackingEventDetails(2).getValue()).hasValue(2); assertThat(new MutableTrackingEventDetails(9.87f).getValue()).hasValue(9.87f); - // using mutable tracking event details Map expectedMap = Maps.newHashMap(); expectedMap.put("my-str", new Value("str")); @@ -159,31 +170,27 @@ void eventDetails() { .add("my-struct", new Value(new MutableTrackingEventDetails())); assertEquals(expectedMap, details.asMap()); - assertThatCode(() -> OpenFeatureAPI.getInstance().getClient(). - track( - "tracking-event-name", - new ImmutableContext(), - new MutableTrackingEventDetails())) + assertThatCode(() -> OpenFeatureAPI.getInstance() + .getClient() + .track("tracking-event-name", new ImmutableContext(), new MutableTrackingEventDetails())) .doesNotThrowAnyException(); - // using immutable tracking event details - ImmutableMap expectedImmutable = ImmutableMap.of("my-str", new Value("str"), - "my-num", new Value(1), - "my-bool", new Value(true), - "my-struct", new Value(new ImmutableStructure()) - ); + ImmutableMap expectedImmutable = ImmutableMap.of( + "my-str", + new Value("str"), + "my-num", + new Value(1), + "my-bool", + new Value(true), + "my-struct", + new Value(new ImmutableStructure())); ImmutableTrackingEventDetails immutableDetails = new ImmutableTrackingEventDetails(2, expectedMap); assertEquals(expectedImmutable, immutableDetails.asMap()); - assertThatCode(() -> OpenFeatureAPI.getInstance().getClient(). - track( - "tracking-event-name", - new ImmutableContext(), - new ImmutableTrackingEventDetails())) + assertThatCode(() -> OpenFeatureAPI.getInstance() + .getClient() + .track("tracking-event-name", new ImmutableContext(), new ImmutableTrackingEventDetails())) .doesNotThrowAnyException(); - - } - } diff --git a/src/test/java/dev/openfeature/sdk/ValueTest.java b/src/test/java/dev/openfeature/sdk/ValueTest.java index 816190ab8..c25538508 100644 --- a/src/test/java/dev/openfeature/sdk/ValueTest.java +++ b/src/test/java/dev/openfeature/sdk/ValueTest.java @@ -9,16 +9,17 @@ import java.time.Instant; import java.util.ArrayList; import java.util.List; - import org.junit.jupiter.api.Test; public class ValueTest { - @Test public void noArgShouldContainNull() { + @Test + public void noArgShouldContainNull() { Value value = new Value(); assertTrue(value.isNull()); } - @Test public void objectArgShouldContainObject() { + @Test + public void objectArgShouldContainObject() { try { // int is a special case, see intObjectArgShouldConvertToInt() List list = new ArrayList<>(); @@ -30,7 +31,7 @@ public class ValueTest { list.add(Instant.now()); int i = 0; - for (Object l: list) { + for (Object l : list) { Value value = new Value(l); assertEquals(list.get(i), value.asObject()); i++; @@ -40,7 +41,8 @@ public class ValueTest { } } - @Test public void intObjectArgShouldConvertToInt() { + @Test + public void intObjectArgShouldConvertToInt() { try { Object innerValue = 1; Value value = new Value(innerValue); @@ -50,7 +52,8 @@ public class ValueTest { } } - @Test public void invalidObjectArgShouldThrow() { + @Test + public void invalidObjectArgShouldThrow() { class Something {} @@ -59,18 +62,20 @@ class Something {} }); } - @Test public void boolArgShouldContainBool() { + @Test + public void boolArgShouldContainBool() { boolean innerValue = true; Value value = new Value(innerValue); assertTrue(value.isBoolean()); assertEquals(innerValue, value.asBoolean()); } - @Test public void numericArgShouldReturnDoubleOrInt() { + @Test + public void numericArgShouldReturnDoubleOrInt() { double innerDoubleValue = 1.75; Value doubleValue = new Value(innerDoubleValue); assertTrue(doubleValue.isNumber()); - assertEquals(1, doubleValue.asInteger()); // the double value represented by this object converted to type int + assertEquals(1, doubleValue.asInteger()); // the double value represented by this object converted to type int assertEquals(1.75, doubleValue.asDouble()); int innerIntValue = 100; @@ -80,21 +85,24 @@ class Something {} assertEquals(innerIntValue, intValue.asDouble()); } - @Test public void stringArgShouldContainString() { + @Test + public void stringArgShouldContainString() { String innerValue = "hi!"; Value value = new Value(innerValue); assertTrue(value.isString()); assertEquals(innerValue, value.asString()); } - @Test public void dateShouldContainDate() { + @Test + public void dateShouldContainDate() { Instant innerValue = Instant.now(); Value value = new Value(innerValue); assertTrue(value.isInstant()); assertEquals(innerValue, value.asInstant()); } - @Test public void structureShouldContainStructure() { + @Test + public void structureShouldContainStructure() { String INNER_KEY = "key"; String INNER_VALUE = "val"; MutableStructure innerValue = new MutableStructure().add(INNER_KEY, INNER_VALUE); @@ -103,7 +111,8 @@ class Something {} assertEquals(INNER_VALUE, value.asStructure().getValue(INNER_KEY).asString()); } - @Test public void listArgShouldContainList() { + @Test + public void listArgShouldContainList() { String ITEM_VALUE = "val"; List innerValue = new ArrayList(); innerValue.add(new Value(ITEM_VALUE)); @@ -112,7 +121,8 @@ class Something {} assertEquals(ITEM_VALUE, value.asList().get(0).asString()); } - @Test public void listMustBeOfValues() { + @Test + public void listMustBeOfValues() { String item = "item"; List list = new ArrayList<>(); list.add(item); @@ -124,7 +134,8 @@ class Something {} } } - @Test public void emptyListAllowed() { + @Test + public void emptyListAllowed() { List list = new ArrayList<>(); try { Value value = new Value((Object) list); @@ -136,15 +147,17 @@ class Something {} } } - @Test public void valueConstructorValidateListInternals() { + @Test + public void valueConstructorValidateListInternals() { List list = new ArrayList<>(); list.add(new Value("item")); list.add("item"); - assertThrows(InstantiationException.class, ()-> new Value(list)); + assertThrows(InstantiationException.class, () -> new Value(list)); } - @Test public void noOpFinalize() { + @Test + public void noOpFinalize() { Value val = new Value(); assertDoesNotThrow(val::finalize); // does nothing, but we want to defined in and make it final. } diff --git a/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java b/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java index cb9422e32..5bc89d03d 100644 --- a/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java +++ b/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java @@ -6,17 +6,6 @@ import static dev.openfeature.sdk.testutils.TestFlagsUtils.OBJECT_FLAG_KEY; import static dev.openfeature.sdk.testutils.TestFlagsUtils.STRING_FLAG_KEY; -import java.util.Map; -import java.util.HashMap; -import java.util.Optional; - -import org.openjdk.jmh.annotations.Benchmark; -import org.openjdk.jmh.annotations.BenchmarkMode; -import org.openjdk.jmh.annotations.Fork; -import org.openjdk.jmh.annotations.Measurement; -import org.openjdk.jmh.annotations.Mode; -import org.openjdk.jmh.annotations.Warmup; - import dev.openfeature.sdk.Client; import dev.openfeature.sdk.EvaluationContext; import dev.openfeature.sdk.Hook; @@ -26,6 +15,13 @@ import dev.openfeature.sdk.NoOpProvider; import dev.openfeature.sdk.OpenFeatureAPI; import dev.openfeature.sdk.Value; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Mode; /** * Runs a large volume of flag evaluations on a VM with 1G memory and GC @@ -38,7 +34,7 @@ public class AllocationBenchmark { @Benchmark @BenchmarkMode(Mode.SingleShotTime) - @Fork(jvmArgsAppend = { "-Xmx1024m", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseEpsilonGC" }) + @Fork(jvmArgsAppend = {"-Xmx1024m", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseEpsilonGC"}) public void run() { OpenFeatureAPI.getInstance().setProviderAndWait(new NoOpProvider()); @@ -50,7 +46,7 @@ public void run() { Client client = OpenFeatureAPI.getInstance().getClient(); Map clientAttrs = new HashMap<>(); - clientAttrs.put("client", new Value(2)); + clientAttrs.put("client", new Value(2)); client.setEvaluationContext(new ImmutableContext(clientAttrs)); client.addHooks(new Hook() { @Override @@ -60,7 +56,7 @@ public Optional before(HookContext ctx, Map invocationAttrs = new HashMap<>(); - invocationAttrs.put("invoke", new Value(3)); + invocationAttrs.put("invoke", new Value(3)); EvaluationContext invocationContext = new ImmutableContext(invocationAttrs); for (int i = 0; i < ITERATIONS; i++) { diff --git a/src/test/java/dev/openfeature/sdk/benchmark/AllocationProfiler.java b/src/test/java/dev/openfeature/sdk/benchmark/AllocationProfiler.java index 8051a167e..db048f8d7 100644 --- a/src/test/java/dev/openfeature/sdk/benchmark/AllocationProfiler.java +++ b/src/test/java/dev/openfeature/sdk/benchmark/AllocationProfiler.java @@ -8,7 +8,6 @@ import java.io.PrintStream; import java.util.ArrayList; import java.util.Collection; - import org.openjdk.jmh.infra.BenchmarkParams; import org.openjdk.jmh.infra.IterationParams; import org.openjdk.jmh.profile.InternalProfiler; @@ -45,16 +44,16 @@ public void beforeIteration(BenchmarkParams benchmarkParams, IterationParams ite } @Override - public Collection afterIteration(BenchmarkParams benchmarkParams, IterationParams iterationParams, - IterationResult result) { + public Collection afterIteration( + BenchmarkParams benchmarkParams, IterationParams iterationParams, IterationResult result) { long totalHeap = Runtime.getRuntime().totalMemory(); AllocationTotals allocationTotals = AllocationProfiler.printHeapHistogram(System.out, 120); Collection results = new ArrayList<>(); results.add(new ScalarResult("+totalHeap", totalHeap, "bytes", AggregationPolicy.MAX)); - results.add(new ScalarResult("+totalAllocatedInstances", allocationTotals.instances, "instances", - AggregationPolicy.MAX)); + results.add(new ScalarResult( + "+totalAllocatedInstances", allocationTotals.instances, "instances", AggregationPolicy.MAX)); results.add(new ScalarResult("+totalAllocatedBytes", allocationTotals.bytes, "bytes", AggregationPolicy.MAX)); return results; @@ -66,25 +65,19 @@ private static String getJmapExcutable() { if (javaHome.endsWith(jreDir)) { javaHome = javaHome.substring(0, javaHome.length() - jreDir.length()); } - return (javaHome + - File.separator + - "bin" + - File.separator + - "jmap" + - (Utils.isWindows() ? ".exe" : "")); + return (javaHome + File.separator + "bin" + File.separator + "jmap" + (Utils.isWindows() ? ".exe" : "")); } // runs JMAP executable in a new process to collect a heap dump - // heavily inspired by: https://github.com/cache2k/cache2k-benchmark/blob/master/jmh-suite/src/main/java/org/cache2k/benchmark/jmh/HeapProfiler.java + // heavily inspired by: + // https://github.com/cache2k/cache2k-benchmark/blob/master/jmh-suite/src/main/java/org/cache2k/benchmark/jmh/HeapProfiler.java private static AllocationTotals printHeapHistogram(PrintStream out, int maxLines) { long totalBytes = 0; long totalInstances = 0; boolean partial = false; try { - Process jmapProcess = Runtime.getRuntime().exec(new String[] { - getJmapExcutable(), - "-histo:live", - Long.toString(Utils.getPid()) }); + Process jmapProcess = Runtime.getRuntime() + .exec(new String[] {getJmapExcutable(), "-histo:live", Long.toString(Utils.getPid())}); InputStream in = jmapProcess.getInputStream(); LineNumberReader r = new LineNumberReader(new InputStreamReader(in)); String line; @@ -121,4 +114,4 @@ private static AllocationTotals printHeapHistogram(PrintStream out, int maxLines } return new AllocationTotals(totalInstances, totalBytes); } -} \ No newline at end of file +} diff --git a/src/test/java/dev/openfeature/sdk/e2e/EvaluationTest.java b/src/test/java/dev/openfeature/sdk/e2e/EvaluationTest.java index 3e0f2ee89..8a3381412 100644 --- a/src/test/java/dev/openfeature/sdk/e2e/EvaluationTest.java +++ b/src/test/java/dev/openfeature/sdk/e2e/EvaluationTest.java @@ -1,21 +1,16 @@ package dev.openfeature.sdk.e2e; +import static io.cucumber.junit.platform.engine.Constants.GLUE_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.Suite; -import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME; -import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME; - @Suite @IncludeEngines("cucumber") @SelectClasspathResource("features/evaluation.feature") @ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "pretty") @ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "dev.openfeature.sdk.e2e.evaluation") -public class EvaluationTest { - -} - - - +public class EvaluationTest {} diff --git a/src/test/java/dev/openfeature/sdk/e2e/evaluation/StepDefinitions.java b/src/test/java/dev/openfeature/sdk/e2e/evaluation/StepDefinitions.java index cf1905926..c1e56429d 100644 --- a/src/test/java/dev/openfeature/sdk/e2e/evaluation/StepDefinitions.java +++ b/src/test/java/dev/openfeature/sdk/e2e/evaluation/StepDefinitions.java @@ -1,27 +1,26 @@ package dev.openfeature.sdk.e2e.evaluation; -import dev.openfeature.sdk.Value; -import dev.openfeature.sdk.EvaluationContext; -import dev.openfeature.sdk.Reason; +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; +import dev.openfeature.sdk.FlagEvaluationDetails; +import dev.openfeature.sdk.ImmutableContext; import dev.openfeature.sdk.OpenFeatureAPI; +import dev.openfeature.sdk.Reason; import dev.openfeature.sdk.Structure; -import dev.openfeature.sdk.ImmutableContext; -import dev.openfeature.sdk.FlagEvaluationDetails; +import dev.openfeature.sdk.Value; import dev.openfeature.sdk.providers.memory.Flag; import dev.openfeature.sdk.providers.memory.InMemoryProvider; import io.cucumber.java.BeforeAll; import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import io.cucumber.java.en.When; -import lombok.SneakyThrows; - import java.util.HashMap; import java.util.Map; - -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 lombok.SneakyThrows; public class StepDefinitions { @@ -66,8 +65,8 @@ public static void setup() { // boolean value @When("a boolean flag with key {string} is evaluated with default value {string}") - public void a_boolean_flag_with_key_boolean_flag_is_evaluated_with_default_value_false(String flagKey, - String defaultValue) { + public void a_boolean_flag_with_key_boolean_flag_is_evaluated_with_default_value_false( + String flagKey, String defaultValue) { this.booleanFlagValue = client.getBooleanValue(flagKey, Boolean.valueOf(defaultValue)); } @@ -115,12 +114,19 @@ public void an_object_flag_with_key_is_evaluated_with_a_null_default_value(Strin this.objectFlagValue = client.getObjectValue(flagKey, new Value()); } - @Then("the resolved object value should be contain fields {string}, {string}, and {string}, with values {string}, {string} and {int}, respectively") - public void the_resolved_object_value_should_be_contain_fields_and_with_values_and_respectively(String boolField, - String stringField, String numberField, String boolValue, String stringValue, int numberValue) { + @Then( + "the resolved object value should be contain fields {string}, {string}, and {string}, with values {string}, {string} and {int}, respectively") + public void the_resolved_object_value_should_be_contain_fields_and_with_values_and_respectively( + String boolField, + String stringField, + String numberField, + String boolValue, + String stringValue, + int numberValue) { Structure structure = this.objectFlagValue.asStructure(); - assertEquals(Boolean.valueOf(boolValue), structure.asMap().get(boolField).asBoolean()); + assertEquals( + Boolean.valueOf(boolValue), structure.asMap().get(boolField).asBoolean()); assertEquals(stringValue, structure.asMap().get(stringField).asString()); assertEquals(numberValue, structure.asMap().get(numberField).asInteger()); } @@ -131,15 +137,15 @@ public void the_resolved_object_value_should_be_contain_fields_and_with_values_a // boolean details @When("a boolean flag with key {string} is evaluated with details and default value {string}") - public void a_boolean_flag_with_key_is_evaluated_with_details_and_default_value(String flagKey, - String defaultValue) { + public void a_boolean_flag_with_key_is_evaluated_with_details_and_default_value( + String flagKey, String defaultValue) { this.booleanFlagDetails = client.getBooleanDetails(flagKey, Boolean.valueOf(defaultValue)); } - @Then("the resolved boolean details value should be {string}, the variant should be {string}, and the reason should be {string}") + @Then( + "the resolved boolean details value should be {string}, the variant should be {string}, and the reason should be {string}") public void the_resolved_boolean_value_should_be_the_variant_should_be_and_the_reason_should_be( - String expectedValue, - String expectedVariant, String expectedReason) { + String expectedValue, String expectedVariant, String expectedReason) { assertEquals(Boolean.valueOf(expectedValue), booleanFlagDetails.getValue()); assertEquals(expectedVariant, booleanFlagDetails.getVariant()); assertEquals(expectedReason, booleanFlagDetails.getReason()); @@ -147,14 +153,15 @@ public void the_resolved_boolean_value_should_be_the_variant_should_be_and_the_r // string details @When("a string flag with key {string} is evaluated with details and default value {string}") - public void a_string_flag_with_key_is_evaluated_with_details_and_default_value(String flagKey, - String defaultValue) { + public void a_string_flag_with_key_is_evaluated_with_details_and_default_value( + String flagKey, String defaultValue) { this.stringFlagDetails = client.getStringDetails(flagKey, defaultValue); } - @Then("the resolved string details value should be {string}, the variant should be {string}, and the reason should be {string}") - public void the_resolved_string_value_should_be_the_variant_should_be_and_the_reason_should_be(String expectedValue, - String expectedVariant, String expectedReason) { + @Then( + "the resolved string details value should be {string}, the variant should be {string}, and the reason should be {string}") + public void the_resolved_string_value_should_be_the_variant_should_be_and_the_reason_should_be( + String expectedValue, String expectedVariant, String expectedReason) { assertEquals(expectedValue, this.stringFlagDetails.getValue()); assertEquals(expectedVariant, this.stringFlagDetails.getVariant()); assertEquals(expectedReason, this.stringFlagDetails.getReason()); @@ -166,9 +173,10 @@ public void an_integer_flag_with_key_is_evaluated_with_details_and_default_value this.intFlagDetails = client.getIntegerDetails(flagKey, defaultValue); } - @Then("the resolved integer details value should be {int}, the variant should be {string}, and the reason should be {string}") - public void the_resolved_integer_value_should_be_the_variant_should_be_and_the_reason_should_be(int expectedValue, - String expectedVariant, String expectedReason) { + @Then( + "the resolved integer details value should be {int}, the variant should be {string}, and the reason should be {string}") + public void the_resolved_integer_value_should_be_the_variant_should_be_and_the_reason_should_be( + int expectedValue, String expectedVariant, String expectedReason) { assertEquals(expectedValue, this.intFlagDetails.getValue()); assertEquals(expectedVariant, this.intFlagDetails.getVariant()); assertEquals(expectedReason, this.intFlagDetails.getReason()); @@ -180,9 +188,10 @@ public void a_float_flag_with_key_is_evaluated_with_details_and_default_value(St this.doubleFlagDetails = client.getDoubleDetails(flagKey, defaultValue); } - @Then("the resolved float details value should be {double}, the variant should be {string}, and the reason should be {string}") - public void the_resolved_float_value_should_be_the_variant_should_be_and_the_reason_should_be(double expectedValue, - String expectedVariant, String expectedReason) { + @Then( + "the resolved float details value should be {double}, the variant should be {string}, and the reason should be {string}") + public void the_resolved_float_value_should_be_the_variant_should_be_and_the_reason_should_be( + double expectedValue, String expectedVariant, String expectedReason) { assertEquals(expectedValue, this.doubleFlagDetails.getValue()); assertEquals(expectedVariant, this.doubleFlagDetails.getVariant()); assertEquals(expectedReason, this.doubleFlagDetails.getReason()); @@ -194,13 +203,19 @@ public void an_object_flag_with_key_is_evaluated_with_details_and_a_null_default this.objectFlagDetails = client.getObjectDetails(flagKey, new Value()); } - @Then("the resolved object details value should be contain fields {string}, {string}, and {string}, with values {string}, {string} and {int}, respectively") + @Then( + "the resolved object details value should be contain fields {string}, {string}, and {string}, with values {string}, {string} and {int}, respectively") public void the_resolved_object_value_should_be_contain_fields_and_with_values_and_respectively_again( String boolField, - String stringField, String numberField, String boolValue, String stringValue, int numberValue) { + String stringField, + String numberField, + String boolValue, + String stringValue, + int numberValue) { Structure structure = this.objectFlagDetails.getValue().asStructure(); - assertEquals(Boolean.valueOf(boolValue), structure.asMap().get(boolField).asBoolean()); + assertEquals( + Boolean.valueOf(boolValue), structure.asMap().get(boolField).asBoolean()); assertEquals(stringValue, structure.asMap().get(stringField).asString()); assertEquals(numberValue, structure.asMap().get(numberField).asInteger()); } @@ -215,9 +230,17 @@ public void the_variant_should_be_and_the_reason_should_be(String expectedVarian * Context-aware evaluation */ - @When("context contains keys {string}, {string}, {string}, {string} with values {string}, {string}, {int}, {string}") - public void context_contains_keys_with_values(String field1, String field2, String field3, String field4, - String value1, String value2, Integer value3, String value4) { + @When( + "context contains keys {string}, {string}, {string}, {string} with values {string}, {string}, {int}, {string}") + public void context_contains_keys_with_values( + String field1, + String field2, + String field3, + String field4, + String value1, + String value2, + Integer value3, + String value4) { Map attributes = new HashMap<>(); attributes.put(field1, new Value(value1)); attributes.put(field2, new Value(value2)); @@ -231,7 +254,6 @@ public void an_a_flag_with_key_is_evaluated(String flagKey, String defaultValue) contextAwareFlagKey = flagKey; contextAwareDefaultValue = defaultValue; contextAwareValue = client.getStringValue(flagKey, contextAwareDefaultValue, context); - } @Then("the resolved string response should be {string}") @@ -241,8 +263,8 @@ public void the_resolved_string_response_should_be(String expected) { @Then("the resolved flag value is {string} when the context is empty") public void the_resolved_flag_value_is_when_the_context_is_empty(String expected) { - String emptyContextValue = client.getStringValue(contextAwareFlagKey, contextAwareDefaultValue, - new ImmutableContext()); + String emptyContextValue = + client.getStringValue(contextAwareFlagKey, contextAwareDefaultValue, new ImmutableContext()); assertEquals(expected, emptyContextValue); } @@ -252,8 +274,8 @@ public void the_resolved_flag_value_is_when_the_context_is_empty(String expected // not found @When("a non-existent string flag with key {string} is evaluated with details and a default value {string}") - public void a_non_existent_string_flag_with_key_is_evaluated_with_details_and_a_default_value(String flagKey, - String defaultValue) { + public void a_non_existent_string_flag_with_key_is_evaluated_with_details_and_a_default_value( + String flagKey, String defaultValue) { notFoundFlagKey = flagKey; notFoundDefaultValue = defaultValue; notFoundDetails = client.getStringDetails(notFoundFlagKey, notFoundDefaultValue); @@ -272,8 +294,8 @@ public void the_reason_should_indicate_an_error_and_the_error_code_should_be_fla // type mismatch @When("a string flag with key {string} is evaluated as an integer, with details and a default value {int}") - public void a_string_flag_with_key_is_evaluated_as_an_integer_with_details_and_a_default_value(String flagKey, - int defaultValue) { + public void a_string_flag_with_key_is_evaluated_as_an_integer_with_details_and_a_default_value( + String flagKey, int defaultValue) { typeErrorFlagKey = flagKey; typeErrorDefaultValue = defaultValue; typeErrorDetails = client.getIntegerDetails(typeErrorFlagKey, typeErrorDefaultValue); @@ -289,5 +311,4 @@ public void the_reason_should_indicate_an_error_and_the_error_code_should_be_typ assertEquals(Reason.ERROR.toString(), typeErrorDetails.getReason()); assertTrue(typeErrorDetails.getErrorCode().name().equals(errorCode)); } - } diff --git a/src/test/java/dev/openfeature/sdk/exceptions/ExceptionUtilsTest.java b/src/test/java/dev/openfeature/sdk/exceptions/ExceptionUtilsTest.java index 58e594575..0a9a522cf 100644 --- a/src/test/java/dev/openfeature/sdk/exceptions/ExceptionUtilsTest.java +++ b/src/test/java/dev/openfeature/sdk/exceptions/ExceptionUtilsTest.java @@ -1,6 +1,10 @@ package dev.openfeature.sdk.exceptions; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; + import dev.openfeature.sdk.ErrorCode; +import java.util.stream.Stream; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; @@ -8,11 +12,6 @@ import org.junit.jupiter.params.provider.ArgumentsProvider; import org.junit.jupiter.params.provider.ArgumentsSource; -import java.util.stream.Stream; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; - class ExceptionUtilsTest { @ParameterizedTest @@ -38,8 +37,7 @@ public Stream provideArguments(ExtensionContext context) { Arguments.of(ErrorCode.INVALID_CONTEXT, InvalidContextError.class), Arguments.of(ErrorCode.PARSE_ERROR, ParseError.class), Arguments.of(ErrorCode.TARGETING_KEY_MISSING, TargetingKeyMissingError.class), - Arguments.of(ErrorCode.TYPE_MISMATCH, TypeMismatchError.class) - ); + Arguments.of(ErrorCode.TYPE_MISMATCH, TypeMismatchError.class)); } } } diff --git a/src/test/java/dev/openfeature/sdk/fixtures/HookFixtures.java b/src/test/java/dev/openfeature/sdk/fixtures/HookFixtures.java index 9886c3834..b94e58a11 100644 --- a/src/test/java/dev/openfeature/sdk/fixtures/HookFixtures.java +++ b/src/test/java/dev/openfeature/sdk/fixtures/HookFixtures.java @@ -1,13 +1,13 @@ package dev.openfeature.sdk.fixtures; +import static org.mockito.Mockito.spy; + import dev.openfeature.sdk.BooleanHook; import dev.openfeature.sdk.DoubleHook; import dev.openfeature.sdk.Hook; import dev.openfeature.sdk.IntegerHook; import dev.openfeature.sdk.StringHook; -import static org.mockito.Mockito.spy; - public interface HookFixtures { default Hook mockBooleanHook() { @@ -29,5 +29,4 @@ default Hook mockDoubleHook() { default Hook mockGenericHook() { return spy(Hook.class); } - } diff --git a/src/test/java/dev/openfeature/sdk/fixtures/ProviderFixture.java b/src/test/java/dev/openfeature/sdk/fixtures/ProviderFixture.java index c00b8ff27..b9c6bc159 100644 --- a/src/test/java/dev/openfeature/sdk/fixtures/ProviderFixture.java +++ b/src/test/java/dev/openfeature/sdk/fixtures/ProviderFixture.java @@ -7,15 +7,13 @@ import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; -import java.io.FileNotFoundException; -import java.util.concurrent.CountDownLatch; - -import org.mockito.stubbing.Answer; - import dev.openfeature.sdk.FeatureProvider; import dev.openfeature.sdk.ImmutableContext; import dev.openfeature.sdk.ProviderState; +import java.io.FileNotFoundException; +import java.util.concurrent.CountDownLatch; import lombok.experimental.UtilityClass; +import org.mockito.stubbing.Answer; @UtilityClass public class ProviderFixture { @@ -56,11 +54,12 @@ private static Answer createAnswerExecutingCode(Runnable onAnswer) { public static FeatureProvider createUnblockingProvider(CountDownLatch latch) throws Exception { FeatureProvider provider = createMockedProvider(); doAnswer(invocation -> { - latch.countDown(); - return null; - }).when(provider).initialize(new ImmutableContext()); + latch.countDown(); + return null; + }) + .when(provider) + .initialize(new ImmutableContext()); doReturn("unblockingProvider").when(provider).toString(); return provider; } - } diff --git a/src/test/java/dev/openfeature/sdk/hooks/logging/LoggingHookTest.java b/src/test/java/dev/openfeature/sdk/hooks/logging/LoggingHookTest.java index fad24caf7..b7e463ad7 100644 --- a/src/test/java/dev/openfeature/sdk/hooks/logging/LoggingHookTest.java +++ b/src/test/java/dev/openfeature/sdk/hooks/logging/LoggingHookTest.java @@ -45,18 +45,24 @@ class LoggingHookTest { void each() { // create a fake hook context - hookContext = HookContext.builder().flagKey(FLAG_KEY).defaultValue(DEFAULT_VALUE) + hookContext = HookContext.builder() + .flagKey(FLAG_KEY) + .defaultValue(DEFAULT_VALUE) .clientMetadata(new ClientMetadata() { @Override public String getDomain() { return DOMAIN; } - }).providerMetadata(new Metadata() { + }) + .providerMetadata(new Metadata() { @Override public String getName() { return PROVIDER_NAME; } - }).type(FlagValueType.BOOLEAN).ctx(new ImmutableContext()).build(); + }) + .type(FlagValueType.BOOLEAN) + .ctx(new ImmutableContext()) + .build(); // mock logging logger = mock(Logger.class); @@ -95,7 +101,11 @@ void beforeLogsAllPropsAndEvaluationContext() { @Test void afterLogsAllPropsExceptEvaluationContext() { LoggingHook hook = new LoggingHook(); - FlagEvaluationDetails details = FlagEvaluationDetails.builder().reason(REASON).variant(VARIANT).value(VALUE).build(); + FlagEvaluationDetails details = FlagEvaluationDetails.builder() + .reason(REASON) + .variant(VARIANT) + .value(VALUE) + .build(); hook.after(hookContext, details, null); verify(logger).atDebug(); @@ -109,7 +119,11 @@ void afterLogsAllPropsExceptEvaluationContext() { @Test void afterLogsAllPropsAndEvaluationContext() { LoggingHook hook = new LoggingHook(true); - FlagEvaluationDetails details = FlagEvaluationDetails.builder().reason(REASON).variant(VARIANT).value(VALUE).build(); + FlagEvaluationDetails details = FlagEvaluationDetails.builder() + .reason(REASON) + .variant(VARIANT) + .value(VALUE) + .build(); hook.after(hookContext, details, null); verify(logger).atDebug(); @@ -164,4 +178,4 @@ private void verifyErrorProps(LoggingEventBuilder mockBuilder) { verify(mockBuilder).addKeyValue(LoggingHook.ERROR_CODE_KEY, ERROR_CODE); verify(mockBuilder).addKeyValue(LoggingHook.ERROR_MESSAGE_KEY, ERROR_MESSAGE); } -} \ No newline at end of file +} diff --git a/src/test/java/dev/openfeature/sdk/internal/ObjectUtilsTest.java b/src/test/java/dev/openfeature/sdk/internal/ObjectUtilsTest.java index c4525e744..e0efeed6e 100644 --- a/src/test/java/dev/openfeature/sdk/internal/ObjectUtilsTest.java +++ b/src/test/java/dev/openfeature/sdk/internal/ObjectUtilsTest.java @@ -1,12 +1,16 @@ package dev.openfeature.sdk.internal; -import java.util.*; - -import org.junit.jupiter.api.*; - import static dev.openfeature.sdk.internal.ObjectUtils.defaultIfNull; import static org.assertj.core.api.Assertions.assertThat; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + class ObjectUtilsTest { @Nested @@ -89,6 +93,4 @@ void shouldReturnGivenMapIfNotNull() { assertThat(actual).isEqualTo(expectedValue); } } - - } diff --git a/src/test/java/dev/openfeature/sdk/internal/TriConsumerTest.java b/src/test/java/dev/openfeature/sdk/internal/TriConsumerTest.java index 0c85a7cc5..a10fa31fe 100644 --- a/src/test/java/dev/openfeature/sdk/internal/TriConsumerTest.java +++ b/src/test/java/dev/openfeature/sdk/internal/TriConsumerTest.java @@ -3,7 +3,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.concurrent.atomic.AtomicInteger; - import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -31,4 +30,4 @@ void shouldRunAfterAccept() { composed.accept(1, 2, 3); assertEquals(12, result.get()); } -} \ No newline at end of file +} 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 55ddc07cd..86782b397 100644 --- a/src/test/java/dev/openfeature/sdk/providers/memory/InMemoryProviderTest.java +++ b/src/test/java/dev/openfeature/sdk/providers/memory/InMemoryProviderTest.java @@ -1,26 +1,27 @@ package dev.openfeature.sdk.providers.memory; +import static dev.openfeature.sdk.Structure.mapToStructure; +import static dev.openfeature.sdk.testutils.TestFlagsUtils.buildFlags; +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.*; + import com.google.common.collect.ImmutableMap; -import dev.openfeature.sdk.*; +import dev.openfeature.sdk.Client; +import dev.openfeature.sdk.EventDetails; +import dev.openfeature.sdk.ImmutableContext; +import dev.openfeature.sdk.OpenFeatureAPI; +import dev.openfeature.sdk.Value; import dev.openfeature.sdk.exceptions.FlagNotFoundError; -import dev.openfeature.sdk.exceptions.GeneralError; import dev.openfeature.sdk.exceptions.ProviderNotReadyError; import dev.openfeature.sdk.exceptions.TypeMismatchError; -import lombok.SneakyThrows; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; - -import static dev.openfeature.sdk.Structure.mapToStructure; -import static dev.openfeature.sdk.testutils.TestFlagsUtils.buildFlags; -import static org.awaitility.Awaitility.await; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Mockito.*; +import lombok.SneakyThrows; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; class InMemoryProviderTest { @@ -33,16 +34,17 @@ class InMemoryProviderTest { void beforeEach() { Map> flags = buildFlags(); provider = spy(new InMemoryProvider(flags)); - OpenFeatureAPI.getInstance().onProviderConfigurationChanged(eventDetails -> { - }); + OpenFeatureAPI.getInstance().onProviderConfigurationChanged(eventDetails -> {}); OpenFeatureAPI.getInstance().setProviderAndWait(provider); client = OpenFeatureAPI.getInstance().getClient(); provider.updateFlags(flags); - provider.updateFlag("addedFlag", Flag.builder() - .variant("on", true) - .variant("off", false) - .defaultVariant("on") - .build()); + provider.updateFlag( + "addedFlag", + Flag.builder() + .variant("on", true) + .variant("off", false) + .defaultVariant("on") + .build()); } @Test @@ -70,8 +72,7 @@ void getObjectEvaluation() { Value expectedObject = new Value(mapToStructure(ImmutableMap.of( "showImages", new Value(true), "title", new Value("Check out these pics!"), - "imagesPerPage", new Value(100) - ))); + "imagesPerPage", new Value(100)))); assertEquals(expectedObject, client.getObjectValue("object-flag", new Value(true))); } @@ -95,7 +96,9 @@ void shouldThrowIfNotInitialized() { InMemoryProvider inMemoryProvider = new InMemoryProvider(new HashMap<>()); // ErrorCode.PROVIDER_NOT_READY should be returned when evaluated via the client - assertThrows(ProviderNotReadyError.class, () -> inMemoryProvider.getBooleanEvaluation("fail_not_initialized", false, new ImmutableContext())); + assertThrows( + ProviderNotReadyError.class, + () -> inMemoryProvider.getBooleanEvaluation("fail_not_initialized", false, new ImmutableContext())); } @SuppressWarnings("unchecked") @@ -110,6 +113,7 @@ void emitChangedFlagsOnlyIfThereAreChangedFlags() { provider.updateFlags(flags); await().untilAsserted(() -> verify(handler, times(1)) - .accept(argThat(details -> details.getFlagsChanged().size() == buildFlags().size()))); + .accept(argThat(details -> + details.getFlagsChanged().size() == buildFlags().size()))); } -} \ No newline at end of file +} diff --git a/src/test/java/dev/openfeature/sdk/testutils/FeatureProviderTestUtils.java b/src/test/java/dev/openfeature/sdk/testutils/FeatureProviderTestUtils.java index 12fb71b1b..c9ad77d89 100644 --- a/src/test/java/dev/openfeature/sdk/testutils/FeatureProviderTestUtils.java +++ b/src/test/java/dev/openfeature/sdk/testutils/FeatureProviderTestUtils.java @@ -1,13 +1,13 @@ 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 dev.openfeature.sdk.*; import lombok.experimental.UtilityClass; -import static org.awaitility.Awaitility.await; - // todo check the need of this utility class as we now have setProviderAndWait capability @UtilityClass public class FeatureProviderTestUtils { @@ -17,11 +17,11 @@ public static void setFeatureProvider(FeatureProvider 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)); + 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) { diff --git a/src/test/java/dev/openfeature/sdk/testutils/TestEventsProvider.java b/src/test/java/dev/openfeature/sdk/testutils/TestEventsProvider.java index 1944fce22..7cd2ea318 100644 --- a/src/test/java/dev/openfeature/sdk/testutils/TestEventsProvider.java +++ b/src/test/java/dev/openfeature/sdk/testutils/TestEventsProvider.java @@ -1,6 +1,13 @@ package dev.openfeature.sdk.testutils; -import dev.openfeature.sdk.*; +import dev.openfeature.sdk.EvaluationContext; +import dev.openfeature.sdk.EventProvider; +import dev.openfeature.sdk.Metadata; +import dev.openfeature.sdk.ProviderEvaluation; +import dev.openfeature.sdk.ProviderEvent; +import dev.openfeature.sdk.ProviderEventDetails; +import dev.openfeature.sdk.Reason; +import dev.openfeature.sdk.Value; import dev.openfeature.sdk.exceptions.FatalError; import dev.openfeature.sdk.exceptions.GeneralError; import lombok.SneakyThrows; @@ -16,8 +23,7 @@ public class TestEventsProvider extends EventProvider { private Metadata metadata = () -> name; private boolean isFatalInitError = false; - public TestEventsProvider() { - } + public TestEventsProvider() {} public TestEventsProvider(int initTimeoutMs) { this.initTimeoutMs = initTimeoutMs; @@ -110,8 +116,8 @@ public ProviderEvaluation getDoubleEvaluation(String key, Double default } @Override - public ProviderEvaluation getObjectEvaluation(String key, Value defaultValue, - EvaluationContext invocationContext) { + public ProviderEvaluation getObjectEvaluation( + String key, Value defaultValue, EvaluationContext invocationContext) { return ProviderEvaluation.builder() .value(defaultValue) .variant(PASSED_IN_DEFAULT) diff --git a/src/test/java/dev/openfeature/sdk/testutils/TestFlagsUtils.java b/src/test/java/dev/openfeature/sdk/testutils/TestFlagsUtils.java index dd2d03ca1..157b07175 100644 --- a/src/test/java/dev/openfeature/sdk/testutils/TestFlagsUtils.java +++ b/src/test/java/dev/openfeature/sdk/testutils/TestFlagsUtils.java @@ -1,14 +1,13 @@ package dev.openfeature.sdk.testutils; +import static dev.openfeature.sdk.Structure.mapToStructure; + import com.google.common.collect.ImmutableMap; import dev.openfeature.sdk.Value; import dev.openfeature.sdk.providers.memory.Flag; -import lombok.experimental.UtilityClass; - import java.util.HashMap; import java.util.Map; - -import static dev.openfeature.sdk.Structure.mapToStructure; +import lombok.experimental.UtilityClass; /** * Test flags utils. @@ -30,52 +29,67 @@ public class TestFlagsUtils { */ public static Map> buildFlags() { Map> flags = new HashMap<>(); - flags.put(BOOLEAN_FLAG_KEY, Flag.builder() - .variant("on", true) - .variant("off", false) - .defaultVariant("on") - .build()); - flags.put(STRING_FLAG_KEY, Flag.builder() - .variant("greeting", "hi") - .variant("parting", "bye") - .defaultVariant("greeting") - .build()); - flags.put(INT_FLAG_KEY, Flag.builder() - .variant("one", 1) - .variant("ten", 10) - .defaultVariant("ten") - .build()); - flags.put(FLOAT_FLAG_KEY, Flag.builder() - .variant("tenth", 0.1) - .variant("half", 0.5) - .defaultVariant("half") - .build()); - flags.put(OBJECT_FLAG_KEY, Flag.builder() - .variant("empty", new HashMap<>()) - .variant("template", new Value(mapToStructure(ImmutableMap.of( - "showImages", new Value(true), - "title", new Value("Check out these pics!"), - "imagesPerPage", new Value(100) - )))) - .defaultVariant("template") - .build()); - flags.put(CONTEXT_AWARE_FLAG_KEY, Flag.builder() - .variant("internal", "INTERNAL") - .variant("external", "EXTERNAL") - .defaultVariant("external") - .contextEvaluator((flag, evaluationContext) -> { - if (new Value(false).equals(evaluationContext.getValue("customer"))) { - return (String) flag.getVariants().get("internal"); - } else { - return (String) flag.getVariants().get(flag.getDefaultVariant()); - } - }) - .build()); - flags.put(WRONG_FLAG_KEY, Flag.builder() - .variant("one", "uno") - .variant("two", "dos") - .defaultVariant("one") - .build()); + flags.put( + BOOLEAN_FLAG_KEY, + Flag.builder() + .variant("on", true) + .variant("off", false) + .defaultVariant("on") + .build()); + flags.put( + STRING_FLAG_KEY, + Flag.builder() + .variant("greeting", "hi") + .variant("parting", "bye") + .defaultVariant("greeting") + .build()); + flags.put( + INT_FLAG_KEY, + Flag.builder() + .variant("one", 1) + .variant("ten", 10) + .defaultVariant("ten") + .build()); + flags.put( + FLOAT_FLAG_KEY, + Flag.builder() + .variant("tenth", 0.1) + .variant("half", 0.5) + .defaultVariant("half") + .build()); + flags.put( + OBJECT_FLAG_KEY, + Flag.builder() + .variant("empty", new HashMap<>()) + .variant( + "template", + new Value(mapToStructure(ImmutableMap.of( + "showImages", new Value(true), + "title", new Value("Check out these pics!"), + "imagesPerPage", new Value(100))))) + .defaultVariant("template") + .build()); + flags.put( + CONTEXT_AWARE_FLAG_KEY, + Flag.builder() + .variant("internal", "INTERNAL") + .variant("external", "EXTERNAL") + .defaultVariant("external") + .contextEvaluator((flag, evaluationContext) -> { + if (new Value(false).equals(evaluationContext.getValue("customer"))) { + return (String) flag.getVariants().get("internal"); + } else { + return (String) flag.getVariants().get(flag.getDefaultVariant()); + } + }) + .build()); + flags.put( + WRONG_FLAG_KEY, + Flag.builder() + .variant("one", "uno") + .variant("two", "dos") + .defaultVariant("one") + .build()); return flags; } } diff --git a/src/test/java/dev/openfeature/sdk/testutils/stubbing/ConditionStubber.java b/src/test/java/dev/openfeature/sdk/testutils/stubbing/ConditionStubber.java index 11cf26495..886a7bbd8 100644 --- a/src/test/java/dev/openfeature/sdk/testutils/stubbing/ConditionStubber.java +++ b/src/test/java/dev/openfeature/sdk/testutils/stubbing/ConditionStubber.java @@ -1,13 +1,13 @@ package dev.openfeature.sdk.testutils.stubbing; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.mockito.Mockito.doAnswer; + import java.time.Duration; import java.util.concurrent.CountDownLatch; - import lombok.experimental.UtilityClass; -import org.mockito.stubbing.*; - -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static org.mockito.Mockito.doAnswer; +import org.mockito.stubbing.Answer; +import org.mockito.stubbing.Stubber; @UtilityClass public class ConditionStubber { @@ -33,5 +33,4 @@ public static Stubber doBlock(CountDownLatch latch, Answer answer) { return answer.answer(invocation); }); } - } From 20bbb2337cb5afbee9b8d5143b45416673cb4154 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Jan 2025 18:24:06 +0000 Subject: [PATCH 083/745] chore(deps): update dependency org.assertj:assertj-core to v3.27.1 (#1266) 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 e7fe58c67..85a465624 100644 --- a/pom.xml +++ b/pom.xml @@ -77,7 +77,7 @@ org.assertj assertj-core - 3.27.0 + 3.27.1 test From 2e10d34920f57d863c09ce1522c9ccff20413f74 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 4 Jan 2025 15:14:06 +0000 Subject: [PATCH 084/745] chore(deps): update dependency org.assertj:assertj-core to v3.27.2 (#1268) 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 85a465624..fb4413186 100644 --- a/pom.xml +++ b/pom.xml @@ -77,7 +77,7 @@ org.assertj assertj-core - 3.27.1 + 3.27.2 test From a1c558f4ffb95772bd141ab7660e2c5b065482f1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 21:06:18 +0000 Subject: [PATCH 085/745] chore(deps): update actions/cache digest to 53aa38c (#1270) 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 92993ff5e..050d40368 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -32,7 +32,7 @@ jobs: server-password: ${{ secrets.OSSRH_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 + uses: actions/cache@53aa38c736a561b9c17b62df3fe885a17b78ee6d with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 4fa803aa3..142c29e7d 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -25,7 +25,7 @@ jobs: languages: java - name: Cache local Maven repository - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 + uses: actions/cache@53aa38c736a561b9c17b62df3fe885a17b78ee6d with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} From 4086dea703a950dcacc792be9a9346cc1fa8409d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 00:40:07 +0000 Subject: [PATCH 086/745] chore(deps): update github/codeql-action digest to 3407610 (#1269) 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 142c29e7d..d0d3cb7cb 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@5b6e617dc0241b2d60c2bccea90c56b67eceb797 + uses: github/codeql-action/init@3407610120cd5656b6fc71991415cb50748b9489 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5b6e617dc0241b2d60c2bccea90c56b67eceb797 + uses: github/codeql-action/analyze@3407610120cd5656b6fc71991415cb50748b9489 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index f03229c2d..41ecc36d9 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@5b6e617dc0241b2d60c2bccea90c56b67eceb797 + uses: github/codeql-action/init@3407610120cd5656b6fc71991415cb50748b9489 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@5b6e617dc0241b2d60c2bccea90c56b67eceb797 + uses: github/codeql-action/autobuild@3407610120cd5656b6fc71991415cb50748b9489 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5b6e617dc0241b2d60c2bccea90c56b67eceb797 + uses: github/codeql-action/analyze@3407610120cd5656b6fc71991415cb50748b9489 From 3c97b7baaf9eee719479c059cb923d8d64f2c25f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 8 Jan 2025 23:21:18 +0000 Subject: [PATCH 087/745] chore(deps): update github/codeql-action digest to fb65b6c (#1273) 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 d0d3cb7cb..96e800bec 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@3407610120cd5656b6fc71991415cb50748b9489 + uses: github/codeql-action/init@fb65b6ce7884900fde5b15518bec92ad6875180e with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3407610120cd5656b6fc71991415cb50748b9489 + uses: github/codeql-action/analyze@fb65b6ce7884900fde5b15518bec92ad6875180e diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 41ecc36d9..24f3104b0 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@3407610120cd5656b6fc71991415cb50748b9489 + uses: github/codeql-action/init@fb65b6ce7884900fde5b15518bec92ad6875180e with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@3407610120cd5656b6fc71991415cb50748b9489 + uses: github/codeql-action/autobuild@fb65b6ce7884900fde5b15518bec92ad6875180e - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3407610120cd5656b6fc71991415cb50748b9489 + uses: github/codeql-action/analyze@fb65b6ce7884900fde5b15518bec92ad6875180e From ae85278c30eb5279b80ea73ec6b92db040ad0bb7 Mon Sep 17 00:00:00 2001 From: chrfwow Date: Thu, 9 Jan 2025 22:12:14 +0100 Subject: [PATCH 088/745] feat: Add evaluation details to finally hook stage #1246 (#1262) Signed-off-by: christian.lutnik Co-authored-by: Todd Baert --- README.md | 2 +- src/main/java/dev/openfeature/sdk/Hook.java | 2 +- .../java/dev/openfeature/sdk/HookSupport.java | 8 +- .../openfeature/sdk/OpenFeatureClient.java | 2 +- .../sdk/DeveloperExperienceTest.java | 6 +- .../dev/openfeature/sdk/HookSpecTest.java | 100 +++++++++++++++--- .../dev/openfeature/sdk/HookSupportTest.java | 8 +- .../sdk/OpenFeatureClientTest.java | 59 +---------- 8 files changed, 106 insertions(+), 81 deletions(-) diff --git a/README.md b/README.md index e58ef9d8c..44f4c81c4 100644 --- a/README.md +++ b/README.md @@ -426,7 +426,7 @@ class MyHook implements Hook { } @Override - public void finallyAfter(HookContext ctx, Map hints) { + public void finallyAfter(HookContext ctx, FlagEvaluationDetails details, Map hints) { // code that runs regardless of success or error } }; diff --git a/src/main/java/dev/openfeature/sdk/Hook.java b/src/main/java/dev/openfeature/sdk/Hook.java index 9ca7e6b93..08aa18314 100644 --- a/src/main/java/dev/openfeature/sdk/Hook.java +++ b/src/main/java/dev/openfeature/sdk/Hook.java @@ -46,7 +46,7 @@ default void error(HookContext ctx, Exception error, Map hint * @param ctx Information about the particular flag evaluation * @param hints An immutable mapping of data for users to communicate to the hooks. */ - default void finallyAfter(HookContext ctx, Map hints) {} + default void finallyAfter(HookContext ctx, FlagEvaluationDetails details, Map hints) {} default boolean supportsFlagValueType(FlagValueType flagValueType) { return true; diff --git a/src/main/java/dev/openfeature/sdk/HookSupport.java b/src/main/java/dev/openfeature/sdk/HookSupport.java index 95c8ff17d..73518ee8e 100644 --- a/src/main/java/dev/openfeature/sdk/HookSupport.java +++ b/src/main/java/dev/openfeature/sdk/HookSupport.java @@ -29,8 +29,12 @@ public void afterHooks( } public void afterAllHooks( - FlagValueType flagValueType, HookContext hookCtx, List hooks, Map hints) { - executeHooks(flagValueType, hooks, "finally", hook -> hook.finallyAfter(hookCtx, hints)); + FlagValueType flagValueType, + HookContext hookCtx, + FlagEvaluationDetails details, + List hooks, + Map hints) { + executeHooks(flagValueType, hooks, "finally", hook -> hook.finallyAfter(hookCtx, details, hints)); } public void errorHooks( diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index 60f987b77..66f25f60a 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -228,7 +228,7 @@ private FlagEvaluationDetails evaluateFlag( enrichDetailsWithErrorDefaults(defaultValue, details); hookSupport.errorHooks(type, afterHookContext, e, mergedHooks, hints); } finally { - hookSupport.afterAllHooks(type, afterHookContext, mergedHooks, hints); + hookSupport.afterAllHooks(type, afterHookContext, details, mergedHooks, hints); } return details; diff --git a/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java b/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java index c39c5ba31..aacf09169 100644 --- a/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java +++ b/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java @@ -39,7 +39,7 @@ void clientHooks() { Client client = api.getClient(); client.addHooks(exampleHook); Boolean retval = client.getBooleanValue(flagKey, false); - verify(exampleHook, times(1)).finallyAfter(any(), any()); + verify(exampleHook, times(1)).finallyAfter(any(), any(), any()); assertFalse(retval); } @@ -57,8 +57,8 @@ void evalHooks() { false, null, FlagEvaluationOptions.builder().hook(evalHook).build()); - verify(clientHook, times(1)).finallyAfter(any(), any()); - verify(evalHook, times(1)).finallyAfter(any(), any()); + verify(clientHook, times(1)).finallyAfter(any(), any(), any()); + verify(evalHook, times(1)).finallyAfter(any(), any(), any()); assertFalse(retval); } diff --git a/src/test/java/dev/openfeature/sdk/HookSpecTest.java b/src/test/java/dev/openfeature/sdk/HookSpecTest.java index 4a141c611..d6247c649 100644 --- a/src/test/java/dev/openfeature/sdk/HookSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSpecTest.java @@ -1,10 +1,20 @@ package dev.openfeature.sdk; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.fail; -import static org.junit.jupiter.api.Assertions.*; +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 static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import dev.openfeature.sdk.exceptions.FlagNotFoundError; import dev.openfeature.sdk.fixtures.HookFixtures; @@ -187,7 +197,7 @@ void feo_has_hook_list() { void error_hook_run_during_non_finally_stage() { final boolean[] error_called = {false}; Hook h = mockBooleanHook(); - doThrow(RuntimeException.class).when(h).finallyAfter(any(), any()); + doThrow(RuntimeException.class).when(h).finallyAfter(any(), any(), any()); verify(h, times(0)).error(any(), any(), any()); } @@ -219,7 +229,7 @@ void error_hook_must_run_if_resolution_details_returns_an_error_code() { verify(hook, times(1)).before(any(), any()); verify(hook, times(1)).error(any(), captor.capture(), any()); - verify(hook, times(1)).finallyAfter(any(), any()); + verify(hook, times(1)).finallyAfter(any(), any(), any()); verify(hook, never()).after(any(), any(), any()); Exception exception = captor.getValue(); @@ -274,7 +284,10 @@ public void error(HookContext ctx, Exception error, Map } @Override - public void finallyAfter(HookContext ctx, Map hints) { + public void finallyAfter( + HookContext ctx, + FlagEvaluationDetails details, + Map hints) { evalOrder.add("provider finally"); } }); @@ -300,7 +313,8 @@ public void error(HookContext ctx, Exception error, Map } @Override - public void finallyAfter(HookContext ctx, Map hints) { + public void finallyAfter( + HookContext ctx, FlagEvaluationDetails details, Map hints) { evalOrder.add("api finally"); } }); @@ -325,7 +339,8 @@ public void error(HookContext ctx, Exception error, Map } @Override - public void finallyAfter(HookContext ctx, Map hints) { + public void finallyAfter( + HookContext ctx, FlagEvaluationDetails details, Map hints) { evalOrder.add("client finally"); } }); @@ -357,7 +372,10 @@ public void error(HookContext ctx, Exception error, Map } @Override - public void finallyAfter(HookContext ctx, Map hints) { + public void finallyAfter( + HookContext ctx, + FlagEvaluationDetails details, + Map hints) { evalOrder.add("invocation finally"); } }) @@ -462,7 +480,8 @@ public void error(HookContext ctx, Exception error, Map } @Override - public void finallyAfter(HookContext ctx, Map hints) { + public void finallyAfter( + HookContext ctx, FlagEvaluationDetails details, Map hints) { assertThatCode(() -> hints.put(hintKey, "changed value")) .isInstanceOf(UnsupportedOperationException.class); } @@ -509,7 +528,7 @@ void flag_eval_hook_order() { order.verify(hook).before(any(), any()); order.verify(provider).getBooleanEvaluation(any(), any(), any()); order.verify(hook).after(any(), any(), any()); - order.verify(hook).finallyAfter(any(), any()); + order.verify(hook).finallyAfter(any(), any(), any()); } @Specification( @@ -550,6 +569,58 @@ void error_hooks__after() { verify(hook, times(1)).error(any(), any(), any()); } + @Test + void erroneous_flagResolution_setsAppropriateFieldsInFlagEvaluationDetails() { + Hook hook = mockBooleanHook(); + doThrow(RuntimeException.class).when(hook).after(any(), any(), any()); + String flagKey = "test-flag-key"; + Client client = getClient(TestEventsProvider.newInitializedTestEventsProvider()); + client.getBooleanValue( + flagKey, + true, + new ImmutableContext(), + FlagEvaluationOptions.builder().hook(hook).build()); + + ArgumentCaptor> captor = ArgumentCaptor.forClass(FlagEvaluationDetails.class); + verify(hook).finallyAfter(any(), captor.capture(), any()); + + FlagEvaluationDetails evaluationDetails = captor.getValue(); + assertThat(evaluationDetails).isNotNull(); + + assertThat(evaluationDetails.getErrorCode()).isEqualTo(ErrorCode.GENERAL); + assertThat(evaluationDetails.getReason()).isEqualTo("ERROR"); + assertThat(evaluationDetails.getVariant()).isEqualTo("Passed in default"); + assertThat(evaluationDetails.getFlagKey()).isEqualTo(flagKey); + assertThat(evaluationDetails.getFlagMetadata()) + .isEqualTo(ImmutableMetadata.builder().build()); + assertThat(evaluationDetails.getValue()).isTrue(); + } + + @Test + void successful_flagResolution_setsAppropriateFieldsInFlagEvaluationDetails() { + Hook hook = mockBooleanHook(); + String flagKey = "test-flag-key"; + Client client = getClient(TestEventsProvider.newInitializedTestEventsProvider()); + client.getBooleanValue( + flagKey, + true, + new ImmutableContext(), + FlagEvaluationOptions.builder().hook(hook).build()); + + ArgumentCaptor> captor = ArgumentCaptor.forClass(FlagEvaluationDetails.class); + verify(hook).finallyAfter(any(), captor.capture(), any()); + + FlagEvaluationDetails evaluationDetails = captor.getValue(); + assertThat(evaluationDetails).isNotNull(); + assertThat(evaluationDetails.getErrorCode()).isNull(); + assertThat(evaluationDetails.getReason()).isEqualTo("DEFAULT"); + assertThat(evaluationDetails.getVariant()).isEqualTo("Passed in default"); + assertThat(evaluationDetails.getFlagKey()).isEqualTo(flagKey); + assertThat(evaluationDetails.getFlagMetadata()) + .isEqualTo(ImmutableMetadata.builder().build()); + assertThat(evaluationDetails.getValue()).isTrue(); + } + @Test void multi_hooks_early_out__before() { Hook hook = mockBooleanHook(); @@ -649,7 +720,7 @@ void mergeHappensCorrectly() { void first_finally_broken() { Hook hook = mockBooleanHook(); doThrow(RuntimeException.class).when(hook).before(any(), any()); - doThrow(RuntimeException.class).when(hook).finallyAfter(any(), any()); + doThrow(RuntimeException.class).when(hook).finallyAfter(any(), any(), any()); Hook hook2 = mockBooleanHook(); InOrder order = inOrder(hook, hook2); @@ -661,8 +732,8 @@ void first_finally_broken() { FlagEvaluationOptions.builder().hook(hook2).hook(hook).build()); order.verify(hook).before(any(), any()); - order.verify(hook2).finallyAfter(any(), any()); - order.verify(hook).finallyAfter(any(), any()); + order.verify(hook2).finallyAfter(any(), any(), any()); + order.verify(hook).finallyAfter(any(), any(), any()); } @Specification( @@ -711,7 +782,8 @@ void doesnt_use_finally() { .as("Not possible. Finally is a reserved word.") .isInstanceOf(NoSuchMethodException.class); - assertThatCode(() -> Hook.class.getMethod("finallyAfter", HookContext.class, Map.class)) + assertThatCode(() -> + Hook.class.getMethod("finallyAfter", HookContext.class, FlagEvaluationDetails.class, Map.class)) .doesNotThrowAnyException(); } } diff --git a/src/test/java/dev/openfeature/sdk/HookSupportTest.java b/src/test/java/dev/openfeature/sdk/HookSupportTest.java index 73256ab5f..02a8ff90c 100644 --- a/src/test/java/dev/openfeature/sdk/HookSupportTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSupportTest.java @@ -64,7 +64,11 @@ void shouldAlwaysCallGenericHook(FlagValueType flagValueType) { Collections.singletonList(genericHook), Collections.emptyMap()); hookSupport.afterAllHooks( - flagValueType, hookContext, Collections.singletonList(genericHook), Collections.emptyMap()); + flagValueType, + hookContext, + FlagEvaluationDetails.builder().build(), + Collections.singletonList(genericHook), + Collections.emptyMap()); hookSupport.errorHooks( flagValueType, hookContext, @@ -74,7 +78,7 @@ void shouldAlwaysCallGenericHook(FlagValueType flagValueType) { verify(genericHook).before(any(), any()); verify(genericHook).after(any(), any(), any()); - verify(genericHook).finallyAfter(any(), any()); + verify(genericHook).finallyAfter(any(), any(), any()); verify(genericHook).error(any(), any(), any()); } diff --git a/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java b/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java index 50b5254c8..4f4d32004 100644 --- a/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java +++ b/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java @@ -5,13 +5,13 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import dev.openfeature.sdk.exceptions.FatalError; import dev.openfeature.sdk.fixtures.HookFixtures; import dev.openfeature.sdk.testutils.TestEventsProvider; import java.util.HashMap; -import java.util.concurrent.atomic.AtomicBoolean; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -104,59 +104,4 @@ void shouldNotCallEvaluationMethodsWhenProviderIsInNotReadyState() { assertThat(details.getErrorCode()).isEqualTo(ErrorCode.PROVIDER_NOT_READY); } - - private static class MockProvider implements FeatureProvider { - private final AtomicBoolean evaluationCalled = new AtomicBoolean(); - private final ProviderState providerState; - - public MockProvider(ProviderState providerState) { - this.providerState = providerState; - } - - public boolean isEvaluationCalled() { - return evaluationCalled.get(); - } - - @Override - public ProviderState getState() { - return providerState; - } - - @Override - public Metadata getMetadata() { - return null; - } - - @Override - public ProviderEvaluation getBooleanEvaluation( - String key, Boolean defaultValue, EvaluationContext ctx) { - evaluationCalled.set(true); - return null; - } - - @Override - public ProviderEvaluation getStringEvaluation(String key, String defaultValue, EvaluationContext ctx) { - evaluationCalled.set(true); - return null; - } - - @Override - public ProviderEvaluation getIntegerEvaluation( - String key, Integer defaultValue, EvaluationContext ctx) { - evaluationCalled.set(true); - return null; - } - - @Override - public ProviderEvaluation getDoubleEvaluation(String key, Double defaultValue, EvaluationContext ctx) { - evaluationCalled.set(true); - return null; - } - - @Override - public ProviderEvaluation getObjectEvaluation(String key, Value defaultValue, EvaluationContext ctx) { - evaluationCalled.set(true); - return null; - } - } } From d825ff83639a2bd902bf0559209c2b80e17e0316 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 10 Jan 2025 06:08:41 +0000 Subject: [PATCH 089/745] chore(deps): update actions/cache digest to 36f1e14 (#1274) 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 050d40368..bcdd87a0a 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -32,7 +32,7 @@ jobs: server-password: ${{ secrets.OSSRH_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@53aa38c736a561b9c17b62df3fe885a17b78ee6d + uses: actions/cache@36f1e144e1c8edb0a652766b484448563d8baf46 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 96e800bec..352aca474 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -25,7 +25,7 @@ jobs: languages: java - name: Cache local Maven repository - uses: actions/cache@53aa38c736a561b9c17b62df3fe885a17b78ee6d + uses: actions/cache@36f1e144e1c8edb0a652766b484448563d8baf46 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} From 9c92ebb1bdb23c80461f143753f2fb42956462e3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 10 Jan 2025 10:17:41 +0000 Subject: [PATCH 090/745] chore(deps): update github/codeql-action digest to e83e0a4 (#1275) 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 352aca474..f3a625b15 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@fb65b6ce7884900fde5b15518bec92ad6875180e + uses: github/codeql-action/init@e83e0a4f58f2ca25f7dd222e8689519a74bf26fc with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@fb65b6ce7884900fde5b15518bec92ad6875180e + uses: github/codeql-action/analyze@e83e0a4f58f2ca25f7dd222e8689519a74bf26fc diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 24f3104b0..40b0511a7 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@fb65b6ce7884900fde5b15518bec92ad6875180e + uses: github/codeql-action/init@e83e0a4f58f2ca25f7dd222e8689519a74bf26fc with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@fb65b6ce7884900fde5b15518bec92ad6875180e + uses: github/codeql-action/autobuild@e83e0a4f58f2ca25f7dd222e8689519a74bf26fc - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@fb65b6ce7884900fde5b15518bec92ad6875180e + uses: github/codeql-action/analyze@e83e0a4f58f2ca25f7dd222e8689519a74bf26fc From 9274c117abdde734361231048e7f467c07e03da6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 10 Jan 2025 15:10:55 -0500 Subject: [PATCH 091/745] chore(main): release 1.14.0 (#1242) * chore(main): release 1.14.0 * Update CHANGELOG.md 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 | 47 +++++++++++++++++++++++++++++++++++ README.md | 8 +++--- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 54 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 12295c5d8..e2d18dc18 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"1.13.0"} \ No newline at end of file +{".":"1.14.0"} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index d91800bc4..3f7000d46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,52 @@ # Changelog +## [1.14.0](https://github.com/open-feature/java-sdk/compare/v1.13.0...v1.14.0) (2025-01-10) + + +### ⚠ BREAKING CHANGES + +The signature of the `finallyAfter` hook stage has been changed. The signature now includes the `evaluation details`, as per the [OpenFeature specification](https://openfeature.dev/specification/sections/hooks#requirement-438). Note that since hooks are still `experimental,` this does not constitute a change requiring a new major version. To migrate, update any hook that implements the `finallyAfter` stage to accept `evaluation details` as the second argument. + +* Add evaluation details to finally hook stage [#1246](https://github.com/open-feature/java-sdk/issues/1246) ([#1262](https://github.com/open-feature/java-sdk/issues/1262)) ([ae85278](https://github.com/open-feature/java-sdk/commit/ae85278c30eb5279b80ea73ec6b92db040ad0bb7)) + + +### 🐛 Bug Fixes + +* **deps:** update junit5 monorepo ([#1251](https://github.com/open-feature/java-sdk/issues/1251)) ([834f720](https://github.com/open-feature/java-sdk/commit/834f72071806680353f42c750b04e36956736a9e)) + + +### ✨ New Features + +* Add evaluation details to finally hook stage [#1246](https://github.com/open-feature/java-sdk/issues/1246) ([#1262](https://github.com/open-feature/java-sdk/issues/1262)) ([ae85278](https://github.com/open-feature/java-sdk/commit/ae85278c30eb5279b80ea73ec6b92db040ad0bb7)) + + +### 🧹 Chore + +* **deps:** update actions/cache digest to 36f1e14 ([#1274](https://github.com/open-feature/java-sdk/issues/1274)) ([d825ff8](https://github.com/open-feature/java-sdk/commit/d825ff83639a2bd902bf0559209c2b80e17e0316)) +* **deps:** update actions/cache digest to 53aa38c ([#1270](https://github.com/open-feature/java-sdk/issues/1270)) ([a1c558f](https://github.com/open-feature/java-sdk/commit/a1c558f4ffb95772bd141ab7660e2c5b065482f1)) +* **deps:** update actions/setup-java digest to 7136edc ([#1244](https://github.com/open-feature/java-sdk/issues/1244)) ([9acc861](https://github.com/open-feature/java-sdk/commit/9acc8612a5fa7ea086da476195154a007cb55b7e)) +* **deps:** update actions/setup-java digest to 7a6d8a8 ([#1248](https://github.com/open-feature/java-sdk/issues/1248)) ([86e18c5](https://github.com/open-feature/java-sdk/commit/86e18c5d28a9f5fdd7234274720ba7ddcb529268)) +* **deps:** update codecov/codecov-action action to v5.1.2 ([#1255](https://github.com/open-feature/java-sdk/issues/1255)) ([d274cda](https://github.com/open-feature/java-sdk/commit/d274cdac3780286a0b45865864b12c3e4cff9f4b)) +* **deps:** update dependency com.google.guava:guava to v33.4.0-jre ([#1253](https://github.com/open-feature/java-sdk/issues/1253)) ([f39c4b5](https://github.com/open-feature/java-sdk/commit/f39c4b5af5e341bfec230d4cecd2037fc5430400)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.15.11 ([#1249](https://github.com/open-feature/java-sdk/issues/1249)) ([4440cda](https://github.com/open-feature/java-sdk/commit/4440cda6a5b42a903ba11835a975bf6247de845f)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.15.11 ([#1250](https://github.com/open-feature/java-sdk/issues/1250)) ([6772d3f](https://github.com/open-feature/java-sdk/commit/6772d3f3943fb3b7f7522c80b732aa058fd03bb9)) +* **deps:** update dependency org.assertj:assertj-core to v3.27.0 ([#1258](https://github.com/open-feature/java-sdk/issues/1258)) ([c62ade3](https://github.com/open-feature/java-sdk/commit/c62ade3878dabf9194536d551f3316ba5c0ce5e1)) +* **deps:** update dependency org.assertj:assertj-core to v3.27.1 ([#1266](https://github.com/open-feature/java-sdk/issues/1266)) ([20bbb23](https://github.com/open-feature/java-sdk/commit/20bbb2337cb5afbee9b8d5143b45416673cb4154)) +* **deps:** update dependency org.assertj:assertj-core to v3.27.2 ([#1268](https://github.com/open-feature/java-sdk/issues/1268)) ([2e10d34](https://github.com/open-feature/java-sdk/commit/2e10d34920f57d863c09ce1522c9ccff20413f74)) +* **deps:** update github/codeql-action digest to 3407610 ([#1269](https://github.com/open-feature/java-sdk/issues/1269)) ([4086dea](https://github.com/open-feature/java-sdk/commit/4086dea703a950dcacc792be9a9346cc1fa8409d)) +* **deps:** update github/codeql-action digest to 4d64ab6 ([#1243](https://github.com/open-feature/java-sdk/issues/1243)) ([884f8fb](https://github.com/open-feature/java-sdk/commit/884f8fbf77c41e070526da0f73e136d4c3e41a4d)) +* **deps:** update github/codeql-action digest to 562042d ([#1254](https://github.com/open-feature/java-sdk/issues/1254)) ([6a79874](https://github.com/open-feature/java-sdk/commit/6a7987455ef7e46d40b835c7d8dbda29322e3b2d)) +* **deps:** update github/codeql-action digest to 5b6e617 ([#1263](https://github.com/open-feature/java-sdk/issues/1263)) ([f1817d8](https://github.com/open-feature/java-sdk/commit/f1817d8fef585f957de1cfb9222b03cb591ed2e9)) +* **deps:** update github/codeql-action digest to 64cc90b ([#1256](https://github.com/open-feature/java-sdk/issues/1256)) ([992c003](https://github.com/open-feature/java-sdk/commit/992c00396cb2fca6a6a7dc63d727b063a79386b6)) +* **deps:** update github/codeql-action digest to 7876007 ([#1260](https://github.com/open-feature/java-sdk/issues/1260)) ([fc6f35e](https://github.com/open-feature/java-sdk/commit/fc6f35e581cacb0ad149c58a5943ec1429ce25ca)) +* **deps:** update github/codeql-action digest to 78d0136 ([#1245](https://github.com/open-feature/java-sdk/issues/1245)) ([fd1c170](https://github.com/open-feature/java-sdk/commit/fd1c1702c6d4067c432c1522143266ddf470d18d)) +* **deps:** update github/codeql-action digest to 8975792 ([#1241](https://github.com/open-feature/java-sdk/issues/1241)) ([b0abfd0](https://github.com/open-feature/java-sdk/commit/b0abfd02cf9e97f7409df3296818ac990b429058)) +* **deps:** update github/codeql-action digest to 9d59969 ([#1252](https://github.com/open-feature/java-sdk/issues/1252)) ([482a5ae](https://github.com/open-feature/java-sdk/commit/482a5aef1005b2ebe2fdb9ee43243b6c2aeeadc8)) +* **deps:** update github/codeql-action digest to d01b25e ([#1257](https://github.com/open-feature/java-sdk/issues/1257)) ([6d60c96](https://github.com/open-feature/java-sdk/commit/6d60c962fbac48a13d86271b361fb0cfd91a5342)) +* **deps:** update github/codeql-action digest to dd75594 ([#1247](https://github.com/open-feature/java-sdk/issues/1247)) ([6d169f5](https://github.com/open-feature/java-sdk/commit/6d169f55e235a071033a9bf1138484f09a5e472d)) +* **deps:** update github/codeql-action digest to e83e0a4 ([#1275](https://github.com/open-feature/java-sdk/issues/1275)) ([9c92ebb](https://github.com/open-feature/java-sdk/commit/9c92ebb1bdb23c80461f143753f2fb42956462e3)) +* **deps:** update github/codeql-action digest to fb65b6c ([#1273](https://github.com/open-feature/java-sdk/issues/1273)) ([3c97b7b](https://github.com/open-feature/java-sdk/commit/3c97b7baaf9eee719479c059cb923d8d64f2c25f)) + ## [1.13.0](https://github.com/open-feature/java-sdk/compare/v1.12.2...v1.13.0) (2024-12-07) diff --git a/README.md b/README.md index 44f4c81c4..cbb9d9f13 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.13.0 + 1.14.0 ``` @@ -84,7 +84,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:1.13.0' + implementation 'dev.openfeature:sdk:1.14.0' } ``` diff --git a/pom.xml b/pom.xml index fb4413186..5d8ea34ce 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ dev.openfeature sdk - 1.13.0 + 1.14.0 UTF-8 diff --git a/version.txt b/version.txt index feaae22ba..850e74240 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.13.0 +1.14.0 From c2a82dbdbafa134fae4b0c9aef88cf589e09aefa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 10 Jan 2025 21:58:22 +0000 Subject: [PATCH 092/745] chore(deps): update github/codeql-action digest to 87fc816 (#1277) 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 f3a625b15..87e342e0b 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@e83e0a4f58f2ca25f7dd222e8689519a74bf26fc + uses: github/codeql-action/init@87fc816d2538b0c915adeec59d61168692e8ab06 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e83e0a4f58f2ca25f7dd222e8689519a74bf26fc + uses: github/codeql-action/analyze@87fc816d2538b0c915adeec59d61168692e8ab06 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 40b0511a7..6bb64b7aa 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@e83e0a4f58f2ca25f7dd222e8689519a74bf26fc + uses: github/codeql-action/init@87fc816d2538b0c915adeec59d61168692e8ab06 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@e83e0a4f58f2ca25f7dd222e8689519a74bf26fc + uses: github/codeql-action/autobuild@87fc816d2538b0c915adeec59d61168692e8ab06 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e83e0a4f58f2ca25f7dd222e8689519a74bf26fc + uses: github/codeql-action/analyze@87fc816d2538b0c915adeec59d61168692e8ab06 From b997946db1c7663b7ebb775ad45cdb2b0aaeb291 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 11 Jan 2025 06:42:17 +0000 Subject: [PATCH 093/745] chore(deps): update github/codeql-action digest to db7177a (#1279) 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 87e342e0b..878b3628c 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@87fc816d2538b0c915adeec59d61168692e8ab06 + uses: github/codeql-action/init@db7177a1c66bea89f5e7ce32d0ea48bea4a0d460 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@87fc816d2538b0c915adeec59d61168692e8ab06 + uses: github/codeql-action/analyze@db7177a1c66bea89f5e7ce32d0ea48bea4a0d460 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 6bb64b7aa..0cef957d0 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@87fc816d2538b0c915adeec59d61168692e8ab06 + uses: github/codeql-action/init@db7177a1c66bea89f5e7ce32d0ea48bea4a0d460 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@87fc816d2538b0c915adeec59d61168692e8ab06 + uses: github/codeql-action/autobuild@db7177a1c66bea89f5e7ce32d0ea48bea4a0d460 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@87fc816d2538b0c915adeec59d61168692e8ab06 + uses: github/codeql-action/analyze@db7177a1c66bea89f5e7ce32d0ea48bea4a0d460 From a3854d6ab1dba99f4db18f868e89fcc04418e306 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 01:08:23 +0000 Subject: [PATCH 094/745] chore(deps): update github/codeql-action digest to 10a3f07 (#1280) 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 878b3628c..b721179e1 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@db7177a1c66bea89f5e7ce32d0ea48bea4a0d460 + uses: github/codeql-action/init@10a3f072a02acccf25a5b381a29fbac3a805893d with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@db7177a1c66bea89f5e7ce32d0ea48bea4a0d460 + uses: github/codeql-action/analyze@10a3f072a02acccf25a5b381a29fbac3a805893d diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 0cef957d0..d98268853 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@db7177a1c66bea89f5e7ce32d0ea48bea4a0d460 + uses: github/codeql-action/init@10a3f072a02acccf25a5b381a29fbac3a805893d with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@db7177a1c66bea89f5e7ce32d0ea48bea4a0d460 + uses: github/codeql-action/autobuild@10a3f072a02acccf25a5b381a29fbac3a805893d - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@db7177a1c66bea89f5e7ce32d0ea48bea4a0d460 + uses: github/codeql-action/analyze@10a3f072a02acccf25a5b381a29fbac3a805893d From 8a1ab7ea18aff4ee5a6a2fdd1f805b08e51a50a3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 23:40:55 +0000 Subject: [PATCH 095/745] chore(deps): update github/codeql-action digest to 1efc6bb (#1281) 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 b721179e1..3b656a11a 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@10a3f072a02acccf25a5b381a29fbac3a805893d + uses: github/codeql-action/init@1efc6bb9cee638a55957d2a72be3a65436af0e57 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@10a3f072a02acccf25a5b381a29fbac3a805893d + uses: github/codeql-action/analyze@1efc6bb9cee638a55957d2a72be3a65436af0e57 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index d98268853..9aa1a4d93 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@10a3f072a02acccf25a5b381a29fbac3a805893d + uses: github/codeql-action/init@1efc6bb9cee638a55957d2a72be3a65436af0e57 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@10a3f072a02acccf25a5b381a29fbac3a805893d + uses: github/codeql-action/autobuild@1efc6bb9cee638a55957d2a72be3a65436af0e57 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@10a3f072a02acccf25a5b381a29fbac3a805893d + uses: github/codeql-action/analyze@1efc6bb9cee638a55957d2a72be3a65436af0e57 From b390d5f0b0945948cd6b87e6486725d095d5ac8a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 16:46:16 +0000 Subject: [PATCH 096/745] chore(deps): update github/codeql-action digest to 3b4f4d9 (#1282) 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 3b656a11a..6a49332c2 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@1efc6bb9cee638a55957d2a72be3a65436af0e57 + uses: github/codeql-action/init@3b4f4d94c0591488e786754af4206d57afb25431 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1efc6bb9cee638a55957d2a72be3a65436af0e57 + uses: github/codeql-action/analyze@3b4f4d94c0591488e786754af4206d57afb25431 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 9aa1a4d93..2e8cefa44 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@1efc6bb9cee638a55957d2a72be3a65436af0e57 + uses: github/codeql-action/init@3b4f4d94c0591488e786754af4206d57afb25431 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@1efc6bb9cee638a55957d2a72be3a65436af0e57 + uses: github/codeql-action/autobuild@3b4f4d94c0591488e786754af4206d57afb25431 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1efc6bb9cee638a55957d2a72be3a65436af0e57 + uses: github/codeql-action/analyze@3b4f4d94c0591488e786754af4206d57afb25431 From 45b3995bdad9f1b05abb01455a9c8f57028cfde5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 16 Jan 2025 01:12:12 +0000 Subject: [PATCH 097/745] chore(deps): update github/codeql-action digest to 93da9f2 (#1283) 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 6a49332c2..1a9429bff 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@3b4f4d94c0591488e786754af4206d57afb25431 + uses: github/codeql-action/init@93da9f25abe6f581e48ccd6baad84025ff6a738b with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3b4f4d94c0591488e786754af4206d57afb25431 + uses: github/codeql-action/analyze@93da9f25abe6f581e48ccd6baad84025ff6a738b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 2e8cefa44..fd184a68d 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@3b4f4d94c0591488e786754af4206d57afb25431 + uses: github/codeql-action/init@93da9f25abe6f581e48ccd6baad84025ff6a738b with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@3b4f4d94c0591488e786754af4206d57afb25431 + uses: github/codeql-action/autobuild@93da9f25abe6f581e48ccd6baad84025ff6a738b - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3b4f4d94c0591488e786754af4206d57afb25431 + uses: github/codeql-action/analyze@93da9f25abe6f581e48ccd6baad84025ff6a738b From 32a39335de8e61650905fc96dc1a73e65f1fe9f8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 16 Jan 2025 21:00:50 +0000 Subject: [PATCH 098/745] chore(deps): update actions/setup-java digest to 99d3141 (#1285) 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 bcdd87a0a..b2e5cdc69 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -22,7 +22,7 @@ jobs: steps: - uses: actions/checkout@cbb722410c2e876e24abbe8de2cc27693e501dcb - name: Set up JDK 8 - uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b + uses: actions/setup-java@99d3141d9ba96520552bfd7a9545bc1d74da9251 with: java-version: '8' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 1a9429bff..c7e452972 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -13,7 +13,7 @@ jobs: uses: actions/checkout@cbb722410c2e876e24abbe8de2cc27693e501dcb - name: Set up JDK 8 - uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b + uses: actions/setup-java@99d3141d9ba96520552bfd7a9545bc1d74da9251 with: java-version: '8' distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2b1eb9e7f..539b64232 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: uses: actions/checkout@cbb722410c2e876e24abbe8de2cc27693e501dcb - name: Set up JDK 8 if: ${{ steps.release.outputs.release_created }} - uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b + uses: actions/setup-java@99d3141d9ba96520552bfd7a9545bc1d74da9251 with: java-version: '8' distribution: 'temurin' From 640e35e85375e3098f61b7397432d80a95502bdd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 17 Jan 2025 01:30:43 +0000 Subject: [PATCH 099/745] chore(deps): update actions/checkout digest to 85e6279 (#1287) 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 +- .github/workflows/static-code-scanning.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index b2e5cdc69..b0751e5f6 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@cbb722410c2e876e24abbe8de2cc27693e501dcb + - uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 8 uses: actions/setup-java@99d3141d9ba96520552bfd7a9545bc1d74da9251 with: diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index c7e452972..f12c9f1d5 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out the code - uses: actions/checkout@cbb722410c2e876e24abbe8de2cc27693e501dcb + uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 8 uses: actions/setup-java@99d3141d9ba96520552bfd7a9545bc1d74da9251 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 539b64232..f5ea9967b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,7 +28,7 @@ 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@cbb722410c2e876e24abbe8de2cc27693e501dcb + uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 8 if: ${{ steps.release.outputs.release_created }} uses: actions/setup-java@99d3141d9ba96520552bfd7a9545bc1d74da9251 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index fd184a68d..d29742148 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@cbb722410c2e876e24abbe8de2cc27693e501dcb + uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL From c69d3a4bd137c1d6baa47c14228bfe8f96555676 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 17 Jan 2025 05:22:11 +0000 Subject: [PATCH 100/745] chore(deps): update actions/setup-java digest to 51ab6d2 (#1288) 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 b0751e5f6..65487dfe1 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -22,7 +22,7 @@ jobs: steps: - uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 8 - uses: actions/setup-java@99d3141d9ba96520552bfd7a9545bc1d74da9251 + uses: actions/setup-java@51ab6d2e3070fda1eac8cfaab8ffd90e6019d7e1 with: java-version: '8' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index f12c9f1d5..354f623ab 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -13,7 +13,7 @@ jobs: uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 8 - uses: actions/setup-java@99d3141d9ba96520552bfd7a9545bc1d74da9251 + uses: actions/setup-java@51ab6d2e3070fda1eac8cfaab8ffd90e6019d7e1 with: java-version: '8' distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f5ea9967b..aeebf6beb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 8 if: ${{ steps.release.outputs.release_created }} - uses: actions/setup-java@99d3141d9ba96520552bfd7a9545bc1d74da9251 + uses: actions/setup-java@51ab6d2e3070fda1eac8cfaab8ffd90e6019d7e1 with: java-version: '8' distribution: 'temurin' From 882d2dd5bdac007e8a3783efc54fa45faed22054 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 17 Jan 2025 09:37:40 +0000 Subject: [PATCH 101/745] chore(deps): update github/codeql-action digest to 0f1559a (#1286) 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 354f623ab..5d16197bf 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@93da9f25abe6f581e48ccd6baad84025ff6a738b + uses: github/codeql-action/init@0f1559aeaf806072ddd427d1b11e1c956e4851a0 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@93da9f25abe6f581e48ccd6baad84025ff6a738b + uses: github/codeql-action/analyze@0f1559aeaf806072ddd427d1b11e1c956e4851a0 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index d29742148..1b77e161b 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@93da9f25abe6f581e48ccd6baad84025ff6a738b + uses: github/codeql-action/init@0f1559aeaf806072ddd427d1b11e1c956e4851a0 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@93da9f25abe6f581e48ccd6baad84025ff6a738b + uses: github/codeql-action/autobuild@0f1559aeaf806072ddd427d1b11e1c956e4851a0 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@93da9f25abe6f581e48ccd6baad84025ff6a738b + uses: github/codeql-action/analyze@0f1559aeaf806072ddd427d1b11e1c956e4851a0 From 0b5b423bdd378bb1db3e10fe5da7fa2c937a4610 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 18 Jan 2025 04:42:09 +0000 Subject: [PATCH 102/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.16.0 (#1289) 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 5d8ea34ce..d79b8447c 100644 --- a/pom.xml +++ b/pom.xml @@ -167,7 +167,7 @@ net.bytebuddy byte-buddy - 1.15.11 + 1.16.0 test From 6c4205a00817af260ef9b90f54ce878cad33f75a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 18 Jan 2025 08:26:00 +0000 Subject: [PATCH 103/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.16.0 (#1290) 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 d79b8447c..6dec1bc0e 100644 --- a/pom.xml +++ b/pom.xml @@ -174,7 +174,7 @@ net.bytebuddy byte-buddy-agent - 1.15.11 + 1.16.0 test From a5eb21d1a2e6945a4455cacde898bc913bddb96d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 18 Jan 2025 17:02:55 +0000 Subject: [PATCH 104/745] chore(deps): update dependency org.assertj:assertj-core to v3.27.3 (#1291) 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 6dec1bc0e..a315e06a3 100644 --- a/pom.xml +++ b/pom.xml @@ -77,7 +77,7 @@ org.assertj assertj-core - 3.27.2 + 3.27.3 test From 0af9f2901f88b5ef9bed0c570d426939a55af3cf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 Jan 2025 12:47:02 +0000 Subject: [PATCH 105/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.16.1 (#1292) 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 a315e06a3..84439c594 100644 --- a/pom.xml +++ b/pom.xml @@ -167,7 +167,7 @@ net.bytebuddy byte-buddy - 1.16.0 + 1.16.1 test From 6071932cb4207dc83cdedfa67c8a69ed71d9c26a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 Jan 2025 16:48:47 +0000 Subject: [PATCH 106/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.16.1 (#1293) 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 84439c594..54bc4bd70 100644 --- a/pom.xml +++ b/pom.xml @@ -174,7 +174,7 @@ net.bytebuddy byte-buddy-agent - 1.16.0 + 1.16.1 test From 5671184e7f76f979d631c18bb2ebfb15dccfb207 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 21 Jan 2025 01:24:58 +0000 Subject: [PATCH 107/745] chore(deps): update github/codeql-action digest to d90e07f (#1294) 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 5d16197bf..13fc89ee8 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@0f1559aeaf806072ddd427d1b11e1c956e4851a0 + uses: github/codeql-action/init@d90e07f32eb48924444e8069d5f1fbaaad678989 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0f1559aeaf806072ddd427d1b11e1c956e4851a0 + uses: github/codeql-action/analyze@d90e07f32eb48924444e8069d5f1fbaaad678989 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 1b77e161b..1f4fbc24a 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@0f1559aeaf806072ddd427d1b11e1c956e4851a0 + uses: github/codeql-action/init@d90e07f32eb48924444e8069d5f1fbaaad678989 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@0f1559aeaf806072ddd427d1b11e1c956e4851a0 + uses: github/codeql-action/autobuild@d90e07f32eb48924444e8069d5f1fbaaad678989 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0f1559aeaf806072ddd427d1b11e1c956e4851a0 + uses: github/codeql-action/analyze@d90e07f32eb48924444e8069d5f1fbaaad678989 From 122e82f8431fb116ae3b147f7e2245d7f90b1c77 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 21 Jan 2025 22:08:52 +0000 Subject: [PATCH 108/745] chore(deps): update github/codeql-action digest to f89b8a7 (#1295) 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 13fc89ee8..ea30387ef 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@d90e07f32eb48924444e8069d5f1fbaaad678989 + uses: github/codeql-action/init@f89b8a7d5239ba6d1a0f243ead94ea9ca5775ae1 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@d90e07f32eb48924444e8069d5f1fbaaad678989 + uses: github/codeql-action/analyze@f89b8a7d5239ba6d1a0f243ead94ea9ca5775ae1 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 1f4fbc24a..1dcf3feb1 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@d90e07f32eb48924444e8069d5f1fbaaad678989 + uses: github/codeql-action/init@f89b8a7d5239ba6d1a0f243ead94ea9ca5775ae1 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@d90e07f32eb48924444e8069d5f1fbaaad678989 + uses: github/codeql-action/autobuild@f89b8a7d5239ba6d1a0f243ead94ea9ca5775ae1 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@d90e07f32eb48924444e8069d5f1fbaaad678989 + uses: github/codeql-action/analyze@f89b8a7d5239ba6d1a0f243ead94ea9ca5775ae1 From 874e86df5c22a1e5771ca16c76aa13039b5f9b65 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 22 Jan 2025 04:49:00 +0000 Subject: [PATCH 109/745] chore(deps): update actions/setup-java digest to 28b532b (#1296) 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 65487dfe1..707dc1a02 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -22,7 +22,7 @@ jobs: steps: - uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 8 - uses: actions/setup-java@51ab6d2e3070fda1eac8cfaab8ffd90e6019d7e1 + uses: actions/setup-java@28b532bcb39ad928b00bc3cbce25c94d11654854 with: java-version: '8' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index ea30387ef..eecff6a74 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -13,7 +13,7 @@ jobs: uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 8 - uses: actions/setup-java@51ab6d2e3070fda1eac8cfaab8ffd90e6019d7e1 + uses: actions/setup-java@28b532bcb39ad928b00bc3cbce25c94d11654854 with: java-version: '8' distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index aeebf6beb..a3dfa2b2b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 8 if: ${{ steps.release.outputs.release_created }} - uses: actions/setup-java@51ab6d2e3070fda1eac8cfaab8ffd90e6019d7e1 + uses: actions/setup-java@28b532bcb39ad928b00bc3cbce25c94d11654854 with: java-version: '8' distribution: 'temurin' From 305e0329e78116fe697240e420879ac85012d698 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 23 Jan 2025 00:49:44 +0000 Subject: [PATCH 110/745] chore(deps): update github/codeql-action digest to b44b19f (#1297) 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 eecff6a74..e964c1c31 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@f89b8a7d5239ba6d1a0f243ead94ea9ca5775ae1 + uses: github/codeql-action/init@b44b19fe8d2128e72e5616696401b61c348967f8 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f89b8a7d5239ba6d1a0f243ead94ea9ca5775ae1 + uses: github/codeql-action/analyze@b44b19fe8d2128e72e5616696401b61c348967f8 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 1dcf3feb1..0ce0ef099 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@f89b8a7d5239ba6d1a0f243ead94ea9ca5775ae1 + uses: github/codeql-action/init@b44b19fe8d2128e72e5616696401b61c348967f8 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@f89b8a7d5239ba6d1a0f243ead94ea9ca5775ae1 + uses: github/codeql-action/autobuild@b44b19fe8d2128e72e5616696401b61c348967f8 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f89b8a7d5239ba6d1a0f243ead94ea9ca5775ae1 + uses: github/codeql-action/analyze@b44b19fe8d2128e72e5616696401b61c348967f8 From 531fc385b662c5b7b334fee298fc9fe1283c78fb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 23 Jan 2025 04:46:04 +0000 Subject: [PATCH 111/745] chore(deps): update codecov/codecov-action action to v5.2.0 (#1298) 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 707dc1a02..892bc0058 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -49,7 +49,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.1.2 + uses: codecov/codecov-action@v5.2.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 e964c1c31..282b94a8b 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -36,7 +36,7 @@ jobs: run: mvn --batch-mode --update-snapshots --activate-profiles e2e verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.1.2 + uses: codecov/codecov-action@v5.2.0 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From 34919561b73faa0cca489ad480e93cca9a854167 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 24 Jan 2025 02:00:19 +0000 Subject: [PATCH 112/745] chore(deps): update github/codeql-action digest to 7e3036b (#1300) 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 282b94a8b..78923d200 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@b44b19fe8d2128e72e5616696401b61c348967f8 + uses: github/codeql-action/init@7e3036b9cd87fc26dd06747b7aa4b96c27aaef3a with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b44b19fe8d2128e72e5616696401b61c348967f8 + uses: github/codeql-action/analyze@7e3036b9cd87fc26dd06747b7aa4b96c27aaef3a diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 0ce0ef099..8efcc7fbd 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@b44b19fe8d2128e72e5616696401b61c348967f8 + uses: github/codeql-action/init@7e3036b9cd87fc26dd06747b7aa4b96c27aaef3a with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@b44b19fe8d2128e72e5616696401b61c348967f8 + uses: github/codeql-action/autobuild@7e3036b9cd87fc26dd06747b7aa4b96c27aaef3a - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b44b19fe8d2128e72e5616696401b61c348967f8 + uses: github/codeql-action/analyze@7e3036b9cd87fc26dd06747b7aa4b96c27aaef3a From f7f6586d72e3f112a7dafc8f77de273ed49ccc4b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 24 Jan 2025 05:39:08 +0000 Subject: [PATCH 113/745] chore(deps): update codecov/codecov-action action to v5.3.0 (#1301) 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 892bc0058..4841dd81a 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -49,7 +49,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.2.0 + uses: codecov/codecov-action@v5.3.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 78923d200..2e4edcc7c 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -36,7 +36,7 @@ jobs: run: mvn --batch-mode --update-snapshots --activate-profiles e2e verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.2.0 + uses: codecov/codecov-action@v5.3.0 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From 78adc77c23da6116e1f58b3a45dc283c3c58837b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 25 Jan 2025 01:31:55 +0000 Subject: [PATCH 114/745] chore(deps): update github/codeql-action digest to e7c0c9d (#1302) 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 2e4edcc7c..45f2106dd 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@7e3036b9cd87fc26dd06747b7aa4b96c27aaef3a + uses: github/codeql-action/init@e7c0c9d71b7bd108fd12e06b56fc58d3d154164d with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7e3036b9cd87fc26dd06747b7aa4b96c27aaef3a + uses: github/codeql-action/analyze@e7c0c9d71b7bd108fd12e06b56fc58d3d154164d diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 8efcc7fbd..e6b5727d6 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@7e3036b9cd87fc26dd06747b7aa4b96c27aaef3a + uses: github/codeql-action/init@e7c0c9d71b7bd108fd12e06b56fc58d3d154164d with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@7e3036b9cd87fc26dd06747b7aa4b96c27aaef3a + uses: github/codeql-action/autobuild@e7c0c9d71b7bd108fd12e06b56fc58d3d154164d - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7e3036b9cd87fc26dd06747b7aa4b96c27aaef3a + uses: github/codeql-action/analyze@e7c0c9d71b7bd108fd12e06b56fc58d3d154164d From f9fa54be493e1d0843b709008eb0f047e7580d47 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 25 Jan 2025 04:32:24 +0000 Subject: [PATCH 115/745] chore(deps): update codecov/codecov-action action to v5.3.1 (#1303) 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 4841dd81a..53477cdc9 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -49,7 +49,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.3.0 + uses: codecov/codecov-action@v5.3.1 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 45f2106dd..f316bff53 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -36,7 +36,7 @@ jobs: run: mvn --batch-mode --update-snapshots --activate-profiles e2e verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.3.0 + uses: codecov/codecov-action@v5.3.1 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From 6874de64ce589e853f5523019bfa9e1d60840baf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Jan 2025 01:53:26 +0000 Subject: [PATCH 116/745] chore(deps): update github/codeql-action digest to 43cffee (#1304) 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 f316bff53..0e7af106f 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@e7c0c9d71b7bd108fd12e06b56fc58d3d154164d + uses: github/codeql-action/init@43cffee81145631c422e33aaf507d18e57077557 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e7c0c9d71b7bd108fd12e06b56fc58d3d154164d + uses: github/codeql-action/analyze@43cffee81145631c422e33aaf507d18e57077557 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index e6b5727d6..feafd1a46 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@e7c0c9d71b7bd108fd12e06b56fc58d3d154164d + uses: github/codeql-action/init@43cffee81145631c422e33aaf507d18e57077557 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@e7c0c9d71b7bd108fd12e06b56fc58d3d154164d + uses: github/codeql-action/autobuild@43cffee81145631c422e33aaf507d18e57077557 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e7c0c9d71b7bd108fd12e06b56fc58d3d154164d + uses: github/codeql-action/analyze@43cffee81145631c422e33aaf507d18e57077557 From 7916d76635c5ab59dafe6d72058aad9cfcf05f4b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Jan 2025 13:26:01 +0000 Subject: [PATCH 117/745] chore(deps): update github/codeql-action digest to 5f4f998 (#1305) 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 0e7af106f..b52a8c5c7 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@43cffee81145631c422e33aaf507d18e57077557 + uses: github/codeql-action/init@5f4f998a94c376fff5b313abc48c529e181a51d7 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@43cffee81145631c422e33aaf507d18e57077557 + uses: github/codeql-action/analyze@5f4f998a94c376fff5b313abc48c529e181a51d7 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index feafd1a46..542c7dfbd 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@43cffee81145631c422e33aaf507d18e57077557 + uses: github/codeql-action/init@5f4f998a94c376fff5b313abc48c529e181a51d7 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@43cffee81145631c422e33aaf507d18e57077557 + uses: github/codeql-action/autobuild@5f4f998a94c376fff5b313abc48c529e181a51d7 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@43cffee81145631c422e33aaf507d18e57077557 + uses: github/codeql-action/analyze@5f4f998a94c376fff5b313abc48c529e181a51d7 From ba9cc4b85a1082d638d49b9d2d0a4ed5a45f09ee Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Jan 2025 22:03:11 +0000 Subject: [PATCH 118/745] chore(deps): update actions/setup-java digest to 3a4f6e1 (#1306) 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 53477cdc9..338a0985c 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -22,7 +22,7 @@ jobs: steps: - uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 8 - uses: actions/setup-java@28b532bcb39ad928b00bc3cbce25c94d11654854 + uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 with: java-version: '8' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index b52a8c5c7..e670a653f 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -13,7 +13,7 @@ jobs: uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 8 - uses: actions/setup-java@28b532bcb39ad928b00bc3cbce25c94d11654854 + uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 with: java-version: '8' distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a3dfa2b2b..7342889db 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 8 if: ${{ steps.release.outputs.release_created }} - uses: actions/setup-java@28b532bcb39ad928b00bc3cbce25c94d11654854 + uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 with: java-version: '8' distribution: 'temurin' From 6f36434c520dcef27deb04e04941693dc15acb2f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Jan 2025 01:46:15 +0000 Subject: [PATCH 119/745] chore(deps): update github/codeql-action digest to 54b1c84 (#1307) 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 e670a653f..4fa4a6a90 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@5f4f998a94c376fff5b313abc48c529e181a51d7 + uses: github/codeql-action/init@54b1c84213ea9eb9171e2b582ff91d53078adecf with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5f4f998a94c376fff5b313abc48c529e181a51d7 + uses: github/codeql-action/analyze@54b1c84213ea9eb9171e2b582ff91d53078adecf diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 542c7dfbd..9b6e52ee9 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@5f4f998a94c376fff5b313abc48c529e181a51d7 + uses: github/codeql-action/init@54b1c84213ea9eb9171e2b582ff91d53078adecf with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@5f4f998a94c376fff5b313abc48c529e181a51d7 + uses: github/codeql-action/autobuild@54b1c84213ea9eb9171e2b582ff91d53078adecf - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5f4f998a94c376fff5b313abc48c529e181a51d7 + uses: github/codeql-action/analyze@54b1c84213ea9eb9171e2b582ff91d53078adecf From 99d818572a3407ca6b25f6e91f69ef3e83bdc657 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Jan 2025 04:28:35 +0000 Subject: [PATCH 120/745] chore(deps): update github/codeql-action digest to e9987ad (#1308) 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 4fa4a6a90..44eb07353 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@54b1c84213ea9eb9171e2b582ff91d53078adecf + uses: github/codeql-action/init@e9987ad0c1d193b03a7dd5e76c24631552dd1a94 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@54b1c84213ea9eb9171e2b582ff91d53078adecf + uses: github/codeql-action/analyze@e9987ad0c1d193b03a7dd5e76c24631552dd1a94 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 9b6e52ee9..a282d1429 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@54b1c84213ea9eb9171e2b582ff91d53078adecf + uses: github/codeql-action/init@e9987ad0c1d193b03a7dd5e76c24631552dd1a94 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@54b1c84213ea9eb9171e2b582ff91d53078adecf + uses: github/codeql-action/autobuild@e9987ad0c1d193b03a7dd5e76c24631552dd1a94 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@54b1c84213ea9eb9171e2b582ff91d53078adecf + uses: github/codeql-action/analyze@e9987ad0c1d193b03a7dd5e76c24631552dd1a94 From cda34053f7e39318205a181ef93c825bab2ed9fc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Jan 2025 09:03:12 +0000 Subject: [PATCH 121/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.17.0 (#1309) 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 54bc4bd70..e928febc8 100644 --- a/pom.xml +++ b/pom.xml @@ -167,7 +167,7 @@ net.bytebuddy byte-buddy - 1.16.1 + 1.17.0 test From 40fa1733382f4c476a1228c6499044ad83c8f3c4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Jan 2025 12:26:19 +0000 Subject: [PATCH 122/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.17.0 (#1310) 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 e928febc8..989ff4fb3 100644 --- a/pom.xml +++ b/pom.xml @@ -174,7 +174,7 @@ net.bytebuddy byte-buddy-agent - 1.16.1 + 1.17.0 test From 9a1e9abd64220c8d8706f2a64e041ef3f37e1a43 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Jan 2025 21:39:36 +0000 Subject: [PATCH 123/745] chore(deps): update github/codeql-action digest to 0701025 (#1311) 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 44eb07353..d7ade6207 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@e9987ad0c1d193b03a7dd5e76c24631552dd1a94 + uses: github/codeql-action/init@0701025a8b1600e416be4f3bb5a830b1aa6af01e with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e9987ad0c1d193b03a7dd5e76c24631552dd1a94 + uses: github/codeql-action/analyze@0701025a8b1600e416be4f3bb5a830b1aa6af01e diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index a282d1429..8e6d4ed29 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@e9987ad0c1d193b03a7dd5e76c24631552dd1a94 + uses: github/codeql-action/init@0701025a8b1600e416be4f3bb5a830b1aa6af01e with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@e9987ad0c1d193b03a7dd5e76c24631552dd1a94 + uses: github/codeql-action/autobuild@0701025a8b1600e416be4f3bb5a830b1aa6af01e - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e9987ad0c1d193b03a7dd5e76c24631552dd1a94 + uses: github/codeql-action/analyze@0701025a8b1600e416be4f3bb5a830b1aa6af01e From 208411e72338e37bf477ac0b784bbbbe0309b922 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 09:58:39 +0100 Subject: [PATCH 124/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.21.0 (#1312) 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 989ff4fb3..e75dd506a 100644 --- a/pom.xml +++ b/pom.xml @@ -182,7 +182,7 @@ io.cucumber cucumber-bom - 7.20.1 + 7.21.0 pom import From 37ed6a424cdc013ed74c9881826cc56c93ae8228 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Feb 2025 02:27:14 +0000 Subject: [PATCH 125/745] chore(deps): update github/codeql-action digest to 08bc0cf (#1313) 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 d7ade6207..07e669fc5 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@0701025a8b1600e416be4f3bb5a830b1aa6af01e + uses: github/codeql-action/init@08bc0cf022445eacafaa248bf48da20f26b8fd40 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0701025a8b1600e416be4f3bb5a830b1aa6af01e + uses: github/codeql-action/analyze@08bc0cf022445eacafaa248bf48da20f26b8fd40 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 8e6d4ed29..818ff9c41 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@0701025a8b1600e416be4f3bb5a830b1aa6af01e + uses: github/codeql-action/init@08bc0cf022445eacafaa248bf48da20f26b8fd40 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@0701025a8b1600e416be4f3bb5a830b1aa6af01e + uses: github/codeql-action/autobuild@08bc0cf022445eacafaa248bf48da20f26b8fd40 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0701025a8b1600e416be4f3bb5a830b1aa6af01e + uses: github/codeql-action/analyze@08bc0cf022445eacafaa248bf48da20f26b8fd40 From 46903c6f275e5f9dc8884acf3f76f76efcfc58bd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 6 Feb 2025 18:53:02 +0000 Subject: [PATCH 126/745] chore(deps): update github/codeql-action digest to 24e1c2d (#1315) 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 07e669fc5..1eb8a33b3 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@08bc0cf022445eacafaa248bf48da20f26b8fd40 + uses: github/codeql-action/init@24e1c2d337459cce262cbca8d69998e56cd5eb8e with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@08bc0cf022445eacafaa248bf48da20f26b8fd40 + uses: github/codeql-action/analyze@24e1c2d337459cce262cbca8d69998e56cd5eb8e diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 818ff9c41..cc218c557 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@08bc0cf022445eacafaa248bf48da20f26b8fd40 + uses: github/codeql-action/init@24e1c2d337459cce262cbca8d69998e56cd5eb8e with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@08bc0cf022445eacafaa248bf48da20f26b8fd40 + uses: github/codeql-action/autobuild@24e1c2d337459cce262cbca8d69998e56cd5eb8e - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@08bc0cf022445eacafaa248bf48da20f26b8fd40 + uses: github/codeql-action/analyze@24e1c2d337459cce262cbca8d69998e56cd5eb8e From 26e1d7fff342a32880542efa87b017aec506667e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 7 Feb 2025 17:53:29 +0000 Subject: [PATCH 127/745] chore(deps): update github/codeql-action digest to 0a35e8f (#1316) 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 1eb8a33b3..6815fa8ec 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@24e1c2d337459cce262cbca8d69998e56cd5eb8e + uses: github/codeql-action/init@0a35e8f6866a39b001e5f7ad1d0daf9836786896 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@24e1c2d337459cce262cbca8d69998e56cd5eb8e + uses: github/codeql-action/analyze@0a35e8f6866a39b001e5f7ad1d0daf9836786896 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index cc218c557..b573e6365 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@24e1c2d337459cce262cbca8d69998e56cd5eb8e + uses: github/codeql-action/init@0a35e8f6866a39b001e5f7ad1d0daf9836786896 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@24e1c2d337459cce262cbca8d69998e56cd5eb8e + uses: github/codeql-action/autobuild@0a35e8f6866a39b001e5f7ad1d0daf9836786896 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@24e1c2d337459cce262cbca8d69998e56cd5eb8e + uses: github/codeql-action/analyze@0a35e8f6866a39b001e5f7ad1d0daf9836786896 From b7978832b786fe081169ff0efeb702218300c622 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 7 Feb 2025 20:56:17 +0000 Subject: [PATCH 128/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.21.1 (#1317) 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 e75dd506a..8b3ce85af 100644 --- a/pom.xml +++ b/pom.xml @@ -182,7 +182,7 @@ io.cucumber cucumber-bom - 7.21.0 + 7.21.1 pom import From 538140dfe713a421623b179e69b399f82200fe61 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 09:32:43 +0000 Subject: [PATCH 129/745] chore(deps): update github/codeql-action digest to 6063925 (#1320) 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 6815fa8ec..94745b3ef 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@0a35e8f6866a39b001e5f7ad1d0daf9836786896 + uses: github/codeql-action/init@606392577144219644443c010bc0e17ad563e559 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0a35e8f6866a39b001e5f7ad1d0daf9836786896 + uses: github/codeql-action/analyze@606392577144219644443c010bc0e17ad563e559 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index b573e6365..8add2783a 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@0a35e8f6866a39b001e5f7ad1d0daf9836786896 + uses: github/codeql-action/init@606392577144219644443c010bc0e17ad563e559 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@0a35e8f6866a39b001e5f7ad1d0daf9836786896 + uses: github/codeql-action/autobuild@606392577144219644443c010bc0e17ad563e559 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0a35e8f6866a39b001e5f7ad1d0daf9836786896 + uses: github/codeql-action/analyze@606392577144219644443c010bc0e17ad563e559 From 8f3ced590764760244cc81ac10c939ca62504dfe Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Feb 2025 11:46:13 +0000 Subject: [PATCH 130/745] chore(deps): update github/codeql-action digest to affec20 (#1323) 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 94745b3ef..7791fe512 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@606392577144219644443c010bc0e17ad563e559 + uses: github/codeql-action/init@affec202b3ff85f13ab60c1d834aa4996994a484 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@606392577144219644443c010bc0e17ad563e559 + uses: github/codeql-action/analyze@affec202b3ff85f13ab60c1d834aa4996994a484 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 8add2783a..94dd2624d 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@606392577144219644443c010bc0e17ad563e559 + uses: github/codeql-action/init@affec202b3ff85f13ab60c1d834aa4996994a484 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@606392577144219644443c010bc0e17ad563e559 + uses: github/codeql-action/autobuild@affec202b3ff85f13ab60c1d834aa4996994a484 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@606392577144219644443c010bc0e17ad563e559 + uses: github/codeql-action/analyze@affec202b3ff85f13ab60c1d834aa4996994a484 From 69cdc772a639470dd223bf70ef6e9f8bc4d93dea Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Feb 2025 22:35:36 +0000 Subject: [PATCH 131/745] chore(deps): update actions/cache digest to 9fa7e61 (#1324) 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 338a0985c..6ef83234d 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -32,7 +32,7 @@ jobs: server-password: ${{ secrets.OSSRH_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@36f1e144e1c8edb0a652766b484448563d8baf46 + uses: actions/cache@9fa7e61ec7e1f44ac75218e7aaea81da8856fd11 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 7791fe512..8a0b845da 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -25,7 +25,7 @@ jobs: languages: java - name: Cache local Maven repository - uses: actions/cache@36f1e144e1c8edb0a652766b484448563d8baf46 + uses: actions/cache@9fa7e61ec7e1f44ac75218e7aaea81da8856fd11 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} From 3baf0df966f8212864aa7e57bc3d3d09d324fe11 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 13 Feb 2025 02:02:06 +0000 Subject: [PATCH 132/745] chore(deps): update github/codeql-action digest to 1c15a48 (#1325) 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 8a0b845da..6e3c40f48 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@affec202b3ff85f13ab60c1d834aa4996994a484 + uses: github/codeql-action/init@1c15a48f3fb49ce535e9ee4e57e127315f669361 with: languages: java @@ -45,4 +45,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@affec202b3ff85f13ab60c1d834aa4996994a484 + uses: github/codeql-action/analyze@1c15a48f3fb49ce535e9ee4e57e127315f669361 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 94dd2624d..85313855b 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@affec202b3ff85f13ab60c1d834aa4996994a484 + uses: github/codeql-action/init@1c15a48f3fb49ce535e9ee4e57e127315f669361 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@affec202b3ff85f13ab60c1d834aa4996994a484 + uses: github/codeql-action/autobuild@1c15a48f3fb49ce535e9ee4e57e127315f669361 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@affec202b3ff85f13ab60c1d834aa4996994a484 + uses: github/codeql-action/analyze@1c15a48f3fb49ce535e9ee4e57e127315f669361 From 08c38fb553d82a42682c3eb9239329f770063898 Mon Sep 17 00:00:00 2001 From: Jonathan Norris Date: Thu, 13 Feb 2025 11:50:19 -0700 Subject: [PATCH 133/745] fix: TrackingEventDetails interface to include numeric getValue() call (#1328) Signed-off-by: Jonathan Norris --- .../java/dev/openfeature/sdk/TrackingEventDetails.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/dev/openfeature/sdk/TrackingEventDetails.java b/src/main/java/dev/openfeature/sdk/TrackingEventDetails.java index 15b0208c0..484672d8a 100644 --- a/src/main/java/dev/openfeature/sdk/TrackingEventDetails.java +++ b/src/main/java/dev/openfeature/sdk/TrackingEventDetails.java @@ -1,6 +1,14 @@ package dev.openfeature.sdk; +import java.util.Optional; + /** * Data pertinent to a particular tracking event. */ -public interface TrackingEventDetails extends Structure {} +public interface TrackingEventDetails extends Structure { + + /** + * Returns the optional numeric tracking value. + */ + Optional getValue(); +} From c33ac2d9b2e91b85fffb3c21653912fe82006351 Mon Sep 17 00:00:00 2001 From: Philipp Fehre Date: Thu, 13 Feb 2025 20:01:58 +0100 Subject: [PATCH 134/745] fix: possible event-related deadlocks with some providers (#1314) * Move event emitting off the main thread to avoid deadlocks When stacking event emitting inside an EventProvider, when using sychronization the EventProvider can deadlock, to avoid this move the event emitting of the main thread. Signed-off-by: Philipp Fehre * Test fixes Test provider should respect the init-delay during all test Signed-off-by: Philipp Fehre * Add timeout to EventProviderTest With the events being executed on a different thread, we need to wait to make sure the thread is scheduled to have the events emitted. Signed-off-by: Philipp Fehre * Don't reuse the JVM Process Signed-off-by: Philipp Fehre --------- Signed-off-by: Philipp Fehre Co-authored-by: Philipp Fehre Co-authored-by: Michael Beemer Co-authored-by: Todd Baert --- pom.xml | 2 + .../dev/openfeature/sdk/EventProvider.java | 30 ++++- .../dev/openfeature/sdk/EventSupport.java | 4 +- .../openfeature/sdk/EventProviderTest.java | 27 ++++- .../java/dev/openfeature/sdk/EventsTest.java | 10 +- .../TestStackedEmitCallsProvider.java | 103 ++++++++++++++++++ 6 files changed, 163 insertions(+), 13 deletions(-) create mode 100644 src/test/java/dev/openfeature/sdk/testutils/TestStackedEmitCallsProvider.java diff --git a/pom.xml b/pom.xml index 8b3ce85af..6fe155ef1 100644 --- a/pom.xml +++ b/pom.xml @@ -265,6 +265,8 @@ maven-surefire-plugin 3.5.2 + 1 + false ${surefireArgLine} diff --git a/src/main/java/dev/openfeature/sdk/EventProvider.java b/src/main/java/dev/openfeature/sdk/EventProvider.java index e9cdae55b..659c6ad46 100644 --- a/src/main/java/dev/openfeature/sdk/EventProvider.java +++ b/src/main/java/dev/openfeature/sdk/EventProvider.java @@ -1,6 +1,10 @@ package dev.openfeature.sdk; import dev.openfeature.sdk.internal.TriConsumer; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; /** * Abstract EventProvider. Providers must extend this class to support events. @@ -14,8 +18,10 @@ * * @see FeatureProvider */ +@Slf4j public abstract class EventProvider implements FeatureProvider { private EventProviderListener eventProviderListener; + private final ExecutorService emitterExecutor = Executors.newCachedThreadPool(); void setEventProviderListener(EventProviderListener eventProviderListener) { this.eventProviderListener = eventProviderListener; @@ -46,6 +52,24 @@ void detach() { this.onEmit = null; } + /** + * Stop the event emitter executor and block until either termination has completed + * or timeout period has elapsed. + */ + @Override + public void shutdown() { + emitterExecutor.shutdown(); + try { + if (!emitterExecutor.awaitTermination(EventSupport.SHUTDOWN_TIMEOUT_SECONDS, TimeUnit.SECONDS)) { + log.warn("Emitter executor did not terminate before the timeout period had elapsed"); + emitterExecutor.shutdownNow(); + } + } catch (InterruptedException e) { + emitterExecutor.shutdownNow(); + Thread.currentThread().interrupt(); + } + } + /** * Emit the specified {@link ProviderEvent}. * @@ -56,8 +80,10 @@ public void emit(ProviderEvent event, ProviderEventDetails details) { if (eventProviderListener != null) { eventProviderListener.onEmit(event, details); } - if (this.onEmit != null) { - this.onEmit.accept(this, event, details); + + final TriConsumer localOnEmit = this.onEmit; + if (localOnEmit != null) { + emitterExecutor.submit(() -> localOnEmit.accept(this, event, details)); } } diff --git a/src/main/java/dev/openfeature/sdk/EventSupport.java b/src/main/java/dev/openfeature/sdk/EventSupport.java index d3af45991..5ebe90a4c 100644 --- a/src/main/java/dev/openfeature/sdk/EventSupport.java +++ b/src/main/java/dev/openfeature/sdk/EventSupport.java @@ -19,15 +19,15 @@ @Slf4j class EventSupport { + public static final int SHUTDOWN_TIMEOUT_SECONDS = 3; + // we use a v4 uuid as a "placeholder" for anonymous clients, since // ConcurrentHashMap doesn't support nulls private static final String defaultClientUuid = UUID.randomUUID().toString(); - private static final int SHUTDOWN_TIMEOUT_SECONDS = 3; private final Map handlerStores = new ConcurrentHashMap<>(); private final HandlerStore globalHandlerStore = new HandlerStore(); private final ExecutorService taskExecutor = Executors.newCachedThreadPool(runnable -> { final Thread thread = new Thread(runnable); - thread.setDaemon(true); return thread; }); diff --git a/src/test/java/dev/openfeature/sdk/EventProviderTest.java b/src/test/java/dev/openfeature/sdk/EventProviderTest.java index d8af6e8d3..a159877f0 100644 --- a/src/test/java/dev/openfeature/sdk/EventProviderTest.java +++ b/src/test/java/dev/openfeature/sdk/EventProviderTest.java @@ -5,13 +5,18 @@ import static org.mockito.Mockito.*; import dev.openfeature.sdk.internal.TriConsumer; +import dev.openfeature.sdk.testutils.TestStackedEmitCallsProvider; +import io.cucumber.java.AfterAll; import lombok.SneakyThrows; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; class EventProviderTest { + private static final int TIMEOUT = 300; + private TestEventProvider eventProvider; @BeforeEach @@ -21,6 +26,11 @@ void setup() { eventProvider.initialize(null); } + @AfterAll + public static void resetDefaultProvider() { + OpenFeatureAPI.getInstance().setProviderAndWait(new NoOpProvider()); + } + @Test @DisplayName("should run attached onEmit with emitters") void emitsEventsWhenAttached() { @@ -34,10 +44,10 @@ void emitsEventsWhenAttached() { eventProvider.emitProviderStale(details); eventProvider.emitProviderError(details); - verify(onEmit, times(2)).accept(eventProvider, ProviderEvent.PROVIDER_READY, details); - verify(onEmit, times(1)).accept(eventProvider, ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, details); - verify(onEmit, times(1)).accept(eventProvider, ProviderEvent.PROVIDER_STALE, details); - verify(onEmit, times(1)).accept(eventProvider, ProviderEvent.PROVIDER_ERROR, details); + verify(onEmit, timeout(TIMEOUT).times(2)).accept(eventProvider, ProviderEvent.PROVIDER_READY, details); + verify(onEmit, timeout(TIMEOUT)).accept(eventProvider, ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, details); + verify(onEmit, timeout(TIMEOUT)).accept(eventProvider, ProviderEvent.PROVIDER_STALE, details); + verify(onEmit, timeout(TIMEOUT)).accept(eventProvider, ProviderEvent.PROVIDER_ERROR, details); } @Test @@ -75,6 +85,15 @@ void doesNotThrowWhenOnEmitSame() { eventProvider.attach(onEmit2); // should not throw, same instance. noop } + @Test + @SneakyThrows + @Timeout(value = 2, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) + @DisplayName("should not deadlock on emit called during emit") + void doesNotDeadlockOnEmitStackedCalls() { + TestStackedEmitCallsProvider provider = new TestStackedEmitCallsProvider(); + OpenFeatureAPI.getInstance().setProviderAndWait(provider); + } + static class TestEventProvider extends EventProvider { private static final String NAME = "TestEventProvider"; diff --git a/src/test/java/dev/openfeature/sdk/EventsTest.java b/src/test/java/dev/openfeature/sdk/EventsTest.java index 02a5953b9..e59024652 100644 --- a/src/test/java/dev/openfeature/sdk/EventsTest.java +++ b/src/test/java/dev/openfeature/sdk/EventsTest.java @@ -19,7 +19,7 @@ class EventsTest { - private static final int TIMEOUT = 300; + private static final int TIMEOUT = 500; private static final int INIT_DELAY = TIMEOUT / 2; @AfterAll @@ -601,13 +601,13 @@ void matchingStaleEventsMustRunImmediately() { OpenFeatureAPI api = OpenFeatureAPI.getInstance(); // provider which is already stale - TestEventsProvider provider = TestEventsProvider.newInitializedTestEventsProvider(); + TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); Client client = api.getClient(name); api.setProviderAndWait(name, provider); provider.emitProviderStale(ProviderEventDetails.builder().build()); assertThat(client.getProviderState()).isEqualTo(ProviderState.STALE); - // should run even thought handler was added after stale + // should run even though handler was added after stale client.onProviderStale(handler); verify(handler, timeout(TIMEOUT)).accept(any()); } @@ -623,13 +623,13 @@ void matchingErrorEventsMustRunImmediately() { OpenFeatureAPI api = OpenFeatureAPI.getInstance(); // provider which is already in error - TestEventsProvider provider = new TestEventsProvider(); + TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); Client client = api.getClient(name); api.setProviderAndWait(name, provider); provider.emitProviderError(ProviderEventDetails.builder().build()); assertThat(client.getProviderState()).isEqualTo(ProviderState.ERROR); - // should run even thought handler was added after error + // should run even though handler was added after error client.onProviderError(handler); verify(handler, timeout(TIMEOUT)).accept(any()); } diff --git a/src/test/java/dev/openfeature/sdk/testutils/TestStackedEmitCallsProvider.java b/src/test/java/dev/openfeature/sdk/testutils/TestStackedEmitCallsProvider.java new file mode 100644 index 000000000..d1bf65c57 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/testutils/TestStackedEmitCallsProvider.java @@ -0,0 +1,103 @@ +package dev.openfeature.sdk.testutils; + +import dev.openfeature.sdk.EvaluationContext; +import dev.openfeature.sdk.EventProvider; +import dev.openfeature.sdk.Metadata; +import dev.openfeature.sdk.ProviderEvaluation; +import dev.openfeature.sdk.ProviderEvent; +import dev.openfeature.sdk.ProviderEventDetails; +import dev.openfeature.sdk.Value; +import java.util.function.Consumer; + +public class TestStackedEmitCallsProvider extends EventProvider { + private final NestedBlockingEmitter nestedBlockingEmitter = new NestedBlockingEmitter(this::onProviderEvent); + + @Override + public Metadata getMetadata() { + return () -> getClass().getSimpleName(); + } + + @Override + public void initialize(EvaluationContext evaluationContext) throws Exception { + synchronized (nestedBlockingEmitter) { + nestedBlockingEmitter.init(); + while (!nestedBlockingEmitter.isReady()) { + try { + nestedBlockingEmitter.wait(); + } catch (InterruptedException e) { + } + } + } + } + + private void onProviderEvent(ProviderEvent providerEvent) { + synchronized (nestedBlockingEmitter) { + if (providerEvent == ProviderEvent.PROVIDER_READY) { + nestedBlockingEmitter.setReady(); + /* + * This line deadlocked in the original implementation without the emitterExecutor see + * https://github.com/open-feature/java-sdk/issues/1299 + */ + emitProviderReady(ProviderEventDetails.builder().build()); + } + } + } + + @Override + public ProviderEvaluation getBooleanEvaluation(String key, Boolean defaultValue, EvaluationContext ctx) { + throw new UnsupportedOperationException("Unimplemented method 'getBooleanEvaluation'"); + } + + @Override + public ProviderEvaluation getStringEvaluation(String key, String defaultValue, EvaluationContext ctx) { + throw new UnsupportedOperationException("Unimplemented method 'getStringEvaluation'"); + } + + @Override + public ProviderEvaluation getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx) { + throw new UnsupportedOperationException("Unimplemented method 'getIntegerEvaluation'"); + } + + @Override + public ProviderEvaluation getDoubleEvaluation(String key, Double defaultValue, EvaluationContext ctx) { + throw new UnsupportedOperationException("Unimplemented method 'getDoubleEvaluation'"); + } + + @Override + public ProviderEvaluation getObjectEvaluation(String key, Value defaultValue, EvaluationContext ctx) { + throw new UnsupportedOperationException("Unimplemented method 'getObjectEvaluation'"); + } + + static class NestedBlockingEmitter { + + private final Consumer emitProviderEvent; + private volatile boolean isReady; + + public NestedBlockingEmitter(Consumer emitProviderEvent) { + this.emitProviderEvent = emitProviderEvent; + } + + public void init() { + // run init outside monitored thread + new Thread(() -> { + try { + Thread.sleep(500); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + emitProviderEvent.accept(ProviderEvent.PROVIDER_READY); + }) + .start(); + } + + public boolean isReady() { + return isReady; + } + + public synchronized void setReady() { + isReady = true; + this.notifyAll(); + } + } +} From 9ab26182eae4974b60d166777c51dfcb07957150 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 14 Feb 2025 14:13:05 +0000 Subject: [PATCH 135/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.17.1 (#1329) 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 6fe155ef1..cb3bff866 100644 --- a/pom.xml +++ b/pom.xml @@ -167,7 +167,7 @@ net.bytebuddy byte-buddy - 1.17.0 + 1.17.1 test From 4ba5695eeea6a7ab2fe1d2c595fa482d4b7868dc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 14 Feb 2025 18:13:42 +0000 Subject: [PATCH 136/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.17.1 (#1330) 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 cb3bff866..1f5bf005b 100644 --- a/pom.xml +++ b/pom.xml @@ -174,7 +174,7 @@ net.bytebuddy byte-buddy-agent - 1.17.0 + 1.17.1 test From 9e782308d3b1baa66841c4151389c28e0f947d7b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2025 11:18:26 +0100 Subject: [PATCH 137/745] chore(main): release 1.14.1 (#1278) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 55 +++++++++++++++++++++++++++++++++++ README.md | 8 ++--- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 62 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index e2d18dc18..f459d7afd 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"1.14.0"} \ No newline at end of file +{".":"1.14.1"} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f7000d46..6301fce0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,60 @@ # Changelog +## [1.14.1](https://github.com/open-feature/java-sdk/compare/v1.14.0...v1.14.1) (2025-02-14) + + +### 🐛 Bug Fixes + +* **deps:** update dependency io.cucumber:cucumber-bom to v7.21.0 ([#1312](https://github.com/open-feature/java-sdk/issues/1312)) ([208411e](https://github.com/open-feature/java-sdk/commit/208411e72338e37bf477ac0b784bbbbe0309b922)) +* **deps:** update dependency io.cucumber:cucumber-bom to v7.21.1 ([#1317](https://github.com/open-feature/java-sdk/issues/1317)) ([b797883](https://github.com/open-feature/java-sdk/commit/b7978832b786fe081169ff0efeb702218300c622)) +* possible event-related deadlocks with some providers ([#1314](https://github.com/open-feature/java-sdk/issues/1314)) ([c33ac2d](https://github.com/open-feature/java-sdk/commit/c33ac2d9b2e91b85fffb3c21653912fe82006351)) +* TrackingEventDetails interface to include numeric getValue() call ([#1328](https://github.com/open-feature/java-sdk/issues/1328)) ([08c38fb](https://github.com/open-feature/java-sdk/commit/08c38fb553d82a42682c3eb9239329f770063898)) + + +### 🧹 Chore + +* **deps:** update actions/cache digest to 9fa7e61 ([#1324](https://github.com/open-feature/java-sdk/issues/1324)) ([69cdc77](https://github.com/open-feature/java-sdk/commit/69cdc772a639470dd223bf70ef6e9f8bc4d93dea)) +* **deps:** update actions/checkout digest to 85e6279 ([#1287](https://github.com/open-feature/java-sdk/issues/1287)) ([640e35e](https://github.com/open-feature/java-sdk/commit/640e35e85375e3098f61b7397432d80a95502bdd)) +* **deps:** update actions/setup-java digest to 28b532b ([#1296](https://github.com/open-feature/java-sdk/issues/1296)) ([874e86d](https://github.com/open-feature/java-sdk/commit/874e86df5c22a1e5771ca16c76aa13039b5f9b65)) +* **deps:** update actions/setup-java digest to 3a4f6e1 ([#1306](https://github.com/open-feature/java-sdk/issues/1306)) ([ba9cc4b](https://github.com/open-feature/java-sdk/commit/ba9cc4b85a1082d638d49b9d2d0a4ed5a45f09ee)) +* **deps:** update actions/setup-java digest to 51ab6d2 ([#1288](https://github.com/open-feature/java-sdk/issues/1288)) ([c69d3a4](https://github.com/open-feature/java-sdk/commit/c69d3a4bd137c1d6baa47c14228bfe8f96555676)) +* **deps:** update actions/setup-java digest to 99d3141 ([#1285](https://github.com/open-feature/java-sdk/issues/1285)) ([32a3933](https://github.com/open-feature/java-sdk/commit/32a39335de8e61650905fc96dc1a73e65f1fe9f8)) +* **deps:** update codecov/codecov-action action to v5.2.0 ([#1298](https://github.com/open-feature/java-sdk/issues/1298)) ([531fc38](https://github.com/open-feature/java-sdk/commit/531fc385b662c5b7b334fee298fc9fe1283c78fb)) +* **deps:** update codecov/codecov-action action to v5.3.0 ([#1301](https://github.com/open-feature/java-sdk/issues/1301)) ([f7f6586](https://github.com/open-feature/java-sdk/commit/f7f6586d72e3f112a7dafc8f77de273ed49ccc4b)) +* **deps:** update codecov/codecov-action action to v5.3.1 ([#1303](https://github.com/open-feature/java-sdk/issues/1303)) ([f9fa54b](https://github.com/open-feature/java-sdk/commit/f9fa54be493e1d0843b709008eb0f047e7580d47)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.16.0 ([#1289](https://github.com/open-feature/java-sdk/issues/1289)) ([0b5b423](https://github.com/open-feature/java-sdk/commit/0b5b423bdd378bb1db3e10fe5da7fa2c937a4610)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.16.1 ([#1292](https://github.com/open-feature/java-sdk/issues/1292)) ([0af9f29](https://github.com/open-feature/java-sdk/commit/0af9f2901f88b5ef9bed0c570d426939a55af3cf)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.17.0 ([#1309](https://github.com/open-feature/java-sdk/issues/1309)) ([cda3405](https://github.com/open-feature/java-sdk/commit/cda34053f7e39318205a181ef93c825bab2ed9fc)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.17.1 ([#1329](https://github.com/open-feature/java-sdk/issues/1329)) ([9ab2618](https://github.com/open-feature/java-sdk/commit/9ab26182eae4974b60d166777c51dfcb07957150)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.16.0 ([#1290](https://github.com/open-feature/java-sdk/issues/1290)) ([6c4205a](https://github.com/open-feature/java-sdk/commit/6c4205a00817af260ef9b90f54ce878cad33f75a)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.16.1 ([#1293](https://github.com/open-feature/java-sdk/issues/1293)) ([6071932](https://github.com/open-feature/java-sdk/commit/6071932cb4207dc83cdedfa67c8a69ed71d9c26a)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.17.0 ([#1310](https://github.com/open-feature/java-sdk/issues/1310)) ([40fa173](https://github.com/open-feature/java-sdk/commit/40fa1733382f4c476a1228c6499044ad83c8f3c4)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.17.1 ([#1330](https://github.com/open-feature/java-sdk/issues/1330)) ([4ba5695](https://github.com/open-feature/java-sdk/commit/4ba5695eeea6a7ab2fe1d2c595fa482d4b7868dc)) +* **deps:** update dependency org.assertj:assertj-core to v3.27.3 ([#1291](https://github.com/open-feature/java-sdk/issues/1291)) ([a5eb21d](https://github.com/open-feature/java-sdk/commit/a5eb21d1a2e6945a4455cacde898bc913bddb96d)) +* **deps:** update github/codeql-action digest to 0701025 ([#1311](https://github.com/open-feature/java-sdk/issues/1311)) ([9a1e9ab](https://github.com/open-feature/java-sdk/commit/9a1e9abd64220c8d8706f2a64e041ef3f37e1a43)) +* **deps:** update github/codeql-action digest to 08bc0cf ([#1313](https://github.com/open-feature/java-sdk/issues/1313)) ([37ed6a4](https://github.com/open-feature/java-sdk/commit/37ed6a424cdc013ed74c9881826cc56c93ae8228)) +* **deps:** update github/codeql-action digest to 0a35e8f ([#1316](https://github.com/open-feature/java-sdk/issues/1316)) ([26e1d7f](https://github.com/open-feature/java-sdk/commit/26e1d7fff342a32880542efa87b017aec506667e)) +* **deps:** update github/codeql-action digest to 0f1559a ([#1286](https://github.com/open-feature/java-sdk/issues/1286)) ([882d2dd](https://github.com/open-feature/java-sdk/commit/882d2dd5bdac007e8a3783efc54fa45faed22054)) +* **deps:** update github/codeql-action digest to 10a3f07 ([#1280](https://github.com/open-feature/java-sdk/issues/1280)) ([a3854d6](https://github.com/open-feature/java-sdk/commit/a3854d6ab1dba99f4db18f868e89fcc04418e306)) +* **deps:** update github/codeql-action digest to 1c15a48 ([#1325](https://github.com/open-feature/java-sdk/issues/1325)) ([3baf0df](https://github.com/open-feature/java-sdk/commit/3baf0df966f8212864aa7e57bc3d3d09d324fe11)) +* **deps:** update github/codeql-action digest to 1efc6bb ([#1281](https://github.com/open-feature/java-sdk/issues/1281)) ([8a1ab7e](https://github.com/open-feature/java-sdk/commit/8a1ab7ea18aff4ee5a6a2fdd1f805b08e51a50a3)) +* **deps:** update github/codeql-action digest to 24e1c2d ([#1315](https://github.com/open-feature/java-sdk/issues/1315)) ([46903c6](https://github.com/open-feature/java-sdk/commit/46903c6f275e5f9dc8884acf3f76f76efcfc58bd)) +* **deps:** update github/codeql-action digest to 3b4f4d9 ([#1282](https://github.com/open-feature/java-sdk/issues/1282)) ([b390d5f](https://github.com/open-feature/java-sdk/commit/b390d5f0b0945948cd6b87e6486725d095d5ac8a)) +* **deps:** update github/codeql-action digest to 43cffee ([#1304](https://github.com/open-feature/java-sdk/issues/1304)) ([6874de6](https://github.com/open-feature/java-sdk/commit/6874de64ce589e853f5523019bfa9e1d60840baf)) +* **deps:** update github/codeql-action digest to 54b1c84 ([#1307](https://github.com/open-feature/java-sdk/issues/1307)) ([6f36434](https://github.com/open-feature/java-sdk/commit/6f36434c520dcef27deb04e04941693dc15acb2f)) +* **deps:** update github/codeql-action digest to 5f4f998 ([#1305](https://github.com/open-feature/java-sdk/issues/1305)) ([7916d76](https://github.com/open-feature/java-sdk/commit/7916d76635c5ab59dafe6d72058aad9cfcf05f4b)) +* **deps:** update github/codeql-action digest to 6063925 ([#1320](https://github.com/open-feature/java-sdk/issues/1320)) ([538140d](https://github.com/open-feature/java-sdk/commit/538140dfe713a421623b179e69b399f82200fe61)) +* **deps:** update github/codeql-action digest to 7e3036b ([#1300](https://github.com/open-feature/java-sdk/issues/1300)) ([3491956](https://github.com/open-feature/java-sdk/commit/34919561b73faa0cca489ad480e93cca9a854167)) +* **deps:** update github/codeql-action digest to 87fc816 ([#1277](https://github.com/open-feature/java-sdk/issues/1277)) ([c2a82db](https://github.com/open-feature/java-sdk/commit/c2a82dbdbafa134fae4b0c9aef88cf589e09aefa)) +* **deps:** update github/codeql-action digest to 93da9f2 ([#1283](https://github.com/open-feature/java-sdk/issues/1283)) ([45b3995](https://github.com/open-feature/java-sdk/commit/45b3995bdad9f1b05abb01455a9c8f57028cfde5)) +* **deps:** update github/codeql-action digest to affec20 ([#1323](https://github.com/open-feature/java-sdk/issues/1323)) ([8f3ced5](https://github.com/open-feature/java-sdk/commit/8f3ced590764760244cc81ac10c939ca62504dfe)) +* **deps:** update github/codeql-action digest to b44b19f ([#1297](https://github.com/open-feature/java-sdk/issues/1297)) ([305e032](https://github.com/open-feature/java-sdk/commit/305e0329e78116fe697240e420879ac85012d698)) +* **deps:** update github/codeql-action digest to d90e07f ([#1294](https://github.com/open-feature/java-sdk/issues/1294)) ([5671184](https://github.com/open-feature/java-sdk/commit/5671184e7f76f979d631c18bb2ebfb15dccfb207)) +* **deps:** update github/codeql-action digest to db7177a ([#1279](https://github.com/open-feature/java-sdk/issues/1279)) ([b997946](https://github.com/open-feature/java-sdk/commit/b997946db1c7663b7ebb775ad45cdb2b0aaeb291)) +* **deps:** update github/codeql-action digest to e7c0c9d ([#1302](https://github.com/open-feature/java-sdk/issues/1302)) ([78adc77](https://github.com/open-feature/java-sdk/commit/78adc77c23da6116e1f58b3a45dc283c3c58837b)) +* **deps:** update github/codeql-action digest to e9987ad ([#1308](https://github.com/open-feature/java-sdk/issues/1308)) ([99d8185](https://github.com/open-feature/java-sdk/commit/99d818572a3407ca6b25f6e91f69ef3e83bdc657)) +* **deps:** update github/codeql-action digest to f89b8a7 ([#1295](https://github.com/open-feature/java-sdk/issues/1295)) ([122e82f](https://github.com/open-feature/java-sdk/commit/122e82f8431fb116ae3b147f7e2245d7f90b1c77)) + ## [1.14.0](https://github.com/open-feature/java-sdk/compare/v1.13.0...v1.14.0) (2025-01-10) diff --git a/README.md b/README.md index cbb9d9f13..49d5562e0 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.0 + 1.14.1 ``` @@ -84,7 +84,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:1.14.0' + implementation 'dev.openfeature:sdk:1.14.1' } ``` diff --git a/pom.xml b/pom.xml index 1f5bf005b..a6a54e5ae 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ dev.openfeature sdk - 1.14.0 + 1.14.1 UTF-8 diff --git a/version.txt b/version.txt index 850e74240..63e799cf4 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.14.0 +1.14.1 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 138/745] 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 6e3c40f48..78ce975a4 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 85313855b..8143c1f4f 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 139/745] 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 78ce975a4..0f83d29a5 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 8143c1f4f..b6e2a3f75 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 140/745] 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 0f83d29a5..70dbb28f6 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 b6e2a3f75..8bf7512fa 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 141/745] 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 a6a54e5ae..bbc1b8db7 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 9175a7cd7..bd60cc78a 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 66f25f60a..a393d83e8 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 bec866820..ab024a750 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 8f304eaac..bd0ac2c21 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 2f214d8ac..0ad09db29 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 cd7e8b295..beadf7aad 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 aacf09169..32fa605c2 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 a159877f0..ebf8901cb 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 e59024652..157c0bafe 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 2ad88d328..3b02b172d 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 d6247c649..4b08510dd 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 3353f5644..4bcd73127 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 4b7af5530..ad86f4bc3 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 000000000..dd9916eed --- /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 63145ecb6..e8e8b27b0 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 000000000..f33c5b4d7 --- /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 4f4d32004..97a1417a1 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 98652635d..7041df5c1 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 e7caf9274..1bb7d4b62 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 a8f6e30f3..ba3543745 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 000000000..8bf8b2888 --- /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 86782b397..4d2a8b287 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 c9ad77d89..000000000 --- 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 142/745] 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 6ef83234d..4016b9e1d 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 70dbb28f6..3a22db334 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 7342889db..3e4914478 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 bbc1b8db7..de54a7ce3 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 143/745] 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 de54a7ce3..83d06efbc 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 144/745] 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 3a22db334..cf8e85cba 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 8bf7512fa..acca30a48 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 145/745] 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 4016b9e1d..a76348f98 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 cf8e85cba..1c5bdf1ed 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 146/745] 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 83d06efbc..728d45b95 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 147/745] 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 728d45b95..d850e4f0c 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 c2b6f5838..f8311a9a5 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 a393d83e8..3022ff006 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 61778d85b..f2dc6b495 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 d3fdb985c..3be1b6316 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 f8b9ba58e..26d0421cd 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 8a3381412..b7c834312 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 000000000..2c4ffdb57 --- /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 000000000..ac107cfd6 --- /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 000000000..ee513b00e --- /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 000000000..902ee11d0 --- /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 000000000..390e067f3 --- /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 000000000..1e6a9172f --- /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 000000000..82cdb2e79 --- /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 c1e56429d..6897e2738 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 157b07175..c1767ff6f 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 148/745] 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 1c5bdf1ed..e53191f9b 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 acca30a48..4883c6268 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 149/745] 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 d850e4f0c..c67645f51 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 150/745] 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 c67645f51..a435bc890 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 151/745] 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 a435bc890..c90352b32 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 152/745] 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 e53191f9b..3e5645e4f 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 4883c6268..039a43dea 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 153/745] 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 00a51aff5..022b84144 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 c90352b32..36797998f 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 154/745] 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 3e5645e4f..819a7abe3 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 039a43dea..4361546f5 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 155/745] 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 36797998f..29a371938 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 156/745] 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 819a7abe3..cbc5b0db7 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 4361546f5..58f4adbcd 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 157/745] 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 a76348f98..e8bfeac71 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 cbc5b0db7..144abda84 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 158/745] 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 144abda84..c605e05da 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 58f4adbcd..c3bb651de 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 159/745] 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 e8bfeac71..d17b2eae8 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 c605e05da..40a9431a3 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 160/745] 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 29a371938..5213c470a 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 161/745] 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 5213c470a..d89ae290b 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 162/745] 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 d17b2eae8..f98c51af5 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 40a9431a3..7555d95f3 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 3e4914478..7f12331f1 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 163/745] 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 7555d95f3..dd1b97f21 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 c3bb651de..7016c9699 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 164/745] 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 d89ae290b..b7401c8b4 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 165/745] 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 b7401c8b4..8c95d14f5 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 166/745] 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 dd1b97f21..9bc2309fc 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 7016c9699..89d5cae4b 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 167/745] 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 9bc2309fc..433d057c7 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 89d5cae4b..5bde3c9ec 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 168/745] 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 f8311a9a5..7f57a174d 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 26d0421cd..22912661f 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 000000000..e06e862a5 --- /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 ee513b00e..68c708b4a 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 000000000..ccb78e72a --- /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 6897e2738..924c9d59e 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 169/745] 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 433d057c7..4547a278e 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 5bde3c9ec..b1379a3e7 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 170/745] 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 4547a278e..4629ea474 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 b1379a3e7..1a9372065 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 171/745] 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 4629ea474..8cb6af5f8 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 1a9372065..4e749aa41 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 172/745] 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 8cb6af5f8..b6165dd39 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 4e749aa41..efffa1fb7 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 173/745] 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 6c652114c..7962705c3 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 e32e61013..c75b046e0 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 23a452e08..8560c369e 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 c47a49eb3..849359424 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 a06e2f2d3..f3158456d 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 e69a974b3..2b39be741 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 000000000..e3bd03165 --- /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 dff95adca..6a0eed59b 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 953e3f636..6c471d09a 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 000000000..ebd11af0d --- /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 c25538508..697edb7be 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 174/745] 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 b6165dd39..a34dfc220 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 efffa1fb7..5bf01677f 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 175/745] 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 8c95d14f5..9572b3c7e 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 176/745] 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 9572b3c7e..c2205ec14 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 177/745] 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 c2205ec14..a5c57d538 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 178/745] 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 a34dfc220..139ec099b 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 5bf01677f..1d52b734b 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 179/745] 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 139ec099b..9a0b3f77c 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 1d52b734b..afffc816f 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 180/745] 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 f98c51af5..bd4ffe800 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 9a0b3f77c..1a1f2af74 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 181/745] 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 bd4ffe800..091f14b4b 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 1a1f2af74..1e1424be9 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 7f12331f1..a3b669e7d 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 182/745] 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 1e1424be9..9ca39ef10 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 afffc816f..bba3e4b5c 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 183/745] 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 9ca39ef10..8554c833a 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 bba3e4b5c..520afd099 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 184/745] 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 a5c57d538..f04d32ee5 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 185/745] 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 8554c833a..4409f1523 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 520afd099..e43a306b3 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 186/745] 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 f04d32ee5..1ab82f468 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 187/745] 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 1ab82f468..93a1d43da 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 188/745] 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 93a1d43da..f0d531dab 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 189/745] 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 4409f1523..6e72dfb2c 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 e43a306b3..a9b7a349d 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 190/745] 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 bce134066..1b909c15e 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 191/745] 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 091f14b4b..b156383eb 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 6e72dfb2c..fc1ac720a 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 a3b669e7d..28b5798e2 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 192/745] 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 3022ff006..e68d28f79 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 000000000..9ebd24758 --- /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 4b08510dd..3a953d18a 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 193/745] 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 f459d7afd..762e32db5 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 6301fce0d..914cbfef3 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 49d5562e0..22d85bd2d 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 f0d531dab..7b8e0d587 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 63e799cf4..a4cc55716 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.14.1 +1.14.2 From d7b591c9f910afad303d6d814f65c7f9dab33b89 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Mar 2025 23:40:23 +0000 Subject: [PATCH 194/745] chore(deps): update github/codeql-action digest to 9bd18b4 (#1394) 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 fc1ac720a..5a5248b15 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@486ab5a2922b634015408a83e10f6867efb5922c + uses: github/codeql-action/init@9bd18b486fd4e8174d935b2c781f53e02afb1eb6 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@486ab5a2922b634015408a83e10f6867efb5922c + uses: github/codeql-action/analyze@9bd18b486fd4e8174d935b2c781f53e02afb1eb6 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index a9b7a349d..bd468faf5 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@486ab5a2922b634015408a83e10f6867efb5922c + uses: github/codeql-action/init@9bd18b486fd4e8174d935b2c781f53e02afb1eb6 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@486ab5a2922b634015408a83e10f6867efb5922c + uses: github/codeql-action/autobuild@9bd18b486fd4e8174d935b2c781f53e02afb1eb6 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@486ab5a2922b634015408a83e10f6867efb5922c + uses: github/codeql-action/analyze@9bd18b486fd4e8174d935b2c781f53e02afb1eb6 From 37d76be697e83f524250a82b2a67cdb4a953d7bc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 28 Mar 2025 23:26:09 +0000 Subject: [PATCH 195/745] chore(deps): update github/codeql-action digest to 9f45e74 (#1396) 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 5a5248b15..3580d2222 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@9bd18b486fd4e8174d935b2c781f53e02afb1eb6 + uses: github/codeql-action/init@9f45e7498becbbc08084a122b4be9ab534ac6d88 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9bd18b486fd4e8174d935b2c781f53e02afb1eb6 + uses: github/codeql-action/analyze@9f45e7498becbbc08084a122b4be9ab534ac6d88 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index bd468faf5..ce8fea7b6 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@9bd18b486fd4e8174d935b2c781f53e02afb1eb6 + uses: github/codeql-action/init@9f45e7498becbbc08084a122b4be9ab534ac6d88 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@9bd18b486fd4e8174d935b2c781f53e02afb1eb6 + uses: github/codeql-action/autobuild@9f45e7498becbbc08084a122b4be9ab534ac6d88 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9bd18b486fd4e8174d935b2c781f53e02afb1eb6 + uses: github/codeql-action/analyze@9f45e7498becbbc08084a122b4be9ab534ac6d88 From 1fcf0e77d956c88c54e10942d96d2afd4d79315c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 05:38:29 +0000 Subject: [PATCH 196/745] chore(deps): update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.5.3 (#1398) 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 7b8e0d587..3e7ff47cc 100644 --- a/pom.xml +++ b/pom.xml @@ -287,7 +287,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.5.2 + 3.5.3 ${surefireArgLine} @@ -690,7 +690,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.5.2 + 3.5.3 ${surefireArgLine} From d6ebc161a93ad703e25592abdb0bf0fd9e281bbc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 10:47:07 +0000 Subject: [PATCH 197/745] chore(deps): update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.3 (#1399) 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 3e7ff47cc..65c370ea2 100644 --- a/pom.xml +++ b/pom.xml @@ -268,7 +268,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.5.2 + 3.5.3 1 false @@ -674,7 +674,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.5.2 + 3.5.3 ${surefireArgLine} From 1f2d0715087ebd4554826d8552b250e4b8b950c8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 15:00:52 +0000 Subject: [PATCH 198/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.17.5 (#1400) 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 65c370ea2..d3c8d1875 100644 --- a/pom.xml +++ b/pom.xml @@ -189,7 +189,7 @@ net.bytebuddy byte-buddy - 1.17.4 + 1.17.5 test From 384953d30ecff83d60a2e5b9790e8228d1a52ac7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 18:29:21 +0000 Subject: [PATCH 199/745] chore(deps): update github/codeql-action digest to efffb48 (#1402) 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 3580d2222..2967f1db5 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@9f45e7498becbbc08084a122b4be9ab534ac6d88 + uses: github/codeql-action/init@efffb483ec7bb162c4b7935f8b35ab6b94136c7b with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9f45e7498becbbc08084a122b4be9ab534ac6d88 + uses: github/codeql-action/analyze@efffb483ec7bb162c4b7935f8b35ab6b94136c7b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index ce8fea7b6..21ca3e569 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@9f45e7498becbbc08084a122b4be9ab534ac6d88 + uses: github/codeql-action/init@efffb483ec7bb162c4b7935f8b35ab6b94136c7b with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@9f45e7498becbbc08084a122b4be9ab534ac6d88 + uses: github/codeql-action/autobuild@efffb483ec7bb162c4b7935f8b35ab6b94136c7b - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9f45e7498becbbc08084a122b4be9ab534ac6d88 + uses: github/codeql-action/analyze@efffb483ec7bb162c4b7935f8b35ab6b94136c7b From 07301bda3f5b65550eff1e025fc9c0bec3c25275 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 23:11:43 +0000 Subject: [PATCH 200/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.17.5 (#1401) 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 d3c8d1875..59d543027 100644 --- a/pom.xml +++ b/pom.xml @@ -196,7 +196,7 @@ net.bytebuddy byte-buddy-agent - 1.17.4 + 1.17.5 test From ef32f11571de4d3a981efec4f61113eb8b0d7d9d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 03:02:58 +0000 Subject: [PATCH 201/745] fix(deps): update dependency org.projectlombok:lombok to v1.18.38 (#1403) 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 59d543027..9e5128c38 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ org.projectlombok lombok - 1.18.36 + 1.18.38 provided From f834e11acc7ecf903e972d80e9dab324be97847e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 22:21:36 +0000 Subject: [PATCH 202/745] chore(deps): update actions/setup-java digest to 148017a (#1404) 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 b156383eb..151aa999b 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@3b6c050358614dd082e53cdbc55580431fc4e437 + uses: actions/setup-java@148017a9b0c6af80330bcc5db11d1c670d2e7074 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 2967f1db5..838a54f68 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@3b6c050358614dd082e53cdbc55580431fc4e437 + uses: actions/setup-java@148017a9b0c6af80330bcc5db11d1c670d2e7074 with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 28b5798e2..10f92e236 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@3b6c050358614dd082e53cdbc55580431fc4e437 + uses: actions/setup-java@148017a9b0c6af80330bcc5db11d1c670d2e7074 with: java-version: '17' distribution: 'temurin' From 5b2f1513ab75ef6692978830e59eba87ffa494d5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 17:47:53 +0000 Subject: [PATCH 203/745] chore(deps): update github/codeql-action digest to dab8a02 (#1405) 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 838a54f68..152452a15 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@efffb483ec7bb162c4b7935f8b35ab6b94136c7b + uses: github/codeql-action/init@dab8a02091b7e1893928f2da086a62b5a8118c33 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@efffb483ec7bb162c4b7935f8b35ab6b94136c7b + uses: github/codeql-action/analyze@dab8a02091b7e1893928f2da086a62b5a8118c33 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 21ca3e569..66756bf4d 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@efffb483ec7bb162c4b7935f8b35ab6b94136c7b + uses: github/codeql-action/init@dab8a02091b7e1893928f2da086a62b5a8118c33 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@efffb483ec7bb162c4b7935f8b35ab6b94136c7b + uses: github/codeql-action/autobuild@dab8a02091b7e1893928f2da086a62b5a8118c33 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@efffb483ec7bb162c4b7935f8b35ab6b94136c7b + uses: github/codeql-action/analyze@dab8a02091b7e1893928f2da086a62b5a8118c33 From e211397d517e1263e1251f9c99093bf05cecd93f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 02:18:17 +0000 Subject: [PATCH 204/745] chore(deps): update github/codeql-action digest to e13fe0d (#1406) 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 152452a15..2ff95affa 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@dab8a02091b7e1893928f2da086a62b5a8118c33 + uses: github/codeql-action/init@e13fe0dd2d51f2b63b05fee9b9cda14b2050f678 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@dab8a02091b7e1893928f2da086a62b5a8118c33 + uses: github/codeql-action/analyze@e13fe0dd2d51f2b63b05fee9b9cda14b2050f678 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 66756bf4d..41db9e1be 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@dab8a02091b7e1893928f2da086a62b5a8118c33 + uses: github/codeql-action/init@e13fe0dd2d51f2b63b05fee9b9cda14b2050f678 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@dab8a02091b7e1893928f2da086a62b5a8118c33 + uses: github/codeql-action/autobuild@e13fe0dd2d51f2b63b05fee9b9cda14b2050f678 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@dab8a02091b7e1893928f2da086a62b5a8118c33 + uses: github/codeql-action/analyze@e13fe0dd2d51f2b63b05fee9b9cda14b2050f678 From ca160cab7ccd71527e06a0851502353ac50b8d0d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 18:12:31 +0000 Subject: [PATCH 205/745] chore(deps): update github/codeql-action digest to 362ef4c (#1408) 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 2ff95affa..6fde6ef26 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@e13fe0dd2d51f2b63b05fee9b9cda14b2050f678 + uses: github/codeql-action/init@362ef4ce205154842cd1d34794abd82bb8f12cd5 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e13fe0dd2d51f2b63b05fee9b9cda14b2050f678 + uses: github/codeql-action/analyze@362ef4ce205154842cd1d34794abd82bb8f12cd5 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 41db9e1be..8e161d754 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@e13fe0dd2d51f2b63b05fee9b9cda14b2050f678 + uses: github/codeql-action/init@362ef4ce205154842cd1d34794abd82bb8f12cd5 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@e13fe0dd2d51f2b63b05fee9b9cda14b2050f678 + uses: github/codeql-action/autobuild@362ef4ce205154842cd1d34794abd82bb8f12cd5 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e13fe0dd2d51f2b63b05fee9b9cda14b2050f678 + uses: github/codeql-action/analyze@362ef4ce205154842cd1d34794abd82bb8f12cd5 From 345cdcfa10da64c61d769746f335f38ac564e9ad Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 18:42:05 +0000 Subject: [PATCH 206/745] chore(deps): update dependency org.mockito:mockito-core to v5.17.0 (#1409) 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 9e5128c38..6b303c904 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ ${maven.compiler.source} 5.12.1 7.21.1 - 5.16.1 + 5.17.0 **/e2e/*.java ${project.groupId}.${project.artifactId} From 3c69f2f36c4e975d690ecc2e790df632a33001ba Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 5 Apr 2025 06:25:16 +0000 Subject: [PATCH 207/745] chore(deps): update io.cucumber.version to v7.22.0 (#1410) 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 6b303c904..a6e5be43a 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ 1.8 ${maven.compiler.source} 5.12.1 - 7.21.1 + 7.22.0 5.17.0 **/e2e/*.java From e25181982af8e5d37be4876b71b337ca86e8454b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 5 Apr 2025 10:23:07 +0000 Subject: [PATCH 208/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.22.0 (#1411) 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 a6e5be43a..a725224ce 100644 --- a/pom.xml +++ b/pom.xml @@ -204,7 +204,7 @@ io.cucumber cucumber-bom - 7.21.1 + 7.22.0 pom import From 5b327eeb770d0a4222f3599be79543b7bed9abc2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 01:31:00 +0000 Subject: [PATCH 209/745] chore(deps): update github/codeql-action digest to d26c46a (#1413) 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 6fde6ef26..7400975d4 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@362ef4ce205154842cd1d34794abd82bb8f12cd5 + uses: github/codeql-action/init@d26c46acea4065b13fc57703621e0a7c8b9e836b with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@362ef4ce205154842cd1d34794abd82bb8f12cd5 + uses: github/codeql-action/analyze@d26c46acea4065b13fc57703621e0a7c8b9e836b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 8e161d754..654d3fff4 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@362ef4ce205154842cd1d34794abd82bb8f12cd5 + uses: github/codeql-action/init@d26c46acea4065b13fc57703621e0a7c8b9e836b with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@362ef4ce205154842cd1d34794abd82bb8f12cd5 + uses: github/codeql-action/autobuild@d26c46acea4065b13fc57703621e0a7c8b9e836b - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@362ef4ce205154842cd1d34794abd82bb8f12cd5 + uses: github/codeql-action/analyze@d26c46acea4065b13fc57703621e0a7c8b9e836b From e066d3f749c09bb1ef79e3bcace1d205a39787df Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 06:34:39 +0000 Subject: [PATCH 210/745] chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v2.44.4 (#1414) 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 a725224ce..7f9d47e66 100644 --- a/pom.xml +++ b/pom.xml @@ -473,7 +473,7 @@ com.diffplug.spotless spotless-maven-plugin - 2.44.3 + 2.44.4 From a5789038acc36cb2b0ddf12e534a1317e1c9b8e8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 23:02:50 +0000 Subject: [PATCH 211/745] chore(deps): update actions/setup-java digest to c5195ef (#1415) 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 151aa999b..e9c3dd12c 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@148017a9b0c6af80330bcc5db11d1c670d2e7074 + uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 7400975d4..501c96995 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@148017a9b0c6af80330bcc5db11d1c670d2e7074 + uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 10f92e236..f5c1a2e74 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@148017a9b0c6af80330bcc5db11d1c670d2e7074 + uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 with: java-version: '17' distribution: 'temurin' From 4607c62f15f7ee572207b8ec012ad4b3626e0184 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 9 Apr 2025 22:09:23 +0000 Subject: [PATCH 212/745] chore(deps): update github/codeql-action digest to 56dd02f (#1416) 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 501c96995..c7e8f2957 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@d26c46acea4065b13fc57703621e0a7c8b9e836b + uses: github/codeql-action/init@56dd02f26d99811d607284494ff84b7d862fe837 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@d26c46acea4065b13fc57703621e0a7c8b9e836b + uses: github/codeql-action/analyze@56dd02f26d99811d607284494ff84b7d862fe837 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 654d3fff4..2f9c1f074 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@d26c46acea4065b13fc57703621e0a7c8b9e836b + uses: github/codeql-action/init@56dd02f26d99811d607284494ff84b7d862fe837 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@d26c46acea4065b13fc57703621e0a7c8b9e836b + uses: github/codeql-action/autobuild@56dd02f26d99811d607284494ff84b7d862fe837 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@d26c46acea4065b13fc57703621e0a7c8b9e836b + uses: github/codeql-action/analyze@56dd02f26d99811d607284494ff84b7d862fe837 From 0c77c8446032eaac7e068d48901e1423c21db326 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 11 Apr 2025 02:21:54 +0000 Subject: [PATCH 213/745] chore(deps): update github/codeql-action digest to 4c3e536 (#1417) 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 c7e8f2957..ef35c9dce 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@56dd02f26d99811d607284494ff84b7d862fe837 + uses: github/codeql-action/init@4c3e5362829f0b0bb62ff5f6c938d7f95574c306 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@56dd02f26d99811d607284494ff84b7d862fe837 + uses: github/codeql-action/analyze@4c3e5362829f0b0bb62ff5f6c938d7f95574c306 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 2f9c1f074..ea6035c18 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@56dd02f26d99811d607284494ff84b7d862fe837 + uses: github/codeql-action/init@4c3e5362829f0b0bb62ff5f6c938d7f95574c306 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@56dd02f26d99811d607284494ff84b7d862fe837 + uses: github/codeql-action/autobuild@4c3e5362829f0b0bb62ff5f6c938d7f95574c306 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@56dd02f26d99811d607284494ff84b7d862fe837 + uses: github/codeql-action/analyze@4c3e5362829f0b0bb62ff5f6c938d7f95574c306 From 97b442ed6e8f2b99ca949ffd63e5cbf57718c796 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 11 Apr 2025 21:45:27 +0000 Subject: [PATCH 214/745] fix(deps): update junit5 monorepo (#1418) 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 7f9d47e66..5028322be 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ UTF-8 1.8 ${maven.compiler.source} - 5.12.1 + 5.12.2 7.22.0 5.17.0 @@ -125,7 +125,7 @@ org.junit.platform junit-platform-suite - 1.12.1 + 1.12.2 test @@ -212,7 +212,7 @@ org.junit junit-bom - 5.12.1 + 5.12.2 pom import From a6389e89f60aa7f4871f47d78fedd27a7f9991b4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Apr 2025 03:44:53 +0000 Subject: [PATCH 215/745] chore(deps): update codecov/codecov-action action to v5.4.2 (#1419) 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 e9c3dd12c..72a3a3c32 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.4.0 + uses: codecov/codecov-action@v5.4.2 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 ef35c9dce..900a4025e 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.4.0 + uses: codecov/codecov-action@v5.4.2 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From 665dd51eb2b3b79d3ffccb6cef64d544aa5e7206 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Wed, 16 Apr 2025 12:45:16 -0400 Subject: [PATCH 216/745] chore: add publish env (#1420) * chore: add publish env Signed-off-by: Todd Baert * Update release.yml Signed-off-by: Todd Baert * Update merge.yml Signed-off-by: Todd Baert --------- Signed-off-by: Todd Baert --- .github/workflows/merge.yml | 4 +++- .github/workflows/release.yml | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index 72a3a3c32..edb3c6ef7 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -9,13 +9,15 @@ name: on-merge on: push: - branches: [ master, main ] + branches: + - main permissions: contents: read jobs: build: + environment: publish runs-on: ubuntu-latest steps: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f5c1a2e74..7359285d0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,6 +12,7 @@ permissions: # added using https://github.com/step-security/secure-workflows jobs: release-please: + environment: publish permissions: contents: write # for google-github-actions/release-please-action to create release commit pull-requests: write # for google-github-actions/release-please-action to create release PR From a3e2a59aebee051ae8c7eb1c5769a04dc9da8de3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 16 Apr 2025 21:41:52 +0000 Subject: [PATCH 217/745] chore(deps): update actions/setup-java digest to f4f1212 (#1421) 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 edb3c6ef7..58e096350 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -23,7 +23,7 @@ jobs: steps: - uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 17 - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 + uses: actions/setup-java@f4f1212c880fdec8162ea9a6493f4495191887b4 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 900a4025e..08c65f7ed 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@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 + uses: actions/setup-java@f4f1212c880fdec8162ea9a6493f4495191887b4 with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7359285d0..e9b6c7641 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,7 +32,7 @@ jobs: uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - name: Set up JDK 17 if: ${{ steps.release.outputs.release_created }} - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 + uses: actions/setup-java@f4f1212c880fdec8162ea9a6493f4495191887b4 with: java-version: '17' distribution: 'temurin' From 498fd382659669315b0db61db5f19ce054467bc9 Mon Sep 17 00:00:00 2001 From: Simon Schrottner Date: Thu, 17 Apr 2025 17:33:57 +0200 Subject: [PATCH 218/745] chore: update codeowners to give global maintainers code ownership (#1412) Signed-off-by: Simon Schrottner --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index e75c1d5f1..342eb8df1 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -3,4 +3,4 @@ # # Managed by Peribolos: https://github.com/open-feature/community/blob/main/config/open-feature/sdk-java/workgroup.yaml # -* @open-feature/sdk-java-maintainers +* @open-feature/sdk-java-maintainers @open-feature/maintainers From e19ccaa35d9ac4d89d72ea58a70d416d202078db Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 18 Apr 2025 08:15:55 +0200 Subject: [PATCH 219/745] chore(deps): update dependency org.jacoco:jacoco-maven-plugin to v0.8.13 (#1407) 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 5028322be..bac8ef2ef 100644 --- a/pom.xml +++ b/pom.xml @@ -354,7 +354,7 @@ org.jacoco jacoco-maven-plugin - 0.8.12 + 0.8.13 From 495da271bee976a942973cd23012f60db895bf24 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 20 Apr 2025 10:02:26 +0000 Subject: [PATCH 220/745] chore(deps): update dependency com.h3xstream.findsecbugs:findsecbugs-plugin to v1.14.0 (#1422) 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 bac8ef2ef..3a81fc2b6 100644 --- a/pom.xml +++ b/pom.xml @@ -420,7 +420,7 @@ com.h3xstream.findsecbugs findsecbugs-plugin - 1.13.0 + 1.14.0 From 6b6849f3a3ee8a7b66d859c8e522bc101d1ccd44 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 19:25:23 +0000 Subject: [PATCH 221/745] chore(deps): update github/codeql-action digest to 2a8cbad (#1423) 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 08c65f7ed..cc7b5f3f7 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@4c3e5362829f0b0bb62ff5f6c938d7f95574c306 + uses: github/codeql-action/init@2a8cbadc02bb64a7fd15d37c977acbad02496c80 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4c3e5362829f0b0bb62ff5f6c938d7f95574c306 + uses: github/codeql-action/analyze@2a8cbadc02bb64a7fd15d37c977acbad02496c80 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index ea6035c18..d7208454a 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@4c3e5362829f0b0bb62ff5f6c938d7f95574c306 + uses: github/codeql-action/init@2a8cbadc02bb64a7fd15d37c977acbad02496c80 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@4c3e5362829f0b0bb62ff5f6c938d7f95574c306 + uses: github/codeql-action/autobuild@2a8cbadc02bb64a7fd15d37c977acbad02496c80 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4c3e5362829f0b0bb62ff5f6c938d7f95574c306 + uses: github/codeql-action/analyze@2a8cbadc02bb64a7fd15d37c977acbad02496c80 From a7828e73a8f2e30f71bd2d9d4da180b2fa436424 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 23 Apr 2025 22:47:18 +0000 Subject: [PATCH 222/745] chore(deps): update github/codeql-action digest to 4ffa236 (#1425) 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 cc7b5f3f7..40829322f 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@2a8cbadc02bb64a7fd15d37c977acbad02496c80 + uses: github/codeql-action/init@4ffa2364a07d4fa8656211f550f36d44e8148dae with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@2a8cbadc02bb64a7fd15d37c977acbad02496c80 + uses: github/codeql-action/analyze@4ffa2364a07d4fa8656211f550f36d44e8148dae diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index d7208454a..79ceaa6f6 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@2a8cbadc02bb64a7fd15d37c977acbad02496c80 + uses: github/codeql-action/init@4ffa2364a07d4fa8656211f550f36d44e8148dae with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@2a8cbadc02bb64a7fd15d37c977acbad02496c80 + uses: github/codeql-action/autobuild@4ffa2364a07d4fa8656211f550f36d44e8148dae - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@2a8cbadc02bb64a7fd15d37c977acbad02496c80 + uses: github/codeql-action/analyze@4ffa2364a07d4fa8656211f550f36d44e8148dae From 844374a42b94deffab6856e978766354a6f46576 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 24 Apr 2025 15:19:34 +0000 Subject: [PATCH 223/745] chore(deps): update io.cucumber.version to v7.22.1 (#1426) 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 3a81fc2b6..8a099a515 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ 1.8 ${maven.compiler.source} 5.12.2 - 7.22.0 + 7.22.1 5.17.0 **/e2e/*.java From 1c4d2efafdebb562f099ba1ec3a6a29eabc8ff91 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 24 Apr 2025 18:19:32 +0000 Subject: [PATCH 224/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.22.1 (#1427) 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 8a099a515..e93e07584 100644 --- a/pom.xml +++ b/pom.xml @@ -204,7 +204,7 @@ io.cucumber cucumber-bom - 7.22.0 + 7.22.1 pom import From 014f8a59da8f1e976e440ed1ea17e85561f98e2d Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Thu, 24 Apr 2025 19:32:45 -0400 Subject: [PATCH 225/745] chore: use PAT for release please Signed-off-by: Todd Baert --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e9b6c7641..ba5298e21 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: - uses: google-github-actions/release-please-action@e4dc86ba9405554aeba3c6bb2d169500e7d3b4ee id: release with: - token: ${{secrets.GITHUB_TOKEN}} + token: ${{secrets.RELEASE_PLEASE_ACTION_TOKEN}} target-branch: main # These steps are only run if this was a merged release-please PR From 45ec4b1b7734c9117f43abf8fe5105c2903c3986 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Thu, 24 Apr 2025 20:58:47 -0400 Subject: [PATCH 226/745] chore: add DCO to release please Signed-off-by: Todd Baert --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ba5298e21..15217bf4e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,6 +25,7 @@ jobs: with: token: ${{secrets.RELEASE_PLEASE_ACTION_TOKEN}} target-branch: main + signoff: "OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com>" # These steps are only run if this was a merged release-please PR - name: checkout From 32137bfa82e9c0391c999bf0be2a36f201620931 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Thu, 24 Apr 2025 21:14:07 -0400 Subject: [PATCH 227/745] chore: add DCO to release please (#1429) * chore: add DCO to release please Signed-off-by: Todd Baert * Update release-please-config.json Signed-off-by: Todd Baert --------- Signed-off-by: Todd Baert --- .github/workflows/release.yml | 1 - release-please-config.json | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 15217bf4e..ba5298e21 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,6 @@ jobs: with: token: ${{secrets.RELEASE_PLEASE_ACTION_TOKEN}} target-branch: main - signoff: "OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com>" # These steps are only run if this was a merged release-please PR - name: checkout diff --git a/release-please-config.json b/release-please-config.json index ad00d89a5..f1b6ee6bf 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -1,5 +1,6 @@ { "bootstrap-sha": "c701a6c4ebbe1170a25ca7636a31508b9628831c", + "signoff": "OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com>", "packages": { ".": { "package-name": "dev.openfeature.sdk", From 1cc851b293008a8dd273e904e4c77a650ad71146 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Thu, 24 Apr 2025 21:41:37 -0400 Subject: [PATCH 228/745] chore: update release please action (#1430) Signed-off-by: Todd Baert --- .github/workflows/release.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ba5298e21..41d308de1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,11 +20,10 @@ jobs: # Release-please creates a PR that tracks all changes steps: - - uses: google-github-actions/release-please-action@e4dc86ba9405554aeba3c6bb2d169500e7d3b4ee + - uses: googleapis/release-please-action@v4 id: release with: token: ${{secrets.RELEASE_PLEASE_ACTION_TOKEN}} - target-branch: main # These steps are only run if this was a merged release-please PR - name: checkout From 99faaf88aa07bd45fc473db5bafce3b8eafaf9e0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 25 Apr 2025 22:07:09 +0000 Subject: [PATCH 229/745] chore(deps): update github/codeql-action digest to f843d94 (#1432) 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 40829322f..f1fcdc0b3 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@4ffa2364a07d4fa8656211f550f36d44e8148dae + uses: github/codeql-action/init@f843d94177a3bba7c0d0366e9bb9ff7de65547a9 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4ffa2364a07d4fa8656211f550f36d44e8148dae + uses: github/codeql-action/analyze@f843d94177a3bba7c0d0366e9bb9ff7de65547a9 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 79ceaa6f6..62b6fc929 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@4ffa2364a07d4fa8656211f550f36d44e8148dae + uses: github/codeql-action/init@f843d94177a3bba7c0d0366e9bb9ff7de65547a9 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@4ffa2364a07d4fa8656211f550f36d44e8148dae + uses: github/codeql-action/autobuild@f843d94177a3bba7c0d0366e9bb9ff7de65547a9 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4ffa2364a07d4fa8656211f550f36d44e8148dae + uses: github/codeql-action/analyze@f843d94177a3bba7c0d0366e9bb9ff7de65547a9 From 96cf9c7f5463e4e0de394117845aebdd9a69425f Mon Sep 17 00:00:00 2001 From: Abhay Porwal Date: Mon, 28 Apr 2025 18:04:19 +0530 Subject: [PATCH 230/745] docs: add try-catch example for setProviderAndWait usage (#1433) * added the detailed instructions for the setProviderAndWait Signed-off-by: Abhay * fixup: checkstyle issues Signed-off-by: Simon Schrottner --------- Signed-off-by: Abhay Signed-off-by: Simon Schrottner Co-authored-by: Abhay Co-authored-by: Simon Schrottner --- README.md | 14 ++++++++++++-- .../java/dev/openfeature/sdk/OpenFeatureAPI.java | 12 +++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 22d85bd2d..429d2ae44 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,12 @@ public void example(){ // configure a provider OpenFeatureAPI api = OpenFeatureAPI.getInstance(); - api.setProviderAndWait(new InMemoryProvider(myFlags)); + try { + api.setProviderAndWait(new InMemoryProvider(myFlags)); + } catch (Exception e) { + // handle initialization failure + e.printStackTrace(); + } // create a client Client client = api.getClient(); @@ -149,7 +154,12 @@ To register a provider in a blocking manner to ensure it is ready before further ```java OpenFeatureAPI api = OpenFeatureAPI.getInstance(); - api.setProviderAndWait(new MyProvider()); + try { + api.setProviderAndWait(new MyProvider()); + } catch (Exception e) { + // handle initialization failure + e.printStackTrace(); + } ``` #### Asynchronous diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java b/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java index bd60cc78a..66d40736f 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java @@ -207,7 +207,13 @@ public void setProvider(String domain, FeatureProvider provider) { } /** - * Set the default provider and wait for initialization to finish. + * Sets the default provider and waits for its initialization to complete. + * + *

Note: If the provider fails during initialization, an {@link OpenFeatureError} will be thrown. + * It is recommended to wrap this call in a try-catch block to handle potential initialization failures gracefully. + * + * @param provider the {@link FeatureProvider} to set as the default. + * @throws OpenFeatureError if the provider fails during initialization. */ public void setProviderAndWait(FeatureProvider provider) throws OpenFeatureError { try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) { @@ -224,8 +230,12 @@ public void setProviderAndWait(FeatureProvider provider) throws OpenFeatureError /** * Add a provider for a domain and wait for initialization to finish. * + *

Note: If the provider fails during initialization, an {@link OpenFeatureError} will be thrown. + * It is recommended to wrap this call in a try-catch block to handle potential initialization failures gracefully. + * * @param domain The domain to bind the provider to. * @param provider The provider to set. + * @throws OpenFeatureError if the provider fails during initialization. */ public void setProviderAndWait(String domain, FeatureProvider provider) throws OpenFeatureError { try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) { From 62ba6db457358d759fe83f23318b1cf4200756ac Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 28 Apr 2025 20:32:23 +0000 Subject: [PATCH 231/745] chore(deps): update amannn/action-semantic-pull-request digest to 3352882 (#1434) 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 1b909c15e..50c295b5d 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@04501d43b574e4c1d23c629ffe4dcec27acfdeff + - uses: amannn/action-semantic-pull-request@335288255954904a41ddda8947c8f2c844b8bfeb env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 7e74f2aa3ad2dc8f7a3e4ad398e7705b3e3db364 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 29 Apr 2025 02:56:28 +0000 Subject: [PATCH 232/745] chore(deps): update github/codeql-action digest to 83605b3 (#1435) 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 f1fcdc0b3..08abd2556 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@f843d94177a3bba7c0d0366e9bb9ff7de65547a9 + uses: github/codeql-action/init@83605b3ce2a0e9ed794fb5c17e77a82069816b16 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f843d94177a3bba7c0d0366e9bb9ff7de65547a9 + uses: github/codeql-action/analyze@83605b3ce2a0e9ed794fb5c17e77a82069816b16 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 62b6fc929..17d29aca5 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@f843d94177a3bba7c0d0366e9bb9ff7de65547a9 + uses: github/codeql-action/init@83605b3ce2a0e9ed794fb5c17e77a82069816b16 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@f843d94177a3bba7c0d0366e9bb9ff7de65547a9 + uses: github/codeql-action/autobuild@83605b3ce2a0e9ed794fb5c17e77a82069816b16 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f843d94177a3bba7c0d0366e9bb9ff7de65547a9 + uses: github/codeql-action/analyze@83605b3ce2a0e9ed794fb5c17e77a82069816b16 From b09e88798fed529161c61b96c20a8f257d355d3c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 29 Apr 2025 19:28:15 +0000 Subject: [PATCH 233/745] chore(deps): update github/codeql-action digest to ed51cb5 (#1436) 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 08abd2556..097079202 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@83605b3ce2a0e9ed794fb5c17e77a82069816b16 + uses: github/codeql-action/init@ed51cb5abd90d0e898e492d5e3f24423da71c2fb with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@83605b3ce2a0e9ed794fb5c17e77a82069816b16 + uses: github/codeql-action/analyze@ed51cb5abd90d0e898e492d5e3f24423da71c2fb diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 17d29aca5..fd88af888 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@83605b3ce2a0e9ed794fb5c17e77a82069816b16 + uses: github/codeql-action/init@ed51cb5abd90d0e898e492d5e3f24423da71c2fb with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@83605b3ce2a0e9ed794fb5c17e77a82069816b16 + uses: github/codeql-action/autobuild@ed51cb5abd90d0e898e492d5e3f24423da71c2fb - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@83605b3ce2a0e9ed794fb5c17e77a82069816b16 + uses: github/codeql-action/analyze@ed51cb5abd90d0e898e492d5e3f24423da71c2fb From f965cbcb37d20724e15b76c15842a88574810b1a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 30 Apr 2025 23:46:35 +0000 Subject: [PATCH 234/745] chore(deps): update github/codeql-action digest to 40e16ed (#1437) 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 097079202..c64e4df18 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@ed51cb5abd90d0e898e492d5e3f24423da71c2fb + uses: github/codeql-action/init@40e16edda1c08370bd06454cc0d3b0d4270d7c75 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ed51cb5abd90d0e898e492d5e3f24423da71c2fb + uses: github/codeql-action/analyze@40e16edda1c08370bd06454cc0d3b0d4270d7c75 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index fd88af888..f469e8fbc 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@ed51cb5abd90d0e898e492d5e3f24423da71c2fb + uses: github/codeql-action/init@40e16edda1c08370bd06454cc0d3b0d4270d7c75 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@ed51cb5abd90d0e898e492d5e3f24423da71c2fb + uses: github/codeql-action/autobuild@40e16edda1c08370bd06454cc0d3b0d4270d7c75 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ed51cb5abd90d0e898e492d5e3f24423da71c2fb + uses: github/codeql-action/analyze@40e16edda1c08370bd06454cc0d3b0d4270d7c75 From 85b200a08b9f8a71de3b5a19eaa057ec04e0801e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 1 May 2025 18:38:45 +0000 Subject: [PATCH 235/745] chore(deps): update github/codeql-action digest to 97a2bfd (#1438) 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 c64e4df18..6807936af 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@40e16edda1c08370bd06454cc0d3b0d4270d7c75 + uses: github/codeql-action/init@97a2bfd2a3d26d458da69e548f7f859d6fca634d with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@40e16edda1c08370bd06454cc0d3b0d4270d7c75 + uses: github/codeql-action/analyze@97a2bfd2a3d26d458da69e548f7f859d6fca634d diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index f469e8fbc..d278a519d 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@40e16edda1c08370bd06454cc0d3b0d4270d7c75 + uses: github/codeql-action/init@97a2bfd2a3d26d458da69e548f7f859d6fca634d with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@40e16edda1c08370bd06454cc0d3b0d4270d7c75 + uses: github/codeql-action/autobuild@97a2bfd2a3d26d458da69e548f7f859d6fca634d - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@40e16edda1c08370bd06454cc0d3b0d4270d7c75 + uses: github/codeql-action/analyze@97a2bfd2a3d26d458da69e548f7f859d6fca634d From f2348ea370412351389c60eef390f36edbea68b0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 2 May 2025 18:13:36 +0000 Subject: [PATCH 236/745] chore(deps): update github/codeql-action digest to 5eb3ed6 (#1439) 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 6807936af..74c7fc822 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@97a2bfd2a3d26d458da69e548f7f859d6fca634d + uses: github/codeql-action/init@5eb3ed6614230b1931d5c08df9e096e4ba524f21 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@97a2bfd2a3d26d458da69e548f7f859d6fca634d + uses: github/codeql-action/analyze@5eb3ed6614230b1931d5c08df9e096e4ba524f21 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index d278a519d..9dee17eec 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@97a2bfd2a3d26d458da69e548f7f859d6fca634d + uses: github/codeql-action/init@5eb3ed6614230b1931d5c08df9e096e4ba524f21 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@97a2bfd2a3d26d458da69e548f7f859d6fca634d + uses: github/codeql-action/autobuild@5eb3ed6614230b1931d5c08df9e096e4ba524f21 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@97a2bfd2a3d26d458da69e548f7f859d6fca634d + uses: github/codeql-action/analyze@5eb3ed6614230b1931d5c08df9e096e4ba524f21 From 4dc988b637a9e9c377edf7df7b29bf6407319f16 Mon Sep 17 00:00:00 2001 From: jarebudev <23311805+jarebudev@users.noreply.github.com> Date: Mon, 5 May 2025 10:30:23 +0100 Subject: [PATCH 237/745] feat!: Raise required Java version to 11 (#1393) * bumped to java 11, altered CI to target java 11 Signed-off-by: jarebudev <23311805+jarebudev@users.noreply.github.com> * changed profile and toolchain Signed-off-by: jarebudev <23311805+jarebudev@users.noreply.github.com> * corrected toolchain version Signed-off-by: jarebudev <23311805+jarebudev@users.noreply.github.com> --------- Signed-off-by: jarebudev <23311805+jarebudev@users.noreply.github.com> Co-authored-by: Simon Schrottner --- .github/workflows/pullrequest.yml | 6 +++--- README.md | 2 +- pom.xml | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 74c7fc822..36989fde1 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -13,15 +13,15 @@ jobs: build: - java: 17 profile: codequality - - java: 8 - profile: java8 + - java: 11 + profile: java11 name: with Java ${{ matrix.build.java }} runs-on: ${{ matrix.os}} steps: - name: Check out the code uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 - - name: Set up JDK 8 + - name: Set up JDK 11 uses: actions/setup-java@f4f1212c880fdec8162ea9a6493f4495191887b4 with: java-version: ${{ matrix.build.java }} diff --git a/README.md b/README.md index 429d2ae44..09f9683eb 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ ### Requirements -- Java 8+ (compiler target is 1.8) +- Java 11+ (compiler target is 11) Note that this library is intended to be used in server-side contexts and has not been evaluated for use on mobile devices. diff --git a/pom.xml b/pom.xml index e93e07584..239aa420e 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ [17,) UTF-8 - 1.8 + 11 ${maven.compiler.source} 5.12.2 7.22.1 @@ -20,7 +20,7 @@ ${project.groupId}.${project.artifactId} false - 8 + 11 OpenFeature Java SDK @@ -646,14 +646,14 @@ - - + + - java8 + java11 - (1.8,9) + [11,) true From 34035105154b7945c02de2a88fe83eb2414526ef Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 May 2025 06:19:41 +0000 Subject: [PATCH 238/745] chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10 (#103) * chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10 * Fix javadoc format Signed-off-by: christian.lutnik --------- Signed-off-by: christian.lutnik Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: christian.lutnik Co-authored-by: Simon Schrottner --- pom.xml | 2 +- src/main/java/dev/openfeature/sdk/FeatureProvider.java | 2 ++ .../java/dev/openfeature/sdk/TransactionContextPropagator.java | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 239aa420e..585533ada 100644 --- a/pom.xml +++ b/pom.xml @@ -457,7 +457,7 @@ com.puppycrawl.tools checkstyle - 9.3 + 10.23.1 diff --git a/src/main/java/dev/openfeature/sdk/FeatureProvider.java b/src/main/java/dev/openfeature/sdk/FeatureProvider.java index 4c630cb80..22819ef10 100644 --- a/src/main/java/dev/openfeature/sdk/FeatureProvider.java +++ b/src/main/java/dev/openfeature/sdk/FeatureProvider.java @@ -30,6 +30,7 @@ default List getProviderHooks() { * can overwrite this method, * if they have special initialization needed prior being called for flag * evaluation. + * *

* It is ok if the method is expensive as it is executed in the background. All * runtime exceptions will be @@ -45,6 +46,7 @@ default void initialize(EvaluationContext evaluationContext) throws Exception { * flags, or the SDK is shut down. * Providers can overwrite this method, if they have special shutdown actions * needed. + * *

* It is ok if the method is expensive as it is executed in the background. All * runtime exceptions will be diff --git a/src/main/java/dev/openfeature/sdk/TransactionContextPropagator.java b/src/main/java/dev/openfeature/sdk/TransactionContextPropagator.java index 05f7d3eb8..9e2718787 100644 --- a/src/main/java/dev/openfeature/sdk/TransactionContextPropagator.java +++ b/src/main/java/dev/openfeature/sdk/TransactionContextPropagator.java @@ -5,6 +5,7 @@ * for the duration of a single transaction. * Examples of potential transaction specific context include: a user id, user agent, IP. * Transaction context is merged with evaluation context prior to flag evaluation. + * *

* The precedence of merging context can be seen in * the specification. From 78657ee79efdc94018387cdf8263a73d4abf7191 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 8 May 2025 03:06:04 +0000 Subject: [PATCH 239/745] chore(deps): update dependency com.tngtech.archunit:archunit-junit5 to v1.4.1 (#1440) 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 585533ada..16d72688a 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ com.tngtech.archunit archunit-junit5 - 1.4.0 + 1.4.1 test From 58454b4eaabfd3327f7ceaff4bf335a5a839ed41 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 May 2025 09:01:29 +0200 Subject: [PATCH 240/745] chore(deps): update io.cucumber.version to v7.22.2 (#1441) 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 16d72688a..a1093bffe 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ 11 ${maven.compiler.source} 5.12.2 - 7.22.1 + 7.22.2 5.17.0 **/e2e/*.java From e568f3a4f560187586d5473aa7bc12a673340e24 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 May 2025 07:07:53 +0000 Subject: [PATCH 241/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.22.2 (#1442) 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 a1093bffe..1d4fb6f73 100644 --- a/pom.xml +++ b/pom.xml @@ -204,7 +204,7 @@ io.cucumber cucumber-bom - 7.22.1 + 7.22.2 pom import From d0ae5482771f4d1701bce25381cdf4e92e2d4882 Mon Sep 17 00:00:00 2001 From: Liran M <77168114+liran2000@users.noreply.github.com> Date: Tue, 13 May 2025 10:45:16 +0300 Subject: [PATCH 242/745] feat: add telemetry helper utils (#1346) * feat: add telemetry helper utils Signed-off-by: liran2000 * updates Signed-off-by: liran2000 * fixup: apply changes according to the semconv The semconv has changed, and some attributes have been renamed. Furthermore, the body usage is deprecated and should be part of the attributes. see: https://github.com/open-telemetry/semantic-conventions/pull/1990/ Signed-off-by: Simon Schrottner * fixup: fix tests Signed-off-by: Simon Schrottner * fixup: fix spotless Signed-off-by: Simon Schrottner --------- Signed-off-by: liran2000 Signed-off-by: Simon Schrottner Co-authored-by: Simon Schrottner --- .../dev/openfeature/sdk/EvaluationEvent.java | 24 ++ .../java/dev/openfeature/sdk/Telemetry.java | 95 +++++++ .../dev/openfeature/sdk/TelemetryTest.java | 231 ++++++++++++++++++ 3 files changed, 350 insertions(+) create mode 100644 src/main/java/dev/openfeature/sdk/EvaluationEvent.java create mode 100644 src/main/java/dev/openfeature/sdk/Telemetry.java create mode 100644 src/test/java/dev/openfeature/sdk/TelemetryTest.java diff --git a/src/main/java/dev/openfeature/sdk/EvaluationEvent.java b/src/main/java/dev/openfeature/sdk/EvaluationEvent.java new file mode 100644 index 000000000..f92e24d5a --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/EvaluationEvent.java @@ -0,0 +1,24 @@ +package dev.openfeature.sdk; + +import java.util.HashMap; +import java.util.Map; +import lombok.Builder; +import lombok.Getter; +import lombok.Singular; + +/** + * Represents an evaluation event. + */ +@Builder +@Getter +public class EvaluationEvent { + + private String name; + + @Singular("attribute") + private Map attributes; + + public Map getAttributes() { + return new HashMap<>(attributes); + } +} diff --git a/src/main/java/dev/openfeature/sdk/Telemetry.java b/src/main/java/dev/openfeature/sdk/Telemetry.java new file mode 100644 index 000000000..7e94983ee --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/Telemetry.java @@ -0,0 +1,95 @@ +package dev.openfeature.sdk; + +/** + * The Telemetry class provides constants and methods for creating OpenTelemetry compliant + * evaluation events. + */ +public class Telemetry { + + private Telemetry() {} + + /* + The OpenTelemetry compliant event attributes for flag evaluation. + Specification: https://opentelemetry.io/docs/specs/semconv/feature-flags/feature-flags-logs/ + */ + public static final String TELEMETRY_KEY = "feature_flag.key"; + public static final String TELEMETRY_ERROR_CODE = "error.type"; + public static final String TELEMETRY_VARIANT = "feature_flag.result.variant"; + public static final String TELEMETRY_VALUE = "feature_flag.result.value"; + public static final String TELEMETRY_CONTEXT_ID = "feature_flag.context.id"; + public static final String TELEMETRY_ERROR_MSG = "feature_flag.evaluation.error.message"; + public static final String TELEMETRY_REASON = "feature_flag.result.reason"; + public static final String TELEMETRY_PROVIDER = "feature_flag.provider.name"; + public static final String TELEMETRY_FLAG_SET_ID = "feature_flag.set.id"; + public static final String TELEMETRY_VERSION = "feature_flag.version"; + + // Well-known flag metadata attributes for telemetry events. + // Specification: https://openfeature.dev/specification/appendix-d#flag-metadata + public static final String TELEMETRY_FLAG_META_CONTEXT_ID = "contextId"; + public static final String TELEMETRY_FLAG_META_FLAG_SET_ID = "flagSetId"; + public static final String TELEMETRY_FLAG_META_VERSION = "version"; + + public static final String FLAG_EVALUATION_EVENT_NAME = "feature_flag.evaluation"; + + /** + * Creates an EvaluationEvent using the provided HookContext and ProviderEvaluation. + * + * @param hookContext the context containing flag evaluation details + * @param evaluationDetails the evaluation result from the provider + * + * @return an EvaluationEvent populated with telemetry data + */ + public static EvaluationEvent createEvaluationEvent( + HookContext hookContext, FlagEvaluationDetails evaluationDetails) { + EvaluationEvent.EvaluationEventBuilder evaluationEventBuilder = EvaluationEvent.builder() + .name(FLAG_EVALUATION_EVENT_NAME) + .attribute(TELEMETRY_KEY, hookContext.getFlagKey()) + .attribute(TELEMETRY_PROVIDER, hookContext.getProviderMetadata().getName()); + + if (evaluationDetails.getReason() != null) { + evaluationEventBuilder.attribute( + TELEMETRY_REASON, evaluationDetails.getReason().toLowerCase()); + } else { + evaluationEventBuilder.attribute( + TELEMETRY_REASON, Reason.UNKNOWN.name().toLowerCase()); + } + + if (evaluationDetails.getVariant() != null) { + evaluationEventBuilder.attribute(TELEMETRY_VARIANT, evaluationDetails.getVariant()); + } else { + evaluationEventBuilder.attribute(TELEMETRY_VALUE, evaluationDetails.getValue()); + } + + String contextId = evaluationDetails.getFlagMetadata().getString(TELEMETRY_FLAG_META_CONTEXT_ID); + if (contextId != null) { + evaluationEventBuilder.attribute(TELEMETRY_CONTEXT_ID, contextId); + } else { + evaluationEventBuilder.attribute( + TELEMETRY_CONTEXT_ID, hookContext.getCtx().getTargetingKey()); + } + + String setID = evaluationDetails.getFlagMetadata().getString(TELEMETRY_FLAG_META_FLAG_SET_ID); + if (setID != null) { + evaluationEventBuilder.attribute(TELEMETRY_FLAG_SET_ID, setID); + } + + String version = evaluationDetails.getFlagMetadata().getString(TELEMETRY_FLAG_META_VERSION); + if (version != null) { + evaluationEventBuilder.attribute(TELEMETRY_VERSION, version); + } + + if (Reason.ERROR.name().equals(evaluationDetails.getReason())) { + if (evaluationDetails.getErrorCode() != null) { + evaluationEventBuilder.attribute(TELEMETRY_ERROR_CODE, evaluationDetails.getErrorCode()); + } else { + evaluationEventBuilder.attribute(TELEMETRY_ERROR_CODE, ErrorCode.GENERAL); + } + + if (evaluationDetails.getErrorMessage() != null) { + evaluationEventBuilder.attribute(TELEMETRY_ERROR_MSG, evaluationDetails.getErrorMessage()); + } + } + + return evaluationEventBuilder.build(); + } +} diff --git a/src/test/java/dev/openfeature/sdk/TelemetryTest.java b/src/test/java/dev/openfeature/sdk/TelemetryTest.java new file mode 100644 index 000000000..2752683b8 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/TelemetryTest.java @@ -0,0 +1,231 @@ +package dev.openfeature.sdk; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.junit.jupiter.api.Test; + +public class TelemetryTest { + + @Test + void testCreatesEvaluationEventWithMandatoryFields() { + // Arrange + String flagKey = "test-flag"; + String providerName = "test-provider"; + String reason = "static"; + + Metadata providerMetadata = mock(Metadata.class); + when(providerMetadata.getName()).thenReturn(providerName); + + HookContext hookContext = HookContext.builder() + .flagKey(flagKey) + .providerMetadata(providerMetadata) + .type(FlagValueType.BOOLEAN) + .defaultValue(false) + .ctx(new ImmutableContext()) + .build(); + + FlagEvaluationDetails evaluation = FlagEvaluationDetails.builder() + .reason(reason) + .value(true) + .build(); + + EvaluationEvent event = Telemetry.createEvaluationEvent(hookContext, evaluation); + + assertEquals(Telemetry.FLAG_EVALUATION_EVENT_NAME, event.getName()); + assertEquals(flagKey, event.getAttributes().get(Telemetry.TELEMETRY_KEY)); + assertEquals(providerName, event.getAttributes().get(Telemetry.TELEMETRY_PROVIDER)); + assertEquals(reason.toLowerCase(), event.getAttributes().get(Telemetry.TELEMETRY_REASON)); + } + + @Test + void testHandlesNullReason() { + // Arrange + String flagKey = "test-flag"; + String providerName = "test-provider"; + + Metadata providerMetadata = mock(Metadata.class); + when(providerMetadata.getName()).thenReturn(providerName); + + HookContext hookContext = HookContext.builder() + .flagKey(flagKey) + .providerMetadata(providerMetadata) + .type(FlagValueType.BOOLEAN) + .defaultValue(false) + .ctx(new ImmutableContext()) + .build(); + + FlagEvaluationDetails evaluation = FlagEvaluationDetails.builder() + .reason(null) + .value(true) + .build(); + + EvaluationEvent event = Telemetry.createEvaluationEvent(hookContext, evaluation); + + assertEquals(Reason.UNKNOWN.name().toLowerCase(), event.getAttributes().get(Telemetry.TELEMETRY_REASON)); + } + + @Test + void testSetsVariantAttributeWhenVariantExists() { + HookContext hookContext = HookContext.builder() + .flagKey("testFlag") + .type(FlagValueType.STRING) + .defaultValue("default") + .ctx(mock(EvaluationContext.class)) + .clientMetadata(mock(ClientMetadata.class)) + .providerMetadata(mock(Metadata.class)) + .build(); + + FlagEvaluationDetails providerEvaluation = FlagEvaluationDetails.builder() + .variant("testVariant") + .flagMetadata(ImmutableMetadata.builder().build()) + .build(); + + EvaluationEvent event = Telemetry.createEvaluationEvent(hookContext, providerEvaluation); + + assertEquals("testVariant", event.getAttributes().get(Telemetry.TELEMETRY_VARIANT)); + } + + @Test + void test_sets_value_in_body_when_variant_is_null() { + HookContext hookContext = HookContext.builder() + .flagKey("testFlag") + .type(FlagValueType.STRING) + .defaultValue("default") + .ctx(mock(EvaluationContext.class)) + .clientMetadata(mock(ClientMetadata.class)) + .providerMetadata(mock(Metadata.class)) + .build(); + + FlagEvaluationDetails providerEvaluation = FlagEvaluationDetails.builder() + .value("testValue") + .flagMetadata(ImmutableMetadata.builder().build()) + .build(); + + EvaluationEvent event = Telemetry.createEvaluationEvent(hookContext, providerEvaluation); + + assertEquals("testValue", event.getAttributes().get(Telemetry.TELEMETRY_VALUE)); + } + + @Test + void testAllFieldsPopulated() { + EvaluationContext evaluationContext = mock(EvaluationContext.class); + when(evaluationContext.getTargetingKey()).thenReturn("realTargetingKey"); + + Metadata providerMetadata = mock(Metadata.class); + when(providerMetadata.getName()).thenReturn("realProviderName"); + + HookContext hookContext = HookContext.builder() + .flagKey("realFlag") + .type(FlagValueType.STRING) + .defaultValue("realDefault") + .ctx(evaluationContext) + .clientMetadata(mock(ClientMetadata.class)) + .providerMetadata(providerMetadata) + .build(); + + FlagEvaluationDetails providerEvaluation = FlagEvaluationDetails.builder() + .flagMetadata(ImmutableMetadata.builder() + .addString("contextId", "realContextId") + .addString("flagSetId", "realFlagSetId") + .addString("version", "realVersion") + .build()) + .reason(Reason.DEFAULT.name()) + .variant("realVariant") + .build(); + + EvaluationEvent event = Telemetry.createEvaluationEvent(hookContext, providerEvaluation); + + assertEquals("realFlag", event.getAttributes().get(Telemetry.TELEMETRY_KEY)); + assertEquals("realProviderName", event.getAttributes().get(Telemetry.TELEMETRY_PROVIDER)); + assertEquals("default", event.getAttributes().get(Telemetry.TELEMETRY_REASON)); + assertEquals("realContextId", event.getAttributes().get(Telemetry.TELEMETRY_CONTEXT_ID)); + assertEquals("realFlagSetId", event.getAttributes().get(Telemetry.TELEMETRY_FLAG_SET_ID)); + assertEquals("realVersion", event.getAttributes().get(Telemetry.TELEMETRY_VERSION)); + assertNull(event.getAttributes().get(Telemetry.TELEMETRY_ERROR_CODE)); + assertEquals("realVariant", event.getAttributes().get(Telemetry.TELEMETRY_VARIANT)); + } + + @Test + void testErrorEvaluation() { + EvaluationContext evaluationContext = mock(EvaluationContext.class); + when(evaluationContext.getTargetingKey()).thenReturn("realTargetingKey"); + + Metadata providerMetadata = mock(Metadata.class); + when(providerMetadata.getName()).thenReturn("realProviderName"); + + HookContext hookContext = HookContext.builder() + .flagKey("realFlag") + .type(FlagValueType.STRING) + .defaultValue("realDefault") + .ctx(evaluationContext) + .clientMetadata(mock(ClientMetadata.class)) + .providerMetadata(providerMetadata) + .build(); + + FlagEvaluationDetails providerEvaluation = FlagEvaluationDetails.builder() + .flagMetadata(ImmutableMetadata.builder() + .addString("contextId", "realContextId") + .addString("flagSetId", "realFlagSetId") + .addString("version", "realVersion") + .build()) + .reason(Reason.ERROR.name()) + .errorMessage("realErrorMessage") + .build(); + + EvaluationEvent event = Telemetry.createEvaluationEvent(hookContext, providerEvaluation); + + assertEquals("realFlag", event.getAttributes().get(Telemetry.TELEMETRY_KEY)); + assertEquals("realProviderName", event.getAttributes().get(Telemetry.TELEMETRY_PROVIDER)); + assertEquals("error", event.getAttributes().get(Telemetry.TELEMETRY_REASON)); + assertEquals("realContextId", event.getAttributes().get(Telemetry.TELEMETRY_CONTEXT_ID)); + assertEquals("realFlagSetId", event.getAttributes().get(Telemetry.TELEMETRY_FLAG_SET_ID)); + assertEquals("realVersion", event.getAttributes().get(Telemetry.TELEMETRY_VERSION)); + assertEquals(ErrorCode.GENERAL, event.getAttributes().get(Telemetry.TELEMETRY_ERROR_CODE)); + assertEquals("realErrorMessage", event.getAttributes().get(Telemetry.TELEMETRY_ERROR_MSG)); + assertNull(event.getAttributes().get(Telemetry.TELEMETRY_VARIANT)); + } + + @Test + void testErrorCodeEvaluation() { + EvaluationContext evaluationContext = mock(EvaluationContext.class); + when(evaluationContext.getTargetingKey()).thenReturn("realTargetingKey"); + + Metadata providerMetadata = mock(Metadata.class); + when(providerMetadata.getName()).thenReturn("realProviderName"); + + HookContext hookContext = HookContext.builder() + .flagKey("realFlag") + .type(FlagValueType.STRING) + .defaultValue("realDefault") + .ctx(evaluationContext) + .clientMetadata(mock(ClientMetadata.class)) + .providerMetadata(providerMetadata) + .build(); + + FlagEvaluationDetails providerEvaluation = FlagEvaluationDetails.builder() + .flagMetadata(ImmutableMetadata.builder() + .addString("contextId", "realContextId") + .addString("flagSetId", "realFlagSetId") + .addString("version", "realVersion") + .build()) + .reason(Reason.ERROR.name()) + .errorMessage("realErrorMessage") + .errorCode(ErrorCode.INVALID_CONTEXT) + .build(); + + EvaluationEvent event = Telemetry.createEvaluationEvent(hookContext, providerEvaluation); + + assertEquals("realFlag", event.getAttributes().get(Telemetry.TELEMETRY_KEY)); + assertEquals("realProviderName", event.getAttributes().get(Telemetry.TELEMETRY_PROVIDER)); + assertEquals("error", event.getAttributes().get(Telemetry.TELEMETRY_REASON)); + assertEquals("realContextId", event.getAttributes().get(Telemetry.TELEMETRY_CONTEXT_ID)); + assertEquals("realFlagSetId", event.getAttributes().get(Telemetry.TELEMETRY_FLAG_SET_ID)); + assertEquals("realVersion", event.getAttributes().get(Telemetry.TELEMETRY_VERSION)); + assertEquals(ErrorCode.INVALID_CONTEXT, event.getAttributes().get(Telemetry.TELEMETRY_ERROR_CODE)); + assertEquals("realErrorMessage", event.getAttributes().get(Telemetry.TELEMETRY_ERROR_MSG)); + assertNull(event.getAttributes().get(Telemetry.TELEMETRY_VARIANT)); + } +} From 7182a7fc4197e70218e829971dae2cff09f948c9 Mon Sep 17 00:00:00 2001 From: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> Date: Tue, 13 May 2025 12:38:55 -0400 Subject: [PATCH 243/745] chore(main): release 1.15.0 (#1431) Signed-off-by: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 71 +++++++++++++++++++++++++++++++++++ README.md | 8 ++-- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 78 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 762e32db5..634797f5a 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"1.14.2"} +{".":"1.15.0"} diff --git a/CHANGELOG.md b/CHANGELOG.md index 914cbfef3..b18f9cc71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,76 @@ # Changelog +## [1.15.0](https://github.com/open-feature/java-sdk/compare/v1.14.2...v1.15.0) (2025-05-13) + + +### NOTABLE CHANGES + +* Raise required Java version to 11 ([#1393](https://github.com/open-feature/java-sdk/issues/1393)) + +### 🐛 Bug Fixes + +* **deps:** update dependency io.cucumber:cucumber-bom to v7.22.0 ([#1411](https://github.com/open-feature/java-sdk/issues/1411)) ([e251819](https://github.com/open-feature/java-sdk/commit/e25181982af8e5d37be4876b71b337ca86e8454b)) +* **deps:** update dependency io.cucumber:cucumber-bom to v7.22.1 ([#1427](https://github.com/open-feature/java-sdk/issues/1427)) ([1c4d2ef](https://github.com/open-feature/java-sdk/commit/1c4d2efafdebb562f099ba1ec3a6a29eabc8ff91)) +* **deps:** update dependency io.cucumber:cucumber-bom to v7.22.2 ([#1442](https://github.com/open-feature/java-sdk/issues/1442)) ([e568f3a](https://github.com/open-feature/java-sdk/commit/e568f3a4f560187586d5473aa7bc12a673340e24)) +* **deps:** update dependency org.projectlombok:lombok to v1.18.38 ([#1403](https://github.com/open-feature/java-sdk/issues/1403)) ([ef32f11](https://github.com/open-feature/java-sdk/commit/ef32f11571de4d3a981efec4f61113eb8b0d7d9d)) +* **deps:** update junit5 monorepo ([#1418](https://github.com/open-feature/java-sdk/issues/1418)) ([97b442e](https://github.com/open-feature/java-sdk/commit/97b442ed6e8f2b99ca949ffd63e5cbf57718c796)) + + +### ✨ New Features + +* add telemetry helper utils ([#1346](https://github.com/open-feature/java-sdk/issues/1346)) ([d0ae548](https://github.com/open-feature/java-sdk/commit/d0ae5482771f4d1701bce25381cdf4e92e2d4882)) +* Raise required Java version to 11 ([#1393](https://github.com/open-feature/java-sdk/issues/1393)) ([4dc988b](https://github.com/open-feature/java-sdk/commit/4dc988b637a9e9c377edf7df7b29bf6407319f16)) + + +### 🧹 Chore + +* add DCO to release please ([45ec4b1](https://github.com/open-feature/java-sdk/commit/45ec4b1b7734c9117f43abf8fe5105c2903c3986)) +* add DCO to release please ([#1429](https://github.com/open-feature/java-sdk/issues/1429)) ([32137bf](https://github.com/open-feature/java-sdk/commit/32137bfa82e9c0391c999bf0be2a36f201620931)) +* add publish env ([#1420](https://github.com/open-feature/java-sdk/issues/1420)) ([665dd51](https://github.com/open-feature/java-sdk/commit/665dd51eb2b3b79d3ffccb6cef64d544aa5e7206)) +* **deps:** update actions/setup-java digest to 148017a ([#1404](https://github.com/open-feature/java-sdk/issues/1404)) ([f834e11](https://github.com/open-feature/java-sdk/commit/f834e11acc7ecf903e972d80e9dab324be97847e)) +* **deps:** update actions/setup-java digest to c5195ef ([#1415](https://github.com/open-feature/java-sdk/issues/1415)) ([a578903](https://github.com/open-feature/java-sdk/commit/a5789038acc36cb2b0ddf12e534a1317e1c9b8e8)) +* **deps:** update actions/setup-java digest to f4f1212 ([#1421](https://github.com/open-feature/java-sdk/issues/1421)) ([a3e2a59](https://github.com/open-feature/java-sdk/commit/a3e2a59aebee051ae8c7eb1c5769a04dc9da8de3)) +* **deps:** update amannn/action-semantic-pull-request digest to 3352882 ([#1434](https://github.com/open-feature/java-sdk/issues/1434)) ([62ba6db](https://github.com/open-feature/java-sdk/commit/62ba6db457358d759fe83f23318b1cf4200756ac)) +* **deps:** update codecov/codecov-action action to v5.4.2 ([#1419](https://github.com/open-feature/java-sdk/issues/1419)) ([a6389e8](https://github.com/open-feature/java-sdk/commit/a6389e89f60aa7f4871f47d78fedd27a7f9991b4)) +* **deps:** update dependency com.diffplug.spotless:spotless-maven-plugin to v2.44.4 ([#1414](https://github.com/open-feature/java-sdk/issues/1414)) ([e066d3f](https://github.com/open-feature/java-sdk/commit/e066d3f749c09bb1ef79e3bcace1d205a39787df)) +* **deps:** update dependency com.h3xstream.findsecbugs:findsecbugs-plugin to v1.14.0 ([#1422](https://github.com/open-feature/java-sdk/issues/1422)) ([495da27](https://github.com/open-feature/java-sdk/commit/495da271bee976a942973cd23012f60db895bf24)) +* **deps:** update dependency com.puppycrawl.tools:checkstyle to v10 ([#103](https://github.com/open-feature/java-sdk/issues/103)) ([3403510](https://github.com/open-feature/java-sdk/commit/34035105154b7945c02de2a88fe83eb2414526ef)) +* **deps:** update dependency com.tngtech.archunit:archunit-junit5 to v1.4.1 ([#1440](https://github.com/open-feature/java-sdk/issues/1440)) ([78657ee](https://github.com/open-feature/java-sdk/commit/78657ee79efdc94018387cdf8263a73d4abf7191)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.17.5 ([#1400](https://github.com/open-feature/java-sdk/issues/1400)) ([1f2d071](https://github.com/open-feature/java-sdk/commit/1f2d0715087ebd4554826d8552b250e4b8b950c8)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.17.5 ([#1401](https://github.com/open-feature/java-sdk/issues/1401)) ([07301bd](https://github.com/open-feature/java-sdk/commit/07301bda3f5b65550eff1e025fc9c0bec3c25275)) +* **deps:** update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.5.3 ([#1398](https://github.com/open-feature/java-sdk/issues/1398)) ([1fcf0e7](https://github.com/open-feature/java-sdk/commit/1fcf0e77d956c88c54e10942d96d2afd4d79315c)) +* **deps:** update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.3 ([#1399](https://github.com/open-feature/java-sdk/issues/1399)) ([d6ebc16](https://github.com/open-feature/java-sdk/commit/d6ebc161a93ad703e25592abdb0bf0fd9e281bbc)) +* **deps:** update dependency org.jacoco:jacoco-maven-plugin to v0.8.13 ([#1407](https://github.com/open-feature/java-sdk/issues/1407)) ([e19ccaa](https://github.com/open-feature/java-sdk/commit/e19ccaa35d9ac4d89d72ea58a70d416d202078db)) +* **deps:** update dependency org.mockito:mockito-core to v5.17.0 ([#1409](https://github.com/open-feature/java-sdk/issues/1409)) ([345cdcf](https://github.com/open-feature/java-sdk/commit/345cdcfa10da64c61d769746f335f38ac564e9ad)) +* **deps:** update github/codeql-action digest to 2a8cbad ([#1423](https://github.com/open-feature/java-sdk/issues/1423)) ([6b6849f](https://github.com/open-feature/java-sdk/commit/6b6849f3a3ee8a7b66d859c8e522bc101d1ccd44)) +* **deps:** update github/codeql-action digest to 362ef4c ([#1408](https://github.com/open-feature/java-sdk/issues/1408)) ([ca160ca](https://github.com/open-feature/java-sdk/commit/ca160cab7ccd71527e06a0851502353ac50b8d0d)) +* **deps:** update github/codeql-action digest to 40e16ed ([#1437](https://github.com/open-feature/java-sdk/issues/1437)) ([f965cbc](https://github.com/open-feature/java-sdk/commit/f965cbcb37d20724e15b76c15842a88574810b1a)) +* **deps:** update github/codeql-action digest to 4c3e536 ([#1417](https://github.com/open-feature/java-sdk/issues/1417)) ([0c77c84](https://github.com/open-feature/java-sdk/commit/0c77c8446032eaac7e068d48901e1423c21db326)) +* **deps:** update github/codeql-action digest to 4ffa236 ([#1425](https://github.com/open-feature/java-sdk/issues/1425)) ([a7828e7](https://github.com/open-feature/java-sdk/commit/a7828e73a8f2e30f71bd2d9d4da180b2fa436424)) +* **deps:** update github/codeql-action digest to 56dd02f ([#1416](https://github.com/open-feature/java-sdk/issues/1416)) ([4607c62](https://github.com/open-feature/java-sdk/commit/4607c62f15f7ee572207b8ec012ad4b3626e0184)) +* **deps:** update github/codeql-action digest to 5eb3ed6 ([#1439](https://github.com/open-feature/java-sdk/issues/1439)) ([f2348ea](https://github.com/open-feature/java-sdk/commit/f2348ea370412351389c60eef390f36edbea68b0)) +* **deps:** update github/codeql-action digest to 83605b3 ([#1435](https://github.com/open-feature/java-sdk/issues/1435)) ([7e74f2a](https://github.com/open-feature/java-sdk/commit/7e74f2aa3ad2dc8f7a3e4ad398e7705b3e3db364)) +* **deps:** update github/codeql-action digest to 97a2bfd ([#1438](https://github.com/open-feature/java-sdk/issues/1438)) ([85b200a](https://github.com/open-feature/java-sdk/commit/85b200a08b9f8a71de3b5a19eaa057ec04e0801e)) +* **deps:** update github/codeql-action digest to 9bd18b4 ([#1394](https://github.com/open-feature/java-sdk/issues/1394)) ([d7b591c](https://github.com/open-feature/java-sdk/commit/d7b591c9f910afad303d6d814f65c7f9dab33b89)) +* **deps:** update github/codeql-action digest to 9f45e74 ([#1396](https://github.com/open-feature/java-sdk/issues/1396)) ([37d76be](https://github.com/open-feature/java-sdk/commit/37d76be697e83f524250a82b2a67cdb4a953d7bc)) +* **deps:** update github/codeql-action digest to d26c46a ([#1413](https://github.com/open-feature/java-sdk/issues/1413)) ([5b327ee](https://github.com/open-feature/java-sdk/commit/5b327eeb770d0a4222f3599be79543b7bed9abc2)) +* **deps:** update github/codeql-action digest to dab8a02 ([#1405](https://github.com/open-feature/java-sdk/issues/1405)) ([5b2f151](https://github.com/open-feature/java-sdk/commit/5b2f1513ab75ef6692978830e59eba87ffa494d5)) +* **deps:** update github/codeql-action digest to e13fe0d ([#1406](https://github.com/open-feature/java-sdk/issues/1406)) ([e211397](https://github.com/open-feature/java-sdk/commit/e211397d517e1263e1251f9c99093bf05cecd93f)) +* **deps:** update github/codeql-action digest to ed51cb5 ([#1436](https://github.com/open-feature/java-sdk/issues/1436)) ([b09e887](https://github.com/open-feature/java-sdk/commit/b09e88798fed529161c61b96c20a8f257d355d3c)) +* **deps:** update github/codeql-action digest to efffb48 ([#1402](https://github.com/open-feature/java-sdk/issues/1402)) ([384953d](https://github.com/open-feature/java-sdk/commit/384953d30ecff83d60a2e5b9790e8228d1a52ac7)) +* **deps:** update github/codeql-action digest to f843d94 ([#1432](https://github.com/open-feature/java-sdk/issues/1432)) ([99faaf8](https://github.com/open-feature/java-sdk/commit/99faaf88aa07bd45fc473db5bafce3b8eafaf9e0)) +* **deps:** update io.cucumber.version to v7.22.0 ([#1410](https://github.com/open-feature/java-sdk/issues/1410)) ([3c69f2f](https://github.com/open-feature/java-sdk/commit/3c69f2f36c4e975d690ecc2e790df632a33001ba)) +* **deps:** update io.cucumber.version to v7.22.1 ([#1426](https://github.com/open-feature/java-sdk/issues/1426)) ([844374a](https://github.com/open-feature/java-sdk/commit/844374a42b94deffab6856e978766354a6f46576)) +* **deps:** update io.cucumber.version to v7.22.2 ([#1441](https://github.com/open-feature/java-sdk/issues/1441)) ([58454b4](https://github.com/open-feature/java-sdk/commit/58454b4eaabfd3327f7ceaff4bf335a5a839ed41)) +* update codeowners to give global maintainers code ownership ([#1412](https://github.com/open-feature/java-sdk/issues/1412)) ([498fd38](https://github.com/open-feature/java-sdk/commit/498fd382659669315b0db61db5f19ce054467bc9)) +* update release please action ([#1430](https://github.com/open-feature/java-sdk/issues/1430)) ([1cc851b](https://github.com/open-feature/java-sdk/commit/1cc851b293008a8dd273e904e4c77a650ad71146)) +* use PAT for release please ([014f8a5](https://github.com/open-feature/java-sdk/commit/014f8a59da8f1e976e440ed1ea17e85561f98e2d)) + + +### 📚 Documentation + +* add try-catch example for setProviderAndWait usage ([#1433](https://github.com/open-feature/java-sdk/issues/1433)) ([96cf9c7](https://github.com/open-feature/java-sdk/commit/96cf9c7f5463e4e0de394117845aebdd9a69425f)) + ## [1.14.2](https://github.com/open-feature/java-sdk/compare/v1.14.1...v1.14.2) (2025-03-27) diff --git a/README.md b/README.md index 09f9683eb..3f1a487b3 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.2 + 1.15.0 ``` @@ -84,7 +84,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:1.14.2' + implementation 'dev.openfeature:sdk:1.15.0' } ``` diff --git a/pom.xml b/pom.xml index 1d4fb6f73..1ae9f9b17 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ dev.openfeature sdk - 1.14.2 + 1.15.0 [17,) diff --git a/version.txt b/version.txt index a4cc55716..141f2e805 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.14.2 +1.15.0 From bc10bacb5a68d0d2e498cb41c087505490f19de8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 13 May 2025 22:40:47 +0000 Subject: [PATCH 244/745] chore(deps): update github/codeql-action digest to 15bce5b (#1443) 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 36989fde1..ae3651a3c 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@5eb3ed6614230b1931d5c08df9e096e4ba524f21 + uses: github/codeql-action/init@15bce5bb14748fcfd6fe32738ca1cba36e5f218f with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5eb3ed6614230b1931d5c08df9e096e4ba524f21 + uses: github/codeql-action/analyze@15bce5bb14748fcfd6fe32738ca1cba36e5f218f diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 9dee17eec..f9a9cf613 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@5eb3ed6614230b1931d5c08df9e096e4ba524f21 + uses: github/codeql-action/init@15bce5bb14748fcfd6fe32738ca1cba36e5f218f with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@5eb3ed6614230b1931d5c08df9e096e4ba524f21 + uses: github/codeql-action/autobuild@15bce5bb14748fcfd6fe32738ca1cba36e5f218f - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5eb3ed6614230b1931d5c08df9e096e4ba524f21 + uses: github/codeql-action/analyze@15bce5bb14748fcfd6fe32738ca1cba36e5f218f From e2813b2e5df8e548caf16e3e425b35962045ca6c Mon Sep 17 00:00:00 2001 From: chrfwow Date: Wed, 14 May 2025 11:11:36 +0200 Subject: [PATCH 245/745] feat: add logging on provider state transitions (#1444) * NOISSUE add logging on provider state transitions Signed-off-by: christian.lutnik * fix npe Signed-off-by: christian.lutnik * fix failing test Signed-off-by: christian.lutnik * fix failing test Signed-off-by: christian.lutnik * format Signed-off-by: christian.lutnik --------- Signed-off-by: christian.lutnik Co-authored-by: Simon Schrottner --- .../sdk/FeatureProviderStateManager.java | 43 +++++++++++++------ .../openfeature/sdk/OpenFeatureAPITest.java | 3 +- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/main/java/dev/openfeature/sdk/FeatureProviderStateManager.java b/src/main/java/dev/openfeature/sdk/FeatureProviderStateManager.java index 2c39ece6b..5fd70221b 100644 --- a/src/main/java/dev/openfeature/sdk/FeatureProviderStateManager.java +++ b/src/main/java/dev/openfeature/sdk/FeatureProviderStateManager.java @@ -2,14 +2,14 @@ import dev.openfeature.sdk.exceptions.OpenFeatureError; import java.util.concurrent.atomic.AtomicBoolean; -import lombok.Getter; +import java.util.concurrent.atomic.AtomicReference; +import lombok.extern.slf4j.Slf4j; +@Slf4j class FeatureProviderStateManager implements EventProviderListener { private final FeatureProvider delegate; private final AtomicBoolean isInitialized = new AtomicBoolean(); - - @Getter - private ProviderState state = ProviderState.NOT_READY; + private final AtomicReference state = new AtomicReference<>(ProviderState.NOT_READY); public FeatureProviderStateManager(FeatureProvider delegate) { this.delegate = delegate; @@ -24,17 +24,17 @@ public void initialize(EvaluationContext evaluationContext) throws Exception { } try { delegate.initialize(evaluationContext); - state = ProviderState.READY; + setState(ProviderState.READY); } catch (OpenFeatureError openFeatureError) { if (ErrorCode.PROVIDER_FATAL.equals(openFeatureError.getErrorCode())) { - state = ProviderState.FATAL; + setState(ProviderState.FATAL); } else { - state = ProviderState.ERROR; + setState(ProviderState.ERROR); } isInitialized.set(false); throw openFeatureError; } catch (Exception e) { - state = ProviderState.ERROR; + setState(ProviderState.ERROR); isInitialized.set(false); throw e; } @@ -42,7 +42,7 @@ public void initialize(EvaluationContext evaluationContext) throws Exception { public void shutdown() { delegate.shutdown(); - state = ProviderState.NOT_READY; + setState(ProviderState.NOT_READY); isInitialized.set(false); } @@ -50,17 +50,34 @@ public void shutdown() { public void onEmit(ProviderEvent event, ProviderEventDetails details) { if (ProviderEvent.PROVIDER_ERROR.equals(event)) { if (details != null && details.getErrorCode() == ErrorCode.PROVIDER_FATAL) { - state = ProviderState.FATAL; + setState(ProviderState.FATAL); } else { - state = ProviderState.ERROR; + setState(ProviderState.ERROR); } } else if (ProviderEvent.PROVIDER_STALE.equals(event)) { - state = ProviderState.STALE; + setState(ProviderState.STALE); } else if (ProviderEvent.PROVIDER_READY.equals(event)) { - state = ProviderState.READY; + setState(ProviderState.READY); + } + } + + private void setState(ProviderState state) { + ProviderState oldState = this.state.getAndSet(state); + if (oldState != state) { + String providerName; + if (delegate.getMetadata() == null || delegate.getMetadata().getName() == null) { + providerName = "unknown"; + } else { + providerName = delegate.getMetadata().getName(); + } + log.info("Provider {} transitioned from state {} to state {}", providerName, oldState, state); } } + public ProviderState getState() { + return state.get(); + } + FeatureProvider getProvider() { return delegate; } diff --git a/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java b/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java index e8e8b27b0..66fd06d55 100644 --- a/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java +++ b/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java @@ -5,6 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import dev.openfeature.sdk.providers.memory.InMemoryProvider; @@ -112,7 +113,7 @@ void featureProviderTrackIsCalled() throws Exception { api.getClient().track("track-event", new ImmutableContext(), new MutableTrackingEventDetails(22.2f)); verify(featureProvider).initialize(any()); - verify(featureProvider).getMetadata(); + verify(featureProvider, times(2)).getMetadata(); verify(featureProvider).track(any(), any(), any()); } } From f6bd30db93e37e596d211d899315a62d9f810199 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Wed, 14 May 2025 07:57:13 -0400 Subject: [PATCH 246/745] chore: update boostrap sha for release please Creating a new build Signed-off-by: Todd Baert --- release-please-config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release-please-config.json b/release-please-config.json index f1b6ee6bf..bc4fa6b53 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -1,5 +1,5 @@ { - "bootstrap-sha": "c701a6c4ebbe1170a25ca7636a31508b9628831c", + "bootstrap-sha": "d7b591c9f910afad303d6d814f65c7f9dab33b89", "signoff": "OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com>", "packages": { ".": { From cfd95127289d81e2511ae21438ce94ae443b447a Mon Sep 17 00:00:00 2001 From: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> Date: Wed, 14 May 2025 08:12:11 -0400 Subject: [PATCH 247/745] chore(main): release 1.15.1 (#1448) * chore(main): release 1.15.1 Signed-off-by: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> * fixup: change version Signed-off-by: Simon Schrottner --------- Signed-off-by: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> Signed-off-by: Simon Schrottner Co-authored-by: Simon Schrottner --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++-- README.md | 8 ++++---- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 634797f5a..8c4a75878 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"1.15.0"} +{".":"1.15.1"} diff --git a/CHANGELOG.md b/CHANGELOG.md index b18f9cc71..8d2871346 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## [1.15.0](https://github.com/open-feature/java-sdk/compare/v1.14.2...v1.15.0) (2025-05-13) +## [1.15.1](https://github.com/open-feature/java-sdk/compare/v1.14.2...v1.15.1) (2025-05-14) ### NOTABLE CHANGES @@ -18,6 +18,7 @@ ### ✨ New Features +* add logging on provider state transitions ([#1444](https://github.com/open-feature/java-sdk/issues/1444)) ([e2813b2](https://github.com/open-feature/java-sdk/commit/e2813b2e5df8e548caf16e3e425b35962045ca6c)) * add telemetry helper utils ([#1346](https://github.com/open-feature/java-sdk/issues/1346)) ([d0ae548](https://github.com/open-feature/java-sdk/commit/d0ae5482771f4d1701bce25381cdf4e92e2d4882)) * Raise required Java version to 11 ([#1393](https://github.com/open-feature/java-sdk/issues/1393)) ([4dc988b](https://github.com/open-feature/java-sdk/commit/4dc988b637a9e9c377edf7df7b29bf6407319f16)) @@ -42,6 +43,7 @@ * **deps:** update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.3 ([#1399](https://github.com/open-feature/java-sdk/issues/1399)) ([d6ebc16](https://github.com/open-feature/java-sdk/commit/d6ebc161a93ad703e25592abdb0bf0fd9e281bbc)) * **deps:** update dependency org.jacoco:jacoco-maven-plugin to v0.8.13 ([#1407](https://github.com/open-feature/java-sdk/issues/1407)) ([e19ccaa](https://github.com/open-feature/java-sdk/commit/e19ccaa35d9ac4d89d72ea58a70d416d202078db)) * **deps:** update dependency org.mockito:mockito-core to v5.17.0 ([#1409](https://github.com/open-feature/java-sdk/issues/1409)) ([345cdcf](https://github.com/open-feature/java-sdk/commit/345cdcfa10da64c61d769746f335f38ac564e9ad)) +* **deps:** update github/codeql-action digest to 15bce5b ([#1443](https://github.com/open-feature/java-sdk/issues/1443)) ([bc10bac](https://github.com/open-feature/java-sdk/commit/bc10bacb5a68d0d2e498cb41c087505490f19de8)) * **deps:** update github/codeql-action digest to 2a8cbad ([#1423](https://github.com/open-feature/java-sdk/issues/1423)) ([6b6849f](https://github.com/open-feature/java-sdk/commit/6b6849f3a3ee8a7b66d859c8e522bc101d1ccd44)) * **deps:** update github/codeql-action digest to 362ef4c ([#1408](https://github.com/open-feature/java-sdk/issues/1408)) ([ca160ca](https://github.com/open-feature/java-sdk/commit/ca160cab7ccd71527e06a0851502353ac50b8d0d)) * **deps:** update github/codeql-action digest to 40e16ed ([#1437](https://github.com/open-feature/java-sdk/issues/1437)) ([f965cbc](https://github.com/open-feature/java-sdk/commit/f965cbcb37d20724e15b76c15842a88574810b1a)) @@ -51,7 +53,6 @@ * **deps:** update github/codeql-action digest to 5eb3ed6 ([#1439](https://github.com/open-feature/java-sdk/issues/1439)) ([f2348ea](https://github.com/open-feature/java-sdk/commit/f2348ea370412351389c60eef390f36edbea68b0)) * **deps:** update github/codeql-action digest to 83605b3 ([#1435](https://github.com/open-feature/java-sdk/issues/1435)) ([7e74f2a](https://github.com/open-feature/java-sdk/commit/7e74f2aa3ad2dc8f7a3e4ad398e7705b3e3db364)) * **deps:** update github/codeql-action digest to 97a2bfd ([#1438](https://github.com/open-feature/java-sdk/issues/1438)) ([85b200a](https://github.com/open-feature/java-sdk/commit/85b200a08b9f8a71de3b5a19eaa057ec04e0801e)) -* **deps:** update github/codeql-action digest to 9bd18b4 ([#1394](https://github.com/open-feature/java-sdk/issues/1394)) ([d7b591c](https://github.com/open-feature/java-sdk/commit/d7b591c9f910afad303d6d814f65c7f9dab33b89)) * **deps:** update github/codeql-action digest to 9f45e74 ([#1396](https://github.com/open-feature/java-sdk/issues/1396)) ([37d76be](https://github.com/open-feature/java-sdk/commit/37d76be697e83f524250a82b2a67cdb4a953d7bc)) * **deps:** update github/codeql-action digest to d26c46a ([#1413](https://github.com/open-feature/java-sdk/issues/1413)) ([5b327ee](https://github.com/open-feature/java-sdk/commit/5b327eeb770d0a4222f3599be79543b7bed9abc2)) * **deps:** update github/codeql-action digest to dab8a02 ([#1405](https://github.com/open-feature/java-sdk/issues/1405)) ([5b2f151](https://github.com/open-feature/java-sdk/commit/5b2f1513ab75ef6692978830e59eba87ffa494d5)) @@ -62,6 +63,8 @@ * **deps:** update io.cucumber.version to v7.22.0 ([#1410](https://github.com/open-feature/java-sdk/issues/1410)) ([3c69f2f](https://github.com/open-feature/java-sdk/commit/3c69f2f36c4e975d690ecc2e790df632a33001ba)) * **deps:** update io.cucumber.version to v7.22.1 ([#1426](https://github.com/open-feature/java-sdk/issues/1426)) ([844374a](https://github.com/open-feature/java-sdk/commit/844374a42b94deffab6856e978766354a6f46576)) * **deps:** update io.cucumber.version to v7.22.2 ([#1441](https://github.com/open-feature/java-sdk/issues/1441)) ([58454b4](https://github.com/open-feature/java-sdk/commit/58454b4eaabfd3327f7ceaff4bf335a5a839ed41)) +* **main:** release 1.15.0 ([#1431](https://github.com/open-feature/java-sdk/issues/1431)) ([7182a7f](https://github.com/open-feature/java-sdk/commit/7182a7fc4197e70218e829971dae2cff09f948c9)) +* update boostrap sha for release please ([f6bd30d](https://github.com/open-feature/java-sdk/commit/f6bd30db93e37e596d211d899315a62d9f810199)) * update codeowners to give global maintainers code ownership ([#1412](https://github.com/open-feature/java-sdk/issues/1412)) ([498fd38](https://github.com/open-feature/java-sdk/commit/498fd382659669315b0db61db5f19ce054467bc9)) * update release please action ([#1430](https://github.com/open-feature/java-sdk/issues/1430)) ([1cc851b](https://github.com/open-feature/java-sdk/commit/1cc851b293008a8dd273e904e4c77a650ad71146)) * use PAT for release please ([014f8a5](https://github.com/open-feature/java-sdk/commit/014f8a59da8f1e976e440ed1ea17e85561f98e2d)) diff --git a/README.md b/README.md index 3f1a487b3..6593c9b1e 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.15.0 + 1.15.1 ``` @@ -84,7 +84,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:1.15.0' + implementation 'dev.openfeature:sdk:1.15.1' } ``` diff --git a/pom.xml b/pom.xml index 1ae9f9b17..0146f15f8 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ dev.openfeature sdk - 1.15.0 + 1.15.1 [17,) diff --git a/version.txt b/version.txt index 141f2e805..ace44233b 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.15.0 +1.15.1 From d9a72d2aafd787a1814132f000897ad1c94181e4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 May 2025 22:43:05 +0000 Subject: [PATCH 248/745] chore(deps): update github/codeql-action digest to 510dfa3 (#1450) 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 ae3651a3c..d258e0312 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@15bce5bb14748fcfd6fe32738ca1cba36e5f218f + uses: github/codeql-action/init@510dfa3460b15b34a807ab5609b4691aed5ebbee with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@15bce5bb14748fcfd6fe32738ca1cba36e5f218f + uses: github/codeql-action/analyze@510dfa3460b15b34a807ab5609b4691aed5ebbee diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index f9a9cf613..b49e054fa 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@15bce5bb14748fcfd6fe32738ca1cba36e5f218f + uses: github/codeql-action/init@510dfa3460b15b34a807ab5609b4691aed5ebbee with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@15bce5bb14748fcfd6fe32738ca1cba36e5f218f + uses: github/codeql-action/autobuild@510dfa3460b15b34a807ab5609b4691aed5ebbee - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@15bce5bb14748fcfd6fe32738ca1cba36e5f218f + uses: github/codeql-action/analyze@510dfa3460b15b34a807ab5609b4691aed5ebbee From 1714efe81aa6ae025f4f8b12c9c042561498d25e Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Thu, 15 May 2025 11:22:10 -0400 Subject: [PATCH 249/745] chore: improvements to release workflow (#1451) Signed-off-by: Todd Baert Co-authored-by: chrfwow --- .github/workflows/release.yml | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 41d308de1..546747584 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,11 +12,11 @@ permissions: # added using https://github.com/step-security/secure-workflows jobs: release-please: - environment: publish - permissions: - contents: write # for google-github-actions/release-please-action to create release commit - pull-requests: write # for google-github-actions/release-please-action to create release PR runs-on: ubuntu-latest + permissions: + contents: write # for googleapis/release-please-action to create release commit + pull-requests: write # for googleapis/release-please-action to create release PR + issues: write # for googleapis/release-please-action to create labels # Release-please creates a PR that tracks all changes steps: @@ -24,13 +24,22 @@ jobs: id: release with: token: ${{secrets.RELEASE_PLEASE_ACTION_TOKEN}} + outputs: + release_created: ${{ fromJSON(steps.release.outputs.paths_released)[0] != null }} # if we have a single release path, do the release - # These steps are only run if this was a merged release-please PR - - name: checkout - if: ${{ steps.release.outputs.release_created }} + publish: + environment: publish + runs-on: ubuntu-latest + permissions: + contents: read + needs: release-please + if: ${{ fromJSON(needs.release-please.outputs.release_created || false) }} + + steps: + - name: Checkout Repository uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 + - name: Set up JDK 17 - if: ${{ steps.release.outputs.release_created }} uses: actions/setup-java@f4f1212c880fdec8162ea9a6493f4495191887b4 with: java-version: '17' @@ -41,17 +50,15 @@ jobs: server-password: ${{ secrets.OSSRH_PASSWORD }} - name: Configure GPG Key - if: ${{ steps.release.outputs.release_created }} run: | echo -n "$GPG_SIGNING_KEY" | base64 --decode | gpg --import env: GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }} - name: Deploy - if: ${{ steps.release.outputs.release_created }} run: | mvn --batch-mode \ - --settings release/m2-settings.xml clean deploy + --settings release/m2-settings.xml -DskipTests clean deploy env: OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} From b667aa325136b78c01867d40342f81eeb7e16f46 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 May 2025 20:01:17 +0000 Subject: [PATCH 250/745] chore(deps): update github/codeql-action digest to b86edfc (#1453) 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 d258e0312..c9398132d 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@510dfa3460b15b34a807ab5609b4691aed5ebbee + uses: github/codeql-action/init@b86edfc27a1e0d3b55127a7496a1c770a02b2f84 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@510dfa3460b15b34a807ab5609b4691aed5ebbee + uses: github/codeql-action/analyze@b86edfc27a1e0d3b55127a7496a1c770a02b2f84 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index b49e054fa..c63d8876d 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@510dfa3460b15b34a807ab5609b4691aed5ebbee + uses: github/codeql-action/init@b86edfc27a1e0d3b55127a7496a1c770a02b2f84 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@510dfa3460b15b34a807ab5609b4691aed5ebbee + uses: github/codeql-action/autobuild@b86edfc27a1e0d3b55127a7496a1c770a02b2f84 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@510dfa3460b15b34a807ab5609b4691aed5ebbee + uses: github/codeql-action/analyze@b86edfc27a1e0d3b55127a7496a1c770a02b2f84 From e3379395e6bfb0ce811d8372761a3cb015ad2cde Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 16 May 2025 01:40:23 +0000 Subject: [PATCH 251/745] chore(deps): update codecov/codecov-action action to v5.4.3 (#1454) 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 58e096350..c92523417 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -50,7 +50,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.4.2 + uses: codecov/codecov-action@v5.4.3 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 c9398132d..755a4fc04 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.4.2 + uses: codecov/codecov-action@v5.4.3 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From 36eed065e763bbfa0f8f97d704202bbd219332ca Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 16 May 2025 15:06:06 +0000 Subject: [PATCH 252/745] chore(deps): update github/codeql-action digest to 57eebf6 (#1455) 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 755a4fc04..8fbfd3182 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@b86edfc27a1e0d3b55127a7496a1c770a02b2f84 + uses: github/codeql-action/init@57eebf61a2246ab60a0c2f5a85766db783ad3553 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b86edfc27a1e0d3b55127a7496a1c770a02b2f84 + uses: github/codeql-action/analyze@57eebf61a2246ab60a0c2f5a85766db783ad3553 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index c63d8876d..db87c3e3a 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@b86edfc27a1e0d3b55127a7496a1c770a02b2f84 + uses: github/codeql-action/init@57eebf61a2246ab60a0c2f5a85766db783ad3553 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@b86edfc27a1e0d3b55127a7496a1c770a02b2f84 + uses: github/codeql-action/autobuild@57eebf61a2246ab60a0c2f5a85766db783ad3553 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b86edfc27a1e0d3b55127a7496a1c770a02b2f84 + uses: github/codeql-action/analyze@57eebf61a2246ab60a0c2f5a85766db783ad3553 From b45a9370173e3d3b97c78449dfc99225fb572228 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 19 May 2025 23:54:03 +0000 Subject: [PATCH 253/745] chore(deps): update github/codeql-action digest to 396fd27 (#1456) 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 8fbfd3182..9fd72b6de 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@57eebf61a2246ab60a0c2f5a85766db783ad3553 + uses: github/codeql-action/init@396fd27c308b7ab96df64e7e4cb9a7c6e22f4ebc with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@57eebf61a2246ab60a0c2f5a85766db783ad3553 + uses: github/codeql-action/analyze@396fd27c308b7ab96df64e7e4cb9a7c6e22f4ebc diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index db87c3e3a..f0fd3b95e 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@57eebf61a2246ab60a0c2f5a85766db783ad3553 + uses: github/codeql-action/init@396fd27c308b7ab96df64e7e4cb9a7c6e22f4ebc with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@57eebf61a2246ab60a0c2f5a85766db783ad3553 + uses: github/codeql-action/autobuild@396fd27c308b7ab96df64e7e4cb9a7c6e22f4ebc - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@57eebf61a2246ab60a0c2f5a85766db783ad3553 + uses: github/codeql-action/analyze@396fd27c308b7ab96df64e7e4cb9a7c6e22f4ebc From e17b0b29758ae7cdbdac9ddb2178382c55eb1277 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 21 May 2025 04:08:45 +0000 Subject: [PATCH 254/745] chore(deps): update dependency org.mockito:mockito-core to v5.18.0 (#1457) 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 0146f15f8..ff52af7ad 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ ${maven.compiler.source} 5.12.2 7.22.2 - 5.17.0 + 5.18.0 **/e2e/*.java ${project.groupId}.${project.artifactId} From dcbfd265a3875271695af760fce9870e53c69f13 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 22 May 2025 06:29:34 +0000 Subject: [PATCH 255/745] chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.24.0 (#1458) 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 ff52af7ad..6ec4b1fb1 100644 --- a/pom.xml +++ b/pom.xml @@ -457,7 +457,7 @@ com.puppycrawl.tools checkstyle - 10.23.1 + 10.24.0 From 6a95c008e975dd3c7328c32f1d7cf626bbaecfa6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 22 May 2025 22:59:22 +0000 Subject: [PATCH 256/745] chore(deps): update github/codeql-action digest to 7b0fb5a (#1459) 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 9fd72b6de..96cada045 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@396fd27c308b7ab96df64e7e4cb9a7c6e22f4ebc + uses: github/codeql-action/init@7b0fb5a4ac3b38ee6ee9a3ab6ffe59c27e9c4d3b with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@396fd27c308b7ab96df64e7e4cb9a7c6e22f4ebc + uses: github/codeql-action/analyze@7b0fb5a4ac3b38ee6ee9a3ab6ffe59c27e9c4d3b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index f0fd3b95e..1bfc48a62 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@396fd27c308b7ab96df64e7e4cb9a7c6e22f4ebc + uses: github/codeql-action/init@7b0fb5a4ac3b38ee6ee9a3ab6ffe59c27e9c4d3b with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@396fd27c308b7ab96df64e7e4cb9a7c6e22f4ebc + uses: github/codeql-action/autobuild@7b0fb5a4ac3b38ee6ee9a3ab6ffe59c27e9c4d3b - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@396fd27c308b7ab96df64e7e4cb9a7c6e22f4ebc + uses: github/codeql-action/analyze@7b0fb5a4ac3b38ee6ee9a3ab6ffe59c27e9c4d3b From 5e922cf3efc156135563707de92e508b0a4d19f3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 27 May 2025 22:26:25 +0000 Subject: [PATCH 257/745] chore(deps): update github/codeql-action digest to bc02a25 (#1460) 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 96cada045..6ce471baf 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@7b0fb5a4ac3b38ee6ee9a3ab6ffe59c27e9c4d3b + uses: github/codeql-action/init@bc02a25f6449997c5e9d5a368879b28f56ae19a1 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7b0fb5a4ac3b38ee6ee9a3ab6ffe59c27e9c4d3b + uses: github/codeql-action/analyze@bc02a25f6449997c5e9d5a368879b28f56ae19a1 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 1bfc48a62..9405793c7 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@7b0fb5a4ac3b38ee6ee9a3ab6ffe59c27e9c4d3b + uses: github/codeql-action/init@bc02a25f6449997c5e9d5a368879b28f56ae19a1 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@7b0fb5a4ac3b38ee6ee9a3ab6ffe59c27e9c4d3b + uses: github/codeql-action/autobuild@bc02a25f6449997c5e9d5a368879b28f56ae19a1 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7b0fb5a4ac3b38ee6ee9a3ab6ffe59c27e9c4d3b + uses: github/codeql-action/analyze@bc02a25f6449997c5e9d5a368879b28f56ae19a1 From 40b319c5de0461bec13f76978ae09edc958310cd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 28 May 2025 04:12:52 +0000 Subject: [PATCH 258/745] chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v2.44.5 (#1462) 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 6ec4b1fb1..027f477bf 100644 --- a/pom.xml +++ b/pom.xml @@ -473,7 +473,7 @@ com.diffplug.spotless spotless-maven-plugin - 2.44.4 + 2.44.5 From f10aaaa357581b573895f4d6e2329abb705582aa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 28 May 2025 22:25:40 +0000 Subject: [PATCH 259/745] chore(deps): update github/codeql-action digest to 7fd6215 (#1464) 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 6ce471baf..1ee66b175 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@bc02a25f6449997c5e9d5a368879b28f56ae19a1 + uses: github/codeql-action/init@7fd62151d9daff11d4b981415ffb365dcd93f75a with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@bc02a25f6449997c5e9d5a368879b28f56ae19a1 + uses: github/codeql-action/analyze@7fd62151d9daff11d4b981415ffb365dcd93f75a diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 9405793c7..29a95683d 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@bc02a25f6449997c5e9d5a368879b28f56ae19a1 + uses: github/codeql-action/init@7fd62151d9daff11d4b981415ffb365dcd93f75a with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@bc02a25f6449997c5e9d5a368879b28f56ae19a1 + uses: github/codeql-action/autobuild@7fd62151d9daff11d4b981415ffb365dcd93f75a - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@bc02a25f6449997c5e9d5a368879b28f56ae19a1 + uses: github/codeql-action/analyze@7fd62151d9daff11d4b981415ffb365dcd93f75a From 2de76166764bacd34883b13220dd0bad824c8b1a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 29 May 2025 23:00:03 +0000 Subject: [PATCH 260/745] chore(deps): update io.cucumber.version to v7.23.0 (#1465) 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 027f477bf..035a3dcb5 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ 11 ${maven.compiler.source} 5.12.2 - 7.22.2 + 7.23.0 5.18.0 **/e2e/*.java From b6ceff2ecb0e34be2ccdb83f7f37c1177de6f27e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 30 May 2025 02:01:25 +0000 Subject: [PATCH 261/745] chore(deps): update dependency org.codehaus.mojo:exec-maven-plugin to v3.5.1 (#1461) 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 035a3dcb5..c02254e96 100644 --- a/pom.xml +++ b/pom.xml @@ -622,7 +622,7 @@ org.codehaus.mojo exec-maven-plugin - 3.5.0 + 3.5.1 update-test-harness-submodule From 50a6b168a7de40337aa51ef3d79d122030956cb9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 30 May 2025 05:38:25 +0000 Subject: [PATCH 262/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.23.0 (#1466) 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 c02254e96..2f00ce9a8 100644 --- a/pom.xml +++ b/pom.xml @@ -204,7 +204,7 @@ io.cucumber cucumber-bom - 7.22.2 + 7.23.0 pom import From f8260a1c3a345c877eba95bfe41184ad11f6555e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 30 May 2025 21:02:38 +0000 Subject: [PATCH 263/745] fix(deps): update junit5 monorepo (#1467) 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 2f00ce9a8..b9d48d566 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ UTF-8 11 ${maven.compiler.source} - 5.12.2 + 5.13.0 7.23.0 5.18.0 @@ -125,7 +125,7 @@ org.junit.platform junit-platform-suite - 1.12.2 + 1.13.0 test @@ -212,7 +212,7 @@ org.junit junit-bom - 5.12.2 + 5.13.0 pom import From 1558a862497c0e133d11d53ff6d7f28437653d43 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 31 May 2025 21:27:57 +0000 Subject: [PATCH 264/745] chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.25.0 (#1468) 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 b9d48d566..7fb333134 100644 --- a/pom.xml +++ b/pom.xml @@ -457,7 +457,7 @@ com.puppycrawl.tools checkstyle - 10.24.0 + 10.25.0 From 376f81f5c3b66d7e3e298aac30ac7544b84e7362 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Jun 2025 19:28:18 +0000 Subject: [PATCH 265/745] chore(deps): update github/codeql-action digest to 4a00331 (#1469) 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 1ee66b175..7185b39ff 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@7fd62151d9daff11d4b981415ffb365dcd93f75a + uses: github/codeql-action/init@4a00331d4ecf79a214751520faf8e540e60c7567 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7fd62151d9daff11d4b981415ffb365dcd93f75a + uses: github/codeql-action/analyze@4a00331d4ecf79a214751520faf8e540e60c7567 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 29a95683d..2563d859d 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@7fd62151d9daff11d4b981415ffb365dcd93f75a + uses: github/codeql-action/init@4a00331d4ecf79a214751520faf8e540e60c7567 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@7fd62151d9daff11d4b981415ffb365dcd93f75a + uses: github/codeql-action/autobuild@4a00331d4ecf79a214751520faf8e540e60c7567 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7fd62151d9daff11d4b981415ffb365dcd93f75a + uses: github/codeql-action/analyze@4a00331d4ecf79a214751520faf8e540e60c7567 From 6597de7a98e0fae10a541a8a9b60837623c133a8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Jun 2025 18:05:22 +0000 Subject: [PATCH 266/745] chore(deps): update github/codeql-action digest to 075e08a (#1470) 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 7185b39ff..578dfa453 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@4a00331d4ecf79a214751520faf8e540e60c7567 + uses: github/codeql-action/init@075e08aca6be12984ae56ae245bd0767609134f2 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4a00331d4ecf79a214751520faf8e540e60c7567 + uses: github/codeql-action/analyze@075e08aca6be12984ae56ae245bd0767609134f2 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 2563d859d..4273ba2d3 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@4a00331d4ecf79a214751520faf8e540e60c7567 + uses: github/codeql-action/init@075e08aca6be12984ae56ae245bd0767609134f2 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@4a00331d4ecf79a214751520faf8e540e60c7567 + uses: github/codeql-action/autobuild@075e08aca6be12984ae56ae245bd0767609134f2 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4a00331d4ecf79a214751520faf8e540e60c7567 + uses: github/codeql-action/analyze@075e08aca6be12984ae56ae245bd0767609134f2 From 3ed65cfb0cb5ee5b70793cd68a27909c81cd4fab Mon Sep 17 00:00:00 2001 From: Simon Schrottner Date: Wed, 4 Jun 2025 16:44:38 +0200 Subject: [PATCH 267/745] chore: remove unneeded version information (#1428) Signed-off-by: Simon Schrottner --- pom.xml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/pom.xml b/pom.xml index 7fb333134..052f1c6cd 100644 --- a/pom.xml +++ b/pom.xml @@ -12,8 +12,6 @@ UTF-8 11 ${maven.compiler.source} - 5.13.0 - 7.23.0 5.18.0 **/e2e/*.java @@ -97,56 +95,48 @@ org.junit.jupiter junit-jupiter - ${junit.jupiter.version} test org.junit.jupiter junit-jupiter-engine - ${junit.jupiter.version} test org.junit.jupiter junit-jupiter-api - ${junit.jupiter.version} test org.junit.jupiter junit-jupiter-params - ${junit.jupiter.version} test org.junit.platform junit-platform-suite - 1.13.0 test io.cucumber cucumber-java - ${io.cucumber.version} test io.cucumber cucumber-junit-platform-engine - ${io.cucumber.version} test io.cucumber cucumber-picocontainer - ${io.cucumber.version} test From 2dcd6a1dd0c80ee676b9860afd6a6002d0ea4aea Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Jun 2025 06:27:45 +0000 Subject: [PATCH 268/745] chore(deps): update github/codeql-action digest to b1e4dc3 (#1471) 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 578dfa453..a711d4b34 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@075e08aca6be12984ae56ae245bd0767609134f2 + uses: github/codeql-action/init@b1e4dc3db58c9601794e22a9f6d28d45461b9dbf with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@075e08aca6be12984ae56ae245bd0767609134f2 + uses: github/codeql-action/analyze@b1e4dc3db58c9601794e22a9f6d28d45461b9dbf diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 4273ba2d3..c567e9d0f 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@075e08aca6be12984ae56ae245bd0767609134f2 + uses: github/codeql-action/init@b1e4dc3db58c9601794e22a9f6d28d45461b9dbf with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@075e08aca6be12984ae56ae245bd0767609134f2 + uses: github/codeql-action/autobuild@b1e4dc3db58c9601794e22a9f6d28d45461b9dbf - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@075e08aca6be12984ae56ae245bd0767609134f2 + uses: github/codeql-action/analyze@b1e4dc3db58c9601794e22a9f6d28d45461b9dbf From 545d6aac09dbc74c00a0a4e5c26f4ef80be22379 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 7 Jun 2025 13:08:10 +0000 Subject: [PATCH 269/745] fix(deps): update dependency org.junit:junit-bom to v5.13.1 (#1475) 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 052f1c6cd..4f36c2689 100644 --- a/pom.xml +++ b/pom.xml @@ -202,7 +202,7 @@ org.junit junit-bom - 5.13.0 + 5.13.1 pom import From b5d873e44d3c41b42f11569b0fafccc0a002ebdd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 7 Jun 2025 17:39:13 +0000 Subject: [PATCH 270/745] chore(deps): update actions/checkout digest to 09d2aca (#1473) 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 +- .github/workflows/static-code-scanning.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index c92523417..77a649385 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 + - uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f - name: Set up JDK 17 uses: actions/setup-java@f4f1212c880fdec8162ea9a6493f4495191887b4 with: diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index a711d4b34..1cde047fb 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -19,7 +19,7 @@ jobs: runs-on: ${{ matrix.os}} steps: - name: Check out the code - uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 + uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f - name: Set up JDK 11 uses: actions/setup-java@f4f1212c880fdec8162ea9a6493f4495191887b4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 546747584..61df7d93e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,7 +37,7 @@ jobs: steps: - name: Checkout Repository - uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 + uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f - name: Set up JDK 17 uses: actions/setup-java@f4f1212c880fdec8162ea9a6493f4495191887b4 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index c567e9d0f..cb9c940c4 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 + uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL From 4481537cebc213dcfe19bb8cd9b70a4c91a682b2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 7 Jun 2025 21:59:01 +0000 Subject: [PATCH 271/745] chore(deps): update dependency maven to v3.9.10 (#1474) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .mvn/wrapper/maven-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index d58dfb70b..2f94e6169 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -16,4 +16,4 @@ # under the License. wrapperVersion=3.3.2 distributionType=only-script -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.10/apache-maven-3.9.10-bin.zip From 6cca721be5bc6f5926fe64668a7c03728cab3cb0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 10 Jun 2025 01:27:44 +0000 Subject: [PATCH 272/745] chore(deps): update github/codeql-action digest to 7cb9b16 (#1476) 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 1cde047fb..e3b4f4aca 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@b1e4dc3db58c9601794e22a9f6d28d45461b9dbf + uses: github/codeql-action/init@7cb9b16051842e6c23c8b9fbcf92481f92d0644a with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b1e4dc3db58c9601794e22a9f6d28d45461b9dbf + uses: github/codeql-action/analyze@7cb9b16051842e6c23c8b9fbcf92481f92d0644a diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index cb9c940c4..55764e9bf 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@b1e4dc3db58c9601794e22a9f6d28d45461b9dbf + uses: github/codeql-action/init@7cb9b16051842e6c23c8b9fbcf92481f92d0644a with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@b1e4dc3db58c9601794e22a9f6d28d45461b9dbf + uses: github/codeql-action/autobuild@7cb9b16051842e6c23c8b9fbcf92481f92d0644a - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b1e4dc3db58c9601794e22a9f6d28d45461b9dbf + uses: github/codeql-action/analyze@7cb9b16051842e6c23c8b9fbcf92481f92d0644a From 3dd7d5d4262f1f4461e13c13a7d64d2fa8bfd764 Mon Sep 17 00:00:00 2001 From: chrfwow Date: Tue, 10 Jun 2025 17:27:15 +0200 Subject: [PATCH 273/745] feat: add means of awaiting event emission, fix flaky build (#1463) ## This PR - adds the ability to await event emissions by returning a new construct - uses this construct in tests :warning: in rare cases, this could be a breaking change, but the events API is currently experimental, so we will not do a major version ubmp ### Related Issues Fixes #1449 --- .../java/dev/openfeature/sdk/Awaitable.java | 44 +++++++++++ .../dev/openfeature/sdk/EventProvider.java | 47 ++++++++---- .../dev/openfeature/sdk/EventSupport.java | 28 +++---- .../dev/openfeature/sdk/AwaitableTest.java | 75 +++++++++++++++++++ .../sdk/DeveloperExperienceTest.java | 8 +- .../openfeature/sdk/EventProviderTest.java | 1 + .../java/dev/openfeature/sdk/EventsTest.java | 12 +-- .../memory/InMemoryProviderTest.java | 18 ++++- 8 files changed, 189 insertions(+), 44 deletions(-) create mode 100644 src/main/java/dev/openfeature/sdk/Awaitable.java create mode 100644 src/test/java/dev/openfeature/sdk/AwaitableTest.java diff --git a/src/main/java/dev/openfeature/sdk/Awaitable.java b/src/main/java/dev/openfeature/sdk/Awaitable.java new file mode 100644 index 000000000..7d5f477dc --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/Awaitable.java @@ -0,0 +1,44 @@ +package dev.openfeature.sdk; + +/** + * A class to help with synchronization by allowing the optional awaiting of the associated action. + */ +public class Awaitable { + + /** + * An already-completed Awaitable. Awaiting this will return immediately. + */ + public static final Awaitable FINISHED = new Awaitable(true); + + private boolean isDone = false; + + public Awaitable() {} + + private Awaitable(boolean isDone) { + this.isDone = isDone; + } + + /** + * Lets the calling thread wait until some other thread calls {@link Awaitable#wakeup()}. If + * {@link Awaitable#wakeup()} has been called before the current thread invokes this method, it will return + * immediately. + */ + @SuppressWarnings("java:S2142") + public synchronized void await() { + while (!isDone) { + try { + this.wait(); + } catch (InterruptedException ignored) { + // ignored, do not propagate the interrupted state + } + } + } + + /** + * Wakes up all threads that have called {@link Awaitable#await()} and lets them proceed. + */ + public synchronized void wakeup() { + isDone = true; + this.notifyAll(); + } +} diff --git a/src/main/java/dev/openfeature/sdk/EventProvider.java b/src/main/java/dev/openfeature/sdk/EventProvider.java index 659c6ad46..0d7e897c2 100644 --- a/src/main/java/dev/openfeature/sdk/EventProvider.java +++ b/src/main/java/dev/openfeature/sdk/EventProvider.java @@ -76,15 +76,32 @@ public void shutdown() { * @param event The event type * @param details The details of the event */ - public void emit(ProviderEvent event, ProviderEventDetails details) { - if (eventProviderListener != null) { - eventProviderListener.onEmit(event, details); - } + public Awaitable emit(final ProviderEvent event, final ProviderEventDetails details) { + final var localEventProviderListener = this.eventProviderListener; + final var localOnEmit = this.onEmit; - final TriConsumer localOnEmit = this.onEmit; - if (localOnEmit != null) { - emitterExecutor.submit(() -> localOnEmit.accept(this, event, details)); + if (localEventProviderListener == null && localOnEmit == null) { + return Awaitable.FINISHED; } + + final var awaitable = new Awaitable(); + + // These calls need to be executed on a different thread to prevent deadlocks when the provider initialization + // relies on a ready event to be emitted + emitterExecutor.submit(() -> { + try (var ignored = OpenFeatureAPI.lock.readLockAutoCloseable()) { + if (localEventProviderListener != null) { + localEventProviderListener.onEmit(event, details); + } + if (localOnEmit != null) { + localOnEmit.accept(this, event, details); + } + } finally { + awaitable.wakeup(); + } + }); + + return awaitable; } /** @@ -93,8 +110,8 @@ public void emit(ProviderEvent event, ProviderEventDetails details) { * * @param details The details of the event */ - public void emitProviderReady(ProviderEventDetails details) { - emit(ProviderEvent.PROVIDER_READY, details); + public Awaitable emitProviderReady(ProviderEventDetails details) { + return emit(ProviderEvent.PROVIDER_READY, details); } /** @@ -104,8 +121,8 @@ public void emitProviderReady(ProviderEventDetails details) { * * @param details The details of the event */ - public void emitProviderConfigurationChanged(ProviderEventDetails details) { - emit(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, details); + public Awaitable emitProviderConfigurationChanged(ProviderEventDetails details) { + return emit(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, details); } /** @@ -114,8 +131,8 @@ public void emitProviderConfigurationChanged(ProviderEventDetails details) { * * @param details The details of the event */ - public void emitProviderStale(ProviderEventDetails details) { - emit(ProviderEvent.PROVIDER_STALE, details); + public Awaitable emitProviderStale(ProviderEventDetails details) { + return emit(ProviderEvent.PROVIDER_STALE, details); } /** @@ -124,7 +141,7 @@ public void emitProviderStale(ProviderEventDetails details) { * * @param details The details of the event */ - public void emitProviderError(ProviderEventDetails details) { - emit(ProviderEvent.PROVIDER_ERROR, details); + public Awaitable emitProviderError(ProviderEventDetails details) { + return emit(ProviderEvent.PROVIDER_ERROR, details); } } diff --git a/src/main/java/dev/openfeature/sdk/EventSupport.java b/src/main/java/dev/openfeature/sdk/EventSupport.java index 5ebe90a4c..8396795bd 100644 --- a/src/main/java/dev/openfeature/sdk/EventSupport.java +++ b/src/main/java/dev/openfeature/sdk/EventSupport.java @@ -1,12 +1,12 @@ package dev.openfeature.sdk; -import java.util.ArrayList; -import java.util.List; +import java.util.Collection; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -23,13 +23,10 @@ class EventSupport { // we use a v4 uuid as a "placeholder" for anonymous clients, since // ConcurrentHashMap doesn't support nulls - private static final String defaultClientUuid = UUID.randomUUID().toString(); + private static final String DEFAULT_CLIENT_UUID = UUID.randomUUID().toString(); private final Map handlerStores = new ConcurrentHashMap<>(); private final HandlerStore globalHandlerStore = new HandlerStore(); - private final ExecutorService taskExecutor = Executors.newCachedThreadPool(runnable -> { - final Thread thread = new Thread(runnable); - return thread; - }); + private final ExecutorService taskExecutor = Executors.newCachedThreadPool(); /** * Run all the event handlers associated with this domain. @@ -40,11 +37,10 @@ class EventSupport { * @param eventDetails the event details */ public void runClientHandlers(String domain, ProviderEvent event, EventDetails eventDetails) { - domain = Optional.ofNullable(domain).orElse(defaultClientUuid); + domain = Optional.ofNullable(domain).orElse(DEFAULT_CLIENT_UUID); // run handlers if they exist Optional.ofNullable(handlerStores.get(domain)) - .filter(store -> Optional.of(store).isPresent()) .map(store -> store.handlerMap.get(event)) .ifPresent(handlers -> handlers.forEach(handler -> runHandler(handler, eventDetails))); } @@ -69,7 +65,7 @@ public void runGlobalHandlers(ProviderEvent event, EventDetails eventDetails) { * @param handler the handler function to run */ public void addClientHandler(String domain, ProviderEvent event, Consumer handler) { - final String name = Optional.ofNullable(domain).orElse(defaultClientUuid); + final String name = Optional.ofNullable(domain).orElse(DEFAULT_CLIENT_UUID); // lazily create and cache a HandlerStore if it doesn't exist HandlerStore store = Optional.ofNullable(this.handlerStores.get(name)).orElseGet(() -> { @@ -89,7 +85,7 @@ public void addClientHandler(String domain, ProviderEvent event, Consumer handler) { - domain = Optional.ofNullable(domain).orElse(defaultClientUuid); + domain = Optional.ofNullable(domain).orElse(DEFAULT_CLIENT_UUID); this.handlerStores.get(domain).removeHandler(event, handler); } @@ -160,14 +156,14 @@ public void shutdown() { // instantiated when a handler is added to that client. static class HandlerStore { - private final Map>> handlerMap; + private final Map>> handlerMap; HandlerStore() { handlerMap = new ConcurrentHashMap<>(); - handlerMap.put(ProviderEvent.PROVIDER_READY, new ArrayList<>()); - handlerMap.put(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, new ArrayList<>()); - handlerMap.put(ProviderEvent.PROVIDER_ERROR, new ArrayList<>()); - handlerMap.put(ProviderEvent.PROVIDER_STALE, new ArrayList<>()); + handlerMap.put(ProviderEvent.PROVIDER_READY, new ConcurrentLinkedQueue<>()); + handlerMap.put(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, new ConcurrentLinkedQueue<>()); + handlerMap.put(ProviderEvent.PROVIDER_ERROR, new ConcurrentLinkedQueue<>()); + handlerMap.put(ProviderEvent.PROVIDER_STALE, new ConcurrentLinkedQueue<>()); } void addHandler(ProviderEvent event, Consumer handler) { diff --git a/src/test/java/dev/openfeature/sdk/AwaitableTest.java b/src/test/java/dev/openfeature/sdk/AwaitableTest.java new file mode 100644 index 000000000..70ef7902c --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/AwaitableTest.java @@ -0,0 +1,75 @@ +package dev.openfeature.sdk; + +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; + +@Timeout(value = 5, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) +class AwaitableTest { + @Test + void waitingForFinishedIsANoOp() { + var startTime = System.currentTimeMillis(); + Awaitable.FINISHED.await(); + var endTime = System.currentTimeMillis(); + assertTrue(endTime - startTime < 10); + } + + @Test + void waitingForNotFinishedWaitsEvenWhenInterrupted() throws InterruptedException { + var awaitable = new Awaitable(); + var mayProceed = new AtomicBoolean(false); + + var thread = new Thread(() -> { + awaitable.await(); + if (!mayProceed.get()) { + fail(); + } + }); + thread.start(); + + var startTime = System.currentTimeMillis(); + do { + thread.interrupt(); + } while (startTime + 1000 > System.currentTimeMillis()); + mayProceed.set(true); + awaitable.wakeup(); + thread.join(); + } + + @Test + void callingWakeUpWakesUpAllWaitingThreads() throws InterruptedException { + var awaitable = new Awaitable(); + var isRunning = new AtomicInteger(); + + Runnable runnable = () -> { + isRunning.incrementAndGet(); + var start = System.currentTimeMillis(); + awaitable.await(); + var end = System.currentTimeMillis(); + if (end - start > 10) { + fail(); + } + }; + + var numThreads = 2; + var threads = new Thread[numThreads]; + for (int i = 0; i < numThreads; i++) { + threads[i] = new Thread(runnable); + threads[i].start(); + } + + await().atMost(1, TimeUnit.SECONDS).until(() -> isRunning.get() == numThreads); + + awaitable.wakeup(); + + for (int i = 0; i < numThreads; i++) { + threads[i].join(); + } + } +} diff --git a/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java b/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java index 32fa605c2..c954c8b19 100644 --- a/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java +++ b/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java @@ -150,7 +150,7 @@ void shouldPutTheProviderInStateErrorAfterEmittingErrorEvent() { api.setProviderAndWait(domain, provider); Client client = api.getClient(domain); assertThat(client.getProviderState()).isEqualTo(ProviderState.READY); - provider.emitProviderError(ProviderEventDetails.builder().build()); + provider.emitProviderError(ProviderEventDetails.builder().build()).await(); assertThat(client.getProviderState()).isEqualTo(ProviderState.ERROR); } @@ -165,7 +165,7 @@ void shouldPutTheProviderInStateStaleAfterEmittingStaleEvent() { api.setProviderAndWait(domain, provider); Client client = api.getClient(domain); assertThat(client.getProviderState()).isEqualTo(ProviderState.READY); - provider.emitProviderStale(ProviderEventDetails.builder().build()); + provider.emitProviderStale(ProviderEventDetails.builder().build()).await(); assertThat(client.getProviderState()).isEqualTo(ProviderState.STALE); } @@ -180,9 +180,9 @@ void shouldPutTheProviderInStateReadyAfterEmittingReadyEvent() { api.setProviderAndWait(domain, provider); Client client = api.getClient(domain); assertThat(client.getProviderState()).isEqualTo(ProviderState.READY); - provider.emitProviderStale(ProviderEventDetails.builder().build()); + provider.emitProviderStale(ProviderEventDetails.builder().build()).await(); assertThat(client.getProviderState()).isEqualTo(ProviderState.STALE); - provider.emitProviderReady(ProviderEventDetails.builder().build()); + provider.emitProviderReady(ProviderEventDetails.builder().build()).await(); assertThat(client.getProviderState()).isEqualTo(ProviderState.READY); } } diff --git a/src/test/java/dev/openfeature/sdk/EventProviderTest.java b/src/test/java/dev/openfeature/sdk/EventProviderTest.java index ebf8901cb..d04fa88d1 100644 --- a/src/test/java/dev/openfeature/sdk/EventProviderTest.java +++ b/src/test/java/dev/openfeature/sdk/EventProviderTest.java @@ -32,6 +32,7 @@ public static void resetDefaultProvider() { } @Test + @Timeout(value = 2, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) @DisplayName("should run attached onEmit with emitters") void emitsEventsWhenAttached() { TriConsumer onEmit = mockOnEmit(); diff --git a/src/test/java/dev/openfeature/sdk/EventsTest.java b/src/test/java/dev/openfeature/sdk/EventsTest.java index 157c0bafe..b232f1177 100644 --- a/src/test/java/dev/openfeature/sdk/EventsTest.java +++ b/src/test/java/dev/openfeature/sdk/EventsTest.java @@ -24,7 +24,7 @@ class EventsTest { private OpenFeatureAPI api; @BeforeEach - public void setUp() throws Exception { + void setUp() { api = new OpenFeatureAPI(); } @@ -578,7 +578,7 @@ void shouldHaveAllProperties() { number = "5.3.3", text = "Handlers attached after the provider is already in the associated state, MUST run immediately.") void matchingReadyEventsMustRunImmediately() { - final String name = "matchingEventsMustRunImmediately"; + final String name = "matchingReadyEventsMustRunImmediately"; final Consumer handler = mockHandler(); // provider which is already ready @@ -597,14 +597,14 @@ void matchingReadyEventsMustRunImmediately() { number = "5.3.3", text = "Handlers attached after the provider is already in the associated state, MUST run immediately.") void matchingStaleEventsMustRunImmediately() { - final String name = "matchingEventsMustRunImmediately"; + final String name = "matchingStaleEventsMustRunImmediately"; final Consumer handler = mockHandler(); // provider which is already stale TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); Client client = api.getClient(name); api.setProviderAndWait(name, provider); - provider.emitProviderStale(ProviderEventDetails.builder().build()); + provider.emitProviderStale(ProviderEventDetails.builder().build()).await(); assertThat(client.getProviderState()).isEqualTo(ProviderState.STALE); // should run even though handler was added after stale @@ -618,14 +618,14 @@ void matchingStaleEventsMustRunImmediately() { number = "5.3.3", text = "Handlers attached after the provider is already in the associated state, MUST run immediately.") void matchingErrorEventsMustRunImmediately() { - final String name = "matchingEventsMustRunImmediately"; + final String name = "matchingErrorEventsMustRunImmediately"; final Consumer handler = mockHandler(); // provider which is already in error TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); Client client = api.getClient(name); api.setProviderAndWait(name, provider); - provider.emitProviderError(ProviderEventDetails.builder().build()); + provider.emitProviderError(ProviderEventDetails.builder().build()).await(); assertThat(client.getProviderState()).isEqualTo(ProviderState.ERROR); verify(handler, never()).accept(any()); 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 4d2a8b287..970495940 100644 --- a/src/test/java/dev/openfeature/sdk/providers/memory/InMemoryProviderTest.java +++ b/src/test/java/dev/openfeature/sdk/providers/memory/InMemoryProviderTest.java @@ -3,9 +3,14 @@ import static dev.openfeature.sdk.Structure.mapToStructure; import static dev.openfeature.sdk.testutils.TestFlagsUtils.buildFlags; import static org.awaitility.Awaitility.await; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import com.google.common.collect.ImmutableMap; import dev.openfeature.sdk.Client; @@ -19,6 +24,7 @@ import dev.openfeature.sdk.exceptions.TypeMismatchError; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import lombok.SneakyThrows; import org.junit.jupiter.api.BeforeEach; @@ -34,10 +40,11 @@ class InMemoryProviderTest { @SneakyThrows @BeforeEach void beforeEach() { + final var configChangedEventCounter = new AtomicInteger(); Map> flags = buildFlags(); provider = spy(new InMemoryProvider(flags)); api = OpenFeatureAPITestUtil.createAPI(); - api.onProviderConfigurationChanged(eventDetails -> {}); + api.onProviderConfigurationChanged(eventDetails -> configChangedEventCounter.incrementAndGet()); api.setProviderAndWait(provider); client = api.getClient(); provider.updateFlags(flags); @@ -48,6 +55,11 @@ void beforeEach() { .variant("off", false) .defaultVariant("on") .build()); + + // wait for the two config changed events to be fired, otherwise they could mess with our tests + while (configChangedEventCounter.get() < 2) { + Thread.sleep(1); + } } @Test From 0b57bcafc14b946000feb4a3421d73b9616e83cb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 11 Jun 2025 21:43:28 +0000 Subject: [PATCH 274/745] chore(deps): update github/codeql-action digest to 466d6ce (#1477) 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 e3b4f4aca..5537d253f 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@7cb9b16051842e6c23c8b9fbcf92481f92d0644a + uses: github/codeql-action/init@466d6ce58447f9589003cca18ec288b128465541 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7cb9b16051842e6c23c8b9fbcf92481f92d0644a + uses: github/codeql-action/analyze@466d6ce58447f9589003cca18ec288b128465541 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 55764e9bf..e3f9d39ca 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@7cb9b16051842e6c23c8b9fbcf92481f92d0644a + uses: github/codeql-action/init@466d6ce58447f9589003cca18ec288b128465541 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@7cb9b16051842e6c23c8b9fbcf92481f92d0644a + uses: github/codeql-action/autobuild@466d6ce58447f9589003cca18ec288b128465541 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7cb9b16051842e6c23c8b9fbcf92481f92d0644a + uses: github/codeql-action/analyze@466d6ce58447f9589003cca18ec288b128465541 From 844d5e244b02703b624cf75e5bf8448c07e62d3d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 13 Jun 2025 18:52:24 +0000 Subject: [PATCH 275/745] chore(deps): update github/codeql-action digest to be30325 (#1479) 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 5537d253f..5dfbb656f 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@466d6ce58447f9589003cca18ec288b128465541 + uses: github/codeql-action/init@be30325fa679497c9a67f006166793cfa1d5840d with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@466d6ce58447f9589003cca18ec288b128465541 + uses: github/codeql-action/analyze@be30325fa679497c9a67f006166793cfa1d5840d diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index e3f9d39ca..d0f39dafc 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@466d6ce58447f9589003cca18ec288b128465541 + uses: github/codeql-action/init@be30325fa679497c9a67f006166793cfa1d5840d with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@466d6ce58447f9589003cca18ec288b128465541 + uses: github/codeql-action/autobuild@be30325fa679497c9a67f006166793cfa1d5840d - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@466d6ce58447f9589003cca18ec288b128465541 + uses: github/codeql-action/analyze@be30325fa679497c9a67f006166793cfa1d5840d From 8e51e6fe101882184a5d09be31fa65563d82c673 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Jun 2025 18:37:11 +0200 Subject: [PATCH 276/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.17.6 (#1482) 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 4f36c2689..664210c66 100644 --- a/pom.xml +++ b/pom.xml @@ -179,7 +179,7 @@ net.bytebuddy byte-buddy - 1.17.5 + 1.17.6 test From 99a3006de878ab0ba1f0e61a4cb5432914425795 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Jun 2025 16:44:00 +0000 Subject: [PATCH 277/745] chore(deps): update github/codeql-action digest to 3de706a (#1481) 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 5dfbb656f..53d32e03f 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@be30325fa679497c9a67f006166793cfa1d5840d + uses: github/codeql-action/init@3de706a4a34b7e2fe37e4a10aecbdd3ec5dc0664 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@be30325fa679497c9a67f006166793cfa1d5840d + uses: github/codeql-action/analyze@3de706a4a34b7e2fe37e4a10aecbdd3ec5dc0664 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index d0f39dafc..b90bb964b 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@be30325fa679497c9a67f006166793cfa1d5840d + uses: github/codeql-action/init@3de706a4a34b7e2fe37e4a10aecbdd3ec5dc0664 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@be30325fa679497c9a67f006166793cfa1d5840d + uses: github/codeql-action/autobuild@3de706a4a34b7e2fe37e4a10aecbdd3ec5dc0664 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@be30325fa679497c9a67f006166793cfa1d5840d + uses: github/codeql-action/analyze@3de706a4a34b7e2fe37e4a10aecbdd3ec5dc0664 From 936ff60fac471a83a7c14412d2e825b2a7f9704c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Jun 2025 16:50:34 +0000 Subject: [PATCH 278/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.17.6 (#1483) 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 664210c66..e7b875bfc 100644 --- a/pom.xml +++ b/pom.xml @@ -186,7 +186,7 @@ net.bytebuddy byte-buddy-agent - 1.17.5 + 1.17.6 test From 8bf777a7e99be4dfac8917b8e61cb6c23385b8ce Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 17 Jun 2025 04:48:36 +0000 Subject: [PATCH 279/745] chore(deps): update github/codeql-action digest to ef36b69 (#1484) 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 53d32e03f..440023909 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@3de706a4a34b7e2fe37e4a10aecbdd3ec5dc0664 + uses: github/codeql-action/init@ef36b69c6d7c22bd9d0183f534d82d47639dc745 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3de706a4a34b7e2fe37e4a10aecbdd3ec5dc0664 + uses: github/codeql-action/analyze@ef36b69c6d7c22bd9d0183f534d82d47639dc745 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index b90bb964b..d914fe240 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@3de706a4a34b7e2fe37e4a10aecbdd3ec5dc0664 + uses: github/codeql-action/init@ef36b69c6d7c22bd9d0183f534d82d47639dc745 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@3de706a4a34b7e2fe37e4a10aecbdd3ec5dc0664 + uses: github/codeql-action/autobuild@ef36b69c6d7c22bd9d0183f534d82d47639dc745 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3de706a4a34b7e2fe37e4a10aecbdd3ec5dc0664 + uses: github/codeql-action/analyze@ef36b69c6d7c22bd9d0183f534d82d47639dc745 From 7c2af57a362ee11f757a431ee17eff3ee448bf6c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 17 Jun 2025 20:05:59 +0000 Subject: [PATCH 280/745] chore(deps): update actions/cache digest to 640a1c2 (#1485) 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 77a649385..6e50995a9 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -33,7 +33,7 @@ jobs: server-password: ${{ secrets.OSSRH_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 + uses: actions/cache@640a1c2554105b57832a23eea0b4672fc7a790d5 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 440023909..6ad2a03e2 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@5a3ec84eff668545956fd18022155c47e93e2684 + uses: actions/cache@640a1c2554105b57832a23eea0b4672fc7a790d5 with: path: ~/.m2/repository key: ${{ runner.os }}${{ matrix.build.java }}-maven-${{ hashFiles('**/pom.xml') }} From c3eaecdb8b34d3b33946bd205ee92d49584602bd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 20 Jun 2025 01:25:24 +0000 Subject: [PATCH 281/745] chore(deps): update github/codeql-action digest to 66d7255 (#1487) 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 6ad2a03e2..3ac011ce5 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@ef36b69c6d7c22bd9d0183f534d82d47639dc745 + uses: github/codeql-action/init@66d72553a22659994d73473ae27a699b25587b48 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ef36b69c6d7c22bd9d0183f534d82d47639dc745 + uses: github/codeql-action/analyze@66d72553a22659994d73473ae27a699b25587b48 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index d914fe240..478a26250 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@ef36b69c6d7c22bd9d0183f534d82d47639dc745 + uses: github/codeql-action/init@66d72553a22659994d73473ae27a699b25587b48 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@ef36b69c6d7c22bd9d0183f534d82d47639dc745 + uses: github/codeql-action/autobuild@66d72553a22659994d73473ae27a699b25587b48 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ef36b69c6d7c22bd9d0183f534d82d47639dc745 + uses: github/codeql-action/analyze@66d72553a22659994d73473ae27a699b25587b48 From 8fad544b17ee08b4280d7975073d00a874c374db Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 20 Jun 2025 19:08:37 +0000 Subject: [PATCH 282/745] chore(deps): update github/codeql-action digest to ac30a39 (#1488) 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 3ac011ce5..7622ecef2 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@66d72553a22659994d73473ae27a699b25587b48 + uses: github/codeql-action/init@ac30a39d8c6142a41d62949496fef51750e6f1bf with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@66d72553a22659994d73473ae27a699b25587b48 + uses: github/codeql-action/analyze@ac30a39d8c6142a41d62949496fef51750e6f1bf diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 478a26250..08811ea73 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@66d72553a22659994d73473ae27a699b25587b48 + uses: github/codeql-action/init@ac30a39d8c6142a41d62949496fef51750e6f1bf with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@66d72553a22659994d73473ae27a699b25587b48 + uses: github/codeql-action/autobuild@ac30a39d8c6142a41d62949496fef51750e6f1bf - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@66d72553a22659994d73473ae27a699b25587b48 + uses: github/codeql-action/analyze@ac30a39d8c6142a41d62949496fef51750e6f1bf From 312b6df5d2c891ac758bf398f8399ecd25b7597e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 21 Jun 2025 21:10:50 +0000 Subject: [PATCH 283/745] chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.25.1 (#1489) 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 e7b875bfc..67b4c5722 100644 --- a/pom.xml +++ b/pom.xml @@ -447,7 +447,7 @@ com.puppycrawl.tools checkstyle - 10.25.0 + 10.25.1 From e67f5983573afff805a56ef18584d1a7291ccafc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Jun 2025 22:42:58 +0000 Subject: [PATCH 284/745] chore(deps): update actions/setup-java digest to ebb356c (#1490) 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 6e50995a9..37295eb31 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -23,7 +23,7 @@ jobs: steps: - uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f - name: Set up JDK 17 - uses: actions/setup-java@f4f1212c880fdec8162ea9a6493f4495191887b4 + uses: actions/setup-java@ebb356cc4e59bcf94f518203228485f5d40e4b58 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 7622ecef2..8defbae23 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -22,7 +22,7 @@ jobs: uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f - name: Set up JDK 11 - uses: actions/setup-java@f4f1212c880fdec8162ea9a6493f4495191887b4 + uses: actions/setup-java@ebb356cc4e59bcf94f518203228485f5d40e4b58 with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 61df7d93e..53141b448 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,7 +40,7 @@ jobs: uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f - name: Set up JDK 17 - uses: actions/setup-java@f4f1212c880fdec8162ea9a6493f4495191887b4 + uses: actions/setup-java@ebb356cc4e59bcf94f518203228485f5d40e4b58 with: java-version: '17' distribution: 'temurin' From 6f67b06f712c461f331681a76f5cb2c3ddb0d36b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 24 Jun 2025 20:50:48 +0000 Subject: [PATCH 285/745] chore(deps): update github/codeql-action digest to 9b02dc2 (#1491) 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 8defbae23..61ab2e54c 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@ac30a39d8c6142a41d62949496fef51750e6f1bf + uses: github/codeql-action/init@9b02dc2f60288b463e7a66e39c78829b62780db7 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ac30a39d8c6142a41d62949496fef51750e6f1bf + uses: github/codeql-action/analyze@9b02dc2f60288b463e7a66e39c78829b62780db7 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 08811ea73..7d113656c 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@ac30a39d8c6142a41d62949496fef51750e6f1bf + uses: github/codeql-action/init@9b02dc2f60288b463e7a66e39c78829b62780db7 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@ac30a39d8c6142a41d62949496fef51750e6f1bf + uses: github/codeql-action/autobuild@9b02dc2f60288b463e7a66e39c78829b62780db7 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ac30a39d8c6142a41d62949496fef51750e6f1bf + uses: github/codeql-action/analyze@9b02dc2f60288b463e7a66e39c78829b62780db7 From b64efe82d993defe070dfeb9aa60e740ccf757cd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 25 Jun 2025 02:49:37 +0000 Subject: [PATCH 286/745] chore(deps): update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.3.1 (#1493) 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 67b4c5722..e8c280551 100644 --- a/pom.xml +++ b/pom.xml @@ -403,7 +403,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.9.3.0 + 4.9.3.1 spotbugs-exclusions.xml From 300a705e0af959da7ed0e88e9975379ff6fc4138 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 25 Jun 2025 08:32:52 +0200 Subject: [PATCH 287/745] chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.26.0 (#1494) 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 e8c280551..66443a758 100644 --- a/pom.xml +++ b/pom.xml @@ -447,7 +447,7 @@ com.puppycrawl.tools checkstyle - 10.25.1 + 10.26.0 From 34b22e8d93a986fdb81500ab539b4d2fe038b618 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 25 Jun 2025 06:40:04 +0000 Subject: [PATCH 288/745] fix(deps): update dependency org.junit:junit-bom to v5.13.2 (#1492) 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 66443a758..19740e671 100644 --- a/pom.xml +++ b/pom.xml @@ -202,7 +202,7 @@ org.junit junit-bom - 5.13.1 + 5.13.2 pom import From 86a5916f0dc6116b5b9e5dc897ff4b8705ac01e3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 26 Jun 2025 14:54:48 +0200 Subject: [PATCH 289/745] chore(deps): update github/codeql-action digest to 8ef1782 (#1495) 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 61ab2e54c..d6a3d81fd 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@9b02dc2f60288b463e7a66e39c78829b62780db7 + uses: github/codeql-action/init@8ef17824cfb2a3f40cbc7f41bac7e055e53b8164 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9b02dc2f60288b463e7a66e39c78829b62780db7 + uses: github/codeql-action/analyze@8ef17824cfb2a3f40cbc7f41bac7e055e53b8164 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 7d113656c..bb4bc312e 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@9b02dc2f60288b463e7a66e39c78829b62780db7 + uses: github/codeql-action/init@8ef17824cfb2a3f40cbc7f41bac7e055e53b8164 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@9b02dc2f60288b463e7a66e39c78829b62780db7 + uses: github/codeql-action/autobuild@8ef17824cfb2a3f40cbc7f41bac7e055e53b8164 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9b02dc2f60288b463e7a66e39c78829b62780db7 + uses: github/codeql-action/analyze@8ef17824cfb2a3f40cbc7f41bac7e055e53b8164 From fc430c3e1d57a532d8c0c879c3e7e25c46d4ad84 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 27 Jun 2025 07:35:50 +0200 Subject: [PATCH 290/745] chore(deps): update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.3.2 (#1496) 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 19740e671..0da829ac5 100644 --- a/pom.xml +++ b/pom.xml @@ -403,7 +403,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.9.3.1 + 4.9.3.2 spotbugs-exclusions.xml From 49214b7282ddde1ee16cf80f92c11cc90ef7612a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 27 Jun 2025 23:59:31 +0000 Subject: [PATCH 291/745] chore(deps): update github/codeql-action digest to 4c57370 (#1497) 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 d6a3d81fd..46af658f1 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@8ef17824cfb2a3f40cbc7f41bac7e055e53b8164 + uses: github/codeql-action/init@4c57370d0304fbff638216539f81d9163f77712a with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@8ef17824cfb2a3f40cbc7f41bac7e055e53b8164 + uses: github/codeql-action/analyze@4c57370d0304fbff638216539f81d9163f77712a diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index bb4bc312e..8a8f26944 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@8ef17824cfb2a3f40cbc7f41bac7e055e53b8164 + uses: github/codeql-action/init@4c57370d0304fbff638216539f81d9163f77712a with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@8ef17824cfb2a3f40cbc7f41bac7e055e53b8164 + uses: github/codeql-action/autobuild@4c57370d0304fbff638216539f81d9163f77712a - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@8ef17824cfb2a3f40cbc7f41bac7e055e53b8164 + uses: github/codeql-action/analyze@4c57370d0304fbff638216539f81d9163f77712a From 2e3b479cb1e8b0b65652ee813eaa2e1940d53c8e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 01:58:05 +0000 Subject: [PATCH 292/745] chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.26.1 (#1498) 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 0da829ac5..433487606 100644 --- a/pom.xml +++ b/pom.xml @@ -447,7 +447,7 @@ com.puppycrawl.tools checkstyle - 10.26.0 + 10.26.1 From 69519b1ef7274ceae39d6746c5a5a98dc69f562f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 20:37:12 +0000 Subject: [PATCH 293/745] chore(deps): update github/codeql-action digest to dcc1a66 (#1499) 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 46af658f1..89def2ed2 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@4c57370d0304fbff638216539f81d9163f77712a + uses: github/codeql-action/init@dcc1a6637b570d406bec5125dce2e2157d914359 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4c57370d0304fbff638216539f81d9163f77712a + uses: github/codeql-action/analyze@dcc1a6637b570d406bec5125dce2e2157d914359 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 8a8f26944..ca875406d 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@4c57370d0304fbff638216539f81d9163f77712a + uses: github/codeql-action/init@dcc1a6637b570d406bec5125dce2e2157d914359 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@4c57370d0304fbff638216539f81d9163f77712a + uses: github/codeql-action/autobuild@dcc1a6637b570d406bec5125dce2e2157d914359 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4c57370d0304fbff638216539f81d9163f77712a + uses: github/codeql-action/analyze@dcc1a6637b570d406bec5125dce2e2157d914359 From 0515ad54c4f71863373eb1b7f429393923b27d90 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 2 Jul 2025 13:05:20 +0200 Subject: [PATCH 294/745] chore(deps): update dependency org.apache.maven.plugins:maven-gpg-plugin to v3.2.8 (#1501) 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 433487606..78f30389c 100644 --- a/pom.xml +++ b/pom.xml @@ -571,7 +571,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.2.7 + 3.2.8 sign-artifacts From 0fd9d3dcfb1fd65197a42885b12d40a1cc152d3b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Jul 2025 00:11:36 +0000 Subject: [PATCH 295/745] chore(deps): update github/codeql-action digest to 33f8489 (#1502) 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 89def2ed2..c2636fbe8 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@dcc1a6637b570d406bec5125dce2e2157d914359 + uses: github/codeql-action/init@33f84897c384aaa4dcd214fb006aaa3f0f2dc34a with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@dcc1a6637b570d406bec5125dce2e2157d914359 + uses: github/codeql-action/analyze@33f84897c384aaa4dcd214fb006aaa3f0f2dc34a diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index ca875406d..5e2b38a24 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@dcc1a6637b570d406bec5125dce2e2157d914359 + uses: github/codeql-action/init@33f84897c384aaa4dcd214fb006aaa3f0f2dc34a with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@dcc1a6637b570d406bec5125dce2e2157d914359 + uses: github/codeql-action/autobuild@33f84897c384aaa4dcd214fb006aaa3f0f2dc34a - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@dcc1a6637b570d406bec5125dce2e2157d914359 + uses: github/codeql-action/analyze@33f84897c384aaa4dcd214fb006aaa3f0f2dc34a From a5d1cbced4658fadb63f362b4512bdbd68ae7d6a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Jul 2025 19:13:17 +0000 Subject: [PATCH 296/745] chore(deps): update github/codeql-action digest to b694213 (#1503) 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 c2636fbe8..7acac6305 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@33f84897c384aaa4dcd214fb006aaa3f0f2dc34a + uses: github/codeql-action/init@b69421388d5449cc5a5e1ca344d71926bda69e07 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@33f84897c384aaa4dcd214fb006aaa3f0f2dc34a + uses: github/codeql-action/analyze@b69421388d5449cc5a5e1ca344d71926bda69e07 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 5e2b38a24..c210033e4 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@33f84897c384aaa4dcd214fb006aaa3f0f2dc34a + uses: github/codeql-action/init@b69421388d5449cc5a5e1ca344d71926bda69e07 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@33f84897c384aaa4dcd214fb006aaa3f0f2dc34a + uses: github/codeql-action/autobuild@b69421388d5449cc5a5e1ca344d71926bda69e07 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@33f84897c384aaa4dcd214fb006aaa3f0f2dc34a + uses: github/codeql-action/analyze@b69421388d5449cc5a5e1ca344d71926bda69e07 From 08f549afd1fd26581b2a8e063832ec986c5e3267 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 3 Jul 2025 23:29:05 +0000 Subject: [PATCH 297/745] chore(deps): update actions/setup-java digest to 67aec00 (#1504) 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 37295eb31..d4684852d 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -23,7 +23,7 @@ jobs: steps: - uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f - name: Set up JDK 17 - uses: actions/setup-java@ebb356cc4e59bcf94f518203228485f5d40e4b58 + uses: actions/setup-java@67aec007b3fcabe15ca665bfccc1e255dd52e30d with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 7acac6305..00cf0a525 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -22,7 +22,7 @@ jobs: uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f - name: Set up JDK 11 - uses: actions/setup-java@ebb356cc4e59bcf94f518203228485f5d40e4b58 + uses: actions/setup-java@67aec007b3fcabe15ca665bfccc1e255dd52e30d with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 53141b448..baf5b5bbb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,7 +40,7 @@ jobs: uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f - name: Set up JDK 17 - uses: actions/setup-java@ebb356cc4e59bcf94f518203228485f5d40e4b58 + uses: actions/setup-java@67aec007b3fcabe15ca665bfccc1e255dd52e30d with: java-version: '17' distribution: 'temurin' From ebea0fdf1cf3e6f4d2e8aebf2dcb7c7e1f31acc2 Mon Sep 17 00:00:00 2001 From: chrfwow Date: Fri, 4 Jul 2025 15:17:56 +0200 Subject: [PATCH 298/745] fix: Reduce locking and concurrency issues (#1478) * Reduce locking and concurrency issues Signed-off-by: christian.lutnik * Reduce locking and concurrency issues Signed-off-by: christian.lutnik * formatting Signed-off-by: christian.lutnik * use concurrent data structure for hooks Signed-off-by: christian.lutnik * use concurrent data structure for hooks Signed-off-by: christian.lutnik --------- Signed-off-by: christian.lutnik Co-authored-by: Todd Baert --- .../dev/openfeature/sdk/OpenFeatureAPI.java | 82 +++++++++---------- .../openfeature/sdk/OpenFeatureClient.java | 54 ++++++------ .../openfeature/sdk/internal/ObjectUtils.java | 5 +- .../openfeature/sdk/LockingSingeltonTest.java | 55 ------------- 4 files changed, 67 insertions(+), 129 deletions(-) diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java b/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java index 66d40736f..6d0d8feb4 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java @@ -5,9 +5,12 @@ import dev.openfeature.sdk.internal.AutoCloseableReentrantReadWriteLock; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import lombok.extern.slf4j.Slf4j; @@ -21,14 +24,14 @@ public class OpenFeatureAPI implements EventBus { // package-private multi-read/single-write lock static AutoCloseableReentrantReadWriteLock lock = new AutoCloseableReentrantReadWriteLock(); - private final List apiHooks; + private final ConcurrentLinkedQueue apiHooks; private ProviderRepository providerRepository; private EventSupport eventSupport; - private EvaluationContext evaluationContext; + private final AtomicReference evaluationContext = new AtomicReference<>(); private TransactionContextPropagator transactionContextPropagator; protected OpenFeatureAPI() { - apiHooks = new ArrayList<>(); + apiHooks = new ConcurrentLinkedQueue<>(); providerRepository = new ProviderRepository(this); eventSupport = new EventSupport(); transactionContextPropagator = new NoOpTransactionContextPropagator(); @@ -115,9 +118,7 @@ public Client getClient(String domain, String version) { * @return api instance */ public OpenFeatureAPI setEvaluationContext(EvaluationContext evaluationContext) { - try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) { - this.evaluationContext = evaluationContext; - } + this.evaluationContext.set(evaluationContext); return this; } @@ -127,16 +128,14 @@ public OpenFeatureAPI setEvaluationContext(EvaluationContext evaluationContext) * @return evaluation context */ public EvaluationContext getEvaluationContext() { - try (AutoCloseableLock __ = lock.readLockAutoCloseable()) { - return this.evaluationContext; - } + return evaluationContext.get(); } /** * Return the transaction context propagator. */ public TransactionContextPropagator getTransactionContextPropagator() { - try (AutoCloseableLock __ = lock.readLockAutoCloseable()) { + try (AutoCloseableLock ignored = lock.readLockAutoCloseable()) { return this.transactionContextPropagator; } } @@ -150,7 +149,7 @@ public void setTransactionContextPropagator(TransactionContextPropagator transac if (transactionContextPropagator == null) { throw new IllegalArgumentException("Transaction context propagator cannot be null"); } - try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) { + try (AutoCloseableLock ignored = lock.writeLockAutoCloseable()) { this.transactionContextPropagator = transactionContextPropagator; } } @@ -176,7 +175,7 @@ public void setTransactionContext(EvaluationContext evaluationContext) { * Set the default provider. */ public void setProvider(FeatureProvider provider) { - try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) { + try (AutoCloseableLock ignored = lock.writeLockAutoCloseable()) { providerRepository.setProvider( provider, this::attachEventProvider, @@ -194,7 +193,7 @@ public void setProvider(FeatureProvider provider) { * @param provider The provider to set. */ public void setProvider(String domain, FeatureProvider provider) { - try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) { + try (AutoCloseableLock ignored = lock.writeLockAutoCloseable()) { providerRepository.setProvider( domain, provider, @@ -216,7 +215,7 @@ public void setProvider(String domain, FeatureProvider provider) { * @throws OpenFeatureError if the provider fails during initialization. */ public void setProviderAndWait(FeatureProvider provider) throws OpenFeatureError { - try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) { + try (AutoCloseableLock ignored = lock.writeLockAutoCloseable()) { providerRepository.setProvider( provider, this::attachEventProvider, @@ -238,7 +237,7 @@ public void setProviderAndWait(FeatureProvider provider) throws OpenFeatureError * @throws OpenFeatureError if the provider fails during initialization. */ public void setProviderAndWait(String domain, FeatureProvider provider) throws OpenFeatureError { - try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) { + try (AutoCloseableLock ignored = lock.writeLockAutoCloseable()) { providerRepository.setProvider( domain, provider, @@ -252,9 +251,7 @@ public void setProviderAndWait(String domain, FeatureProvider provider) throws O private void attachEventProvider(FeatureProvider provider) { if (provider instanceof EventProvider) { - ((EventProvider) provider).attach((p, event, details) -> { - runHandlersForProvider(p, event, details); - }); + ((EventProvider) provider).attach(this::runHandlersForProvider); } } @@ -307,9 +304,7 @@ public FeatureProvider getProvider(String domain) { * @param hooks The hook to add. */ public void addHooks(Hook... hooks) { - try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) { - this.apiHooks.addAll(Arrays.asList(hooks)); - } + this.apiHooks.addAll(Arrays.asList(hooks)); } /** @@ -318,18 +313,23 @@ public void addHooks(Hook... hooks) { * @return A list of {@link Hook}s. */ public List getHooks() { - try (AutoCloseableLock __ = lock.readLockAutoCloseable()) { - return this.apiHooks; - } + return new ArrayList<>(this.apiHooks); + } + + /** + * Returns a reference to the collection of {@link Hook}s. + * + * @return The collection of {@link Hook}s. + */ + Collection getMutableHooks() { + return this.apiHooks; } /** * Removes all hooks. */ public void clearHooks() { - try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) { - this.apiHooks.clear(); - } + this.apiHooks.clear(); } /** @@ -339,7 +339,7 @@ public void clearHooks() { * Once shut down is complete, API is reset and ready to use again. */ public void shutdown() { - try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) { + try (AutoCloseableLock ignored = lock.writeLockAutoCloseable()) { providerRepository.shutdown(); eventSupport.shutdown(); @@ -385,7 +385,7 @@ public OpenFeatureAPI onProviderError(Consumer handler) { */ @Override public OpenFeatureAPI on(ProviderEvent event, Consumer handler) { - try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) { + try (AutoCloseableLock ignored = lock.writeLockAutoCloseable()) { this.eventSupport.addGlobalHandler(event, handler); return this; } @@ -396,18 +396,20 @@ public OpenFeatureAPI on(ProviderEvent event, Consumer handler) { */ @Override public OpenFeatureAPI removeHandler(ProviderEvent event, Consumer handler) { - this.eventSupport.removeGlobalHandler(event, handler); + try (AutoCloseableLock ignored = lock.writeLockAutoCloseable()) { + this.eventSupport.removeGlobalHandler(event, handler); + } return this; } void removeHandler(String domain, ProviderEvent event, Consumer handler) { - try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) { + try (AutoCloseableLock ignored = lock.writeLockAutoCloseable()) { eventSupport.removeClientHandler(domain, event, handler); } } void addHandler(String domain, ProviderEvent event, Consumer handler) { - try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) { + try (AutoCloseableLock ignored = lock.writeLockAutoCloseable()) { // if the provider is in the state associated with event, run immediately if (Optional.ofNullable(this.providerRepository.getProviderState(domain)) .orElse(ProviderState.READY) @@ -431,32 +433,28 @@ FeatureProviderStateManager getFeatureProviderStateManager(String domain) { * @param details the event details */ private void runHandlersForProvider(FeatureProvider provider, ProviderEvent event, ProviderEventDetails details) { - try (AutoCloseableLock __ = lock.readLockAutoCloseable()) { + try (AutoCloseableLock ignored = lock.readLockAutoCloseable()) { List domainsForProvider = providerRepository.getDomainsForProvider(provider); final String providerName = Optional.ofNullable(provider.getMetadata()) - .map(metadata -> metadata.getName()) + .map(Metadata::getName) .orElse(null); // run the global handlers eventSupport.runGlobalHandlers(event, EventDetails.fromProviderEventDetails(details, providerName)); // run the handlers associated with domains for this provider - domainsForProvider.forEach(domain -> { - eventSupport.runClientHandlers( - domain, event, EventDetails.fromProviderEventDetails(details, providerName, domain)); - }); + domainsForProvider.forEach(domain -> eventSupport.runClientHandlers( + domain, event, EventDetails.fromProviderEventDetails(details, providerName, domain))); if (providerRepository.isDefaultProvider(provider)) { // run handlers for clients that have no bound providers (since this is the default) Set allDomainNames = eventSupport.getAllDomainNames(); Set boundDomains = providerRepository.getAllBoundDomains(); allDomainNames.removeAll(boundDomains); - allDomainNames.forEach(domain -> { - eventSupport.runClientHandlers( - domain, event, EventDetails.fromProviderEventDetails(details, providerName, domain)); - }); + allDomainNames.forEach(domain -> eventSupport.runClientHandlers( + domain, event, EventDetails.fromProviderEventDetails(details, providerName, domain))); } } } diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index e68d28f79..b5522b66a 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -5,9 +5,8 @@ import dev.openfeature.sdk.exceptions.GeneralError; import dev.openfeature.sdk.exceptions.OpenFeatureError; import dev.openfeature.sdk.exceptions.ProviderNotReadyError; -import dev.openfeature.sdk.internal.AutoCloseableLock; -import dev.openfeature.sdk.internal.AutoCloseableReentrantReadWriteLock; import dev.openfeature.sdk.internal.ObjectUtils; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -15,6 +14,8 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -46,11 +47,9 @@ public class OpenFeatureClient implements Client { @Getter private final String version; - private final List clientHooks; + private final ConcurrentLinkedQueue clientHooks; private final HookSupport hookSupport; - AutoCloseableReentrantReadWriteLock hooksLock = new AutoCloseableReentrantReadWriteLock(); - AutoCloseableReentrantReadWriteLock contextLock = new AutoCloseableReentrantReadWriteLock(); - private EvaluationContext evaluationContext; + private final AtomicReference evaluationContext = new AtomicReference<>(); /** * Deprecated public constructor. Use OpenFeature.API.getClient() instead. @@ -68,7 +67,7 @@ public OpenFeatureClient(OpenFeatureAPI openFeatureAPI, String domain, String ve this.openfeatureApi = openFeatureAPI; this.domain = domain; this.version = version; - this.clientHooks = new ArrayList<>(); + this.clientHooks = new ConcurrentLinkedQueue<>(); this.hookSupport = new HookSupport(); } @@ -125,9 +124,7 @@ public void track(String trackingEventName, EvaluationContext context, TrackingE */ @Override public OpenFeatureClient addHooks(Hook... hooks) { - try (AutoCloseableLock __ = this.hooksLock.writeLockAutoCloseable()) { - this.clientHooks.addAll(Arrays.asList(hooks)); - } + this.clientHooks.addAll(Arrays.asList(hooks)); return this; } @@ -136,9 +133,7 @@ public OpenFeatureClient addHooks(Hook... hooks) { */ @Override public List getHooks() { - try (AutoCloseableLock __ = this.hooksLock.readLockAutoCloseable()) { - return this.clientHooks; - } + return new ArrayList<>(this.clientHooks); } /** @@ -146,9 +141,7 @@ public List getHooks() { */ @Override public OpenFeatureClient setEvaluationContext(EvaluationContext evaluationContext) { - try (AutoCloseableLock __ = contextLock.writeLockAutoCloseable()) { - this.evaluationContext = evaluationContext; - } + this.evaluationContext.set(evaluationContext); return this; } @@ -157,32 +150,33 @@ public OpenFeatureClient setEvaluationContext(EvaluationContext evaluationContex */ @Override public EvaluationContext getEvaluationContext() { - try (AutoCloseableLock __ = contextLock.readLockAutoCloseable()) { - return this.evaluationContext; - } + return this.evaluationContext.get(); } + @SuppressFBWarnings( + value = {"REC_CATCH_EXCEPTION"}, + justification = "We don't want to allow any exception to reach the user. " + + "Instead, we return an evaluation result with the appropriate error code.") private FlagEvaluationDetails evaluateFlag( FlagValueType type, String key, T defaultValue, EvaluationContext ctx, FlagEvaluationOptions options) { - FlagEvaluationOptions flagOptions = ObjectUtils.defaultIfNull( + var flagOptions = ObjectUtils.defaultIfNull( options, () -> FlagEvaluationOptions.builder().build()); - Map hints = Collections.unmodifiableMap(flagOptions.getHookHints()); + var hints = Collections.unmodifiableMap(flagOptions.getHookHints()); FlagEvaluationDetails details = null; List mergedHooks = null; HookContext afterHookContext = null; - FeatureProvider provider; try { - FeatureProviderStateManager stateManager = openfeatureApi.getFeatureProviderStateManager(this.domain); + var stateManager = openfeatureApi.getFeatureProviderStateManager(this.domain); // provider must be accessed once to maintain a consistent reference - provider = stateManager.getProvider(); - ProviderState state = stateManager.getState(); + var provider = stateManager.getProvider(); + var state = stateManager.getState(); mergedHooks = ObjectUtils.merge( - provider.getProviderHooks(), flagOptions.getHooks(), clientHooks, openfeatureApi.getHooks()); + provider.getProviderHooks(), flagOptions.getHooks(), clientHooks, openfeatureApi.getMutableHooks()); - EvaluationContext mergedCtx = hookSupport.beforeHooks( + var mergedCtx = hookSupport.beforeHooks( type, HookContext.from( key, @@ -205,12 +199,12 @@ private FlagEvaluationDetails evaluateFlag( throw new FatalError("Provider is in an irrecoverable error state"); } - ProviderEvaluation providerEval = + var providerEval = (ProviderEvaluation) createProviderEvaluation(type, key, defaultValue, provider, mergedCtx); details = FlagEvaluationDetails.from(providerEval, key); if (details.getErrorCode() != null) { - OpenFeatureError error = + var error = ExceptionUtils.instantiateErrorByErrorCode(details.getErrorCode(), details.getErrorMessage()); enrichDetailsWithErrorDefaults(defaultValue, details); hookSupport.errorHooks(type, afterHookContext, error, mergedHooks, hints); @@ -264,7 +258,7 @@ private void invokeTrack(String trackingEventName, EvaluationContext context, Tr */ private EvaluationContext mergeEvaluationContext(EvaluationContext invocationContext) { final EvaluationContext apiContext = openfeatureApi.getEvaluationContext(); - final EvaluationContext clientContext = this.getEvaluationContext(); + final EvaluationContext clientContext = evaluationContext.get(); final EvaluationContext transactionContext = openfeatureApi.getTransactionContext(); return mergeContextMaps(apiContext, transactionContext, clientContext, invocationContext); } diff --git a/src/main/java/dev/openfeature/sdk/internal/ObjectUtils.java b/src/main/java/dev/openfeature/sdk/internal/ObjectUtils.java index b367820c2..86a9ddd70 100644 --- a/src/main/java/dev/openfeature/sdk/internal/ObjectUtils.java +++ b/src/main/java/dev/openfeature/sdk/internal/ObjectUtils.java @@ -1,6 +1,7 @@ package dev.openfeature.sdk.internal; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.function.Supplier; @@ -64,9 +65,9 @@ public static T defaultIfNull(T source, Supplier defaultValue) { * @return resulting object */ @SafeVarargs - public static List merge(List... sources) { + public static List merge(Collection... sources) { List merged = new ArrayList<>(); - for (List source : sources) { + for (Collection source : sources) { merged.addAll(source); } return merged; diff --git a/src/test/java/dev/openfeature/sdk/LockingSingeltonTest.java b/src/test/java/dev/openfeature/sdk/LockingSingeltonTest.java index ad86f4bc3..ae3246cae 100644 --- a/src/test/java/dev/openfeature/sdk/LockingSingeltonTest.java +++ b/src/test/java/dev/openfeature/sdk/LockingSingeltonTest.java @@ -20,7 +20,6 @@ class LockingSingeltonTest { private static OpenFeatureAPI api; private OpenFeatureClient client; private AutoCloseableReentrantReadWriteLock apiLock; - private AutoCloseableReentrantReadWriteLock clientContextLock; private AutoCloseableReentrantReadWriteLock clientHooksLock; @BeforeAll @@ -36,10 +35,7 @@ void beforeEach() { apiLock = setupLock(apiLock, mockInnerReadLock(), mockInnerWriteLock()); OpenFeatureAPI.lock = apiLock; - clientContextLock = setupLock(clientContextLock, mockInnerReadLock(), mockInnerWriteLock()); clientHooksLock = setupLock(clientHooksLock, mockInnerReadLock(), mockInnerWriteLock()); - client.contextLock = clientContextLock; - client.hooksLock = clientHooksLock; } @Nested @@ -137,50 +133,6 @@ void onProviderErrorProviderReadyShouldApiWriteLockAndUnlock() { } } - @Test - void addHooksShouldWriteLockAndUnlock() { - client.addHooks(new Hook() {}); - verify(clientHooksLock.writeLock()).lock(); - verify(clientHooksLock.writeLock()).unlock(); - - api.addHooks(new Hook() {}); - verify(apiLock.writeLock()).lock(); - verify(apiLock.writeLock()).unlock(); - } - - @Test - void getHooksShouldReadLockAndUnlock() { - client.getHooks(); - verify(clientHooksLock.readLock()).lock(); - verify(clientHooksLock.readLock()).unlock(); - - api.getHooks(); - verify(apiLock.readLock()).lock(); - verify(apiLock.readLock()).unlock(); - } - - @Test - void setContextShouldWriteLockAndUnlock() { - client.setEvaluationContext(new ImmutableContext()); - verify(clientContextLock.writeLock()).lock(); - verify(clientContextLock.writeLock()).unlock(); - - api.setEvaluationContext(new ImmutableContext()); - verify(apiLock.writeLock()).lock(); - verify(apiLock.writeLock()).unlock(); - } - - @Test - void getContextShouldReadLockAndUnlock() { - client.getEvaluationContext(); - verify(clientContextLock.readLock()).lock(); - verify(clientContextLock.readLock()).unlock(); - - api.getEvaluationContext(); - verify(apiLock.readLock()).lock(); - verify(apiLock.readLock()).unlock(); - } - @Test void setTransactionalContextPropagatorShouldWriteLockAndUnlock() { api.setTransactionContextPropagator(new NoOpTransactionContextPropagator()); @@ -195,13 +147,6 @@ void getTransactionalContextPropagatorShouldReadLockAndUnlock() { verify(apiLock.readLock()).unlock(); } - @Test - void clearHooksShouldWriteLockAndUnlock() { - api.clearHooks(); - verify(apiLock.writeLock()).lock(); - verify(apiLock.writeLock()).unlock(); - } - private static ReentrantReadWriteLock.ReadLock mockInnerReadLock() { ReentrantReadWriteLock.ReadLock readLockMock = mock(ReentrantReadWriteLock.ReadLock.class); doNothing().when(readLockMock).lock(); From 957c0d1ba38ecc758c1ec164e40070ac93a01d68 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 4 Jul 2025 19:37:31 +0000 Subject: [PATCH 299/745] fix(deps): update dependency org.junit:junit-bom to v5.13.3 (#1505) 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 78f30389c..409c08fdd 100644 --- a/pom.xml +++ b/pom.xml @@ -202,7 +202,7 @@ org.junit junit-bom - 5.13.2 + 5.13.3 pom import From 5425a34a12baa04f9583b83fd1bfdd7e2a6ab5e8 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Mon, 7 Jul 2025 14:30:18 -0400 Subject: [PATCH 300/745] chore: migrate to new publish Signed-off-by: Todd Baert --- pom.xml | 15 +++++++-------- release/m2-settings.xml | 5 +++++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 409c08fdd..85107f93d 100644 --- a/pom.xml +++ b/pom.xml @@ -520,14 +520,13 @@ - org.sonatype.plugins - nexus-staging-maven-plugin - 1.7.0 + org.sonatype.central + central-publishing-maven-plugin + 0.8.0 true - ossrh - https://s01.oss.sonatype.org/ - true + central + true @@ -711,8 +710,8 @@ - ossrh - https://s01.oss.sonatype.org/content/repositories/snapshots + central + https://central.sonatype.com/repository/maven-snapshots/ diff --git a/release/m2-settings.xml b/release/m2-settings.xml index 9b7a585a3..517375160 100644 --- a/release/m2-settings.xml +++ b/release/m2-settings.xml @@ -5,5 +5,10 @@ ${env.OSSRH_USERNAME} ${env.OSSRH_PASSWORD} + + central + ${env.CENTRAL_USERNAME} + ${env.CENTRAL_PASSWORD} + From 6194186b3e791f3cb28da24f5acb3ff96788d65e Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Mon, 7 Jul 2025 14:39:17 -0400 Subject: [PATCH 301/745] chore: skip tests on publish Signed-off-by: Todd Baert --- .github/workflows/merge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index d4684852d..07aec6ada 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -65,7 +65,7 @@ jobs: - name: Deploy run: | mvn --batch-mode \ - --settings release/m2-settings.xml clean deploy + --settings release/m2-settings.xml -DskipTests clean deploy env: OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} From 85d89ee79a52d960322731fb786c0f60245f0d75 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Mon, 7 Jul 2025 14:42:51 -0400 Subject: [PATCH 302/745] chore: update publish env vars Signed-off-by: Todd Baert --- .github/workflows/merge.yml | 10 +++++----- .github/workflows/release.yml | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index 07aec6ada..ccf09bac5 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -28,9 +28,9 @@ jobs: java-version: '17' distribution: 'temurin' cache: maven - server-id: ossrh - server-username: ${{ secrets.OSSRH_USERNAME }} - server-password: ${{ secrets.OSSRH_PASSWORD }} + server-id: central + server-username: ${{ secrets.CENTRAL_USERNAME }} + server-password: ${{ secrets.CENTRAL_PASSWORD }} - name: Cache local Maven repository uses: actions/cache@640a1c2554105b57832a23eea0b4672fc7a790d5 @@ -67,5 +67,5 @@ jobs: mvn --batch-mode \ --settings release/m2-settings.xml -DskipTests clean deploy env: - OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} - OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }} + CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index baf5b5bbb..fcdee10f2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -45,9 +45,9 @@ jobs: java-version: '17' distribution: 'temurin' cache: maven - server-id: ossrh - server-username: ${{ secrets.OSSRH_USERNAME }} - server-password: ${{ secrets.OSSRH_PASSWORD }} + server-id: central + server-username: ${{ secrets.CENTRAL_USERNAME }} + server-password: ${{ secrets.CENTRAL_PASSWORD }} - name: Configure GPG Key run: | @@ -60,5 +60,5 @@ jobs: mvn --batch-mode \ --settings release/m2-settings.xml -DskipTests clean deploy env: - OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} - OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }} + CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }} From d2b1dc3a41fbec371c443a123d2b83b6a17a477b Mon Sep 17 00:00:00 2001 From: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> Date: Mon, 7 Jul 2025 14:54:59 -0400 Subject: [PATCH 303/745] chore(main): release 1.16.0 (#1452) Signed-off-by: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 69 +++++++++++++++++++++++++++++++++++ README.md | 8 ++-- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 76 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 8c4a75878..8997e1812 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"1.15.1"} +{".":"1.16.0"} diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d2871346..2529b1871 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,74 @@ # Changelog +## [1.16.0](https://github.com/open-feature/java-sdk/compare/v1.15.1...v1.16.0) (2025-07-07) + + +### 🐛 Bug Fixes + +* **deps:** update dependency io.cucumber:cucumber-bom to v7.23.0 ([#1466](https://github.com/open-feature/java-sdk/issues/1466)) ([50a6b16](https://github.com/open-feature/java-sdk/commit/50a6b168a7de40337aa51ef3d79d122030956cb9)) +* **deps:** update dependency org.junit:junit-bom to v5.13.1 ([#1475](https://github.com/open-feature/java-sdk/issues/1475)) ([545d6aa](https://github.com/open-feature/java-sdk/commit/545d6aac09dbc74c00a0a4e5c26f4ef80be22379)) +* **deps:** update dependency org.junit:junit-bom to v5.13.2 ([#1492](https://github.com/open-feature/java-sdk/issues/1492)) ([34b22e8](https://github.com/open-feature/java-sdk/commit/34b22e8d93a986fdb81500ab539b4d2fe038b618)) +* **deps:** update dependency org.junit:junit-bom to v5.13.3 ([#1505](https://github.com/open-feature/java-sdk/issues/1505)) ([957c0d1](https://github.com/open-feature/java-sdk/commit/957c0d1ba38ecc758c1ec164e40070ac93a01d68)) +* **deps:** update junit5 monorepo ([#1467](https://github.com/open-feature/java-sdk/issues/1467)) ([f8260a1](https://github.com/open-feature/java-sdk/commit/f8260a1c3a345c877eba95bfe41184ad11f6555e)) +* Reduce locking and concurrency issues ([#1478](https://github.com/open-feature/java-sdk/issues/1478)) ([ebea0fd](https://github.com/open-feature/java-sdk/commit/ebea0fdf1cf3e6f4d2e8aebf2dcb7c7e1f31acc2)) + + +### ✨ New Features + +* add means of awaiting event emission, fix flaky build ([#1463](https://github.com/open-feature/java-sdk/issues/1463)) ([3dd7d5d](https://github.com/open-feature/java-sdk/commit/3dd7d5d4262f1f4461e13c13a7d64d2fa8bfd764)), closes [#1449](https://github.com/open-feature/java-sdk/issues/1449) + + +### 🧹 Chore + +* **deps:** update actions/cache digest to 640a1c2 ([#1485](https://github.com/open-feature/java-sdk/issues/1485)) ([7c2af57](https://github.com/open-feature/java-sdk/commit/7c2af57a362ee11f757a431ee17eff3ee448bf6c)) +* **deps:** update actions/checkout digest to 09d2aca ([#1473](https://github.com/open-feature/java-sdk/issues/1473)) ([b5d873e](https://github.com/open-feature/java-sdk/commit/b5d873e44d3c41b42f11569b0fafccc0a002ebdd)) +* **deps:** update actions/setup-java digest to 67aec00 ([#1504](https://github.com/open-feature/java-sdk/issues/1504)) ([08f549a](https://github.com/open-feature/java-sdk/commit/08f549afd1fd26581b2a8e063832ec986c5e3267)) +* **deps:** update actions/setup-java digest to ebb356c ([#1490](https://github.com/open-feature/java-sdk/issues/1490)) ([e67f598](https://github.com/open-feature/java-sdk/commit/e67f5983573afff805a56ef18584d1a7291ccafc)) +* **deps:** update codecov/codecov-action action to v5.4.3 ([#1454](https://github.com/open-feature/java-sdk/issues/1454)) ([e337939](https://github.com/open-feature/java-sdk/commit/e3379395e6bfb0ce811d8372761a3cb015ad2cde)) +* **deps:** update dependency com.diffplug.spotless:spotless-maven-plugin to v2.44.5 ([#1462](https://github.com/open-feature/java-sdk/issues/1462)) ([40b319c](https://github.com/open-feature/java-sdk/commit/40b319c5de0461bec13f76978ae09edc958310cd)) +* **deps:** update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.3.1 ([#1493](https://github.com/open-feature/java-sdk/issues/1493)) ([b64efe8](https://github.com/open-feature/java-sdk/commit/b64efe82d993defe070dfeb9aa60e740ccf757cd)) +* **deps:** update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.3.2 ([#1496](https://github.com/open-feature/java-sdk/issues/1496)) ([fc430c3](https://github.com/open-feature/java-sdk/commit/fc430c3e1d57a532d8c0c879c3e7e25c46d4ad84)) +* **deps:** update dependency com.puppycrawl.tools:checkstyle to v10.24.0 ([#1458](https://github.com/open-feature/java-sdk/issues/1458)) ([dcbfd26](https://github.com/open-feature/java-sdk/commit/dcbfd265a3875271695af760fce9870e53c69f13)) +* **deps:** update dependency com.puppycrawl.tools:checkstyle to v10.25.0 ([#1468](https://github.com/open-feature/java-sdk/issues/1468)) ([1558a86](https://github.com/open-feature/java-sdk/commit/1558a862497c0e133d11d53ff6d7f28437653d43)) +* **deps:** update dependency com.puppycrawl.tools:checkstyle to v10.25.1 ([#1489](https://github.com/open-feature/java-sdk/issues/1489)) ([312b6df](https://github.com/open-feature/java-sdk/commit/312b6df5d2c891ac758bf398f8399ecd25b7597e)) +* **deps:** update dependency com.puppycrawl.tools:checkstyle to v10.26.0 ([#1494](https://github.com/open-feature/java-sdk/issues/1494)) ([300a705](https://github.com/open-feature/java-sdk/commit/300a705e0af959da7ed0e88e9975379ff6fc4138)) +* **deps:** update dependency com.puppycrawl.tools:checkstyle to v10.26.1 ([#1498](https://github.com/open-feature/java-sdk/issues/1498)) ([2e3b479](https://github.com/open-feature/java-sdk/commit/2e3b479cb1e8b0b65652ee813eaa2e1940d53c8e)) +* **deps:** update dependency maven to v3.9.10 ([#1474](https://github.com/open-feature/java-sdk/issues/1474)) ([4481537](https://github.com/open-feature/java-sdk/commit/4481537cebc213dcfe19bb8cd9b70a4c91a682b2)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.17.6 ([#1482](https://github.com/open-feature/java-sdk/issues/1482)) ([8e51e6f](https://github.com/open-feature/java-sdk/commit/8e51e6fe101882184a5d09be31fa65563d82c673)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.17.6 ([#1483](https://github.com/open-feature/java-sdk/issues/1483)) ([936ff60](https://github.com/open-feature/java-sdk/commit/936ff60fac471a83a7c14412d2e825b2a7f9704c)) +* **deps:** update dependency org.apache.maven.plugins:maven-gpg-plugin to v3.2.8 ([#1501](https://github.com/open-feature/java-sdk/issues/1501)) ([0515ad5](https://github.com/open-feature/java-sdk/commit/0515ad54c4f71863373eb1b7f429393923b27d90)) +* **deps:** update dependency org.codehaus.mojo:exec-maven-plugin to v3.5.1 ([#1461](https://github.com/open-feature/java-sdk/issues/1461)) ([b6ceff2](https://github.com/open-feature/java-sdk/commit/b6ceff2ecb0e34be2ccdb83f7f37c1177de6f27e)) +* **deps:** update dependency org.mockito:mockito-core to v5.18.0 ([#1457](https://github.com/open-feature/java-sdk/issues/1457)) ([e17b0b2](https://github.com/open-feature/java-sdk/commit/e17b0b29758ae7cdbdac9ddb2178382c55eb1277)) +* **deps:** update github/codeql-action digest to 075e08a ([#1470](https://github.com/open-feature/java-sdk/issues/1470)) ([6597de7](https://github.com/open-feature/java-sdk/commit/6597de7a98e0fae10a541a8a9b60837623c133a8)) +* **deps:** update github/codeql-action digest to 33f8489 ([#1502](https://github.com/open-feature/java-sdk/issues/1502)) ([0fd9d3d](https://github.com/open-feature/java-sdk/commit/0fd9d3dcfb1fd65197a42885b12d40a1cc152d3b)) +* **deps:** update github/codeql-action digest to 396fd27 ([#1456](https://github.com/open-feature/java-sdk/issues/1456)) ([b45a937](https://github.com/open-feature/java-sdk/commit/b45a9370173e3d3b97c78449dfc99225fb572228)) +* **deps:** update github/codeql-action digest to 3de706a ([#1481](https://github.com/open-feature/java-sdk/issues/1481)) ([99a3006](https://github.com/open-feature/java-sdk/commit/99a3006de878ab0ba1f0e61a4cb5432914425795)) +* **deps:** update github/codeql-action digest to 466d6ce ([#1477](https://github.com/open-feature/java-sdk/issues/1477)) ([0b57bca](https://github.com/open-feature/java-sdk/commit/0b57bcafc14b946000feb4a3421d73b9616e83cb)) +* **deps:** update github/codeql-action digest to 4a00331 ([#1469](https://github.com/open-feature/java-sdk/issues/1469)) ([376f81f](https://github.com/open-feature/java-sdk/commit/376f81f5c3b66d7e3e298aac30ac7544b84e7362)) +* **deps:** update github/codeql-action digest to 4c57370 ([#1497](https://github.com/open-feature/java-sdk/issues/1497)) ([49214b7](https://github.com/open-feature/java-sdk/commit/49214b7282ddde1ee16cf80f92c11cc90ef7612a)) +* **deps:** update github/codeql-action digest to 510dfa3 ([#1450](https://github.com/open-feature/java-sdk/issues/1450)) ([d9a72d2](https://github.com/open-feature/java-sdk/commit/d9a72d2aafd787a1814132f000897ad1c94181e4)) +* **deps:** update github/codeql-action digest to 57eebf6 ([#1455](https://github.com/open-feature/java-sdk/issues/1455)) ([36eed06](https://github.com/open-feature/java-sdk/commit/36eed065e763bbfa0f8f97d704202bbd219332ca)) +* **deps:** update github/codeql-action digest to 66d7255 ([#1487](https://github.com/open-feature/java-sdk/issues/1487)) ([c3eaecd](https://github.com/open-feature/java-sdk/commit/c3eaecdb8b34d3b33946bd205ee92d49584602bd)) +* **deps:** update github/codeql-action digest to 7b0fb5a ([#1459](https://github.com/open-feature/java-sdk/issues/1459)) ([6a95c00](https://github.com/open-feature/java-sdk/commit/6a95c008e975dd3c7328c32f1d7cf626bbaecfa6)) +* **deps:** update github/codeql-action digest to 7cb9b16 ([#1476](https://github.com/open-feature/java-sdk/issues/1476)) ([6cca721](https://github.com/open-feature/java-sdk/commit/6cca721be5bc6f5926fe64668a7c03728cab3cb0)) +* **deps:** update github/codeql-action digest to 7fd6215 ([#1464](https://github.com/open-feature/java-sdk/issues/1464)) ([f10aaaa](https://github.com/open-feature/java-sdk/commit/f10aaaa357581b573895f4d6e2329abb705582aa)) +* **deps:** update github/codeql-action digest to 8ef1782 ([#1495](https://github.com/open-feature/java-sdk/issues/1495)) ([86a5916](https://github.com/open-feature/java-sdk/commit/86a5916f0dc6116b5b9e5dc897ff4b8705ac01e3)) +* **deps:** update github/codeql-action digest to 9b02dc2 ([#1491](https://github.com/open-feature/java-sdk/issues/1491)) ([6f67b06](https://github.com/open-feature/java-sdk/commit/6f67b06f712c461f331681a76f5cb2c3ddb0d36b)) +* **deps:** update github/codeql-action digest to ac30a39 ([#1488](https://github.com/open-feature/java-sdk/issues/1488)) ([8fad544](https://github.com/open-feature/java-sdk/commit/8fad544b17ee08b4280d7975073d00a874c374db)) +* **deps:** update github/codeql-action digest to b1e4dc3 ([#1471](https://github.com/open-feature/java-sdk/issues/1471)) ([2dcd6a1](https://github.com/open-feature/java-sdk/commit/2dcd6a1dd0c80ee676b9860afd6a6002d0ea4aea)) +* **deps:** update github/codeql-action digest to b694213 ([#1503](https://github.com/open-feature/java-sdk/issues/1503)) ([a5d1cbc](https://github.com/open-feature/java-sdk/commit/a5d1cbced4658fadb63f362b4512bdbd68ae7d6a)) +* **deps:** update github/codeql-action digest to b86edfc ([#1453](https://github.com/open-feature/java-sdk/issues/1453)) ([b667aa3](https://github.com/open-feature/java-sdk/commit/b667aa325136b78c01867d40342f81eeb7e16f46)) +* **deps:** update github/codeql-action digest to bc02a25 ([#1460](https://github.com/open-feature/java-sdk/issues/1460)) ([5e922cf](https://github.com/open-feature/java-sdk/commit/5e922cf3efc156135563707de92e508b0a4d19f3)) +* **deps:** update github/codeql-action digest to be30325 ([#1479](https://github.com/open-feature/java-sdk/issues/1479)) ([844d5e2](https://github.com/open-feature/java-sdk/commit/844d5e244b02703b624cf75e5bf8448c07e62d3d)) +* **deps:** update github/codeql-action digest to dcc1a66 ([#1499](https://github.com/open-feature/java-sdk/issues/1499)) ([69519b1](https://github.com/open-feature/java-sdk/commit/69519b1ef7274ceae39d6746c5a5a98dc69f562f)) +* **deps:** update github/codeql-action digest to ef36b69 ([#1484](https://github.com/open-feature/java-sdk/issues/1484)) ([8bf777a](https://github.com/open-feature/java-sdk/commit/8bf777a7e99be4dfac8917b8e61cb6c23385b8ce)) +* **deps:** update io.cucumber.version to v7.23.0 ([#1465](https://github.com/open-feature/java-sdk/issues/1465)) ([2de7616](https://github.com/open-feature/java-sdk/commit/2de76166764bacd34883b13220dd0bad824c8b1a)) +* improvements to release workflow ([#1451](https://github.com/open-feature/java-sdk/issues/1451)) ([1714efe](https://github.com/open-feature/java-sdk/commit/1714efe81aa6ae025f4f8b12c9c042561498d25e)) +* migrate to new publish ([5425a34](https://github.com/open-feature/java-sdk/commit/5425a34a12baa04f9583b83fd1bfdd7e2a6ab5e8)) +* remove unneeded version information ([#1428](https://github.com/open-feature/java-sdk/issues/1428)) ([3ed65cf](https://github.com/open-feature/java-sdk/commit/3ed65cfb0cb5ee5b70793cd68a27909c81cd4fab)) +* skip tests on publish ([6194186](https://github.com/open-feature/java-sdk/commit/6194186b3e791f3cb28da24f5acb3ff96788d65e)) +* update publish env vars ([85d89ee](https://github.com/open-feature/java-sdk/commit/85d89ee79a52d960322731fb786c0f60245f0d75)) + ## [1.15.1](https://github.com/open-feature/java-sdk/compare/v1.14.2...v1.15.1) (2025-05-14) diff --git a/README.md b/README.md index 6593c9b1e..279efba7c 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.15.1 + 1.16.0 ``` @@ -84,7 +84,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:1.15.1' + implementation 'dev.openfeature:sdk:1.16.0' } ``` diff --git a/pom.xml b/pom.xml index 85107f93d..569ca9cd6 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ dev.openfeature sdk - 1.15.1 + 1.16.0 [17,) diff --git a/version.txt b/version.txt index ace44233b..15b989e39 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.15.1 +1.16.0 From 908755c2c2e3abcef84f29728fd19092a9d66646 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Jul 2025 23:04:40 +0000 Subject: [PATCH 304/745] chore(deps): update actions/setup-java digest to c190c18 (#1508) 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 ccf09bac5..fd7338758 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -23,7 +23,7 @@ jobs: steps: - uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f - name: Set up JDK 17 - uses: actions/setup-java@67aec007b3fcabe15ca665bfccc1e255dd52e30d + uses: actions/setup-java@c190c18febcf6c040d80b10ea201a05a2c320263 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 00cf0a525..12a99d1a7 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -22,7 +22,7 @@ jobs: uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f - name: Set up JDK 11 - uses: actions/setup-java@67aec007b3fcabe15ca665bfccc1e255dd52e30d + uses: actions/setup-java@c190c18febcf6c040d80b10ea201a05a2c320263 with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fcdee10f2..3ca029777 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,7 +40,7 @@ jobs: uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f - name: Set up JDK 17 - uses: actions/setup-java@67aec007b3fcabe15ca665bfccc1e255dd52e30d + uses: actions/setup-java@c190c18febcf6c040d80b10ea201a05a2c320263 with: java-version: '17' distribution: 'temurin' From 26716a51cfc720bdb294b50ff3759f8ae41fe410 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 03:14:51 +0000 Subject: [PATCH 305/745] chore(deps): update github/codeql-action digest to 624d0bc (#1507) 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 12a99d1a7..0c4137ed0 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@b69421388d5449cc5a5e1ca344d71926bda69e07 + uses: github/codeql-action/init@624d0bca90f761ffa7ce50c41875a1a226969a02 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b69421388d5449cc5a5e1ca344d71926bda69e07 + uses: github/codeql-action/analyze@624d0bca90f761ffa7ce50c41875a1a226969a02 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index c210033e4..06fdeb037 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@b69421388d5449cc5a5e1ca344d71926bda69e07 + uses: github/codeql-action/init@624d0bca90f761ffa7ce50c41875a1a226969a02 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@b69421388d5449cc5a5e1ca344d71926bda69e07 + uses: github/codeql-action/autobuild@624d0bca90f761ffa7ce50c41875a1a226969a02 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b69421388d5449cc5a5e1ca344d71926bda69e07 + uses: github/codeql-action/analyze@624d0bca90f761ffa7ce50c41875a1a226969a02 From 488196656ad0fbca5211e270bfc55e3d83fa9a2f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 08:28:26 +0200 Subject: [PATCH 306/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.24.0 (#1510) 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 569ca9cd6..3d2993d2f 100644 --- a/pom.xml +++ b/pom.xml @@ -194,7 +194,7 @@ io.cucumber cucumber-bom - 7.23.0 + 7.24.0 pom import From 1e8f5c880c1a0e8f0ccaa7c4b7452a051973f2b6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 06:34:38 +0000 Subject: [PATCH 307/745] chore(deps): update dependency com.google.guava:guava to v33.4.8-jre (#1382) 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 3d2993d2f..c3b1fdf6a 100644 --- a/pom.xml +++ b/pom.xml @@ -150,7 +150,7 @@ com.google.guava guava - 33.4.0-jre + 33.4.8-jre test From 62738f7f16b783eabb7325bed3ac26be086b35e4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 10:17:05 +0200 Subject: [PATCH 308/745] chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v2.45.0 (#1509) 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 c3b1fdf6a..c4461155f 100644 --- a/pom.xml +++ b/pom.xml @@ -463,7 +463,7 @@ com.diffplug.spotless spotless-maven-plugin - 2.44.5 + 2.45.0 From bf68cbdedf6ce7218fadfe3a39df38019da8bcbb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 10 Jul 2025 20:57:58 +0000 Subject: [PATCH 309/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.25.0 (#1514) 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 c4461155f..23abda623 100644 --- a/pom.xml +++ b/pom.xml @@ -194,7 +194,7 @@ io.cucumber cucumber-bom - 7.24.0 + 7.25.0 pom import From aa0569379bd85d11a5f91bd1078cd9f2b3b311b4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 11 Jul 2025 01:45:44 +0000 Subject: [PATCH 310/745] chore(deps): update github/codeql-action digest to f53ec7c (#1512) 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 0c4137ed0..f6061e994 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@624d0bca90f761ffa7ce50c41875a1a226969a02 + uses: github/codeql-action/init@f53ec7c550f4c3cafe07061ed7fba6f002286003 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@624d0bca90f761ffa7ce50c41875a1a226969a02 + uses: github/codeql-action/analyze@f53ec7c550f4c3cafe07061ed7fba6f002286003 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 06fdeb037..98ed87d1f 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@624d0bca90f761ffa7ce50c41875a1a226969a02 + uses: github/codeql-action/init@f53ec7c550f4c3cafe07061ed7fba6f002286003 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@624d0bca90f761ffa7ce50c41875a1a226969a02 + uses: github/codeql-action/autobuild@f53ec7c550f4c3cafe07061ed7fba6f002286003 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@624d0bca90f761ffa7ce50c41875a1a226969a02 + uses: github/codeql-action/analyze@f53ec7c550f4c3cafe07061ed7fba6f002286003 From 006ae75e2b1c745476dfda35113a06fc7fbceafb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Jul 2025 15:49:08 +0200 Subject: [PATCH 311/745] chore(deps): update github/codeql-action digest to 6f936b5 (#1515) 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 f6061e994..4d0968076 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@f53ec7c550f4c3cafe07061ed7fba6f002286003 + uses: github/codeql-action/init@6f936b5c2d7c8b03088ea6ce53d42c43d402b7b0 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f53ec7c550f4c3cafe07061ed7fba6f002286003 + uses: github/codeql-action/analyze@6f936b5c2d7c8b03088ea6ce53d42c43d402b7b0 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 98ed87d1f..046637f3f 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@f53ec7c550f4c3cafe07061ed7fba6f002286003 + uses: github/codeql-action/init@6f936b5c2d7c8b03088ea6ce53d42c43d402b7b0 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@f53ec7c550f4c3cafe07061ed7fba6f002286003 + uses: github/codeql-action/autobuild@6f936b5c2d7c8b03088ea6ce53d42c43d402b7b0 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f53ec7c550f4c3cafe07061ed7fba6f002286003 + uses: github/codeql-action/analyze@6f936b5c2d7c8b03088ea6ce53d42c43d402b7b0 From 1d3fab6184b4ba45b3e4cee420e24be722c76946 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Jul 2025 16:00:25 +0200 Subject: [PATCH 312/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.26.0 (#1516) 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 23abda623..ee619c2ef 100644 --- a/pom.xml +++ b/pom.xml @@ -194,7 +194,7 @@ io.cucumber cucumber-bom - 7.25.0 + 7.26.0 pom import From 5b3e3656f6efad1f9020937bc3ea18078c4defc8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Jul 2025 23:46:35 +0000 Subject: [PATCH 313/745] chore(deps): update github/codeql-action digest to 0d17ea4 (#1517) 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 4d0968076..221209592 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@6f936b5c2d7c8b03088ea6ce53d42c43d402b7b0 + uses: github/codeql-action/init@0d17ea484359c43eb02ea30721ea1c9162d09b37 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6f936b5c2d7c8b03088ea6ce53d42c43d402b7b0 + uses: github/codeql-action/analyze@0d17ea484359c43eb02ea30721ea1c9162d09b37 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 046637f3f..f535e60fd 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@6f936b5c2d7c8b03088ea6ce53d42c43d402b7b0 + uses: github/codeql-action/init@0d17ea484359c43eb02ea30721ea1c9162d09b37 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@6f936b5c2d7c8b03088ea6ce53d42c43d402b7b0 + uses: github/codeql-action/autobuild@0d17ea484359c43eb02ea30721ea1c9162d09b37 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6f936b5c2d7c8b03088ea6ce53d42c43d402b7b0 + uses: github/codeql-action/analyze@0d17ea484359c43eb02ea30721ea1c9162d09b37 From 1382b367d934feaa5effe851f8b03b02bb2482c1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 16 Jul 2025 03:54:58 +0000 Subject: [PATCH 314/745] chore(deps): update actions/setup-java digest to ae2b61d (#1518) 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 fd7338758..c24b46fd2 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -23,7 +23,7 @@ jobs: steps: - uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f - name: Set up JDK 17 - uses: actions/setup-java@c190c18febcf6c040d80b10ea201a05a2c320263 + uses: actions/setup-java@ae2b61dbc685e60e4427b2e8ed4f0135c6ea8597 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 221209592..43c614013 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -22,7 +22,7 @@ jobs: uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f - name: Set up JDK 11 - uses: actions/setup-java@c190c18febcf6c040d80b10ea201a05a2c320263 + uses: actions/setup-java@ae2b61dbc685e60e4427b2e8ed4f0135c6ea8597 with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3ca029777..6b7d10e6e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,7 +40,7 @@ jobs: uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f - name: Set up JDK 17 - uses: actions/setup-java@c190c18febcf6c040d80b10ea201a05a2c320263 + uses: actions/setup-java@ae2b61dbc685e60e4427b2e8ed4f0135c6ea8597 with: java-version: '17' distribution: 'temurin' From cbf7a5862286dc36023095208c3e865b058dacb0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 16 Jul 2025 06:57:06 +0000 Subject: [PATCH 315/745] chore(deps): update dependency maven to v3.9.11 (#1519) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .mvn/wrapper/maven-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 2f94e6169..12fbe1e90 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -16,4 +16,4 @@ # under the License. wrapperVersion=3.3.2 distributionType=only-script -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.10/apache-maven-3.9.10-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip From ecc8f7e3ade314c050c67710ae96a182534b9692 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 17 Jul 2025 16:35:35 +0200 Subject: [PATCH 316/745] chore(deps): update github/codeql-action digest to 03a2a17 (#1520) 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 43c614013..5316ea13a 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@0d17ea484359c43eb02ea30721ea1c9162d09b37 + uses: github/codeql-action/init@03a2a17e75d20e4ff461b43f161fb2b52165f632 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0d17ea484359c43eb02ea30721ea1c9162d09b37 + uses: github/codeql-action/analyze@03a2a17e75d20e4ff461b43f161fb2b52165f632 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index f535e60fd..3c14fcc3e 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@0d17ea484359c43eb02ea30721ea1c9162d09b37 + uses: github/codeql-action/init@03a2a17e75d20e4ff461b43f161fb2b52165f632 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@0d17ea484359c43eb02ea30721ea1c9162d09b37 + uses: github/codeql-action/autobuild@03a2a17e75d20e4ff461b43f161fb2b52165f632 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0d17ea484359c43eb02ea30721ea1c9162d09b37 + uses: github/codeql-action/analyze@03a2a17e75d20e4ff461b43f161fb2b52165f632 From ac3344c7f6293ac72523a5d0c5e61d4304c0a8b1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 17 Jul 2025 21:51:17 +0000 Subject: [PATCH 317/745] chore(deps): update github/codeql-action digest to 7710ed1 (#1521) 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 5316ea13a..f41b552ed 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@03a2a17e75d20e4ff461b43f161fb2b52165f632 + uses: github/codeql-action/init@7710ed11e398ea99c7f7004c2b2e0f580458db42 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@03a2a17e75d20e4ff461b43f161fb2b52165f632 + uses: github/codeql-action/analyze@7710ed11e398ea99c7f7004c2b2e0f580458db42 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 3c14fcc3e..dee0bfa4f 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@03a2a17e75d20e4ff461b43f161fb2b52165f632 + uses: github/codeql-action/init@7710ed11e398ea99c7f7004c2b2e0f580458db42 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@03a2a17e75d20e4ff461b43f161fb2b52165f632 + uses: github/codeql-action/autobuild@7710ed11e398ea99c7f7004c2b2e0f580458db42 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@03a2a17e75d20e4ff461b43f161fb2b52165f632 + uses: github/codeql-action/analyze@7710ed11e398ea99c7f7004c2b2e0f580458db42 From 844f6df33542b927d38627f9a8ee5f9371e47aca Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 21 Jul 2025 01:00:06 +0000 Subject: [PATCH 318/745] chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v2.46.0 (#1522) 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 ee619c2ef..df35edb23 100644 --- a/pom.xml +++ b/pom.xml @@ -463,7 +463,7 @@ com.diffplug.spotless spotless-maven-plugin - 2.45.0 + 2.46.0 From db47b7e8233970b0bf37dbb5679227d1917e15b7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 21 Jul 2025 15:24:17 +0200 Subject: [PATCH 319/745] fix(deps): update dependency org.junit:junit-bom to v5.13.4 (#1524) 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 df35edb23..8da4b440a 100644 --- a/pom.xml +++ b/pom.xml @@ -202,7 +202,7 @@ org.junit junit-bom - 5.13.3 + 5.13.4 pom import From 66215efaf3a18eeeb4c244775d6a72725a274097 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 21 Jul 2025 23:52:07 +0000 Subject: [PATCH 320/745] chore(deps): update github/codeql-action digest to eefe1b5 (#1523) 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 f41b552ed..c1bc5952b 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@7710ed11e398ea99c7f7004c2b2e0f580458db42 + uses: github/codeql-action/init@eefe1b5db9f28481d2bf2bd096da3873c1cd2a7b with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7710ed11e398ea99c7f7004c2b2e0f580458db42 + uses: github/codeql-action/analyze@eefe1b5db9f28481d2bf2bd096da3873c1cd2a7b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index dee0bfa4f..2eb6ff0e9 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@7710ed11e398ea99c7f7004c2b2e0f580458db42 + uses: github/codeql-action/init@eefe1b5db9f28481d2bf2bd096da3873c1cd2a7b with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@7710ed11e398ea99c7f7004c2b2e0f580458db42 + uses: github/codeql-action/autobuild@eefe1b5db9f28481d2bf2bd096da3873c1cd2a7b - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7710ed11e398ea99c7f7004c2b2e0f580458db42 + uses: github/codeql-action/analyze@eefe1b5db9f28481d2bf2bd096da3873c1cd2a7b From 91e451b29b10031a9697156194af1d209ee5fec6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 22 Jul 2025 04:48:22 +0000 Subject: [PATCH 321/745] chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v2.46.1 (#1526) 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 8da4b440a..5b44a6231 100644 --- a/pom.xml +++ b/pom.xml @@ -463,7 +463,7 @@ com.diffplug.spotless spotless-maven-plugin - 2.46.0 + 2.46.1 From c05757e4895253053e49982dbe8f16ef501fd038 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 23 Jul 2025 04:13:42 +0000 Subject: [PATCH 322/745] chore(deps): update github/codeql-action digest to 76bf77d (#1527) 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 c1bc5952b..c7b319bae 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@eefe1b5db9f28481d2bf2bd096da3873c1cd2a7b + uses: github/codeql-action/init@76bf77db0b4f84ce3351e7dccabb79e3e2aa8ad3 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@eefe1b5db9f28481d2bf2bd096da3873c1cd2a7b + uses: github/codeql-action/analyze@76bf77db0b4f84ce3351e7dccabb79e3e2aa8ad3 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 2eb6ff0e9..b5d1cffab 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@eefe1b5db9f28481d2bf2bd096da3873c1cd2a7b + uses: github/codeql-action/init@76bf77db0b4f84ce3351e7dccabb79e3e2aa8ad3 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@eefe1b5db9f28481d2bf2bd096da3873c1cd2a7b + uses: github/codeql-action/autobuild@76bf77db0b4f84ce3351e7dccabb79e3e2aa8ad3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@eefe1b5db9f28481d2bf2bd096da3873c1cd2a7b + uses: github/codeql-action/analyze@76bf77db0b4f84ce3351e7dccabb79e3e2aa8ad3 From 074a5ec52d7591e5b06801782415d1f2c930086e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 23 Jul 2025 23:34:45 +0000 Subject: [PATCH 323/745] chore(deps): update actions/checkout digest to 8edcb1b (#1529) 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 +- .github/workflows/static-code-scanning.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index c24b46fd2..b1a40f191 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f + - uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709 - name: Set up JDK 17 uses: actions/setup-java@ae2b61dbc685e60e4427b2e8ed4f0135c6ea8597 with: diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index c7b319bae..c1f5fe12c 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -19,7 +19,7 @@ jobs: runs-on: ${{ matrix.os}} steps: - name: Check out the code - uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f + uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709 - name: Set up JDK 11 uses: actions/setup-java@ae2b61dbc685e60e4427b2e8ed4f0135c6ea8597 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6b7d10e6e..8d11a94aa 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,7 +37,7 @@ jobs: steps: - name: Checkout Repository - uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f + uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709 - name: Set up JDK 17 uses: actions/setup-java@ae2b61dbc685e60e4427b2e8ed4f0135c6ea8597 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index b5d1cffab..0d2351c5e 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@09d2acae674a48949e3602304ab46fd20ae0c42f + uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL From b5e335c3ee7865f26bcd688953204280affe2834 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 24 Jul 2025 04:27:17 +0000 Subject: [PATCH 324/745] chore(deps): update github/codeql-action digest to 701df0e (#1528) 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 c1f5fe12c..5c29eebf8 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@76bf77db0b4f84ce3351e7dccabb79e3e2aa8ad3 + uses: github/codeql-action/init@701df0e49d84a24bd8f0d01f80c0dbf69ab07674 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@76bf77db0b4f84ce3351e7dccabb79e3e2aa8ad3 + uses: github/codeql-action/analyze@701df0e49d84a24bd8f0d01f80c0dbf69ab07674 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 0d2351c5e..f36045df5 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@76bf77db0b4f84ce3351e7dccabb79e3e2aa8ad3 + uses: github/codeql-action/init@701df0e49d84a24bd8f0d01f80c0dbf69ab07674 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@76bf77db0b4f84ce3351e7dccabb79e3e2aa8ad3 + uses: github/codeql-action/autobuild@701df0e49d84a24bd8f0d01f80c0dbf69ab07674 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@76bf77db0b4f84ce3351e7dccabb79e3e2aa8ad3 + uses: github/codeql-action/analyze@701df0e49d84a24bd8f0d01f80c0dbf69ab07674 From c06d6d588d529ae52d763a8dcf414b7aa1025d81 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 28 Jul 2025 03:42:49 +0000 Subject: [PATCH 325/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.27.0 (#1530) 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 5b44a6231..3a12111cf 100644 --- a/pom.xml +++ b/pom.xml @@ -194,7 +194,7 @@ io.cucumber cucumber-bom - 7.26.0 + 7.27.0 pom import From 15aaf5800f0fb2b8d22415fa5d9b61dacc651932 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 30 Jul 2025 04:50:26 +0000 Subject: [PATCH 326/745] chore(deps): update github/codeql-action digest to acdac9e (#1531) 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 5c29eebf8..810516eb0 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@701df0e49d84a24bd8f0d01f80c0dbf69ab07674 + uses: github/codeql-action/init@acdac9e37d9d390cc88350d33ef1206ce28c3f71 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@701df0e49d84a24bd8f0d01f80c0dbf69ab07674 + uses: github/codeql-action/analyze@acdac9e37d9d390cc88350d33ef1206ce28c3f71 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index f36045df5..771ab168e 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@701df0e49d84a24bd8f0d01f80c0dbf69ab07674 + uses: github/codeql-action/init@acdac9e37d9d390cc88350d33ef1206ce28c3f71 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@701df0e49d84a24bd8f0d01f80c0dbf69ab07674 + uses: github/codeql-action/autobuild@acdac9e37d9d390cc88350d33ef1206ce28c3f71 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@701df0e49d84a24bd8f0d01f80c0dbf69ab07674 + uses: github/codeql-action/analyze@acdac9e37d9d390cc88350d33ef1206ce28c3f71 From 7cca589a7e2de6f3a9ec2d803dd9564205af722a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 30 Jul 2025 22:58:24 +0000 Subject: [PATCH 327/745] chore(deps): update actions/setup-java digest to e9343db (#1535) 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 b1a40f191..847f26671 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -23,7 +23,7 @@ jobs: steps: - uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709 - name: Set up JDK 17 - uses: actions/setup-java@ae2b61dbc685e60e4427b2e8ed4f0135c6ea8597 + uses: actions/setup-java@e9343db97e09d87a3c50e544105d99fe912c204b with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 810516eb0..b93d73670 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -22,7 +22,7 @@ jobs: uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709 - name: Set up JDK 11 - uses: actions/setup-java@ae2b61dbc685e60e4427b2e8ed4f0135c6ea8597 + uses: actions/setup-java@e9343db97e09d87a3c50e544105d99fe912c204b with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8d11a94aa..347cad75d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,7 +40,7 @@ jobs: uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709 - name: Set up JDK 17 - uses: actions/setup-java@ae2b61dbc685e60e4427b2e8ed4f0135c6ea8597 + uses: actions/setup-java@e9343db97e09d87a3c50e544105d99fe912c204b with: java-version: '17' distribution: 'temurin' From 477d7ce752ecbc5b3ad13753888d5ee6b650c390 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 31 Jul 2025 00:27:38 +0000 Subject: [PATCH 328/745] chore(deps): update github/codeql-action digest to b9b3b12 (#1533) 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 b93d73670..0b65e7f81 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@acdac9e37d9d390cc88350d33ef1206ce28c3f71 + uses: github/codeql-action/init@b9b3b12fa29bb4f95fb2e36128124ff9364aaf0e with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@acdac9e37d9d390cc88350d33ef1206ce28c3f71 + uses: github/codeql-action/analyze@b9b3b12fa29bb4f95fb2e36128124ff9364aaf0e diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 771ab168e..3cc2949b1 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@acdac9e37d9d390cc88350d33ef1206ce28c3f71 + uses: github/codeql-action/init@b9b3b12fa29bb4f95fb2e36128124ff9364aaf0e with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@acdac9e37d9d390cc88350d33ef1206ce28c3f71 + uses: github/codeql-action/autobuild@b9b3b12fa29bb4f95fb2e36128124ff9364aaf0e - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@acdac9e37d9d390cc88350d33ef1206ce28c3f71 + uses: github/codeql-action/analyze@b9b3b12fa29bb4f95fb2e36128124ff9364aaf0e From 09e3c3faf8fe6c3e8c4d46c6fa3e3a7a2dd8f146 Mon Sep 17 00:00:00 2001 From: carla-was-not-available <92949899+carla-was-not-available@users.noreply.github.com> Date: Thu, 31 Jul 2025 09:57:44 +0200 Subject: [PATCH 329/745] feat: Allow Access to ImmutableMetadata Map as unmodifiable Map (#1534) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: Allow Access to ImmutableMetadata Map as unmodifiable Map Oriented on the AbstractStructure closes: #1532 Signed-off-by: Carla Köberl * fixup: adding back java doc Signed-off-by: Carla Köberl --------- Signed-off-by: Carla Köberl Co-authored-by: chrfwow --- .../java/dev/openfeature/sdk/ImmutableMetadata.java | 5 +++++ .../dev/openfeature/sdk/ImmutableMetadataTest.java | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java b/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java index 7f57a174d..f6c1d742e 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java @@ -1,5 +1,6 @@ package dev.openfeature.sdk; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import lombok.EqualsAndHashCode; @@ -97,6 +98,10 @@ public T getValue(final String key, final Class type) { } } + public Map asUnmodifiableMap() { + return Collections.unmodifiableMap(metadata); + } + public boolean isEmpty() { return metadata.isEmpty(); } diff --git a/src/test/java/dev/openfeature/sdk/ImmutableMetadataTest.java b/src/test/java/dev/openfeature/sdk/ImmutableMetadataTest.java index e3bd03165..108fac0fe 100644 --- a/src/test/java/dev/openfeature/sdk/ImmutableMetadataTest.java +++ b/src/test/java/dev/openfeature/sdk/ImmutableMetadataTest.java @@ -3,6 +3,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; +import java.util.Map; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; class ImmutableMetadataTest { @@ -25,4 +27,15 @@ void equalImmutableMetadataAreEqual() { assertEquals(i1, i2); } + + @Test + void retrieveAsUnmodifiableMap() { + ImmutableMetadata metadata = + ImmutableMetadata.builder().addString("key1", "value1").build(); + + Map unmodifiableMap = metadata.asUnmodifiableMap(); + assertEquals(unmodifiableMap.size(), 1); + assertEquals(unmodifiableMap.get("key1"), "value1"); + Assertions.assertThrows(UnsupportedOperationException.class, () -> unmodifiableMap.put("key3", "value3")); + } } From 4addf6458dacbc00bb599a758d87478e6d97d369 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 1 Aug 2025 21:03:59 +0000 Subject: [PATCH 330/745] chore(deps): update github/codeql-action digest to 7273f08 (#1537) 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 0b65e7f81..d50d446ca 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@b9b3b12fa29bb4f95fb2e36128124ff9364aaf0e + uses: github/codeql-action/init@7273f08caa1dcf2c2837f362f1982de0ab4dc344 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b9b3b12fa29bb4f95fb2e36128124ff9364aaf0e + uses: github/codeql-action/analyze@7273f08caa1dcf2c2837f362f1982de0ab4dc344 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 3cc2949b1..882a47478 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@b9b3b12fa29bb4f95fb2e36128124ff9364aaf0e + uses: github/codeql-action/init@7273f08caa1dcf2c2837f362f1982de0ab4dc344 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@b9b3b12fa29bb4f95fb2e36128124ff9364aaf0e + uses: github/codeql-action/autobuild@7273f08caa1dcf2c2837f362f1982de0ab4dc344 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b9b3b12fa29bb4f95fb2e36128124ff9364aaf0e + uses: github/codeql-action/analyze@7273f08caa1dcf2c2837f362f1982de0ab4dc344 From f2dfc63beef1beef6aad7d00cc1aaeb78c0fc57c Mon Sep 17 00:00:00 2001 From: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> Date: Tue, 5 Aug 2025 09:48:07 -0400 Subject: [PATCH 331/745] chore(main): release 1.17.0 (#1511) Signed-off-by: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 41 +++++++++++++++++++++++++++++++++++ README.md | 8 +++---- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 48 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 8997e1812..f5c3b938e 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"1.16.0"} +{".":"1.17.0"} diff --git a/CHANGELOG.md b/CHANGELOG.md index 2529b1871..5513f0e55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,46 @@ # Changelog +## [1.17.0](https://github.com/open-feature/java-sdk/compare/v1.16.0...v1.17.0) (2025-08-01) + + +### 🐛 Bug Fixes + +* **deps:** update dependency io.cucumber:cucumber-bom to v7.24.0 ([#1510](https://github.com/open-feature/java-sdk/issues/1510)) ([4881966](https://github.com/open-feature/java-sdk/commit/488196656ad0fbca5211e270bfc55e3d83fa9a2f)) +* **deps:** update dependency io.cucumber:cucumber-bom to v7.25.0 ([#1514](https://github.com/open-feature/java-sdk/issues/1514)) ([bf68cbd](https://github.com/open-feature/java-sdk/commit/bf68cbdedf6ce7218fadfe3a39df38019da8bcbb)) +* **deps:** update dependency io.cucumber:cucumber-bom to v7.26.0 ([#1516](https://github.com/open-feature/java-sdk/issues/1516)) ([1d3fab6](https://github.com/open-feature/java-sdk/commit/1d3fab6184b4ba45b3e4cee420e24be722c76946)) +* **deps:** update dependency io.cucumber:cucumber-bom to v7.27.0 ([#1530](https://github.com/open-feature/java-sdk/issues/1530)) ([c06d6d5](https://github.com/open-feature/java-sdk/commit/c06d6d588d529ae52d763a8dcf414b7aa1025d81)) +* **deps:** update dependency org.junit:junit-bom to v5.13.4 ([#1524](https://github.com/open-feature/java-sdk/issues/1524)) ([db47b7e](https://github.com/open-feature/java-sdk/commit/db47b7e8233970b0bf37dbb5679227d1917e15b7)) + + +### ✨ New Features + +* Allow Access to ImmutableMetadata Map as unmodifiable Map ([#1534](https://github.com/open-feature/java-sdk/issues/1534)) ([09e3c3f](https://github.com/open-feature/java-sdk/commit/09e3c3faf8fe6c3e8c4d46c6fa3e3a7a2dd8f146)) + + +### 🧹 Chore + +* **deps:** update actions/checkout digest to 8edcb1b ([#1529](https://github.com/open-feature/java-sdk/issues/1529)) ([074a5ec](https://github.com/open-feature/java-sdk/commit/074a5ec52d7591e5b06801782415d1f2c930086e)) +* **deps:** update actions/setup-java digest to ae2b61d ([#1518](https://github.com/open-feature/java-sdk/issues/1518)) ([1382b36](https://github.com/open-feature/java-sdk/commit/1382b367d934feaa5effe851f8b03b02bb2482c1)) +* **deps:** update actions/setup-java digest to c190c18 ([#1508](https://github.com/open-feature/java-sdk/issues/1508)) ([908755c](https://github.com/open-feature/java-sdk/commit/908755c2c2e3abcef84f29728fd19092a9d66646)) +* **deps:** update actions/setup-java digest to e9343db ([#1535](https://github.com/open-feature/java-sdk/issues/1535)) ([7cca589](https://github.com/open-feature/java-sdk/commit/7cca589a7e2de6f3a9ec2d803dd9564205af722a)) +* **deps:** update dependency com.diffplug.spotless:spotless-maven-plugin to v2.45.0 ([#1509](https://github.com/open-feature/java-sdk/issues/1509)) ([62738f7](https://github.com/open-feature/java-sdk/commit/62738f7f16b783eabb7325bed3ac26be086b35e4)) +* **deps:** update dependency com.diffplug.spotless:spotless-maven-plugin to v2.46.0 ([#1522](https://github.com/open-feature/java-sdk/issues/1522)) ([844f6df](https://github.com/open-feature/java-sdk/commit/844f6df33542b927d38627f9a8ee5f9371e47aca)) +* **deps:** update dependency com.diffplug.spotless:spotless-maven-plugin to v2.46.1 ([#1526](https://github.com/open-feature/java-sdk/issues/1526)) ([91e451b](https://github.com/open-feature/java-sdk/commit/91e451b29b10031a9697156194af1d209ee5fec6)) +* **deps:** update dependency com.google.guava:guava to v33.4.8-jre ([#1382](https://github.com/open-feature/java-sdk/issues/1382)) ([1e8f5c8](https://github.com/open-feature/java-sdk/commit/1e8f5c880c1a0e8f0ccaa7c4b7452a051973f2b6)) +* **deps:** update dependency maven to v3.9.11 ([#1519](https://github.com/open-feature/java-sdk/issues/1519)) ([cbf7a58](https://github.com/open-feature/java-sdk/commit/cbf7a5862286dc36023095208c3e865b058dacb0)) +* **deps:** update github/codeql-action digest to 03a2a17 ([#1520](https://github.com/open-feature/java-sdk/issues/1520)) ([ecc8f7e](https://github.com/open-feature/java-sdk/commit/ecc8f7e3ade314c050c67710ae96a182534b9692)) +* **deps:** update github/codeql-action digest to 0d17ea4 ([#1517](https://github.com/open-feature/java-sdk/issues/1517)) ([5b3e365](https://github.com/open-feature/java-sdk/commit/5b3e3656f6efad1f9020937bc3ea18078c4defc8)) +* **deps:** update github/codeql-action digest to 624d0bc ([#1507](https://github.com/open-feature/java-sdk/issues/1507)) ([26716a5](https://github.com/open-feature/java-sdk/commit/26716a51cfc720bdb294b50ff3759f8ae41fe410)) +* **deps:** update github/codeql-action digest to 6f936b5 ([#1515](https://github.com/open-feature/java-sdk/issues/1515)) ([006ae75](https://github.com/open-feature/java-sdk/commit/006ae75e2b1c745476dfda35113a06fc7fbceafb)) +* **deps:** update github/codeql-action digest to 701df0e ([#1528](https://github.com/open-feature/java-sdk/issues/1528)) ([b5e335c](https://github.com/open-feature/java-sdk/commit/b5e335c3ee7865f26bcd688953204280affe2834)) +* **deps:** update github/codeql-action digest to 7273f08 ([#1537](https://github.com/open-feature/java-sdk/issues/1537)) ([4addf64](https://github.com/open-feature/java-sdk/commit/4addf6458dacbc00bb599a758d87478e6d97d369)) +* **deps:** update github/codeql-action digest to 76bf77d ([#1527](https://github.com/open-feature/java-sdk/issues/1527)) ([c05757e](https://github.com/open-feature/java-sdk/commit/c05757e4895253053e49982dbe8f16ef501fd038)) +* **deps:** update github/codeql-action digest to 7710ed1 ([#1521](https://github.com/open-feature/java-sdk/issues/1521)) ([ac3344c](https://github.com/open-feature/java-sdk/commit/ac3344c7f6293ac72523a5d0c5e61d4304c0a8b1)) +* **deps:** update github/codeql-action digest to acdac9e ([#1531](https://github.com/open-feature/java-sdk/issues/1531)) ([15aaf58](https://github.com/open-feature/java-sdk/commit/15aaf5800f0fb2b8d22415fa5d9b61dacc651932)) +* **deps:** update github/codeql-action digest to b9b3b12 ([#1533](https://github.com/open-feature/java-sdk/issues/1533)) ([477d7ce](https://github.com/open-feature/java-sdk/commit/477d7ce752ecbc5b3ad13753888d5ee6b650c390)) +* **deps:** update github/codeql-action digest to eefe1b5 ([#1523](https://github.com/open-feature/java-sdk/issues/1523)) ([66215ef](https://github.com/open-feature/java-sdk/commit/66215efaf3a18eeeb4c244775d6a72725a274097)) +* **deps:** update github/codeql-action digest to f53ec7c ([#1512](https://github.com/open-feature/java-sdk/issues/1512)) ([aa05693](https://github.com/open-feature/java-sdk/commit/aa0569379bd85d11a5f91bd1078cd9f2b3b311b4)) + ## [1.16.0](https://github.com/open-feature/java-sdk/compare/v1.15.1...v1.16.0) (2025-07-07) diff --git a/README.md b/README.md index 279efba7c..24bae2a3c 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.16.0 + 1.17.0 ``` @@ -84,7 +84,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:1.16.0' + implementation 'dev.openfeature:sdk:1.17.0' } ``` diff --git a/pom.xml b/pom.xml index 3a12111cf..1c9c8fa05 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ dev.openfeature sdk - 1.16.0 + 1.17.0 [17,) diff --git a/version.txt b/version.txt index 15b989e39..092afa15d 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.16.0 +1.17.0 From 60568776c471e7c01f8cee6b198fe6df70fc2ca5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 5 Aug 2025 16:24:38 +0000 Subject: [PATCH 332/745] chore(deps): update github/codeql-action digest to bbfff2f (#1538) 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 d50d446ca..42bb6058b 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@7273f08caa1dcf2c2837f362f1982de0ab4dc344 + uses: github/codeql-action/init@bbfff2f20a2d2b1bb30040286e0de8e59432af64 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7273f08caa1dcf2c2837f362f1982de0ab4dc344 + uses: github/codeql-action/analyze@bbfff2f20a2d2b1bb30040286e0de8e59432af64 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 882a47478..b09caa446 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@7273f08caa1dcf2c2837f362f1982de0ab4dc344 + uses: github/codeql-action/init@bbfff2f20a2d2b1bb30040286e0de8e59432af64 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@7273f08caa1dcf2c2837f362f1982de0ab4dc344 + uses: github/codeql-action/autobuild@bbfff2f20a2d2b1bb30040286e0de8e59432af64 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7273f08caa1dcf2c2837f362f1982de0ab4dc344 + uses: github/codeql-action/analyze@bbfff2f20a2d2b1bb30040286e0de8e59432af64 From bc587809341d60eeb575b0d58d75b35972b92053 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Aug 2025 14:53:44 +0200 Subject: [PATCH 333/745] chore(deps): update github/codeql-action digest to b1228d0 (#1540) 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 42bb6058b..37bc7c976 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@bbfff2f20a2d2b1bb30040286e0de8e59432af64 + uses: github/codeql-action/init@b1228d060cad1666537a3dd6154790c05090bd3b with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@bbfff2f20a2d2b1bb30040286e0de8e59432af64 + uses: github/codeql-action/analyze@b1228d060cad1666537a3dd6154790c05090bd3b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index b09caa446..217191206 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@bbfff2f20a2d2b1bb30040286e0de8e59432af64 + uses: github/codeql-action/init@b1228d060cad1666537a3dd6154790c05090bd3b with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@bbfff2f20a2d2b1bb30040286e0de8e59432af64 + uses: github/codeql-action/autobuild@b1228d060cad1666537a3dd6154790c05090bd3b - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@bbfff2f20a2d2b1bb30040286e0de8e59432af64 + uses: github/codeql-action/analyze@b1228d060cad1666537a3dd6154790c05090bd3b From 6efc2ee1e701daf38e3efc2f115dc93025a0e2e2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Aug 2025 00:56:38 +0000 Subject: [PATCH 334/745] chore(deps): update actions/cache digest to 358a730 (#1541) 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 847f26671..015306b03 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -33,7 +33,7 @@ jobs: server-password: ${{ secrets.CENTRAL_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@640a1c2554105b57832a23eea0b4672fc7a790d5 + uses: actions/cache@358a7306cd9d78ceffc19271e69cd8528462fccf 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 37bc7c976..7e7639f20 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@640a1c2554105b57832a23eea0b4672fc7a790d5 + uses: actions/cache@358a7306cd9d78ceffc19271e69cd8528462fccf with: path: ~/.m2/repository key: ${{ runner.os }}${{ matrix.build.java }}-maven-${{ hashFiles('**/pom.xml') }} From 7ccbb714b305deb9fa0e31ace1bd7f044c8c57ed Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Aug 2025 05:07:14 +0000 Subject: [PATCH 335/745] chore(deps): update github/codeql-action digest to e2b6f0f (#1542) 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 7e7639f20..b7410ab49 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@b1228d060cad1666537a3dd6154790c05090bd3b + uses: github/codeql-action/init@e2b6f0f4a336fec2e2b57b908df292ca6d2a0fa3 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b1228d060cad1666537a3dd6154790c05090bd3b + uses: github/codeql-action/analyze@e2b6f0f4a336fec2e2b57b908df292ca6d2a0fa3 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 217191206..23bc98911 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@b1228d060cad1666537a3dd6154790c05090bd3b + uses: github/codeql-action/init@e2b6f0f4a336fec2e2b57b908df292ca6d2a0fa3 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@b1228d060cad1666537a3dd6154790c05090bd3b + uses: github/codeql-action/autobuild@e2b6f0f4a336fec2e2b57b908df292ca6d2a0fa3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b1228d060cad1666537a3dd6154790c05090bd3b + uses: github/codeql-action/analyze@e2b6f0f4a336fec2e2b57b908df292ca6d2a0fa3 From 050379be110b7a980cf5cc02ddf23e00a7ee7202 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Aug 2025 17:33:28 +0000 Subject: [PATCH 336/745] chore(deps): update actions/cache digest to 0400d5f (#1544) 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 015306b03..03ba304e4 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -33,7 +33,7 @@ jobs: server-password: ${{ secrets.CENTRAL_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@358a7306cd9d78ceffc19271e69cd8528462fccf + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 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 b7410ab49..2ef9996d0 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@358a7306cd9d78ceffc19271e69cd8528462fccf + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 with: path: ~/.m2/repository key: ${{ runner.os }}${{ matrix.build.java }}-maven-${{ hashFiles('**/pom.xml') }} From c4fe7d2e81510db4eaa13a4d0046827efecd8a79 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Aug 2025 20:54:38 +0000 Subject: [PATCH 337/745] chore(deps): update dependency org.assertj:assertj-core to v3.27.4 (#1546) 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 1c9c8fa05..a64987c34 100644 --- a/pom.xml +++ b/pom.xml @@ -88,7 +88,7 @@ org.assertj assertj-core - 3.27.3 + 3.27.4 test From 866235e494c229b3d47df80146199db4204b2ece Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Aug 2025 01:32:06 +0000 Subject: [PATCH 338/745] chore(deps): update github/codeql-action digest to 6fe50b2 (#1545) 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 2ef9996d0..a3085f90c 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@e2b6f0f4a336fec2e2b57b908df292ca6d2a0fa3 + uses: github/codeql-action/init@6fe50b283a3d2e5533299f72d99216cd8815500f with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e2b6f0f4a336fec2e2b57b908df292ca6d2a0fa3 + uses: github/codeql-action/analyze@6fe50b283a3d2e5533299f72d99216cd8815500f diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 23bc98911..e8d7d5635 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@e2b6f0f4a336fec2e2b57b908df292ca6d2a0fa3 + uses: github/codeql-action/init@6fe50b283a3d2e5533299f72d99216cd8815500f with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@e2b6f0f4a336fec2e2b57b908df292ca6d2a0fa3 + uses: github/codeql-action/autobuild@6fe50b283a3d2e5533299f72d99216cd8815500f - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e2b6f0f4a336fec2e2b57b908df292ca6d2a0fa3 + uses: github/codeql-action/analyze@6fe50b283a3d2e5533299f72d99216cd8815500f From 09b31383e3b7e693ec43d6016486e3ededf8c2de Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Aug 2025 17:23:25 +0000 Subject: [PATCH 339/745] chore(deps): update github/codeql-action digest to 4474150 (#1547) 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 a3085f90c..8ba31b911 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@6fe50b283a3d2e5533299f72d99216cd8815500f + uses: github/codeql-action/init@4474150eef8c855ab74a7f19f3ae525e469d2de6 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6fe50b283a3d2e5533299f72d99216cd8815500f + uses: github/codeql-action/analyze@4474150eef8c855ab74a7f19f3ae525e469d2de6 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index e8d7d5635..1062db2c3 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@6fe50b283a3d2e5533299f72d99216cd8815500f + uses: github/codeql-action/init@4474150eef8c855ab74a7f19f3ae525e469d2de6 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@6fe50b283a3d2e5533299f72d99216cd8815500f + uses: github/codeql-action/autobuild@4474150eef8c855ab74a7f19f3ae525e469d2de6 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6fe50b283a3d2e5533299f72d99216cd8815500f + uses: github/codeql-action/analyze@4474150eef8c855ab74a7f19f3ae525e469d2de6 From f2fef65eb580b1960ad15b2c46ebe40855551be3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 10 Aug 2025 04:35:37 +0000 Subject: [PATCH 340/745] fix(deps): update dependency com.github.spotbugs:spotbugs to v4.9.4 (#1548) 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 a64987c34..92bb0c1ca 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ com.github.spotbugs spotbugs - 4.8.6 + 4.9.4 provided @@ -419,7 +419,7 @@ com.github.spotbugs spotbugs - 4.8.6 + 4.9.4 From 7f487ee7ecd1c69a63d22eca140bc422a0afc963 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Aug 2025 16:26:43 +0200 Subject: [PATCH 341/745] chore(deps): update actions/cache digest to 638ed79 (#1549) 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 03ba304e4..16712ed2a 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -33,7 +33,7 @@ jobs: server-password: ${{ secrets.CENTRAL_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 + uses: actions/cache@638ed79f9dc94c1de1baef91bcab5edaa19451f4 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 8ba31b911..a654a9114 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@0400d5f644dc74513175e3cd8d07132dd4860809 + uses: actions/cache@638ed79f9dc94c1de1baef91bcab5edaa19451f4 with: path: ~/.m2/repository key: ${{ runner.os }}${{ matrix.build.java }}-maven-${{ hashFiles('**/pom.xml') }} From 527e3f836f664ecace1018de84502592ee75007c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Aug 2025 18:36:18 +0000 Subject: [PATCH 342/745] chore(deps): update actions/checkout digest to 08c6903 (#1550) 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 +- .github/workflows/static-code-scanning.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index 16712ed2a..b5b40ae6c 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 - name: Set up JDK 17 uses: actions/setup-java@e9343db97e09d87a3c50e544105d99fe912c204b with: diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index a654a9114..08a88a7ee 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -19,7 +19,7 @@ jobs: runs-on: ${{ matrix.os}} steps: - name: Check out the code - uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 - name: Set up JDK 11 uses: actions/setup-java@e9343db97e09d87a3c50e544105d99fe912c204b diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 347cad75d..2a31ffe49 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,7 +37,7 @@ jobs: steps: - name: Checkout Repository - uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 - name: Set up JDK 17 uses: actions/setup-java@e9343db97e09d87a3c50e544105d99fe912c204b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 1062db2c3..e6c720ce0 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL From ce2b6e88313ea500c2b71f0b4c06ad4a12522f3e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Aug 2025 21:22:45 +0000 Subject: [PATCH 343/745] chore(deps): update github/codeql-action digest to c6dcdfa (#1551) 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 08a88a7ee..a95814a9b 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@4474150eef8c855ab74a7f19f3ae525e469d2de6 + uses: github/codeql-action/init@c6dcdfa33a7454bb54083cae422eb0d285ad74bc with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4474150eef8c855ab74a7f19f3ae525e469d2de6 + uses: github/codeql-action/analyze@c6dcdfa33a7454bb54083cae422eb0d285ad74bc diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index e6c720ce0..9733bb3ce 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@4474150eef8c855ab74a7f19f3ae525e469d2de6 + uses: github/codeql-action/init@c6dcdfa33a7454bb54083cae422eb0d285ad74bc with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@4474150eef8c855ab74a7f19f3ae525e469d2de6 + uses: github/codeql-action/autobuild@c6dcdfa33a7454bb54083cae422eb0d285ad74bc - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4474150eef8c855ab74a7f19f3ae525e469d2de6 + uses: github/codeql-action/analyze@c6dcdfa33a7454bb54083cae422eb0d285ad74bc From d2f85d5a9e42c0e336546684b27a1e77edc4c620 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 08:15:02 +0200 Subject: [PATCH 344/745] chore(deps): update dependency com.puppycrawl.tools:checkstyle to v11 (#1543) 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 92bb0c1ca..7215c25c6 100644 --- a/pom.xml +++ b/pom.xml @@ -447,7 +447,7 @@ com.puppycrawl.tools checkstyle - 10.26.1 + 11.0.0 From 4bae3294b20f19550a878f331cba2377df14f7c1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 17:10:29 +0000 Subject: [PATCH 345/745] chore(deps): update github/codeql-action digest to eef4c44 (#1552) 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 a95814a9b..b22d3c2a5 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@c6dcdfa33a7454bb54083cae422eb0d285ad74bc + uses: github/codeql-action/init@eef4c44f6bb262e0bbf01432030812aaaabdebf3 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c6dcdfa33a7454bb54083cae422eb0d285ad74bc + uses: github/codeql-action/analyze@eef4c44f6bb262e0bbf01432030812aaaabdebf3 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 9733bb3ce..07868de79 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@c6dcdfa33a7454bb54083cae422eb0d285ad74bc + uses: github/codeql-action/init@eef4c44f6bb262e0bbf01432030812aaaabdebf3 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@c6dcdfa33a7454bb54083cae422eb0d285ad74bc + uses: github/codeql-action/autobuild@eef4c44f6bb262e0bbf01432030812aaaabdebf3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c6dcdfa33a7454bb54083cae422eb0d285ad74bc + uses: github/codeql-action/analyze@eef4c44f6bb262e0bbf01432030812aaaabdebf3 From 35fe5b41bc971f8bc41b82b8c0ef50d719071301 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 13 Aug 2025 22:14:25 +0000 Subject: [PATCH 346/745] chore(deps): update actions/checkout digest to ff7abcd (#1554) 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 +- .github/workflows/static-code-scanning.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index b5b40ae6c..fab41ccf6 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 + - uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 - name: Set up JDK 17 uses: actions/setup-java@e9343db97e09d87a3c50e544105d99fe912c204b with: diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index b22d3c2a5..df7a9fcab 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -19,7 +19,7 @@ jobs: runs-on: ${{ matrix.os}} steps: - name: Check out the code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 + uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 - name: Set up JDK 11 uses: actions/setup-java@e9343db97e09d87a3c50e544105d99fe912c204b diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2a31ffe49..25217734e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,7 +37,7 @@ jobs: steps: - name: Checkout Repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 + uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 - name: Set up JDK 17 uses: actions/setup-java@e9343db97e09d87a3c50e544105d99fe912c204b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 07868de79..fd039c95b 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 + uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL From 88ded5d9290b3c008a597cf55bb1e1f4c05e40ec Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 14 Aug 2025 07:30:04 +0200 Subject: [PATCH 347/745] chore(deps): update github/codeql-action digest to 7eb43b0 (#1555) 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 df7a9fcab..88cb3ba00 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@eef4c44f6bb262e0bbf01432030812aaaabdebf3 + uses: github/codeql-action/init@7eb43b07886e77d5f743a800ad7a8a380f9f3ea3 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@eef4c44f6bb262e0bbf01432030812aaaabdebf3 + uses: github/codeql-action/analyze@7eb43b07886e77d5f743a800ad7a8a380f9f3ea3 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index fd039c95b..9278b0f96 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@eef4c44f6bb262e0bbf01432030812aaaabdebf3 + uses: github/codeql-action/init@7eb43b07886e77d5f743a800ad7a8a380f9f3ea3 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@eef4c44f6bb262e0bbf01432030812aaaabdebf3 + uses: github/codeql-action/autobuild@7eb43b07886e77d5f743a800ad7a8a380f9f3ea3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@eef4c44f6bb262e0bbf01432030812aaaabdebf3 + uses: github/codeql-action/analyze@7eb43b07886e77d5f743a800ad7a8a380f9f3ea3 From 8a6c79627a492eb61ed35ffa91035b0737598b64 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 14 Aug 2025 05:37:13 +0000 Subject: [PATCH 348/745] chore(deps): update amannn/action-semantic-pull-request digest to fdd4d3d (#1553) 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 50c295b5d..4537a5d5f 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@335288255954904a41ddda8947c8f2c844b8bfeb + - uses: amannn/action-semantic-pull-request@fdd4d3ddf614fbcd8c29e4b106d3bbe0cb2c605d env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 03a8018098bbced558e157b60e7ba3ff18527db6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 14 Aug 2025 16:32:17 +0000 Subject: [PATCH 349/745] chore(deps): update github/codeql-action digest to 777f917 (#1556) 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 88cb3ba00..3522c4ee8 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@7eb43b07886e77d5f743a800ad7a8a380f9f3ea3 + uses: github/codeql-action/init@777f9173e88451d6cac565660317ea94437a9587 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7eb43b07886e77d5f743a800ad7a8a380f9f3ea3 + uses: github/codeql-action/analyze@777f9173e88451d6cac565660317ea94437a9587 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 9278b0f96..098e70191 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@7eb43b07886e77d5f743a800ad7a8a380f9f3ea3 + uses: github/codeql-action/init@777f9173e88451d6cac565660317ea94437a9587 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@7eb43b07886e77d5f743a800ad7a8a380f9f3ea3 + uses: github/codeql-action/autobuild@777f9173e88451d6cac565660317ea94437a9587 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7eb43b07886e77d5f743a800ad7a8a380f9f3ea3 + uses: github/codeql-action/analyze@777f9173e88451d6cac565660317ea94437a9587 From dff54123ab38fd3ad59809e5f863b6ace17e4da4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 15 Aug 2025 12:59:02 +0000 Subject: [PATCH 350/745] chore(deps): update dependency org.mockito:mockito-core to v5.19.0 (#1557) 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 7215c25c6..d3dbdbeb1 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ UTF-8 11 ${maven.compiler.source} - 5.18.0 + 5.19.0 **/e2e/*.java ${project.groupId}.${project.artifactId} From f1165da1b910efda6dbe486a21eb7985cccf11ae Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 15 Aug 2025 20:30:10 +0000 Subject: [PATCH 351/745] chore(deps): update github/codeql-action digest to 2330521 (#1558) 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 3522c4ee8..1d7022ed9 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@777f9173e88451d6cac565660317ea94437a9587 + uses: github/codeql-action/init@233052189b8c862bfaf875fb02c115f54d2b9286 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@777f9173e88451d6cac565660317ea94437a9587 + uses: github/codeql-action/analyze@233052189b8c862bfaf875fb02c115f54d2b9286 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 098e70191..c1827bd36 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@777f9173e88451d6cac565660317ea94437a9587 + uses: github/codeql-action/init@233052189b8c862bfaf875fb02c115f54d2b9286 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@777f9173e88451d6cac565660317ea94437a9587 + uses: github/codeql-action/autobuild@233052189b8c862bfaf875fb02c115f54d2b9286 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@777f9173e88451d6cac565660317ea94437a9587 + uses: github/codeql-action/analyze@233052189b8c862bfaf875fb02c115f54d2b9286 From 6fbc9d6cca5716b7477f84ff4093ccc6af06d4e6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 16 Aug 2025 14:30:52 +0000 Subject: [PATCH 352/745] chore(deps): update dependency org.apache.maven.plugins:maven-javadoc-plugin to v3.11.3 (#1559) 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 d3dbdbeb1..d715cb4ee 100644 --- a/pom.xml +++ b/pom.xml @@ -549,7 +549,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.11.2 + 3.11.3 true all,-missing From 124c26f6ea2d20cebb7520afcd94ab6b6c8c8e7b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 17 Aug 2025 05:04:16 +0000 Subject: [PATCH 353/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.17.7 (#1560) 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 d715cb4ee..c51613575 100644 --- a/pom.xml +++ b/pom.xml @@ -179,7 +179,7 @@ net.bytebuddy byte-buddy - 1.17.6 + 1.17.7 test From 84887bfc86eb4905f52bce4641c35a8909f2c463 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 17 Aug 2025 08:23:26 +0000 Subject: [PATCH 354/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.17.7 (#1561) 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 c51613575..4bf71257a 100644 --- a/pom.xml +++ b/pom.xml @@ -186,7 +186,7 @@ net.bytebuddy byte-buddy-agent - 1.17.6 + 1.17.7 test From 508bdac4f075e2cd374dd1728919cfc1619d0097 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 17 Aug 2025 12:20:01 +0200 Subject: [PATCH 355/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.27.1 (#1562) 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 4bf71257a..aadaa0236 100644 --- a/pom.xml +++ b/pom.xml @@ -194,7 +194,7 @@ io.cucumber cucumber-bom - 7.27.0 + 7.27.1 pom import From 19c2a1272a34040f3ac2b603c2bcb645f3707a82 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 13:53:53 +0200 Subject: [PATCH 356/745] chore(deps): update github/codeql-action digest to 6ec994e (#1564) 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 1d7022ed9..eb6167915 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@233052189b8c862bfaf875fb02c115f54d2b9286 + uses: github/codeql-action/init@6ec994ecba29cf3cf0724e281b919d68714895ce with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@233052189b8c862bfaf875fb02c115f54d2b9286 + uses: github/codeql-action/analyze@6ec994ecba29cf3cf0724e281b919d68714895ce diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index c1827bd36..ca6f5cafa 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@233052189b8c862bfaf875fb02c115f54d2b9286 + uses: github/codeql-action/init@6ec994ecba29cf3cf0724e281b919d68714895ce with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@233052189b8c862bfaf875fb02c115f54d2b9286 + uses: github/codeql-action/autobuild@6ec994ecba29cf3cf0724e281b919d68714895ce - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@233052189b8c862bfaf875fb02c115f54d2b9286 + uses: github/codeql-action/analyze@6ec994ecba29cf3cf0724e281b919d68714895ce From 47af5279d6abd0080eae16d630bd202976f9a4b1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 12:00:26 +0000 Subject: [PATCH 357/745] chore(deps): update amannn/action-semantic-pull-request digest to a46a7c8 (#1563) 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 4537a5d5f..2b81d26fc 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@fdd4d3ddf614fbcd8c29e4b106d3bbe0cb2c605d + - uses: amannn/action-semantic-pull-request@a46a7c8dc4bb34503174eba2f2f7ef80dffc8ed7 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From ea23114d424ce042681d6b42cdc6b2e2086ccbf8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 17:52:00 +0000 Subject: [PATCH 358/745] chore(deps): update github/codeql-action digest to e96e340 (#1565) 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 eb6167915..47d60a904 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@6ec994ecba29cf3cf0724e281b919d68714895ce + uses: github/codeql-action/init@e96e340c1e95e91449de06aabfa9525b7b98113f with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6ec994ecba29cf3cf0724e281b919d68714895ce + uses: github/codeql-action/analyze@e96e340c1e95e91449de06aabfa9525b7b98113f diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index ca6f5cafa..8e971c0cf 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@6ec994ecba29cf3cf0724e281b919d68714895ce + uses: github/codeql-action/init@e96e340c1e95e91449de06aabfa9525b7b98113f with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@6ec994ecba29cf3cf0724e281b919d68714895ce + uses: github/codeql-action/autobuild@e96e340c1e95e91449de06aabfa9525b7b98113f - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6ec994ecba29cf3cf0724e281b919d68714895ce + uses: github/codeql-action/analyze@e96e340c1e95e91449de06aabfa9525b7b98113f From 8a9f25177f2d4bab1b5215f172bbb8ed1a5ad788 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 22:52:24 +0000 Subject: [PATCH 359/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.27.2 (#1566) 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 aadaa0236..360148608 100644 --- a/pom.xml +++ b/pom.xml @@ -194,7 +194,7 @@ io.cucumber cucumber-bom - 7.27.1 + 7.27.2 pom import From c8d48e1a739f02b25e7980dcd5652851756729f2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 19 Aug 2025 18:46:55 +0000 Subject: [PATCH 360/745] chore(deps): update amannn/action-semantic-pull-request digest to 24e6f01 (#1568) 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 2b81d26fc..d35937a43 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@a46a7c8dc4bb34503174eba2f2f7ef80dffc8ed7 + - uses: amannn/action-semantic-pull-request@24e6f016c1e110f5353026c0b6129a4118b9146c env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 907b75d3481e71621249b0246e0ca67c42c9a890 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Aug 2025 00:08:00 +0000 Subject: [PATCH 361/745] chore(deps): update github/codeql-action digest to 6dee5bc (#1569) 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 47d60a904..6b34bc33c 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@e96e340c1e95e91449de06aabfa9525b7b98113f + uses: github/codeql-action/init@6dee5bc9c165ca206a70f4e3d18271971cf6ff26 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e96e340c1e95e91449de06aabfa9525b7b98113f + uses: github/codeql-action/analyze@6dee5bc9c165ca206a70f4e3d18271971cf6ff26 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 8e971c0cf..b03adc251 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@e96e340c1e95e91449de06aabfa9525b7b98113f + uses: github/codeql-action/init@6dee5bc9c165ca206a70f4e3d18271971cf6ff26 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@e96e340c1e95e91449de06aabfa9525b7b98113f + uses: github/codeql-action/autobuild@6dee5bc9c165ca206a70f4e3d18271971cf6ff26 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e96e340c1e95e91449de06aabfa9525b7b98113f + uses: github/codeql-action/analyze@6dee5bc9c165ca206a70f4e3d18271971cf6ff26 From fb6ab353b403542a1f7e6ccafb07e25ae1d5e2be Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Aug 2025 23:59:33 +0000 Subject: [PATCH 362/745] chore(deps): update amannn/action-semantic-pull-request digest to 677b895 (#1570) 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 d35937a43..75bf2eee0 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@24e6f016c1e110f5353026c0b6129a4118b9146c + - uses: amannn/action-semantic-pull-request@677b89571e961351de6fcbd96c8b2503787962e2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 58c82de9656562f137feafb9e6eff20521695803 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 21 Aug 2025 02:24:56 +0000 Subject: [PATCH 363/745] chore(deps): update actions/setup-java digest to 0913e9a (#1572) 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 fab41ccf6..6b9f87b2f 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -23,7 +23,7 @@ jobs: steps: - uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 - name: Set up JDK 17 - uses: actions/setup-java@e9343db97e09d87a3c50e544105d99fe912c204b + uses: actions/setup-java@0913e9a06eb8b69c62db76aa61f580c2b3a5b4e0 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 6b34bc33c..717efaf91 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -22,7 +22,7 @@ jobs: uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 - name: Set up JDK 11 - uses: actions/setup-java@e9343db97e09d87a3c50e544105d99fe912c204b + uses: actions/setup-java@0913e9a06eb8b69c62db76aa61f580c2b3a5b4e0 with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 25217734e..4cddbd9f0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,7 +40,7 @@ jobs: uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 - name: Set up JDK 17 - uses: actions/setup-java@e9343db97e09d87a3c50e544105d99fe912c204b + uses: actions/setup-java@0913e9a06eb8b69c62db76aa61f580c2b3a5b4e0 with: java-version: '17' distribution: 'temurin' From fc7ec6511fd92c872e55e2b4f96f1dc6215ed029 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 21 Aug 2025 05:31:57 +0000 Subject: [PATCH 364/745] chore(deps): update github/codeql-action digest to db69a51 (#1571) 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 717efaf91..866f504c7 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@6dee5bc9c165ca206a70f4e3d18271971cf6ff26 + uses: github/codeql-action/init@db69a5182d331d562e511302ae3c9aafd5fada6c with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6dee5bc9c165ca206a70f4e3d18271971cf6ff26 + uses: github/codeql-action/analyze@db69a5182d331d562e511302ae3c9aafd5fada6c diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index b03adc251..a840e24b9 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@6dee5bc9c165ca206a70f4e3d18271971cf6ff26 + uses: github/codeql-action/init@db69a5182d331d562e511302ae3c9aafd5fada6c with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@6dee5bc9c165ca206a70f4e3d18271971cf6ff26 + uses: github/codeql-action/autobuild@db69a5182d331d562e511302ae3c9aafd5fada6c - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6dee5bc9c165ca206a70f4e3d18271971cf6ff26 + uses: github/codeql-action/analyze@db69a5182d331d562e511302ae3c9aafd5fada6c From d33222439e84435baeb0a49d33651208e659ad27 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 21 Aug 2025 08:29:30 +0200 Subject: [PATCH 365/745] chore(deps): update actions/setup-java digest to dded088 (#1574) 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 6b9f87b2f..7f20015c3 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -23,7 +23,7 @@ jobs: steps: - uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 - name: Set up JDK 17 - uses: actions/setup-java@0913e9a06eb8b69c62db76aa61f580c2b3a5b4e0 + uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 866f504c7..8f7c9dd0b 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -22,7 +22,7 @@ jobs: uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 - name: Set up JDK 11 - uses: actions/setup-java@0913e9a06eb8b69c62db76aa61f580c2b3a5b4e0 + uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4cddbd9f0..5669160e9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,7 +40,7 @@ jobs: uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 - name: Set up JDK 17 - uses: actions/setup-java@0913e9a06eb8b69c62db76aa61f580c2b3a5b4e0 + uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 with: java-version: '17' distribution: 'temurin' From 2c2b380e13d2be5a988b70212ea243efdb60999b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 21 Aug 2025 06:36:00 +0000 Subject: [PATCH 366/745] chore(deps): update codecov/codecov-action action to v5.5.0 (#1573) 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 7f20015c3..2aa47264f 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -50,7 +50,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.4.3 + uses: codecov/codecov-action@v5.5.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 8f7c9dd0b..4c91ab906 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.4.3 + uses: codecov/codecov-action@v5.5.0 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From d9c1df0c5ec247f64c37648128d56b7e83444ca9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 22 Aug 2025 02:46:37 +0000 Subject: [PATCH 367/745] chore(deps): update github/codeql-action digest to 5b49155 (#1575) 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 4c91ab906..2c88440d0 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@db69a5182d331d562e511302ae3c9aafd5fada6c + uses: github/codeql-action/init@5b49155c7f37b5ec074ffd26b428e6b64b1bf412 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@db69a5182d331d562e511302ae3c9aafd5fada6c + uses: github/codeql-action/analyze@5b49155c7f37b5ec074ffd26b428e6b64b1bf412 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index a840e24b9..36b4ef34c 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@db69a5182d331d562e511302ae3c9aafd5fada6c + uses: github/codeql-action/init@5b49155c7f37b5ec074ffd26b428e6b64b1bf412 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@db69a5182d331d562e511302ae3c9aafd5fada6c + uses: github/codeql-action/autobuild@5b49155c7f37b5ec074ffd26b428e6b64b1bf412 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@db69a5182d331d562e511302ae3c9aafd5fada6c + uses: github/codeql-action/analyze@5b49155c7f37b5ec074ffd26b428e6b64b1bf412 From 894165ddd7216dc30c1ca4c9f43c0a4c21970f17 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 22 Aug 2025 02:57:20 +0000 Subject: [PATCH 368/745] chore(deps): update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.4.0 (#1576) 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 360148608..ddbbc3563 100644 --- a/pom.xml +++ b/pom.xml @@ -403,7 +403,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.9.3.2 + 4.9.4.0 spotbugs-exclusions.xml From 532ad2f3d404753189a529cdc262ba6ef8d3d586 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 22 Aug 2025 18:59:57 +0000 Subject: [PATCH 369/745] chore(deps): update amannn/action-semantic-pull-request digest to e7d011b (#1577) 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 75bf2eee0..7629cb0c7 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@677b89571e961351de6fcbd96c8b2503787962e2 + - uses: amannn/action-semantic-pull-request@e7d011b07ef37e089bea6539210f6a0d360d8af9 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 5efac69dae28ff26227e5a9e83c6edbea9b9b6b5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 28 Aug 2025 17:13:21 +0000 Subject: [PATCH 370/745] chore(deps): update github/codeql-action digest to a880e53 (#1581) 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 2c88440d0..42a991537 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@5b49155c7f37b5ec074ffd26b428e6b64b1bf412 + uses: github/codeql-action/init@a880e53ace196b47e0797a3df224607ff5a52f96 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5b49155c7f37b5ec074ffd26b428e6b64b1bf412 + uses: github/codeql-action/analyze@a880e53ace196b47e0797a3df224607ff5a52f96 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 36b4ef34c..d32f0473c 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@5b49155c7f37b5ec074ffd26b428e6b64b1bf412 + uses: github/codeql-action/init@a880e53ace196b47e0797a3df224607ff5a52f96 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@5b49155c7f37b5ec074ffd26b428e6b64b1bf412 + uses: github/codeql-action/autobuild@a880e53ace196b47e0797a3df224607ff5a52f96 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5b49155c7f37b5ec074ffd26b428e6b64b1bf412 + uses: github/codeql-action/analyze@a880e53ace196b47e0797a3df224607ff5a52f96 From 080fc6e9a60c15eb748891245258c9c5378e4248 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 31 Aug 2025 12:34:45 +0000 Subject: [PATCH 371/745] chore(deps): update github/codeql-action digest to 02ab253 (#1583) 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 42a991537..857b134f6 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@a880e53ace196b47e0797a3df224607ff5a52f96 + uses: github/codeql-action/init@02ab253bd299d261d00cdf8a9bca38fea2697d50 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@a880e53ace196b47e0797a3df224607ff5a52f96 + uses: github/codeql-action/analyze@02ab253bd299d261d00cdf8a9bca38fea2697d50 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index d32f0473c..0c469ad82 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@a880e53ace196b47e0797a3df224607ff5a52f96 + uses: github/codeql-action/init@02ab253bd299d261d00cdf8a9bca38fea2697d50 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@a880e53ace196b47e0797a3df224607ff5a52f96 + uses: github/codeql-action/autobuild@02ab253bd299d261d00cdf8a9bca38fea2697d50 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@a880e53ace196b47e0797a3df224607ff5a52f96 + uses: github/codeql-action/analyze@02ab253bd299d261d00cdf8a9bca38fea2697d50 From cba90dd227514464fd90bd605f73c358748c09e1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 31 Aug 2025 16:22:03 +0000 Subject: [PATCH 372/745] chore(deps): update dependency maven-wrapper to v3.3.3 (#1584) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .mvn/wrapper/maven-wrapper.properties | 17 -- mvnw | 50 +++- mvnw.cmd | 338 ++++++++++++++------------ 3 files changed, 232 insertions(+), 173 deletions(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 12fbe1e90..44f3cf2c1 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,19 +1,2 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -wrapperVersion=3.3.2 distributionType=only-script distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip diff --git a/mvnw b/mvnw index 19529ddf8..e9cf8d330 100644 --- a/mvnw +++ b/mvnw @@ -19,7 +19,7 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Apache Maven Wrapper startup batch script, version 3.3.2 +# Apache Maven Wrapper startup batch script, version 3.3.3 # # Optional ENV vars # ----------------- @@ -105,14 +105,17 @@ trim() { printf "%s" "${1}" | tr -d '[:space:]' } +scriptDir="$(dirname "$0")" +scriptName="$(basename "$0")" + # parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties while IFS="=" read -r key value; do case "${key-}" in distributionUrl) distributionUrl=$(trim "${value-}") ;; distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; esac -done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" -[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" +done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" case "${distributionUrl##*/}" in maven-mvnd-*bin.*) @@ -130,7 +133,7 @@ maven-mvnd-*bin.*) distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" ;; maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; -*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; esac # apply MVNW_REPOURL and calculate MAVEN_HOME @@ -227,7 +230,7 @@ if [ -n "${distributionSha256Sum-}" ]; then echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 exit 1 elif command -v sha256sum >/dev/null; then - if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then distributionSha256Result=true fi elif command -v shasum >/dev/null; then @@ -252,8 +255,41 @@ if command -v unzip >/dev/null; then else tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" fi -printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" -mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +actualDistributionDir="" + +# First try the expected directory name (for regular distributions) +if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then + if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then + actualDistributionDir="$distributionUrlNameMain" + fi +fi + +# If not found, search for any directory with the Maven executable (for snapshots) +if [ -z "$actualDistributionDir" ]; then + # enable globbing to iterate over items + set +f + for dir in "$TMP_DOWNLOAD_DIR"/*; do + if [ -d "$dir" ]; then + if [ -f "$dir/bin/$MVN_CMD" ]; then + actualDistributionDir="$(basename "$dir")" + break + fi + fi + done + set -f +fi + +if [ -z "$actualDistributionDir" ]; then + verbose "Contents of $TMP_DOWNLOAD_DIR:" + verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" + die "Could not find Maven distribution directory in extracted archive" +fi + +verbose "Found extracted Maven distribution directory: $actualDistributionDir" +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" clean || : exec_maven "$@" diff --git a/mvnw.cmd b/mvnw.cmd index 249bdf382..3fd2be860 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -1,149 +1,189 @@ -<# : batch portion -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Apache Maven Wrapper startup batch script, version 3.3.2 -@REM -@REM Optional ENV vars -@REM MVNW_REPOURL - repo url base for downloading maven distribution -@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven -@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output -@REM ---------------------------------------------------------------------------- - -@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) -@SET __MVNW_CMD__= -@SET __MVNW_ERROR__= -@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% -@SET PSModulePath= -@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( - IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) -) -@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% -@SET __MVNW_PSMODULEP_SAVE= -@SET __MVNW_ARG0_NAME__= -@SET MVNW_USERNAME= -@SET MVNW_PASSWORD= -@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) -@echo Cannot start maven from wrapper >&2 && exit /b 1 -@GOTO :EOF -: end batch / begin powershell #> - -$ErrorActionPreference = "Stop" -if ($env:MVNW_VERBOSE -eq "true") { - $VerbosePreference = "Continue" -} - -# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties -$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl -if (!$distributionUrl) { - Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" -} - -switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { - "maven-mvnd-*" { - $USE_MVND = $true - $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" - $MVN_CMD = "mvnd.cmd" - break - } - default { - $USE_MVND = $false - $MVN_CMD = $script -replace '^mvnw','mvn' - break - } -} - -# apply MVNW_REPOURL and calculate MAVEN_HOME -# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ -if ($env:MVNW_REPOURL) { - $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } - $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" -} -$distributionUrlName = $distributionUrl -replace '^.*/','' -$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' -$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" -if ($env:MAVEN_USER_HOME) { - $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" -} -$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' -$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" - -if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { - Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" - Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" - exit $? -} - -if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { - Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" -} - -# prepare tmp dir -$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile -$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" -$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null -trap { - if ($TMP_DOWNLOAD_DIR.Exists) { - try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } - catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } - } -} - -New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null - -# Download and Install Apache Maven -Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." -Write-Verbose "Downloading from: $distributionUrl" -Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" - -$webclient = New-Object System.Net.WebClient -if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { - $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) -} -[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null - -# If specified, validate the SHA-256 sum of the Maven distribution zip file -$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum -if ($distributionSha256Sum) { - if ($USE_MVND) { - Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." - } - Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash - if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { - Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." - } -} - -# unzip and move -Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null -Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null -try { - Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null -} catch { - if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { - Write-Error "fail to move MAVEN_HOME" - } -} finally { - try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } - catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } -} - -Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.3 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' + +$MAVEN_M2_PATH = "$HOME/.m2" +if ($env:MAVEN_USER_HOME) { + $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" +} + +if (-not (Test-Path -Path $MAVEN_M2_PATH)) { + New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null +} + +$MAVEN_WRAPPER_DISTS = $null +if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { + $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" +} else { + $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" +} + +$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" +$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +$actualDistributionDir = "" + +# First try the expected directory name (for regular distributions) +$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" +$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" +if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { + $actualDistributionDir = $distributionUrlNameMain +} + +# If not found, search for any directory with the Maven executable (for snapshots) +if (!$actualDistributionDir) { + Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { + $testPath = Join-Path $_.FullName "bin/$MVN_CMD" + if (Test-Path -Path $testPath -PathType Leaf) { + $actualDistributionDir = $_.Name + } + } +} + +if (!$actualDistributionDir) { + Write-Error "Could not find Maven distribution directory in extracted archive" +} + +Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" From 8dd40fabcae6a90ee7abe1b0a0d8f55f345e3331 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 31 Aug 2025 20:45:50 +0000 Subject: [PATCH 373/745] chore(deps): update dependency com.puppycrawl.tools:checkstyle to v11.0.1 (#1585) 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 ddbbc3563..0cc91fb1f 100644 --- a/pom.xml +++ b/pom.xml @@ -447,7 +447,7 @@ com.puppycrawl.tools checkstyle - 11.0.0 + 11.0.1 From a08ff4d96ccf9236ad882892280b600a05409394 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 12 Sep 2025 01:57:03 +0000 Subject: [PATCH 374/745] chore(deps): update actions/setup-java digest to a7ab372 (#1589) 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 2aa47264f..fcdc668d1 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -23,7 +23,7 @@ jobs: steps: - uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 - name: Set up JDK 17 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 + uses: actions/setup-java@a7ab372554b6eb1a8eb25e7d9aec1cc9f3ea1a76 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 857b134f6..ed687234c 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -22,7 +22,7 @@ jobs: uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 - name: Set up JDK 11 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 + uses: actions/setup-java@a7ab372554b6eb1a8eb25e7d9aec1cc9f3ea1a76 with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5669160e9..f130b89d7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,7 +40,7 @@ jobs: uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 - name: Set up JDK 17 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 + uses: actions/setup-java@a7ab372554b6eb1a8eb25e7d9aec1cc9f3ea1a76 with: java-version: '17' distribution: 'temurin' From 9e4881fdcb577a693cfe587b58dce5a74fb3caf4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 12 Sep 2025 09:05:10 +0000 Subject: [PATCH 375/745] chore(deps): update github/codeql-action digest to 0d33fd9 (#1590) 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 ed687234c..f7af6d776 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@02ab253bd299d261d00cdf8a9bca38fea2697d50 + uses: github/codeql-action/init@0d33fd9f263def169b43518224e68932ef8cc79a with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@02ab253bd299d261d00cdf8a9bca38fea2697d50 + uses: github/codeql-action/analyze@0d33fd9f263def169b43518224e68932ef8cc79a diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 0c469ad82..8e27e55d2 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@02ab253bd299d261d00cdf8a9bca38fea2697d50 + uses: github/codeql-action/init@0d33fd9f263def169b43518224e68932ef8cc79a with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@02ab253bd299d261d00cdf8a9bca38fea2697d50 + uses: github/codeql-action/autobuild@0d33fd9f263def169b43518224e68932ef8cc79a - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@02ab253bd299d261d00cdf8a9bca38fea2697d50 + uses: github/codeql-action/analyze@0d33fd9f263def169b43518224e68932ef8cc79a From ca72b19d33985dfaae1cda009afd6795c5752259 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 12 Sep 2025 14:25:06 +0200 Subject: [PATCH 376/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.28.2 (#1593) 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 0cc91fb1f..c829914fa 100644 --- a/pom.xml +++ b/pom.xml @@ -194,7 +194,7 @@ io.cucumber cucumber-bom - 7.27.2 + 7.28.2 pom import From 8b3f7f07f4aa555301d484544939fa5a0b4de746 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Sep 2025 01:54:11 +0000 Subject: [PATCH 377/745] chore(deps): update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.4.2 (#1592) 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 c829914fa..d833caba2 100644 --- a/pom.xml +++ b/pom.xml @@ -403,7 +403,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.9.4.0 + 4.9.4.2 spotbugs-exclusions.xml From e47913a07ee064fe340db978250710a7cb17795d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Sep 2025 04:08:39 +0000 Subject: [PATCH 378/745] chore(deps): update codecov/codecov-action action to v5.5.1 (#1591) 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 fcdc668d1..2a3633045 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -50,7 +50,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.5.0 + uses: codecov/codecov-action@v5.5.1 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 f7af6d776..76c90f40b 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.5.0 + uses: codecov/codecov-action@v5.5.1 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From 5df4317caa97bdd055ec1f809d2b5e49642b5312 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Sep 2025 08:54:51 +0000 Subject: [PATCH 379/745] chore(deps): update github/codeql-action digest to aa90e97 (#1594) 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 76c90f40b..67da3cb06 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@0d33fd9f263def169b43518224e68932ef8cc79a + uses: github/codeql-action/init@aa90e97ad2ed17cde6a43e89f70138299e64f837 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0d33fd9f263def169b43518224e68932ef8cc79a + uses: github/codeql-action/analyze@aa90e97ad2ed17cde6a43e89f70138299e64f837 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 8e27e55d2..7c16abc16 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@0d33fd9f263def169b43518224e68932ef8cc79a + uses: github/codeql-action/init@aa90e97ad2ed17cde6a43e89f70138299e64f837 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@0d33fd9f263def169b43518224e68932ef8cc79a + uses: github/codeql-action/autobuild@aa90e97ad2ed17cde6a43e89f70138299e64f837 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0d33fd9f263def169b43518224e68932ef8cc79a + uses: github/codeql-action/analyze@aa90e97ad2ed17cde6a43e89f70138299e64f837 From 3606154aa7ded57f41c324559268335531606b6c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Sep 2025 11:41:50 +0000 Subject: [PATCH 380/745] chore(deps): update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.5.4 (#1596) 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 d833caba2..c334e95fd 100644 --- a/pom.xml +++ b/pom.xml @@ -277,7 +277,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.5.3 + 3.5.4 ${surefireArgLine} @@ -679,7 +679,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.5.3 + 3.5.4 ${surefireArgLine} From a17bd3a388927781b86e91064748a71670bb2a2a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Sep 2025 16:23:54 +0000 Subject: [PATCH 381/745] chore(deps): update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.4 (#1595) 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 c334e95fd..437bce69a 100644 --- a/pom.xml +++ b/pom.xml @@ -258,7 +258,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.5.3 + 3.5.4 1 false @@ -663,7 +663,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.5.3 + 3.5.4 ${surefireArgLine} From e1812767b684b21d417e31dadc8d031cd64cdab1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Sep 2025 17:02:04 +0000 Subject: [PATCH 382/745] fix(deps): update dependency org.projectlombok:lombok to v1.18.40 (#1597) 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 437bce69a..0ffe763e7 100644 --- a/pom.xml +++ b/pom.xml @@ -52,7 +52,7 @@ org.projectlombok lombok - 1.18.38 + 1.18.40 provided From 5474c736f711ed06cbca2bd0d4d0cfd458a54d10 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 15 Sep 2025 04:55:34 +0000 Subject: [PATCH 383/745] fix(deps): update dependency com.github.spotbugs:spotbugs to v4.9.5 (#1598) 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 0ffe763e7..ada93b719 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ com.github.spotbugs spotbugs - 4.9.4 + 4.9.5 provided @@ -419,7 +419,7 @@ com.github.spotbugs spotbugs - 4.9.4 + 4.9.5 From 1b08e3db42635bbe79c61437db2359bd74a98348 Mon Sep 17 00:00:00 2001 From: alexandraoberaigner <82218944+alexandraoberaigner@users.noreply.github.com> Date: Mon, 15 Sep 2025 14:50:16 +0200 Subject: [PATCH 384/745] feat: add hook data (#1587) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added hook data Signed-off-by: mdxabu * to support null values while maintaining thread safety, you must avoid ConcurrentHashMap and use a synchronized HashMap instead Signed-off-by: mdxabu * Build successfully runned:spotless plugin Signed-off-by: mdxabu * fixup: fix comment Co-authored-by: alexandraoberaigner <82218944+alexandraoberaigner@users.noreply.github.com> Signed-off-by: Simon Schrottner * fixup: remove synchronized map Co-authored-by: alexandraoberaigner <82218944+alexandraoberaigner@users.noreply.github.com> Signed-off-by: Simon Schrottner * fixup: removed unneeded import Signed-off-by: Simon Schrottner * fixup: spotless Signed-off-by: Simon Schrottner * Update src/main/java/dev/openfeature/sdk/HookData.java Co-authored-by: chrfwow Signed-off-by: Abu * Update src/main/java/dev/openfeature/sdk/HookData.java Co-authored-by: chrfwow Signed-off-by: Abu * feat: add support for hook data sharing between stages Signed-off-by: Alexandra Oberaigner * fixup: tests Signed-off-by: Simon Schrottner * fixup: pr comments and extraction of own pair class Signed-off-by: Simon Schrottner * feat: add HookContext decorator Signed-off-by: Simon Schrottner * fixup: add default method for interface Signed-off-by: Simon Schrottner * feat: performance boost Signed-off-by: Simon Schrottner * feat: performance improvements Signed-off-by: Simon Schrottner * fixup: lazy init Signed-off-by: Simon Schrottner * fixup: pr comments Signed-off-by: Simon Schrottner --------- Signed-off-by: mdxabu Signed-off-by: Simon Schrottner Signed-off-by: Abu Signed-off-by: Alexandra Oberaigner Co-authored-by: mdxabu Co-authored-by: Simon Schrottner Co-authored-by: Michael Beemer Co-authored-by: chrfwow --- .../java/dev/openfeature/sdk/HookContext.java | 63 +++--- .../openfeature/sdk/HookContextWithData.java | 50 +++++ .../sdk/HookContextWithoutData.java | 48 +++++ .../java/dev/openfeature/sdk/HookData.java | 81 ++++++++ .../java/dev/openfeature/sdk/HookSupport.java | 105 +++++++--- .../dev/openfeature/sdk/ImmutableContext.java | 2 + .../openfeature/sdk/OpenFeatureClient.java | 43 ++-- src/main/java/dev/openfeature/sdk/Pair.java | 28 +++ .../dev/openfeature/sdk/HookContextTest.java | 44 ++++- .../dev/openfeature/sdk/HookDataTest.java | 79 ++++++++ .../dev/openfeature/sdk/HookSupportTest.java | 184 ++++++++++++++++-- .../sdk/benchmark/AllocationBenchmark.java | 24 +++ 12 files changed, 642 insertions(+), 109 deletions(-) create mode 100644 src/main/java/dev/openfeature/sdk/HookContextWithData.java create mode 100644 src/main/java/dev/openfeature/sdk/HookContextWithoutData.java create mode 100644 src/main/java/dev/openfeature/sdk/HookData.java create mode 100644 src/main/java/dev/openfeature/sdk/Pair.java create mode 100644 src/test/java/dev/openfeature/sdk/HookDataTest.java diff --git a/src/main/java/dev/openfeature/sdk/HookContext.java b/src/main/java/dev/openfeature/sdk/HookContext.java index e14eeb643..e88e812a6 100644 --- a/src/main/java/dev/openfeature/sdk/HookContext.java +++ b/src/main/java/dev/openfeature/sdk/HookContext.java @@ -1,32 +1,13 @@ package dev.openfeature.sdk; -import lombok.Builder; -import lombok.NonNull; -import lombok.Value; -import lombok.With; +import dev.openfeature.sdk.HookContextWithoutData.HookContextWithoutDataBuilder; /** - * A data class to hold immutable context that {@link Hook} instances use. - * - * @param the type for the flag being evaluated + * A interface to hold immutable context that {@link Hook} instances use. */ -@Value -@Builder -@With -public class HookContext { - @NonNull String flagKey; - - @NonNull FlagValueType type; - - @NonNull T defaultValue; - - @NonNull EvaluationContext ctx; - - ClientMetadata clientMetadata; - Metadata providerMetadata; - +public interface HookContext { /** - * Builds a {@link HookContext} instances from request data. + * Builds a {@link HookContextWithoutData} instances from request data. * * @param key feature flag key * @param type flag value type @@ -36,21 +17,39 @@ public class HookContext { * @param defaultValue Fallback value * @param type that the flag is evaluating against * @return resulting context for hook + * @deprecated this should not be instantiated outside the SDK anymore */ - public static HookContext from( + @Deprecated + static HookContext from( String key, FlagValueType type, ClientMetadata clientMetadata, Metadata providerMetadata, EvaluationContext ctx, T defaultValue) { - return HookContext.builder() - .flagKey(key) - .type(type) - .clientMetadata(clientMetadata) - .providerMetadata(providerMetadata) - .ctx(ctx) - .defaultValue(defaultValue) - .build(); + return new HookContextWithoutData<>(key, type, defaultValue, ctx, clientMetadata, providerMetadata); + } + + /** + * Returns a builder for our default HookContext object. + */ + static HookContextWithoutDataBuilder builder() { + return HookContextWithoutData.builder(); + } + + String getFlagKey(); + + FlagValueType getType(); + + T getDefaultValue(); + + EvaluationContext getCtx(); + + ClientMetadata getClientMetadata(); + + Metadata getProviderMetadata(); + + default HookData getHookData() { + return null; } } diff --git a/src/main/java/dev/openfeature/sdk/HookContextWithData.java b/src/main/java/dev/openfeature/sdk/HookContextWithData.java new file mode 100644 index 000000000..137477c11 --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/HookContextWithData.java @@ -0,0 +1,50 @@ +package dev.openfeature.sdk; + +class HookContextWithData implements HookContext { + private final HookContext context; + private final HookData data; + + private HookContextWithData(HookContext context, HookData data) { + this.context = context; + this.data = data; + } + + public static HookContextWithData of(HookContext context, HookData data) { + return new HookContextWithData<>(context, data); + } + + @Override + public String getFlagKey() { + return context.getFlagKey(); + } + + @Override + public FlagValueType getType() { + return context.getType(); + } + + @Override + public T getDefaultValue() { + return context.getDefaultValue(); + } + + @Override + public EvaluationContext getCtx() { + return context.getCtx(); + } + + @Override + public ClientMetadata getClientMetadata() { + return context.getClientMetadata(); + } + + @Override + public Metadata getProviderMetadata() { + return context.getProviderMetadata(); + } + + @Override + public HookData getHookData() { + return data; + } +} diff --git a/src/main/java/dev/openfeature/sdk/HookContextWithoutData.java b/src/main/java/dev/openfeature/sdk/HookContextWithoutData.java new file mode 100644 index 000000000..6e5394ee1 --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/HookContextWithoutData.java @@ -0,0 +1,48 @@ +package dev.openfeature.sdk; + +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Data; +import lombok.NonNull; +import lombok.Setter; +import lombok.With; + +/** + * A data class to hold immutable context that {@link Hook} instances use. + * + * @param the type for the flag being evaluated + */ +@Data +@Builder +@With +@Setter(AccessLevel.PRIVATE) +class HookContextWithoutData implements HookContext { + @NonNull String flagKey; + + @NonNull FlagValueType type; + + @NonNull T defaultValue; + + @Setter(AccessLevel.PACKAGE) + @NonNull EvaluationContext ctx; + + ClientMetadata clientMetadata; + Metadata providerMetadata; + + /** + * Builds a {@link HookContextWithoutData} instances from request data. + * + * @param key feature flag key + * @param type flag value type + * @param clientMetadata info on which client is calling + * @param providerMetadata info on the provider + * @param defaultValue Fallback value + * @param type that the flag is evaluating against + * @return resulting context for hook + */ + static HookContextWithoutData from( + String key, FlagValueType type, ClientMetadata clientMetadata, Metadata providerMetadata, T defaultValue) { + return new HookContextWithoutData<>( + key, type, defaultValue, ImmutableContext.EMPTY, clientMetadata, providerMetadata); + } +} diff --git a/src/main/java/dev/openfeature/sdk/HookData.java b/src/main/java/dev/openfeature/sdk/HookData.java new file mode 100644 index 000000000..c7c644a93 --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/HookData.java @@ -0,0 +1,81 @@ +package dev.openfeature.sdk; + +import java.util.HashMap; +import java.util.Map; + +/** + * Hook data provides a way for hooks to maintain state across their execution stages. + * Each hook instance gets its own isolated data store that persists only for the duration + * of a single flag evaluation. + */ +public interface HookData { + + /** + * Sets a value for the given key. + * + * @param key the key to store the value under + * @param value the value to store + */ + void set(String key, Object value); + + /** + * Gets the value for the given key. + * + * @param key the key to retrieve the value for + * @return the value, or null if not found + */ + Object get(String key); + + /** + * Gets the value for the given key, cast to the specified type. + * + * @param the type to cast to + * @param key the key to retrieve the value for + * @param type the class to cast to + * @return the value cast to the specified type, or null if not found + * @throws ClassCastException if the value cannot be cast to the specified type + */ + T get(String key, Class type); + + /** + * Default implementation uses a HashMap. + */ + static HookData create() { + return new DefaultHookData(); + } + + /** + * Default implementation of HookData. + */ + class DefaultHookData implements HookData { + private Map data; + + @Override + public void set(String key, Object value) { + if (data == null) { + data = new HashMap<>(); + } + data.put(key, value); + } + + @Override + public Object get(String key) { + if (data == null) { + return null; + } + return data.get(key); + } + + @Override + public T get(String key, Class type) { + Object value = get(key); + if (value == null) { + return null; + } + if (!type.isInstance(value)) { + throw new ClassCastException("Value for key '" + key + "' is not of type " + type.getName()); + } + return type.cast(value); + } + } +} diff --git a/src/main/java/dev/openfeature/sdk/HookSupport.java b/src/main/java/dev/openfeature/sdk/HookSupport.java index 73518ee8e..e9ebbbe58 100644 --- a/src/main/java/dev/openfeature/sdk/HookSupport.java +++ b/src/main/java/dev/openfeature/sdk/HookSupport.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.function.Consumer; +import java.util.function.BiConsumer; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -15,52 +15,81 @@ class HookSupport { public EvaluationContext beforeHooks( - FlagValueType flagValueType, HookContext hookCtx, List hooks, Map hints) { - return callBeforeHooks(flagValueType, hookCtx, hooks, hints); + FlagValueType flagValueType, + HookContext hookCtx, + List> hookDataPairs, + Map hints) { + return callBeforeHooks(flagValueType, hookCtx, hookDataPairs, hints); } public void afterHooks( FlagValueType flagValueType, HookContext hookContext, FlagEvaluationDetails details, - List hooks, + List> hookDataPairs, Map hints) { - executeHooksUnchecked(flagValueType, hooks, hook -> hook.after(hookContext, details, hints)); + executeHooksUnchecked( + flagValueType, hookDataPairs, hookContext, (hook, ctx) -> hook.after(ctx, details, hints)); } public void afterAllHooks( FlagValueType flagValueType, HookContext hookCtx, FlagEvaluationDetails details, - List hooks, + List> hookDataPairs, Map hints) { - executeHooks(flagValueType, hooks, "finally", hook -> hook.finallyAfter(hookCtx, details, hints)); + executeHooks( + flagValueType, + hookDataPairs, + hookCtx, + "finally", + (hook, ctx) -> hook.finallyAfter(ctx, details, hints)); } public void errorHooks( FlagValueType flagValueType, HookContext hookCtx, Exception e, - List hooks, + List> hookDataPairs, Map hints) { - executeHooks(flagValueType, hooks, "error", hook -> hook.error(hookCtx, e, hints)); + executeHooks(flagValueType, hookDataPairs, hookCtx, "error", (hook, ctx) -> hook.error(ctx, e, hints)); + } + + public List> getHookDataPairs(List hooks, FlagValueType flagValueType) { + var pairs = new ArrayList>(); + for (Hook hook : hooks) { + if (hook.supportsFlagValueType(flagValueType)) { + pairs.add(Pair.of(hook, HookData.create())); + } + } + return pairs; } private void executeHooks( - FlagValueType flagValueType, List hooks, String hookMethod, Consumer> hookCode) { - if (hooks != null) { - for (Hook hook : hooks) { - if (hook.supportsFlagValueType(flagValueType)) { - executeChecked(hook, hookCode, hookMethod); - } + FlagValueType flagValueType, + List> hookDataPairs, + HookContext hookContext, + String hookMethod, + BiConsumer, HookContext> hookCode) { + if (hookDataPairs != null) { + for (Pair hookDataPair : hookDataPairs) { + Hook hook = hookDataPair.getLeft(); + HookData hookData = hookDataPair.getRight(); + executeChecked(hook, hookData, hookContext, hookCode, hookMethod); } } } // before, error, and finally hooks shouldn't throw - private void executeChecked(Hook hook, Consumer> hookCode, String hookMethod) { + private void executeChecked( + Hook hook, + HookData hookData, + HookContext hookContext, + BiConsumer, HookContext> hookCode, + String hookMethod) { try { - hookCode.accept(hook); + var hookCtxWithData = HookContextWithData.of(hookContext, hookData); + hookCode.accept(hook, hookCtxWithData); } catch (Exception exception) { log.error( "Unhandled exception when running {} hook {} (only 'after' hooks should throw)", @@ -71,29 +100,41 @@ private void executeChecked(Hook hook, Consumer> hookCode, String } // after hooks can throw in order to do validation - private void executeHooksUnchecked(FlagValueType flagValueType, List hooks, Consumer> hookCode) { - if (hooks != null) { - for (Hook hook : hooks) { - if (hook.supportsFlagValueType(flagValueType)) { - hookCode.accept(hook); - } + private void executeHooksUnchecked( + FlagValueType flagValueType, + List> hookDataPairs, + HookContext hookContext, + BiConsumer, HookContext> hookCode) { + if (hookDataPairs != null) { + for (Pair hookDataPair : hookDataPairs) { + Hook hook = hookDataPair.getLeft(); + HookData hookData = hookDataPair.getRight(); + var hookCtxWithData = HookContextWithData.of(hookContext, hookData); + hookCode.accept(hook, hookCtxWithData); } } } private EvaluationContext callBeforeHooks( - FlagValueType flagValueType, HookContext hookCtx, List hooks, Map hints) { + FlagValueType flagValueType, + HookContext hookCtx, + List> hookDataPairs, + Map hints) { // These traverse backwards from normal. - List reversedHooks = new ArrayList<>(hooks); + List> reversedHooks = new ArrayList<>(hookDataPairs); Collections.reverse(reversedHooks); EvaluationContext context = hookCtx.getCtx(); - for (Hook hook : reversedHooks) { - if (hook.supportsFlagValueType(flagValueType)) { - Optional optional = - Optional.ofNullable(hook.before(hookCtx, hints)).orElse(Optional.empty()); - if (optional.isPresent()) { - context = context.merge(optional.get()); - } + + for (Pair hookDataPair : reversedHooks) { + Hook hook = hookDataPair.getLeft(); + HookData hookData = hookDataPair.getRight(); + + // Create a new context with this hook's data + HookContext contextWithHookData = HookContextWithData.of(hookCtx, hookData); + Optional optional = + Optional.ofNullable(hook.before(contextWithHookData, hints)).orElse(Optional.empty()); + if (optional.isPresent()) { + context = context.merge(optional.get()); } } return context; diff --git a/src/main/java/dev/openfeature/sdk/ImmutableContext.java b/src/main/java/dev/openfeature/sdk/ImmutableContext.java index 8560c369e..e4916dfca 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableContext.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableContext.java @@ -20,6 +20,8 @@ @SuppressWarnings("PMD.BeanMembersShouldSerialize") public final class ImmutableContext implements EvaluationContext { + public static final ImmutableContext EMPTY = new ImmutableContext(); + @Delegate(excludes = DelegateExclusions.class) private final ImmutableStructure structure; diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index b5522b66a..10c359e3e 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -164,32 +164,27 @@ private FlagEvaluationDetails evaluateFlag( var hints = Collections.unmodifiableMap(flagOptions.getHookHints()); FlagEvaluationDetails details = null; - List mergedHooks = null; - HookContext afterHookContext = null; + List mergedHooks; + List> hookDataPairs = null; + HookContextWithoutData hookContext = null; try { - var stateManager = openfeatureApi.getFeatureProviderStateManager(this.domain); + final var stateManager = openfeatureApi.getFeatureProviderStateManager(this.domain); // provider must be accessed once to maintain a consistent reference - var provider = stateManager.getProvider(); - var state = stateManager.getState(); + final var provider = stateManager.getProvider(); + final var state = stateManager.getState(); + hookContext = + HookContextWithoutData.from(key, type, this.getMetadata(), provider.getMetadata(), defaultValue); + + // we are setting the evaluation context one after the other, so that we have a hook context in each + // possible exception case. + hookContext.setCtx(mergeEvaluationContext(ctx)); mergedHooks = ObjectUtils.merge( provider.getProviderHooks(), flagOptions.getHooks(), clientHooks, openfeatureApi.getMutableHooks()); - - var mergedCtx = hookSupport.beforeHooks( - type, - HookContext.from( - key, - type, - this.getMetadata(), - provider.getMetadata(), - mergeEvaluationContext(ctx), - defaultValue), - mergedHooks, - hints); - - afterHookContext = - HookContext.from(key, type, this.getMetadata(), provider.getMetadata(), mergedCtx, defaultValue); + hookDataPairs = hookSupport.getHookDataPairs(mergedHooks, type); + var mergedCtx = hookSupport.beforeHooks(type, hookContext, hookDataPairs, hints); + hookContext.setCtx(mergedCtx); // "short circuit" if the provider is in NOT_READY or FATAL state if (ProviderState.NOT_READY.equals(state)) { @@ -207,9 +202,9 @@ private FlagEvaluationDetails evaluateFlag( var error = ExceptionUtils.instantiateErrorByErrorCode(details.getErrorCode(), details.getErrorMessage()); enrichDetailsWithErrorDefaults(defaultValue, details); - hookSupport.errorHooks(type, afterHookContext, error, mergedHooks, hints); + hookSupport.errorHooks(type, hookContext, error, hookDataPairs, hints); } else { - hookSupport.afterHooks(type, afterHookContext, details, mergedHooks, hints); + hookSupport.afterHooks(type, hookContext, details, hookDataPairs, hints); } } catch (Exception e) { if (details == null) { @@ -222,9 +217,9 @@ private FlagEvaluationDetails evaluateFlag( } details.setErrorMessage(e.getMessage()); enrichDetailsWithErrorDefaults(defaultValue, details); - hookSupport.errorHooks(type, afterHookContext, e, mergedHooks, hints); + hookSupport.errorHooks(type, hookContext, e, hookDataPairs, hints); } finally { - hookSupport.afterAllHooks(type, afterHookContext, details, mergedHooks, hints); + hookSupport.afterAllHooks(type, hookContext, details, hookDataPairs, hints); } return details; diff --git a/src/main/java/dev/openfeature/sdk/Pair.java b/src/main/java/dev/openfeature/sdk/Pair.java new file mode 100644 index 000000000..bc6614093 --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/Pair.java @@ -0,0 +1,28 @@ +package dev.openfeature.sdk; + +class Pair { + private final K key; + private final V value; + + private Pair(K key, V value) { + this.key = key; + this.value = value; + } + + public K getLeft() { + return key; + } + + public V getRight() { + return value; + } + + @Override + public String toString() { + return "Pair{" + "key=" + key + ", value=" + value + '}'; + } + + public static Pair of(K key, V value) { + return new Pair<>(key, value); + } +} diff --git a/src/test/java/dev/openfeature/sdk/HookContextTest.java b/src/test/java/dev/openfeature/sdk/HookContextTest.java index 2196b8b1f..123052b7d 100644 --- a/src/test/java/dev/openfeature/sdk/HookContextTest.java +++ b/src/test/java/dev/openfeature/sdk/HookContextTest.java @@ -1,6 +1,6 @@ package dev.openfeature.sdk; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; import org.junit.jupiter.api.Test; @@ -29,4 +29,46 @@ void metadata_field_is_type_metadata() { "The before stage MUST run before flag resolution occurs. It accepts a hook context (required) and hook hints (optional) as parameters. It has no return value.") @Test void not_applicable_for_dynamic_context() {} + + @Test + void shouldCreateHookContextWithHookData() { + HookData hookData = HookData.create(); + hookData.set("test", "value"); + + HookContextWithData context = HookContextWithData.of(mock(HookContext.class), hookData); + + assertNotNull(context.getHookData()); + assertEquals("value", context.getHookData().get("test")); + } + + @Test + void shouldCreateHookContextWithoutHookData() { + HookContext context = HookContext.builder() + .flagKey("test-flag") + .type(FlagValueType.STRING) + .defaultValue("default") + .ctx(new ImmutableContext()) + .build(); + + assertNull(context.getHookData()); + } + + @Test + void shouldCreateHookContextWithHookDataUsingWith() { + HookContext originalContext = HookContext.builder() + .flagKey("test-flag") + .type(FlagValueType.STRING) + .defaultValue("default") + .ctx(new ImmutableContext()) + .build(); + + HookData hookData = HookData.create(); + hookData.set("timing", System.currentTimeMillis()); + + HookContext contextWithHookData = HookContextWithData.of(originalContext, hookData); + + assertNull(originalContext.getHookData()); + assertNotNull(contextWithHookData.getHookData()); + assertNotNull(contextWithHookData.getHookData().get("timing")); + } } diff --git a/src/test/java/dev/openfeature/sdk/HookDataTest.java b/src/test/java/dev/openfeature/sdk/HookDataTest.java new file mode 100644 index 000000000..eacbeeb78 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/HookDataTest.java @@ -0,0 +1,79 @@ +package dev.openfeature.sdk; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class HookDataTest { + + @Test + void shouldStoreAndRetrieveValues() { + HookData hookData = HookData.create(); + + hookData.set("key1", "value1"); + hookData.set("key2", 42); + hookData.set("key3", true); + + assertEquals("value1", hookData.get("key1")); + assertEquals(42, hookData.get("key2")); + assertEquals(true, hookData.get("key3")); + } + + @Test + void shouldReturnNullForMissingKeys() { + HookData hookData = HookData.create(); + + assertNull(hookData.get("nonexistent")); + } + + @Test + void shouldSupportTypeSafeRetrieval() { + HookData hookData = HookData.create(); + + hookData.set("string", "hello"); + hookData.set("integer", 123); + hookData.set("boolean", false); + + assertEquals("hello", hookData.get("string", String.class)); + assertEquals(Integer.valueOf(123), hookData.get("integer", Integer.class)); + assertEquals(Boolean.FALSE, hookData.get("boolean", Boolean.class)); + } + + @Test + void shouldReturnNullForMissingKeysWithType() { + HookData hookData = HookData.create(); + + assertNull(hookData.get("missing", String.class)); + } + + @Test + void shouldThrowClassCastExceptionForWrongType() { + HookData hookData = HookData.create(); + + hookData.set("string", "not a number"); + + assertThrows(ClassCastException.class, () -> { + hookData.get("string", Integer.class); + }); + } + + @Test + void shouldOverwriteExistingValues() { + HookData hookData = HookData.create(); + + hookData.set("key", "original"); + assertEquals("original", hookData.get("key")); + + hookData.set("key", "updated"); + assertEquals("updated", hookData.get("key")); + } + + @Test + void shouldSupportNullValues() { + HookData hookData = HookData.create(); + + hookData.set("nullKey", null); + assertNull(hookData.get("nullKey")); + assertNull(hookData.get("nullKey", String.class)); + } +} diff --git a/src/test/java/dev/openfeature/sdk/HookSupportTest.java b/src/test/java/dev/openfeature/sdk/HookSupportTest.java index 02a8ff90c..67ec03d94 100644 --- a/src/test/java/dev/openfeature/sdk/HookSupportTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSupportTest.java @@ -9,6 +9,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Optional; import org.junit.jupiter.api.DisplayName; @@ -23,8 +24,15 @@ void shouldMergeEvaluationContextsOnBeforeHooksCorrectly() { Map attributes = new HashMap<>(); attributes.put("baseKey", new Value("baseValue")); EvaluationContext baseContext = new ImmutableContext(attributes); - HookContext hookContext = new HookContext<>( - "flagKey", FlagValueType.STRING, "defaultValue", baseContext, () -> "client", () -> "provider"); + FlagValueType valueType = FlagValueType.STRING; + HookContext hookContext = HookContextWithoutData.builder() + .flagKey("flagKey") + .type(valueType) + .defaultValue("defaultValue") + .ctx(baseContext) + .clientMetadata(() -> "client") + .providerMetadata(() -> "provider") + .build(); Hook hook1 = mockStringHook(); Hook hook2 = mockStringHook(); when(hook1.before(any(), any())).thenReturn(Optional.of(evaluationContextWithValue("bla", "blubber"))); @@ -32,7 +40,10 @@ void shouldMergeEvaluationContextsOnBeforeHooksCorrectly() { HookSupport hookSupport = new HookSupport(); EvaluationContext result = hookSupport.beforeHooks( - FlagValueType.STRING, hookContext, Arrays.asList(hook1, hook2), Collections.emptyMap()); + valueType, + hookContext, + hookSupport.getHookDataPairs(Arrays.asList(hook1, hook2), valueType), + Collections.emptyMap()); assertThat(result.getValue("bla").asString()).isEqualTo("blubber"); assertThat(result.getValue("foo").asString()).isEqualTo("bar"); @@ -45,36 +56,32 @@ void shouldMergeEvaluationContextsOnBeforeHooksCorrectly() { void shouldAlwaysCallGenericHook(FlagValueType flagValueType) { Hook genericHook = mockGenericHook(); HookSupport hookSupport = new HookSupport(); + var hookDataPairs = hookSupport.getHookDataPairs(Collections.singletonList(genericHook), flagValueType); EvaluationContext baseContext = new ImmutableContext(); IllegalStateException expectedException = new IllegalStateException("All fine, just a test"); - HookContext hookContext = new HookContext<>( - "flagKey", - flagValueType, - createDefaultValue(flagValueType), - baseContext, - () -> "client", - () -> "provider"); + HookContext hookContext = HookContext.builder() + .flagKey("flagKey") + .type(flagValueType) + .defaultValue(createDefaultValue(flagValueType)) + .ctx(baseContext) + .clientMetadata(() -> "client") + .providerMetadata(() -> "provider") + .build(); - hookSupport.beforeHooks( - flagValueType, hookContext, Collections.singletonList(genericHook), Collections.emptyMap()); + hookSupport.beforeHooks(flagValueType, hookContext, hookDataPairs, Collections.emptyMap()); hookSupport.afterHooks( flagValueType, hookContext, FlagEvaluationDetails.builder().build(), - Collections.singletonList(genericHook), + hookDataPairs, Collections.emptyMap()); hookSupport.afterAllHooks( flagValueType, hookContext, FlagEvaluationDetails.builder().build(), - Collections.singletonList(genericHook), - Collections.emptyMap()); - hookSupport.errorHooks( - flagValueType, - hookContext, - expectedException, - Collections.singletonList(genericHook), + hookDataPairs, Collections.emptyMap()); + hookSupport.errorHooks(flagValueType, hookContext, expectedException, hookDataPairs, Collections.emptyMap()); verify(genericHook).before(any(), any()); verify(genericHook).after(any(), any(), any()); @@ -82,6 +89,101 @@ void shouldAlwaysCallGenericHook(FlagValueType flagValueType) { verify(genericHook).error(any(), any(), any()); } + @ParameterizedTest + @EnumSource(value = FlagValueType.class) + @DisplayName("should allow hooks to store and retrieve data across stages") + void shouldPassDataAcrossStages(FlagValueType flagValueType) { + HookSupport hookSupport = new HookSupport(); + HookContext hookContext = getObjectHookContext(flagValueType); + + TestHookWithData testHook = new TestHookWithData("test-key", "value"); + var pairs = hookSupport.getHookDataPairs(List.of(testHook), flagValueType); + + callAllHooks(flagValueType, hookSupport, hookContext, testHook); + + assertHookData(testHook, "value"); + } + + @ParameterizedTest + @EnumSource(value = FlagValueType.class) + @DisplayName("should isolate data between different hook instances") + void shouldIsolateDataBetweenHooks(FlagValueType flagValueType) { + HookSupport hookSupport = new HookSupport(); + HookContext hookContext = getObjectHookContext(flagValueType); + + TestHookWithData testHook1 = new TestHookWithData("test-key", "value-1"); + TestHookWithData testHook2 = new TestHookWithData("test-key", "value-2"); + var pairs = hookSupport.getHookDataPairs(List.of(testHook1, testHook2), flagValueType); + + callAllHooks(flagValueType, hookSupport, hookContext, pairs); + + assertHookData(testHook1, "value-1"); + assertHookData(testHook2, "value-2"); + } + + @ParameterizedTest + @EnumSource(value = FlagValueType.class) + @DisplayName("should isolate data between the same hook instances") + void shouldIsolateDataBetweenSameHooks(FlagValueType flagValueType) { + + HookSupport hookSupport = new HookSupport(); + HookContext hookContext = getObjectHookContext(flagValueType); + + TestHookWithData testHook = new TestHookWithData("test-key", "value-1"); + + // run hooks first time + callAllHooks(flagValueType, hookSupport, hookContext, testHook); + assertHookData(testHook, "value-1"); + + // re-run with different value, will throw if HookData contains already data + testHook.value = "value-2"; + callAllHooks(flagValueType, hookSupport, hookContext, testHook); + + assertHookData(testHook, "value-2"); + } + + private HookContext getObjectHookContext(FlagValueType flagValueType) { + EvaluationContext baseContext = new ImmutableContext(); + HookContext hookContext = HookContext.builder() + .flagKey("flagKey") + .type(flagValueType) + .defaultValue(createDefaultValue(flagValueType)) + .ctx(baseContext) + .clientMetadata(() -> "client") + .providerMetadata(() -> "provider") + .build(); + return hookContext; + } + + private static void assertHookData(TestHookWithData testHook1, String expected) { + assertThat(testHook1.onBeforeValue).isEqualTo(expected); + assertThat(testHook1.onFinallyAfterValue).isEqualTo(expected); + assertThat(testHook1.onAfterValue).isEqualTo(expected); + assertThat(testHook1.onErrorValue).isEqualTo(expected); + } + + private static void callAllHooks( + FlagValueType flagValueType, + HookSupport hookSupport, + HookContext hookContext, + TestHookWithData testHook) { + var pairs = hookSupport.getHookDataPairs(List.of(testHook), flagValueType); + callAllHooks(flagValueType, hookSupport, hookContext, pairs); + } + + private static void callAllHooks( + FlagValueType flagValueType, + HookSupport hookSupport, + HookContext hookContext, + List> pairs) { + hookSupport.beforeHooks(flagValueType, hookContext, pairs, Collections.emptyMap()); + hookSupport.afterHooks( + flagValueType, hookContext, new FlagEvaluationDetails<>(), pairs, Collections.emptyMap()); + hookSupport.errorHooks(flagValueType, hookContext, new Exception(), pairs, Collections.emptyMap()); + hookSupport.afterAllHooks( + flagValueType, hookContext, new FlagEvaluationDetails<>(), pairs, Collections.emptyMap()); + } + private Object createDefaultValue(FlagValueType flagValueType) { switch (flagValueType) { case INTEGER: @@ -105,4 +207,46 @@ private EvaluationContext evaluationContextWithValue(String key, String value) { EvaluationContext baseContext = new ImmutableContext(attributes); return baseContext; } + + private class TestHookWithData implements Hook { + + private final String key; + Object value; + + Object onBeforeValue; + Object onAfterValue; + Object onErrorValue; + Object onFinallyAfterValue; + + TestHookWithData(String key, Object value) { + this.key = key; + this.value = value; + } + + @Override + public Optional before(HookContext ctx, Map hints) { + var storedValue = ctx.getHookData().get(key); + if (storedValue != null) { + throw new Error("Hook data isolation violated! Data is already set."); + } + ctx.getHookData().set(key, value); + onBeforeValue = ctx.getHookData().get(key); + return Optional.empty(); + } + + @Override + public void after(HookContext ctx, FlagEvaluationDetails details, Map hints) { + onAfterValue = ctx.getHookData().get(key); + } + + @Override + public void error(HookContext ctx, Exception error, Map hints) { + onErrorValue = ctx.getHookData().get(key); + } + + @Override + public void finallyAfter(HookContext ctx, FlagEvaluationDetails details, Map hints) { + onFinallyAfterValue = ctx.getHookData().get(key); + } + } } diff --git a/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java b/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java index 5bc89d03d..9fe043722 100644 --- a/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java +++ b/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java @@ -54,6 +54,30 @@ public Optional before(HookContext ctx, Map() { + @Override + public Optional before(HookContext ctx, Map hints) { + return Optional.ofNullable(new ImmutableContext()); + } + }); + client.addHooks(new Hook() { + @Override + public Optional before(HookContext ctx, Map hints) { + return Optional.ofNullable(new ImmutableContext()); + } + }); + client.addHooks(new Hook() { + @Override + public Optional before(HookContext ctx, Map hints) { + return Optional.ofNullable(new ImmutableContext()); + } + }); + client.addHooks(new Hook() { + @Override + public Optional before(HookContext ctx, Map hints) { + return Optional.ofNullable(new ImmutableContext()); + } + }); Map invocationAttrs = new HashMap<>(); invocationAttrs.put("invoke", new Value(3)); From a7964beda575c46eddc15f44d21c23b5a52802c7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 13:13:26 +0200 Subject: [PATCH 385/745] chore(deps): update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.5.0 (#1601) 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 ada93b719..c20641ac1 100644 --- a/pom.xml +++ b/pom.xml @@ -403,7 +403,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.9.4.2 + 4.9.5.0 spotbugs-exclusions.xml From c126bdb2d772a85417dbb77b92079a8a2107b8b6 Mon Sep 17 00:00:00 2001 From: alexandraoberaigner <82218944+alexandraoberaigner@users.noreply.github.com> Date: Tue, 16 Sep 2025 13:35:57 +0200 Subject: [PATCH 386/745] fix: javadoc error on-merge action (#1599) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: make builder visible for javadocs, move javadoc gen to codequality profile Signed-off-by: Alexandra Oberaigner --- pom.xml | 46 +++++++++---------- .../sdk/HookContextWithoutData.java | 7 +++ 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/pom.xml b/pom.xml index c20641ac1..86b5a8201 100644 --- a/pom.xml +++ b/pom.xml @@ -507,29 +507,6 @@ - - - - - deploy - - true - - - - - - - org.sonatype.central - central-publishing-maven-plugin - 0.8.0 - true - - central - true - - - @@ -565,6 +542,29 @@ + + + + + deploy + + true + + + + + + + org.sonatype.central + central-publishing-maven-plugin + 0.8.0 + true + + central + true + + + diff --git a/src/main/java/dev/openfeature/sdk/HookContextWithoutData.java b/src/main/java/dev/openfeature/sdk/HookContextWithoutData.java index 6e5394ee1..df1ed6ad1 100644 --- a/src/main/java/dev/openfeature/sdk/HookContextWithoutData.java +++ b/src/main/java/dev/openfeature/sdk/HookContextWithoutData.java @@ -45,4 +45,11 @@ static HookContextWithoutData from( return new HookContextWithoutData<>( key, type, defaultValue, ImmutableContext.EMPTY, clientMetadata, providerMetadata); } + + /** + * Make the builder visible for javadocs. + * + * @param flag value type + */ + public static class HookContextWithoutDataBuilder {} } From 55a9a5ace2e899a8c57149b7638333faaca2836f Mon Sep 17 00:00:00 2001 From: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> Date: Tue, 16 Sep 2025 08:11:14 -0400 Subject: [PATCH 387/745] chore(main): release 1.18.0 (#1539) Signed-off-by: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 70 +++++++++++++++++++++++++++++++++++ README.md | 8 ++-- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 77 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index f5c3b938e..b0c190560 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"1.17.0"} +{".":"1.18.0"} diff --git a/CHANGELOG.md b/CHANGELOG.md index 5513f0e55..dafacd904 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,75 @@ # Changelog +## [1.18.0](https://github.com/open-feature/java-sdk/compare/v1.17.0...v1.18.0) (2025-09-16) + + +### 🐛 Bug Fixes + +* **deps:** update dependency com.github.spotbugs:spotbugs to v4.9.4 ([#1548](https://github.com/open-feature/java-sdk/issues/1548)) ([f2fef65](https://github.com/open-feature/java-sdk/commit/f2fef65eb580b1960ad15b2c46ebe40855551be3)) +* **deps:** update dependency com.github.spotbugs:spotbugs to v4.9.5 ([#1598](https://github.com/open-feature/java-sdk/issues/1598)) ([5474c73](https://github.com/open-feature/java-sdk/commit/5474c736f711ed06cbca2bd0d4d0cfd458a54d10)) +* **deps:** update dependency io.cucumber:cucumber-bom to v7.27.1 ([#1562](https://github.com/open-feature/java-sdk/issues/1562)) ([508bdac](https://github.com/open-feature/java-sdk/commit/508bdac4f075e2cd374dd1728919cfc1619d0097)) +* **deps:** update dependency io.cucumber:cucumber-bom to v7.27.2 ([#1566](https://github.com/open-feature/java-sdk/issues/1566)) ([8a9f251](https://github.com/open-feature/java-sdk/commit/8a9f25177f2d4bab1b5215f172bbb8ed1a5ad788)) +* **deps:** update dependency io.cucumber:cucumber-bom to v7.28.2 ([#1593](https://github.com/open-feature/java-sdk/issues/1593)) ([ca72b19](https://github.com/open-feature/java-sdk/commit/ca72b19d33985dfaae1cda009afd6795c5752259)) +* **deps:** update dependency org.projectlombok:lombok to v1.18.40 ([#1597](https://github.com/open-feature/java-sdk/issues/1597)) ([e181276](https://github.com/open-feature/java-sdk/commit/e1812767b684b21d417e31dadc8d031cd64cdab1)) +* javadoc error on-merge action ([#1599](https://github.com/open-feature/java-sdk/issues/1599)) ([c126bdb](https://github.com/open-feature/java-sdk/commit/c126bdb2d772a85417dbb77b92079a8a2107b8b6)) +* make builder visible for javadocs, move javadoc gen to codequality profile ([c126bdb](https://github.com/open-feature/java-sdk/commit/c126bdb2d772a85417dbb77b92079a8a2107b8b6)) + + +### ✨ New Features + +* add hook data ([#1587](https://github.com/open-feature/java-sdk/issues/1587)) ([1b08e3d](https://github.com/open-feature/java-sdk/commit/1b08e3db42635bbe79c61437db2359bd74a98348)) + + +### 🧹 Chore + +* **deps:** update actions/cache digest to 0400d5f ([#1544](https://github.com/open-feature/java-sdk/issues/1544)) ([050379b](https://github.com/open-feature/java-sdk/commit/050379be110b7a980cf5cc02ddf23e00a7ee7202)) +* **deps:** update actions/cache digest to 358a730 ([#1541](https://github.com/open-feature/java-sdk/issues/1541)) ([6efc2ee](https://github.com/open-feature/java-sdk/commit/6efc2ee1e701daf38e3efc2f115dc93025a0e2e2)) +* **deps:** update actions/cache digest to 638ed79 ([#1549](https://github.com/open-feature/java-sdk/issues/1549)) ([7f487ee](https://github.com/open-feature/java-sdk/commit/7f487ee7ecd1c69a63d22eca140bc422a0afc963)) +* **deps:** update actions/checkout digest to 08c6903 ([#1550](https://github.com/open-feature/java-sdk/issues/1550)) ([527e3f8](https://github.com/open-feature/java-sdk/commit/527e3f836f664ecace1018de84502592ee75007c)) +* **deps:** update actions/checkout digest to ff7abcd ([#1554](https://github.com/open-feature/java-sdk/issues/1554)) ([35fe5b4](https://github.com/open-feature/java-sdk/commit/35fe5b41bc971f8bc41b82b8c0ef50d719071301)) +* **deps:** update actions/setup-java digest to 0913e9a ([#1572](https://github.com/open-feature/java-sdk/issues/1572)) ([58c82de](https://github.com/open-feature/java-sdk/commit/58c82de9656562f137feafb9e6eff20521695803)) +* **deps:** update actions/setup-java digest to a7ab372 ([#1589](https://github.com/open-feature/java-sdk/issues/1589)) ([a08ff4d](https://github.com/open-feature/java-sdk/commit/a08ff4d96ccf9236ad882892280b600a05409394)) +* **deps:** update actions/setup-java digest to dded088 ([#1574](https://github.com/open-feature/java-sdk/issues/1574)) ([d332224](https://github.com/open-feature/java-sdk/commit/d33222439e84435baeb0a49d33651208e659ad27)) +* **deps:** update amannn/action-semantic-pull-request digest to 24e6f01 ([#1568](https://github.com/open-feature/java-sdk/issues/1568)) ([c8d48e1](https://github.com/open-feature/java-sdk/commit/c8d48e1a739f02b25e7980dcd5652851756729f2)) +* **deps:** update amannn/action-semantic-pull-request digest to 677b895 ([#1570](https://github.com/open-feature/java-sdk/issues/1570)) ([fb6ab35](https://github.com/open-feature/java-sdk/commit/fb6ab353b403542a1f7e6ccafb07e25ae1d5e2be)) +* **deps:** update amannn/action-semantic-pull-request digest to a46a7c8 ([#1563](https://github.com/open-feature/java-sdk/issues/1563)) ([47af527](https://github.com/open-feature/java-sdk/commit/47af5279d6abd0080eae16d630bd202976f9a4b1)) +* **deps:** update amannn/action-semantic-pull-request digest to e7d011b ([#1577](https://github.com/open-feature/java-sdk/issues/1577)) ([532ad2f](https://github.com/open-feature/java-sdk/commit/532ad2f3d404753189a529cdc262ba6ef8d3d586)) +* **deps:** update amannn/action-semantic-pull-request digest to fdd4d3d ([#1553](https://github.com/open-feature/java-sdk/issues/1553)) ([8a6c796](https://github.com/open-feature/java-sdk/commit/8a6c79627a492eb61ed35ffa91035b0737598b64)) +* **deps:** update codecov/codecov-action action to v5.5.0 ([#1573](https://github.com/open-feature/java-sdk/issues/1573)) ([2c2b380](https://github.com/open-feature/java-sdk/commit/2c2b380e13d2be5a988b70212ea243efdb60999b)) +* **deps:** update codecov/codecov-action action to v5.5.1 ([#1591](https://github.com/open-feature/java-sdk/issues/1591)) ([e47913a](https://github.com/open-feature/java-sdk/commit/e47913a07ee064fe340db978250710a7cb17795d)) +* **deps:** update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.4.0 ([#1576](https://github.com/open-feature/java-sdk/issues/1576)) ([894165d](https://github.com/open-feature/java-sdk/commit/894165ddd7216dc30c1ca4c9f43c0a4c21970f17)) +* **deps:** update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.4.2 ([#1592](https://github.com/open-feature/java-sdk/issues/1592)) ([8b3f7f0](https://github.com/open-feature/java-sdk/commit/8b3f7f07f4aa555301d484544939fa5a0b4de746)) +* **deps:** update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.5.0 ([#1601](https://github.com/open-feature/java-sdk/issues/1601)) ([a7964be](https://github.com/open-feature/java-sdk/commit/a7964beda575c46eddc15f44d21c23b5a52802c7)) +* **deps:** update dependency com.puppycrawl.tools:checkstyle to v11 ([#1543](https://github.com/open-feature/java-sdk/issues/1543)) ([d2f85d5](https://github.com/open-feature/java-sdk/commit/d2f85d5a9e42c0e336546684b27a1e77edc4c620)) +* **deps:** update dependency com.puppycrawl.tools:checkstyle to v11.0.1 ([#1585](https://github.com/open-feature/java-sdk/issues/1585)) ([8dd40fa](https://github.com/open-feature/java-sdk/commit/8dd40fabcae6a90ee7abe1b0a0d8f55f345e3331)) +* **deps:** update dependency maven-wrapper to v3.3.3 ([#1584](https://github.com/open-feature/java-sdk/issues/1584)) ([cba90dd](https://github.com/open-feature/java-sdk/commit/cba90dd227514464fd90bd605f73c358748c09e1)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.17.7 ([#1560](https://github.com/open-feature/java-sdk/issues/1560)) ([124c26f](https://github.com/open-feature/java-sdk/commit/124c26f6ea2d20cebb7520afcd94ab6b6c8c8e7b)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.17.7 ([#1561](https://github.com/open-feature/java-sdk/issues/1561)) ([84887bf](https://github.com/open-feature/java-sdk/commit/84887bfc86eb4905f52bce4641c35a8909f2c463)) +* **deps:** update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.5.4 ([#1596](https://github.com/open-feature/java-sdk/issues/1596)) ([3606154](https://github.com/open-feature/java-sdk/commit/3606154aa7ded57f41c324559268335531606b6c)) +* **deps:** update dependency org.apache.maven.plugins:maven-javadoc-plugin to v3.11.3 ([#1559](https://github.com/open-feature/java-sdk/issues/1559)) ([6fbc9d6](https://github.com/open-feature/java-sdk/commit/6fbc9d6cca5716b7477f84ff4093ccc6af06d4e6)) +* **deps:** update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.4 ([#1595](https://github.com/open-feature/java-sdk/issues/1595)) ([a17bd3a](https://github.com/open-feature/java-sdk/commit/a17bd3a388927781b86e91064748a71670bb2a2a)) +* **deps:** update dependency org.assertj:assertj-core to v3.27.4 ([#1546](https://github.com/open-feature/java-sdk/issues/1546)) ([c4fe7d2](https://github.com/open-feature/java-sdk/commit/c4fe7d2e81510db4eaa13a4d0046827efecd8a79)) +* **deps:** update dependency org.mockito:mockito-core to v5.19.0 ([#1557](https://github.com/open-feature/java-sdk/issues/1557)) ([dff5412](https://github.com/open-feature/java-sdk/commit/dff54123ab38fd3ad59809e5f863b6ace17e4da4)) +* **deps:** update github/codeql-action digest to 02ab253 ([#1583](https://github.com/open-feature/java-sdk/issues/1583)) ([080fc6e](https://github.com/open-feature/java-sdk/commit/080fc6e9a60c15eb748891245258c9c5378e4248)) +* **deps:** update github/codeql-action digest to 0d33fd9 ([#1590](https://github.com/open-feature/java-sdk/issues/1590)) ([9e4881f](https://github.com/open-feature/java-sdk/commit/9e4881fdcb577a693cfe587b58dce5a74fb3caf4)) +* **deps:** update github/codeql-action digest to 2330521 ([#1558](https://github.com/open-feature/java-sdk/issues/1558)) ([f1165da](https://github.com/open-feature/java-sdk/commit/f1165da1b910efda6dbe486a21eb7985cccf11ae)) +* **deps:** update github/codeql-action digest to 4474150 ([#1547](https://github.com/open-feature/java-sdk/issues/1547)) ([09b3138](https://github.com/open-feature/java-sdk/commit/09b31383e3b7e693ec43d6016486e3ededf8c2de)) +* **deps:** update github/codeql-action digest to 5b49155 ([#1575](https://github.com/open-feature/java-sdk/issues/1575)) ([d9c1df0](https://github.com/open-feature/java-sdk/commit/d9c1df0c5ec247f64c37648128d56b7e83444ca9)) +* **deps:** update github/codeql-action digest to 6dee5bc ([#1569](https://github.com/open-feature/java-sdk/issues/1569)) ([907b75d](https://github.com/open-feature/java-sdk/commit/907b75d3481e71621249b0246e0ca67c42c9a890)) +* **deps:** update github/codeql-action digest to 6ec994e ([#1564](https://github.com/open-feature/java-sdk/issues/1564)) ([19c2a12](https://github.com/open-feature/java-sdk/commit/19c2a1272a34040f3ac2b603c2bcb645f3707a82)) +* **deps:** update github/codeql-action digest to 6fe50b2 ([#1545](https://github.com/open-feature/java-sdk/issues/1545)) ([866235e](https://github.com/open-feature/java-sdk/commit/866235e494c229b3d47df80146199db4204b2ece)) +* **deps:** update github/codeql-action digest to 777f917 ([#1556](https://github.com/open-feature/java-sdk/issues/1556)) ([03a8018](https://github.com/open-feature/java-sdk/commit/03a8018098bbced558e157b60e7ba3ff18527db6)) +* **deps:** update github/codeql-action digest to 7eb43b0 ([#1555](https://github.com/open-feature/java-sdk/issues/1555)) ([88ded5d](https://github.com/open-feature/java-sdk/commit/88ded5d9290b3c008a597cf55bb1e1f4c05e40ec)) +* **deps:** update github/codeql-action digest to a880e53 ([#1581](https://github.com/open-feature/java-sdk/issues/1581)) ([5efac69](https://github.com/open-feature/java-sdk/commit/5efac69dae28ff26227e5a9e83c6edbea9b9b6b5)) +* **deps:** update github/codeql-action digest to aa90e97 ([#1594](https://github.com/open-feature/java-sdk/issues/1594)) ([5df4317](https://github.com/open-feature/java-sdk/commit/5df4317caa97bdd055ec1f809d2b5e49642b5312)) +* **deps:** update github/codeql-action digest to b1228d0 ([#1540](https://github.com/open-feature/java-sdk/issues/1540)) ([bc58780](https://github.com/open-feature/java-sdk/commit/bc587809341d60eeb575b0d58d75b35972b92053)) +* **deps:** update github/codeql-action digest to bbfff2f ([#1538](https://github.com/open-feature/java-sdk/issues/1538)) ([6056877](https://github.com/open-feature/java-sdk/commit/60568776c471e7c01f8cee6b198fe6df70fc2ca5)) +* **deps:** update github/codeql-action digest to c6dcdfa ([#1551](https://github.com/open-feature/java-sdk/issues/1551)) ([ce2b6e8](https://github.com/open-feature/java-sdk/commit/ce2b6e88313ea500c2b71f0b4c06ad4a12522f3e)) +* **deps:** update github/codeql-action digest to db69a51 ([#1571](https://github.com/open-feature/java-sdk/issues/1571)) ([fc7ec65](https://github.com/open-feature/java-sdk/commit/fc7ec6511fd92c872e55e2b4f96f1dc6215ed029)) +* **deps:** update github/codeql-action digest to e2b6f0f ([#1542](https://github.com/open-feature/java-sdk/issues/1542)) ([7ccbb71](https://github.com/open-feature/java-sdk/commit/7ccbb714b305deb9fa0e31ace1bd7f044c8c57ed)) +* **deps:** update github/codeql-action digest to e96e340 ([#1565](https://github.com/open-feature/java-sdk/issues/1565)) ([ea23114](https://github.com/open-feature/java-sdk/commit/ea23114d424ce042681d6b42cdc6b2e2086ccbf8)) +* **deps:** update github/codeql-action digest to eef4c44 ([#1552](https://github.com/open-feature/java-sdk/issues/1552)) ([4bae329](https://github.com/open-feature/java-sdk/commit/4bae3294b20f19550a878f331cba2377df14f7c1)) + ## [1.17.0](https://github.com/open-feature/java-sdk/compare/v1.16.0...v1.17.0) (2025-08-01) diff --git a/README.md b/README.md index 24bae2a3c..39f558f8f 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.17.0 + 1.18.0 ``` @@ -84,7 +84,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:1.17.0' + implementation 'dev.openfeature:sdk:1.18.0' } ``` diff --git a/pom.xml b/pom.xml index 86b5a8201..70d5f32fe 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ dev.openfeature sdk - 1.17.0 + 1.18.0 [17,) diff --git a/version.txt b/version.txt index 092afa15d..84cc52946 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.17.0 +1.18.0 From 6fb139f8425fb76368b1e1baa745aa182f8c13f7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 12:55:08 +0000 Subject: [PATCH 388/745] chore(deps): update github/codeql-action digest to 573acd9 (#1600) 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 67da3cb06..3149c89dd 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@aa90e97ad2ed17cde6a43e89f70138299e64f837 + uses: github/codeql-action/init@573acd9552f33577783abde4acb66a1058e762e5 with: languages: java @@ -55,4 +55,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@aa90e97ad2ed17cde6a43e89f70138299e64f837 + uses: github/codeql-action/analyze@573acd9552f33577783abde4acb66a1058e762e5 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 7c16abc16..2ab9903d2 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@aa90e97ad2ed17cde6a43e89f70138299e64f837 + uses: github/codeql-action/init@573acd9552f33577783abde4acb66a1058e762e5 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@aa90e97ad2ed17cde6a43e89f70138299e64f837 + uses: github/codeql-action/autobuild@573acd9552f33577783abde4acb66a1058e762e5 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@aa90e97ad2ed17cde6a43e89f70138299e64f837 + uses: github/codeql-action/analyze@573acd9552f33577783abde4acb66a1058e762e5 From e89fab2cc3c134d77b2e5236734bf2fa2871a8e7 Mon Sep 17 00:00:00 2001 From: Simon Schrottner Date: Tue, 16 Sep 2025 15:45:51 +0200 Subject: [PATCH 389/745] test: improve gherkin test suite only relying on the newest version, with data loading (#1578) * test: improve gherkin test suite only relying on the newest version, with data loading Signed-off-by: Simon Schrottner * Update src/test/java/dev/openfeature/sdk/e2e/steps/ContextSteps.java Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Simon Schrottner * Update src/test/java/dev/openfeature/sdk/testutils/jackson/CelContextEvaluator.java Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Simon Schrottner * test: improve gherkin test suite only relying on the newest version, with data loading Signed-off-by: Simon Schrottner diff --git c/src/test/java/dev/openfeature/sdk/e2e/steps/ContextSteps.java i/src/test/java/dev/openfeature/sdk/e2e/steps/ContextSteps.java index e4cd603..121b567 100644 --- c/src/test/java/dev/openfeature/sdk/e2e/steps/ContextSteps.java +++ i/src/test/java/dev/openfeature/sdk/e2e/steps/ContextSteps.java @@ -114,9 +114,9 @@ public class ContextSteps { public void a_context_containing_a_key_with_type_and_with_value(String key, String type, String value) throws ClassNotFoundException, InstantiationException { Map map = state.context.asMap(); - Map map = state.context.asMap(); map.put(key, new Value(Utils.convert(value, type))); state.context = new MutableContext(state.context.getTargetingKey(), map); + } @Given("a context containing a targeting key with value {string}") public void a_context_containing_a_targeting_key_with_value(String string) { diff --git c/src/test/java/dev/openfeature/sdk/testutils/jackson/CelContextEvaluator.java i/src/test/java/dev/openfeature/sdk/testutils/jackson/CelContextEvaluator.java index 20f3f5f..138c23f 100644 --- c/src/test/java/dev/openfeature/sdk/testutils/jackson/CelContextEvaluator.java +++ i/src/test/java/dev/openfeature/sdk/testutils/jackson/CelContextEvaluator.java @@ -46,7 +46,6 @@ public class CelContextEvaluator implements ContextEvaluator { // Evaluate with context, overriding defaults. objectMap.putAll(evaluationContext.asObjectMap()); } - } Object result = program.eval(objectMap); diff --git c/src/test/java/dev/openfeature/sdk/testutils/jackson/VariantsMapDeserializer.java i/src/test/java/dev/openfeature/sdk/testutils/jackson/VariantsMapDeserializer.java index 339d8c8..9a63f58 100644 --- c/src/test/java/dev/openfeature/sdk/testutils/jackson/VariantsMapDeserializer.java +++ i/src/test/java/dev/openfeature/sdk/testutils/jackson/VariantsMapDeserializer.java @@ -50,6 +50,7 @@ public class VariantsMapDeserializer extends JsonDeserializer list = new ArrayList<>(); - for (JsonNode item : node) { - list.add(convertJsonNodeToValue(item)); - } - return list; } else if (node.isObject()) { - Map map = new HashMap<>(); - Iterator> fields = node.fields(); - while (fields.hasNext()) { - Map.Entry field = fields.next(); - Object o = convertJsonNodeToValue(field.getValue()); - if (o instanceof Value) { - map.put(field.getKey(), (Value) o); - } else { - map.put(field.getKey(), new Value(o)); - } - } - return new Value(new MutableStructure(map)); + return Value.objectToValue(node); } throw new IllegalArgumentException("Unsupported JSON node type: " + node.getNodeType()); Signed-off-by: Simon Schrottner * Update src/test/java/dev/openfeature/sdk/e2e/steps/FlagStepDefinitions.java Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Simon Schrottner * Update src/test/java/dev/openfeature/sdk/testutils/TestFlagsUtils.java Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Simon Schrottner * test: improve gherkin test suite only relying on the newest version, with data loading Signed-off-by: Simon Schrottner diff --git c/src/test/java/dev/openfeature/sdk/e2e/steps/ContextSteps.java i/src/test/java/dev/openfeature/sdk/e2e/steps/ContextSteps.java index e4cd603..121b567 100644 --- c/src/test/java/dev/openfeature/sdk/e2e/steps/ContextSteps.java +++ i/src/test/java/dev/openfeature/sdk/e2e/steps/ContextSteps.java @@ -114,9 +114,9 @@ public class ContextSteps { public void a_context_containing_a_key_with_type_and_with_value(String key, String type, String value) throws ClassNotFoundException, InstantiationException { Map map = state.context.asMap(); - Map map = state.context.asMap(); map.put(key, new Value(Utils.convert(value, type))); state.context = new MutableContext(state.context.getTargetingKey(), map); + } @Given("a context containing a targeting key with value {string}") public void a_context_containing_a_targeting_key_with_value(String string) { diff --git c/src/test/java/dev/openfeature/sdk/testutils/jackson/CelContextEvaluator.java i/src/test/java/dev/openfeature/sdk/testutils/jackson/CelContextEvaluator.java index 20f3f5f..138c23f 100644 --- c/src/test/java/dev/openfeature/sdk/testutils/jackson/CelContextEvaluator.java +++ i/src/test/java/dev/openfeature/sdk/testutils/jackson/CelContextEvaluator.java @@ -46,7 +46,6 @@ public class CelContextEvaluator implements ContextEvaluator { // Evaluate with context, overriding defaults. objectMap.putAll(evaluationContext.asObjectMap()); } - } Object result = program.eval(objectMap); diff --git c/src/test/java/dev/openfeature/sdk/testutils/jackson/VariantsMapDeserializer.java i/src/test/java/dev/openfeature/sdk/testutils/jackson/VariantsMapDeserializer.java index 339d8c8..9a63f58 100644 --- c/src/test/java/dev/openfeature/sdk/testutils/jackson/VariantsMapDeserializer.java +++ i/src/test/java/dev/openfeature/sdk/testutils/jackson/VariantsMapDeserializer.java @@ -50,6 +50,7 @@ public class VariantsMapDeserializer extends JsonDeserializer list = new ArrayList<>(); - for (JsonNode item : node) { - list.add(convertJsonNodeToValue(item)); - } - return list; } else if (node.isObject()) { - Map map = new HashMap<>(); - Iterator> fields = node.fields(); - while (fields.hasNext()) { - Map.Entry field = fields.next(); - Object o = convertJsonNodeToValue(field.getValue()); - if (o instanceof Value) { - map.put(field.getKey(), (Value) o); - } else { - map.put(field.getKey(), new Value(o)); - } - } - return new Value(new MutableStructure(map)); + return Value.objectToValue(node); } throw new IllegalArgumentException("Unsupported JSON node type: " + node.getNodeType()); Signed-off-by: Simon Schrottner diff --git c/src/test/java/dev/openfeature/sdk/e2e/Utils.java i/src/test/java/dev/openfeature/sdk/e2e/Utils.java index 1500d99..565968c 100644 --- c/src/test/java/dev/openfeature/sdk/e2e/Utils.java +++ i/src/test/java/dev/openfeature/sdk/e2e/Utils.java @@ -7,6 +7,8 @@ import java.util.Objects; public final class Utils { + public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private Utils() {} public static Object convert(String value, String type) { @@ -27,7 +29,7 @@ public final class Utils { return Long.parseLong(value); case "object": try { - return Value.objectToValue(new ObjectMapper().readValue(value, Object.class)); + return Value.objectToValue(OBJECT_MAPPER.readValue(value, Object.class)); } catch (JsonProcessingException e) { throw new RuntimeException(e); } diff --git c/src/test/java/dev/openfeature/sdk/testutils/TestFlagsUtils.java i/src/test/java/dev/openfeature/sdk/testutils/TestFlagsUtils.java index 78a2fc5..13fe32f 100644 --- c/src/test/java/dev/openfeature/sdk/testutils/TestFlagsUtils.java +++ i/src/test/java/dev/openfeature/sdk/testutils/TestFlagsUtils.java @@ -17,6 +17,8 @@ import java.util.Map; import lombok.experimental.UtilityClass; import lombok.extern.slf4j.Slf4j; +import static dev.openfeature.sdk.e2e.Utils.OBJECT_MAPPER; + /** * Test flags utils. */ @@ -41,7 +43,8 @@ public class TestFlagsUtils { */ public static synchronized Map> buildFlags() { if (flags == null) { - ObjectMapper objectMapper = new ObjectMapper(); + if (flags == null) { + ObjectMapper objectMapper = OBJECT_MAPPER; objectMapper.configure(StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION.mappedFeature(), true); objectMapper.addMixIn(Flag.class, InMemoryFlagMixin.class); objectMapper.addMixIn(Flag.FlagBuilder.class, InMemoryFlagMixin.FlagBuilderMixin.class); Signed-off-by: Simon Schrottner * fixup: add provider-status tests Signed-off-by: Simon Schrottner * fixup: update spec Signed-off-by: Simon Schrottner * fixup: add missing steps and adapt to new spec steps Signed-off-by: Simon Schrottner * fix: race condition? Signed-off-by: Simon Schrottner --------- Signed-off-by: Simon Schrottner Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- pom.xml | 33 +++++ spec | 2 +- .../sdk/providers/memory/Flag.java | 1 + .../providers/memory/InMemoryProvider.java | 36 +++-- ...aluationTest.java => GherkinSpecTest.java} | 4 +- .../java/dev/openfeature/sdk/e2e/Utils.java | 11 ++ .../sdk/e2e/steps/ContextSteps.java | 28 ++++ .../sdk/e2e/steps/FlagStepDefinitions.java | 32 +++- .../sdk/e2e/steps/ProviderSteps.java | 140 +++++++++++++++++- .../sdk/e2e/steps/StepDefinitions.java | 1 + .../sdk/testutils/TestFlagsUtils.java | 120 +++++---------- .../jackson/CelContextEvaluator.java | 61 ++++++++ .../jackson/ContextEvaluatorDeserializer.java | 25 ++++ .../ImmutableMetadataDeserializer.java | 41 +++++ .../testutils/jackson/InMemoryFlagMixin.java | 20 +++ .../jackson/VariantsMapDeserializer.java | 65 ++++++++ 16 files changed, 525 insertions(+), 95 deletions(-) rename src/test/java/dev/openfeature/sdk/e2e/{EvaluationTest.java => GherkinSpecTest.java} (82%) create mode 100644 src/test/java/dev/openfeature/sdk/testutils/jackson/CelContextEvaluator.java create mode 100644 src/test/java/dev/openfeature/sdk/testutils/jackson/ContextEvaluatorDeserializer.java create mode 100644 src/test/java/dev/openfeature/sdk/testutils/jackson/ImmutableMetadataDeserializer.java create mode 100644 src/test/java/dev/openfeature/sdk/testutils/jackson/InMemoryFlagMixin.java create mode 100644 src/test/java/dev/openfeature/sdk/testutils/jackson/VariantsMapDeserializer.java diff --git a/pom.xml b/pom.xml index 70d5f32fe..932dd584f 100644 --- a/pom.xml +++ b/pom.xml @@ -168,6 +168,31 @@ test + + com.fasterxml.jackson.core + jackson-core + test + + + + com.fasterxml.jackson.core + jackson-annotations + test + + + + com.fasterxml.jackson.core + jackson-databind + test + + + + dev.cel + cel + 0.10.1 + test + + @@ -191,6 +216,14 @@ + + com.fasterxml.jackson + jackson-bom + 2.16.1 + pom + import + + io.cucumber cucumber-bom diff --git a/spec b/spec index d4a9a9109..e33a15e92 160000 --- a/spec +++ b/spec @@ -1 +1 @@ -Subproject commit d4a9a910946eded57cf82d6fd4921785a5e64c2b +Subproject commit e33a15e92bd0e45f0de087e7e55ee7e87f952c29 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 f2dc6b495..4422dc51f 100644 --- a/src/main/java/dev/openfeature/sdk/providers/memory/Flag.java +++ b/src/main/java/dev/openfeature/sdk/providers/memory/Flag.java @@ -20,4 +20,5 @@ public class Flag { private String defaultVariant; private ContextEvaluator contextEvaluator; private ImmutableMetadata flagMetadata; + private boolean disabled; } 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 3be1b6316..1773ae8a8 100644 --- a/src/main/java/dev/openfeature/sdk/providers/memory/InMemoryProvider.java +++ b/src/main/java/dev/openfeature/sdk/providers/memory/InMemoryProvider.java @@ -97,36 +97,37 @@ public void updateFlag(String flagKey, Flag newFlag) { @Override public ProviderEvaluation getBooleanEvaluation( String key, Boolean defaultValue, EvaluationContext evaluationContext) { - return getEvaluation(key, evaluationContext, Boolean.class); + return getEvaluation(key, defaultValue, evaluationContext, Boolean.class); } @Override public ProviderEvaluation getStringEvaluation( String key, String defaultValue, EvaluationContext evaluationContext) { - return getEvaluation(key, evaluationContext, String.class); + return getEvaluation(key, defaultValue, evaluationContext, String.class); } @Override public ProviderEvaluation getIntegerEvaluation( String key, Integer defaultValue, EvaluationContext evaluationContext) { - return getEvaluation(key, evaluationContext, Integer.class); + return getEvaluation(key, defaultValue, evaluationContext, Integer.class); } @Override public ProviderEvaluation getDoubleEvaluation( String key, Double defaultValue, EvaluationContext evaluationContext) { - return getEvaluation(key, evaluationContext, Double.class); + return getEvaluation(key, defaultValue, evaluationContext, Double.class); } @SneakyThrows @Override public ProviderEvaluation getObjectEvaluation( String key, Value defaultValue, EvaluationContext evaluationContext) { - return getEvaluation(key, evaluationContext, Value.class); + return getEvaluation(key, defaultValue, evaluationContext, Value.class); } private ProviderEvaluation getEvaluation( - String key, EvaluationContext evaluationContext, Class expectedType) throws OpenFeatureError { + String key, T defaultValue, EvaluationContext evaluationContext, Class expectedType) + throws OpenFeatureError { if (!ProviderState.READY.equals(state)) { if (ProviderState.NOT_READY.equals(state)) { throw new ProviderNotReadyError("provider not yet initialized"); @@ -138,11 +139,28 @@ private ProviderEvaluation getEvaluation( } Flag flag = flags.get(key); if (flag == null) { - throw new FlagNotFoundError("flag " + key + "not found"); + throw new FlagNotFoundError("flag " + key + " not found"); + } + if (flag.isDisabled()) { + return ProviderEvaluation.builder() + .reason(Reason.DISABLED.name()) + .value(defaultValue) + .flagMetadata(flag.getFlagMetadata()) + .build(); } T value; + Reason reason = Reason.STATIC; if (flag.getContextEvaluator() != null) { - value = (T) flag.getContextEvaluator().evaluate(flag, evaluationContext); + try { + value = (T) flag.getContextEvaluator().evaluate(flag, evaluationContext); + reason = Reason.TARGETING_MATCH; + } catch (Exception e) { + value = null; + } + if (value == null) { + value = (T) flag.getVariants().get(flag.getDefaultVariant()); + reason = Reason.DEFAULT; + } } else if (!expectedType.isInstance(flag.getVariants().get(flag.getDefaultVariant()))) { throw new TypeMismatchError("flag " + key + "is not of expected type"); } else { @@ -151,7 +169,7 @@ private ProviderEvaluation getEvaluation( return ProviderEvaluation.builder() .value(value) .variant(flag.getDefaultVariant()) - .reason(Reason.STATIC.toString()) + .reason(reason.toString()) .flagMetadata(flag.getFlagMetadata()) .build(); } diff --git a/src/test/java/dev/openfeature/sdk/e2e/EvaluationTest.java b/src/test/java/dev/openfeature/sdk/e2e/GherkinSpecTest.java similarity index 82% rename from src/test/java/dev/openfeature/sdk/e2e/EvaluationTest.java rename to src/test/java/dev/openfeature/sdk/e2e/GherkinSpecTest.java index b7c834312..89c7161be 100644 --- a/src/test/java/dev/openfeature/sdk/e2e/EvaluationTest.java +++ b/src/test/java/dev/openfeature/sdk/e2e/GherkinSpecTest.java @@ -5,6 +5,7 @@ import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME; import org.junit.platform.suite.api.ConfigurationParameter; +import org.junit.platform.suite.api.ExcludeTags; import org.junit.platform.suite.api.IncludeEngines; import org.junit.platform.suite.api.SelectDirectories; import org.junit.platform.suite.api.Suite; @@ -15,4 +16,5 @@ @ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "pretty") @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 {} +@ExcludeTags({"deprecated", "reason-codes-cached", "async", "immutability", "evaluation-options"}) +public class GherkinSpecTest {} diff --git a/src/test/java/dev/openfeature/sdk/e2e/Utils.java b/src/test/java/dev/openfeature/sdk/e2e/Utils.java index 902ee11d0..565968c1c 100644 --- a/src/test/java/dev/openfeature/sdk/e2e/Utils.java +++ b/src/test/java/dev/openfeature/sdk/e2e/Utils.java @@ -1,9 +1,14 @@ package dev.openfeature.sdk.e2e; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import dev.openfeature.sdk.Value; import java.util.Objects; public final class Utils { + public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private Utils() {} public static Object convert(String value, String type) { @@ -22,6 +27,12 @@ public static Object convert(String value, String type) { return Double.parseDouble(value); case "long": return Long.parseLong(value); + case "object": + try { + return Value.objectToValue(OBJECT_MAPPER.readValue(value, Object.class)); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } } throw new RuntimeException("Unknown config type: " + type); } diff --git a/src/test/java/dev/openfeature/sdk/e2e/steps/ContextSteps.java b/src/test/java/dev/openfeature/sdk/e2e/steps/ContextSteps.java index ccb78e72a..ce9bb8b5f 100644 --- a/src/test/java/dev/openfeature/sdk/e2e/steps/ContextSteps.java +++ b/src/test/java/dev/openfeature/sdk/e2e/steps/ContextSteps.java @@ -8,11 +8,14 @@ import dev.openfeature.sdk.Hook; import dev.openfeature.sdk.HookContext; import dev.openfeature.sdk.ImmutableContext; +import dev.openfeature.sdk.ImmutableStructure; +import dev.openfeature.sdk.MutableContext; 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 dev.openfeature.sdk.e2e.Utils; import io.cucumber.datatable.DataTable; import io.cucumber.java.en.And; import io.cucumber.java.en.Given; @@ -101,4 +104,29 @@ public void contextEntriesForEachLevelFromAPILevelDownToTheLevelWithKeyAndValue( } } } + + @Given("a context containing a key {string} with null value") + public void a_context_containing_a_key_with_null_value(String key) { + a_context_containing_a_key_with_type_and_with_value(key, "String", null); + } + + @Given("a context containing a key {string}, with type {string} and with value {string}") + public void a_context_containing_a_key_with_type_and_with_value(String key, String type, String value) { + Map map = state.context.asMap(); + map.put(key, Value.objectToValue(Utils.convert(value, type))); + state.context = new MutableContext(state.context.getTargetingKey(), map); + } + + @Given("a context containing a targeting key with value {string}") + public void a_context_containing_a_targeting_key_with_value(String string) { + state.context.setTargetingKey(string); + } + + @Given("a context containing a nested property with outer key {string} and inner key {string}, with value {string}") + public void a_context_containing_a_nested_property_with_outer_key_and_inner_key_with_value( + String outer, String inner, String value) { + Map innerMap = new HashMap<>(); + innerMap.put(inner, new Value(value)); + state.context.add(outer, new ImmutableStructure(innerMap)); + } } diff --git a/src/test/java/dev/openfeature/sdk/e2e/steps/FlagStepDefinitions.java b/src/test/java/dev/openfeature/sdk/e2e/steps/FlagStepDefinitions.java index 390e067f3..dccdbf9af 100644 --- a/src/test/java/dev/openfeature/sdk/e2e/steps/FlagStepDefinitions.java +++ b/src/test/java/dev/openfeature/sdk/e2e/steps/FlagStepDefinitions.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThat; +import dev.openfeature.sdk.ErrorCode; import dev.openfeature.sdk.FlagEvaluationDetails; import dev.openfeature.sdk.ImmutableMetadata; import dev.openfeature.sdk.Value; @@ -23,7 +24,7 @@ public FlagStepDefinitions(State state) { this.state = state; } - @Given("a {}-flag with key {string} and a default value {string}") + @Given("a {}-flag with key {string} and a fallback value {string}") public void givenAFlag(String type, String name, String defaultValue) { state.flag = new Flag(type, name, Utils.convert(defaultValue, type)); } @@ -60,7 +61,20 @@ public void the_flag_was_evaluated_with_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)); + Object evaluationValue = state.evaluation.getValue(); + if (state.flag.type.equalsIgnoreCase("object")) { + assertThat(((Value) evaluationValue).asStructure().asObjectMap()) + .isEqualTo(((Value) Utils.convert(value, state.flag.type)) + .asStructure() + .asObjectMap()); + } else { + assertThat(evaluationValue).isEqualTo(Utils.convert(value, state.flag.type)); + } + } + + @Then("the flag key should be {string}") + public void the_flag_key_should_be(String key) { + assertThat(state.evaluation.getFlagKey()).isEqualTo(key); } @Then("the reason should be {string}") @@ -73,6 +87,20 @@ public void the_variant_should_be(String variant) { assertThat(state.evaluation.getVariant()).isEqualTo(variant); } + @Then("the error-code should be {string}") + public void the_error_code_should_be(String errorCode) { + if (errorCode.isEmpty()) { + assertThat(state.evaluation.getErrorCode()).isNull(); + } else { + assertThat(state.evaluation.getErrorCode()).isEqualTo(ErrorCode.valueOf(errorCode)); + } + } + + @Then("the error message should contain {string}") + public void the_error_message_should_contain(String messageSubstring) { + assertThat(state.evaluation.getErrorMessage()).contains(messageSubstring); + } + @Then("the resolved metadata value \"{}\" with type \"{}\" should be \"{}\"") public void theResolvedMetadataValueShouldBe(String key, String type, String value) throws NoSuchFieldException, IllegalAccessException { diff --git a/src/test/java/dev/openfeature/sdk/e2e/steps/ProviderSteps.java b/src/test/java/dev/openfeature/sdk/e2e/steps/ProviderSteps.java index 82cdb2e79..d9dde3c2b 100644 --- a/src/test/java/dev/openfeature/sdk/e2e/steps/ProviderSteps.java +++ b/src/test/java/dev/openfeature/sdk/e2e/steps/ProviderSteps.java @@ -1,13 +1,32 @@ package dev.openfeature.sdk.e2e.steps; import static dev.openfeature.sdk.testutils.TestFlagsUtils.buildFlags; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; +import dev.openfeature.sdk.Client; +import dev.openfeature.sdk.ErrorCode; +import dev.openfeature.sdk.EventProvider; +import dev.openfeature.sdk.FeatureProvider; import dev.openfeature.sdk.OpenFeatureAPI; +import dev.openfeature.sdk.ProviderEvaluation; +import dev.openfeature.sdk.ProviderEventDetails; +import dev.openfeature.sdk.ProviderState; +import dev.openfeature.sdk.Reason; +import dev.openfeature.sdk.Value; import dev.openfeature.sdk.e2e.State; +import dev.openfeature.sdk.exceptions.FatalError; import dev.openfeature.sdk.providers.memory.Flag; import dev.openfeature.sdk.providers.memory.InMemoryProvider; import io.cucumber.java.en.Given; +import io.cucumber.java.en.Then; import java.util.Map; +import org.awaitility.Awaitility; public class ProviderSteps { private final State state; @@ -16,11 +35,128 @@ public ProviderSteps(State state) { this.state = state; } - @Given("a stable provider") - public void aStableProvider() { + @Given("a {} provider") + public void a_provider_with_status(String providerType) throws Exception { + // Normalize input to handle both single word and quoted strings + String normalizedType = + providerType.toLowerCase().replaceAll("[\"\\s]+", " ").trim(); + + switch (normalizedType) { + case "not ready": + setupMockProvider(ErrorCode.PROVIDER_NOT_READY, "Provider in not ready state", ProviderState.NOT_READY); + break; + case "stable": + case "ready": + setupStableProvider(); + break; + case "fatal": + setupMockProvider(ErrorCode.PROVIDER_FATAL, "Provider in fatal state", ProviderState.FATAL); + break; + case "error": + setupMockProvider(ErrorCode.GENERAL, "Provider in error state", ProviderState.ERROR); + break; + case "stale": + setupMockProvider(null, null, ProviderState.STALE); + break; + default: + throw new IllegalArgumentException("Unsupported provider type: " + providerType); + } + } + + // =============================== + // Provider Status Assertion Steps + // =============================== + + @Then("the provider status should be {string}") + public void the_provider_status_should_be(String expectedStatus) { + ProviderState actualStatus = state.client.getProviderState(); + ProviderState expected = ProviderState.valueOf(expectedStatus); + assertThat(actualStatus).isEqualTo(expected); + } + + // =============================== + // Helper Methods + // =============================== + + private void setupStableProvider() throws Exception { Map> flags = buildFlags(); InMemoryProvider provider = new InMemoryProvider(flags); OpenFeatureAPI.getInstance().setProviderAndWait(provider); state.client = OpenFeatureAPI.getInstance().getClient(); } + + private void setupMockProvider(ErrorCode errorCode, String errorMessage, ProviderState providerState) + throws Exception { + EventProvider mockProvider = spy(EventProvider.class); + + switch (providerState) { + case NOT_READY: + doAnswer(invocationOnMock -> { + while (true) {} + }) + .when(mockProvider) + .initialize(any()); + break; + case FATAL: + doThrow(new FatalError(errorMessage)).when(mockProvider).initialize(any()); + break; + } + // Configure all evaluation methods with a single helper + configureMockEvaluations(mockProvider, errorCode, errorMessage); + + OpenFeatureAPI.getInstance().setProvider(providerState.name(), mockProvider); + Client client = OpenFeatureAPI.getInstance().getClient(providerState.name()); + state.client = client; + + ProviderEventDetails details = + ProviderEventDetails.builder().errorCode(errorCode).build(); + switch (providerState) { + case FATAL: + case ERROR: + mockProvider.emitProviderReady(details); + mockProvider.emitProviderError(details); + break; + case STALE: + mockProvider.emitProviderReady(details); + mockProvider.emitProviderStale(details); + break; + default: + } + Awaitility.await().until(() -> { + ProviderState providerState1 = client.getProviderState(); + return providerState1 == providerState; + }); + } + + private void configureMockEvaluations(FeatureProvider mockProvider, ErrorCode errorCode, String errorMessage) { + // Configure Boolean evaluation + when(mockProvider.getBooleanEvaluation(anyString(), any(Boolean.class), any())) + .thenAnswer(invocation -> createProviderEvaluation(invocation.getArgument(1), errorCode, errorMessage)); + + // Configure String evaluation + when(mockProvider.getStringEvaluation(anyString(), any(String.class), any())) + .thenAnswer(invocation -> createProviderEvaluation(invocation.getArgument(1), errorCode, errorMessage)); + + // Configure Integer evaluation + when(mockProvider.getIntegerEvaluation(anyString(), any(Integer.class), any())) + .thenAnswer(invocation -> createProviderEvaluation(invocation.getArgument(1), errorCode, errorMessage)); + + // Configure Double evaluation + when(mockProvider.getDoubleEvaluation(anyString(), any(Double.class), any())) + .thenAnswer(invocation -> createProviderEvaluation(invocation.getArgument(1), errorCode, errorMessage)); + + // Configure Object evaluation + when(mockProvider.getObjectEvaluation(anyString(), any(Value.class), any())) + .thenAnswer(invocation -> createProviderEvaluation(invocation.getArgument(1), errorCode, errorMessage)); + } + + private ProviderEvaluation createProviderEvaluation( + T defaultValue, ErrorCode errorCode, String errorMessage) { + return ProviderEvaluation.builder() + .value(defaultValue) + .errorCode(errorCode) + .errorMessage(errorMessage) + .reason(Reason.ERROR.toString()) + .build(); + } } 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 924c9d59e..c31e9eb7e 100644 --- a/src/test/java/dev/openfeature/sdk/e2e/steps/StepDefinitions.java +++ b/src/test/java/dev/openfeature/sdk/e2e/steps/StepDefinitions.java @@ -21,6 +21,7 @@ import java.util.Map; import lombok.SneakyThrows; +@Deprecated public class StepDefinitions { private static Client client; diff --git a/src/test/java/dev/openfeature/sdk/testutils/TestFlagsUtils.java b/src/test/java/dev/openfeature/sdk/testutils/TestFlagsUtils.java index c1767ff6f..7c45166f9 100644 --- a/src/test/java/dev/openfeature/sdk/testutils/TestFlagsUtils.java +++ b/src/test/java/dev/openfeature/sdk/testutils/TestFlagsUtils.java @@ -1,18 +1,28 @@ package dev.openfeature.sdk.testutils; -import static dev.openfeature.sdk.Structure.mapToStructure; +import static dev.openfeature.sdk.e2e.Utils.OBJECT_MAPPER; -import com.google.common.collect.ImmutableMap; +import com.fasterxml.jackson.core.StreamReadFeature; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; import dev.openfeature.sdk.ImmutableMetadata; -import dev.openfeature.sdk.Value; +import dev.openfeature.sdk.providers.memory.ContextEvaluator; import dev.openfeature.sdk.providers.memory.Flag; -import java.util.HashMap; +import dev.openfeature.sdk.testutils.jackson.ContextEvaluatorDeserializer; +import dev.openfeature.sdk.testutils.jackson.ImmutableMetadataDeserializer; +import dev.openfeature.sdk.testutils.jackson.InMemoryFlagMixin; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.Collections; import java.util.Map; import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; /** * Test flags utils. */ +@Slf4j @UtilityClass public class TestFlagsUtils { @@ -25,87 +35,37 @@ public class TestFlagsUtils { public static final String WRONG_FLAG_KEY = "wrong-flag"; public static final String METADATA_FLAG_KEY = "metadata-flag"; + private static Map> flags; /** * Building flags for testing purposes. * * @return map of flags */ - public static Map> buildFlags() { - Map> flags = new HashMap<>(); - flags.put( - BOOLEAN_FLAG_KEY, - Flag.builder() - .variant("on", true) - .variant("off", false) - .defaultVariant("on") - .build()); - flags.put( - STRING_FLAG_KEY, - Flag.builder() - .variant("greeting", "hi") - .variant("parting", "bye") - .defaultVariant("greeting") - .build()); - flags.put( - INT_FLAG_KEY, - Flag.builder() - .variant("one", 1) - .variant("ten", 10) - .defaultVariant("ten") - .build()); - flags.put( - FLOAT_FLAG_KEY, - Flag.builder() - .variant("tenth", 0.1) - .variant("half", 0.5) - .defaultVariant("half") - .build()); - flags.put( - OBJECT_FLAG_KEY, - Flag.builder() - .variant("empty", new HashMap<>()) - .variant( - "template", - new Value(mapToStructure(ImmutableMap.of( - "showImages", new Value(true), - "title", new Value("Check out these pics!"), - "imagesPerPage", new Value(100))))) - .defaultVariant("template") - .build()); - flags.put( - CONTEXT_AWARE_FLAG_KEY, - Flag.builder() - .variant("internal", "INTERNAL") - .variant("external", "EXTERNAL") - .defaultVariant("external") - .contextEvaluator((flag, evaluationContext) -> { - if (new Value(false).equals(evaluationContext.getValue("customer"))) { - return (String) flag.getVariants().get("internal"); - } else { - return (String) flag.getVariants().get(flag.getDefaultVariant()); - } - }) - .build()); - flags.put( - WRONG_FLAG_KEY, - Flag.builder() - .variant("one", "uno") - .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()); + public static synchronized Map> buildFlags() { + if (flags == null) { + ObjectMapper objectMapper = OBJECT_MAPPER; + objectMapper.configure(StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION.mappedFeature(), true); + objectMapper.addMixIn(Flag.class, InMemoryFlagMixin.class); + objectMapper.addMixIn(Flag.FlagBuilder.class, InMemoryFlagMixin.FlagBuilderMixin.class); + + SimpleModule module = new SimpleModule(); + module.addDeserializer(ImmutableMetadata.class, new ImmutableMetadataDeserializer()); + module.addDeserializer(ContextEvaluator.class, new ContextEvaluatorDeserializer()); + objectMapper.registerModule(module); + + Map> flagsJson; + try { + flagsJson = objectMapper.readValue( + Paths.get("spec/specification/assets/gherkin/test-flags.json") + .toFile(), + new TypeReference<>() {}); + + } catch (IOException e) { + throw new RuntimeException(e); + } + flags = Collections.unmodifiableMap(flagsJson); + } + return flags; } } diff --git a/src/test/java/dev/openfeature/sdk/testutils/jackson/CelContextEvaluator.java b/src/test/java/dev/openfeature/sdk/testutils/jackson/CelContextEvaluator.java new file mode 100644 index 000000000..6ca3875ef --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/testutils/jackson/CelContextEvaluator.java @@ -0,0 +1,61 @@ +package dev.openfeature.sdk.testutils.jackson; + +import dev.cel.common.types.SimpleType; +import dev.cel.compiler.CelCompiler; +import dev.cel.compiler.CelCompilerFactory; +import dev.cel.runtime.CelRuntime; +import dev.cel.runtime.CelRuntimeFactory; +import dev.openfeature.sdk.EvaluationContext; +import dev.openfeature.sdk.providers.memory.ContextEvaluator; +import dev.openfeature.sdk.providers.memory.Flag; +import java.util.HashMap; +import java.util.Map; + +public class CelContextEvaluator implements ContextEvaluator { + private final CelRuntime.Program program; + + public CelContextEvaluator(String expression) { + try { + CelRuntime celRuntime = + CelRuntimeFactory.standardCelRuntimeBuilder().build(); + CelCompiler celCompiler = CelCompilerFactory.standardCelCompilerBuilder() + .addVar("customer", SimpleType.BOOL) + .addVar("email", SimpleType.STRING) + .addVar("age", SimpleType.INT) + .addVar("dummy", SimpleType.STRING) + .setResultType(SimpleType.STRING) + // Add other variables you expect + .build(); + + var ast = celCompiler.compile(expression).getAst(); + this.program = celRuntime.createProgram(ast); + } catch (Exception e) { + throw new RuntimeException("Failed to compile CEL expression: " + expression, e); + } + } + + @Override + @SuppressWarnings("unchecked") + public T evaluate(Flag flag, EvaluationContext evaluationContext) { + try { + Map objectMap = new HashMap<>(); + // Provide defaults for all declared variables to prevent runtime errors. + objectMap.put("email", ""); + objectMap.put("customer", true); + objectMap.put("age", 0); + objectMap.put("dummy", ""); + + if (evaluationContext != null) { + // Evaluate with context, overriding defaults. + objectMap.putAll(evaluationContext.asObjectMap()); + } + + Object result = program.eval(objectMap); + + String stringResult = (String) result; + return (T) flag.getVariants().get(stringResult); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/test/java/dev/openfeature/sdk/testutils/jackson/ContextEvaluatorDeserializer.java b/src/test/java/dev/openfeature/sdk/testutils/jackson/ContextEvaluatorDeserializer.java new file mode 100644 index 000000000..e348fc8c5 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/testutils/jackson/ContextEvaluatorDeserializer.java @@ -0,0 +1,25 @@ +package dev.openfeature.sdk.testutils.jackson; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import dev.openfeature.sdk.providers.memory.ContextEvaluator; +import java.io.IOException; + +public class ContextEvaluatorDeserializer extends JsonDeserializer> { + @Override + public ContextEvaluator deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + JsonNode node = p.getCodec().readTree(p); + + if (node.isTextual()) { + return new CelContextEvaluator<>(node.asText()); + } + + if (node.isObject() && node.has("expression")) { + return new CelContextEvaluator<>(node.get("expression").asText()); + } + + return null; + } +} diff --git a/src/test/java/dev/openfeature/sdk/testutils/jackson/ImmutableMetadataDeserializer.java b/src/test/java/dev/openfeature/sdk/testutils/jackson/ImmutableMetadataDeserializer.java new file mode 100644 index 000000000..09f7c6f24 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/testutils/jackson/ImmutableMetadataDeserializer.java @@ -0,0 +1,41 @@ +package dev.openfeature.sdk.testutils.jackson; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import dev.openfeature.sdk.ImmutableMetadata; +import java.io.IOException; +import java.util.Map; + +public class ImmutableMetadataDeserializer extends JsonDeserializer { + @Override + public ImmutableMetadata deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + Map properties = p.readValueAs(new TypeReference>() {}); + + ImmutableMetadata.ImmutableMetadataBuilder builder = ImmutableMetadata.builder(); + + if (properties != null) { + for (Map.Entry entry : properties.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + + if (value instanceof String) { + builder.addString(key, (String) value); + } else if (value instanceof Integer) { + builder.addInteger(key, (Integer) value); + } else if (value instanceof Long) { + builder.addLong(key, (Long) value); + } else if (value instanceof Float) { + builder.addFloat(key, (Float) value); + } else if (value instanceof Double) { + builder.addDouble(key, (Double) value); + } else if (value instanceof Boolean) { + builder.addBoolean(key, (Boolean) value); + } + } + } + + return builder.build(); + } +} diff --git a/src/test/java/dev/openfeature/sdk/testutils/jackson/InMemoryFlagMixin.java b/src/test/java/dev/openfeature/sdk/testutils/jackson/InMemoryFlagMixin.java new file mode 100644 index 000000000..dd0154cdd --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/testutils/jackson/InMemoryFlagMixin.java @@ -0,0 +1,20 @@ +package dev.openfeature.sdk.testutils.jackson; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import dev.openfeature.sdk.providers.memory.Flag; +import java.util.Map; + +@JsonDeserialize(builder = Flag.FlagBuilder.class) +@SuppressWarnings("rawtypes") +public abstract class InMemoryFlagMixin { + + @JsonPOJOBuilder(withPrefix = "") + public abstract class FlagBuilderMixin { + + @JsonProperty("variants") + @JsonDeserialize(using = VariantsMapDeserializer.class) + public abstract Flag.FlagBuilder variants(Map variants); + } +} diff --git a/src/test/java/dev/openfeature/sdk/testutils/jackson/VariantsMapDeserializer.java b/src/test/java/dev/openfeature/sdk/testutils/jackson/VariantsMapDeserializer.java new file mode 100644 index 000000000..f7a621cbb --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/testutils/jackson/VariantsMapDeserializer.java @@ -0,0 +1,65 @@ +package dev.openfeature.sdk.testutils.jackson; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import dev.openfeature.sdk.Value; +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class VariantsMapDeserializer extends JsonDeserializer> { + + @Override + public Map deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + JsonNode node = p.getCodec().readTree(p); + Map variants = new HashMap<>(); + + Iterator> fields = node.fields(); + while (fields.hasNext()) { + Map.Entry field = fields.next(); + String variantKey = field.getKey(); + JsonNode variantNode = field.getValue(); + + // Convert the variant value to OpenFeature Value + Object variantValue = convertToValue(p, variantNode); + variants.put(variantKey, variantValue); + } + + return variants; + } + + private Object convertToValue(JsonParser p, JsonNode node) throws JsonProcessingException { + // If the node has a "value" property, use that + if (node.isObject() && node.has("value")) { + return convertJsonNodeToValue(p, node.get("value")); + } + + // Otherwise, treat the entire node as the value + return convertJsonNodeToValue(p, node); + } + + private Object convertJsonNodeToValue(JsonParser p, JsonNode node) throws JsonProcessingException { + if (node.isNull()) { + return null; + } else if (node.isBoolean()) { + return node.asBoolean(); + } else if (node.isInt()) { + return node.asInt(); + } else if (node.isDouble()) { + return node.asDouble(); + } else if (node.isTextual()) { + return node.asText(); + } else if (node.isArray()) { + return Value.objectToValue(p.getCodec().treeToValue(node, List.class)); + } else if (node.isObject()) { + return Value.objectToValue(p.getCodec().treeToValue(node, Object.class)); + } + + throw new IllegalArgumentException("Unsupported JSON node type: " + node.getNodeType()); + } +} From b69339067a75a524911dded9798a06e58d628bce Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 16:30:28 +0200 Subject: [PATCH 390/745] fix(deps): update dependency com.fasterxml.jackson:jackson-bom to v2.20.0 (#1604) 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 932dd584f..516a241f0 100644 --- a/pom.xml +++ b/pom.xml @@ -219,7 +219,7 @@ com.fasterxml.jackson jackson-bom - 2.16.1 + 2.20.0 pom import From af189f8fedecfc7fc126730dae48c5437876892c Mon Sep 17 00:00:00 2001 From: chrfwow Date: Tue, 16 Sep 2025 16:45:17 +0200 Subject: [PATCH 391/745] feat: Add vmlens checks (#1567) * Add vmlens Signed-off-by: christian.lutnik * fix test and gitignore Signed-off-by: christian.lutnik * remove vmlens agent binary Signed-off-by: christian.lutnik * remove unused import Signed-off-by: christian.lutnik * remove vmlens from gitignore, add failing test to check if vmlens still works Signed-off-by: christian.lutnik * remove failing test Signed-off-by: christian.lutnik * remove volatile Signed-off-by: christian.lutnik * update vmlens Signed-off-by: christian.lutnik --------- Signed-off-by: christian.lutnik Co-authored-by: Simon Schrottner --- .github/workflows/pullrequest.yml | 2 +- pom.xml | 25 +++++- .../openfeature/sdk/vmlens/VmLensTest.java | 77 +++++++++++++++++++ 3 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 src/test/java/dev/openfeature/sdk/vmlens/VmLensTest.java diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 3149c89dd..742bf1af4 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -21,7 +21,7 @@ jobs: - name: Check out the code uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 - - name: Set up JDK 11 + - name: Set up JDK ${{ matrix.build.java }} uses: actions/setup-java@a7ab372554b6eb1a8eb25e7d9aec1cc9f3ea1a76 with: java-version: ${{ matrix.build.java }} diff --git a/pom.xml b/pom.xml index 516a241f0..67b031257 100644 --- a/pom.xml +++ b/pom.xml @@ -193,6 +193,13 @@ test + + com.vmlens + api + 1.2.13 + test + + @@ -239,7 +246,6 @@ pom import - @@ -331,7 +337,6 @@ - @@ -343,6 +348,22 @@ + + com.vmlens + vmlens-maven-plugin + 1.2.13 + + + test + + test + + + true + + + + maven-dependency-plugin 3.8.1 diff --git a/src/test/java/dev/openfeature/sdk/vmlens/VmLensTest.java b/src/test/java/dev/openfeature/sdk/vmlens/VmLensTest.java new file mode 100644 index 000000000..136c35965 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/vmlens/VmLensTest.java @@ -0,0 +1,77 @@ +package dev.openfeature.sdk.vmlens; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.vmlens.api.AllInterleavings; +import com.vmlens.api.Runner; +import dev.openfeature.sdk.ImmutableContext; +import dev.openfeature.sdk.OpenFeatureAPI; +import dev.openfeature.sdk.OpenFeatureAPITestUtil; +import dev.openfeature.sdk.Value; +import dev.openfeature.sdk.providers.memory.Flag; +import dev.openfeature.sdk.providers.memory.InMemoryProvider; +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class VmLensTest { + final OpenFeatureAPI api = OpenFeatureAPITestUtil.createAPI(); + + @BeforeEach + void setUp() { + var flags = new HashMap>(); + flags.put("a", Flag.builder().variant("a", "def").defaultVariant("a").build()); + flags.put("b", Flag.builder().variant("a", "as").defaultVariant("a").build()); + api.setProviderAndWait(new InMemoryProvider(flags)); + } + + @AfterEach + void tearDown() { + api.clearHooks(); + api.shutdown(); + } + + @Test + void concurrentClientCreations() { + try (AllInterleavings allInterleavings = new AllInterleavings("Concurrent creations of the Client")) { + while (allInterleavings.hasNext()) { + Runner.runParallel(api::getClient, api::getClient); + } + } + // keep the linter happy + assertTrue(true); + } + + @Test + void concurrentFlagEvaluations() { + var client = api.getClient(); + try (AllInterleavings allInterleavings = new AllInterleavings("Concurrent evaluations")) { + while (allInterleavings.hasNext()) { + Runner.runParallel( + () -> assertEquals("def", client.getStringValue("a", "a")), + () -> assertEquals("as", client.getStringValue("b", "b"))); + } + } + } + + @Test + void concurrentContextSetting() { + var client = api.getClient(); + var contextA = new ImmutableContext(Map.of("a", new Value("b"))); + var contextB = new ImmutableContext(Map.of("c", new Value("d"))); + try (AllInterleavings allInterleavings = + new AllInterleavings("Concurrently setting the context and evaluating a flag")) { + while (allInterleavings.hasNext()) { + Runner.runParallel( + () -> assertEquals("def", client.getStringValue("a", "a")), + () -> client.setEvaluationContext(contextA), + () -> client.setEvaluationContext(contextB)); + assertThat(client.getEvaluationContext()).isIn(contextA, contextB); + } + } + } +} From a92a367fef71cc9ec26f6b1b6609fb8e6b2543bc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 18:07:43 +0200 Subject: [PATCH 392/745] chore(deps): update dependency com.vmlens:vmlens-maven-plugin to v1.2.14 (#1606) 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 67b031257..4c59a9b96 100644 --- a/pom.xml +++ b/pom.xml @@ -351,7 +351,7 @@ com.vmlens vmlens-maven-plugin - 1.2.13 + 1.2.14 test From e7922212d8cd964a8a24dacc518ff31c77fcfae6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Sep 2025 08:29:52 +0200 Subject: [PATCH 393/745] chore(deps): update dependency dev.cel:cel to v0.11.0 (#1603) 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 4c59a9b96..abbb6f008 100644 --- a/pom.xml +++ b/pom.xml @@ -189,7 +189,7 @@ dev.cel cel - 0.10.1 + 0.11.0 test From 45ff89f530e8c73636618676b9db46c61235df57 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Sep 2025 10:27:28 +0000 Subject: [PATCH 394/745] fix(deps): update dependency com.github.spotbugs:spotbugs to v4.9.6 (#1609) 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 abbb6f008..0754cafbd 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ com.github.spotbugs spotbugs - 4.9.5 + 4.9.6 provided @@ -473,7 +473,7 @@ com.github.spotbugs spotbugs - 4.9.5 + 4.9.6 From a40667e9cb635f9ba31f6975ba72bc5932fca094 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Sep 2025 14:12:03 +0000 Subject: [PATCH 395/745] chore(deps): update actions/setup-java digest to ead9eaa (#1608) 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 2a3633045..a7e2b1bc3 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -23,7 +23,7 @@ jobs: steps: - uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 - name: Set up JDK 17 - uses: actions/setup-java@a7ab372554b6eb1a8eb25e7d9aec1cc9f3ea1a76 + uses: actions/setup-java@ead9eaa3cfe0b0fc2fa749519ae09c3d4f4080b0 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 742bf1af4..819d0eac2 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -22,7 +22,7 @@ jobs: uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 - name: Set up JDK ${{ matrix.build.java }} - uses: actions/setup-java@a7ab372554b6eb1a8eb25e7d9aec1cc9f3ea1a76 + uses: actions/setup-java@ead9eaa3cfe0b0fc2fa749519ae09c3d4f4080b0 with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f130b89d7..c6104f125 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,7 +40,7 @@ jobs: uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 - name: Set up JDK 17 - uses: actions/setup-java@a7ab372554b6eb1a8eb25e7d9aec1cc9f3ea1a76 + uses: actions/setup-java@ead9eaa3cfe0b0fc2fa749519ae09c3d4f4080b0 with: java-version: '17' distribution: 'temurin' From 984560196d4a34fb21c8946d1dc675cf6565e90f Mon Sep 17 00:00:00 2001 From: chrfwow Date: Wed, 17 Sep 2025 17:35:53 +0200 Subject: [PATCH 396/745] fix: revert hook data to resolve bytecode incompatibility (#1613) * revert v2 Signed-off-by: christian.lutnik * remove vmlens to speed up the build Signed-off-by: christian.lutnik --------- Signed-off-by: christian.lutnik --- pom.xml | 4 +- .../java/dev/openfeature/sdk/HookContext.java | 63 +++--- .../openfeature/sdk/HookContextWithData.java | 50 ----- .../sdk/HookContextWithoutData.java | 55 ------ .../java/dev/openfeature/sdk/HookData.java | 81 -------- .../java/dev/openfeature/sdk/HookSupport.java | 105 +++------- .../dev/openfeature/sdk/ImmutableContext.java | 2 - .../openfeature/sdk/OpenFeatureClient.java | 43 ++-- src/main/java/dev/openfeature/sdk/Pair.java | 28 --- .../dev/openfeature/sdk/HookContextTest.java | 44 +---- .../dev/openfeature/sdk/HookDataTest.java | 79 -------- .../dev/openfeature/sdk/HookSupportTest.java | 184 ++---------------- .../sdk/benchmark/AllocationBenchmark.java | 24 --- 13 files changed, 111 insertions(+), 651 deletions(-) delete mode 100644 src/main/java/dev/openfeature/sdk/HookContextWithData.java delete mode 100644 src/main/java/dev/openfeature/sdk/HookContextWithoutData.java delete mode 100644 src/main/java/dev/openfeature/sdk/HookData.java delete mode 100644 src/main/java/dev/openfeature/sdk/Pair.java delete mode 100644 src/test/java/dev/openfeature/sdk/HookDataTest.java diff --git a/pom.xml b/pom.xml index 0754cafbd..07c0e23a7 100644 --- a/pom.xml +++ b/pom.xml @@ -348,7 +348,7 @@ - + maven-dependency-plugin 3.8.1 diff --git a/src/main/java/dev/openfeature/sdk/HookContext.java b/src/main/java/dev/openfeature/sdk/HookContext.java index e88e812a6..e14eeb643 100644 --- a/src/main/java/dev/openfeature/sdk/HookContext.java +++ b/src/main/java/dev/openfeature/sdk/HookContext.java @@ -1,13 +1,32 @@ package dev.openfeature.sdk; -import dev.openfeature.sdk.HookContextWithoutData.HookContextWithoutDataBuilder; +import lombok.Builder; +import lombok.NonNull; +import lombok.Value; +import lombok.With; /** - * A interface to hold immutable context that {@link Hook} instances use. + * A data class to hold immutable context that {@link Hook} instances use. + * + * @param the type for the flag being evaluated */ -public interface HookContext { +@Value +@Builder +@With +public class HookContext { + @NonNull String flagKey; + + @NonNull FlagValueType type; + + @NonNull T defaultValue; + + @NonNull EvaluationContext ctx; + + ClientMetadata clientMetadata; + Metadata providerMetadata; + /** - * Builds a {@link HookContextWithoutData} instances from request data. + * Builds a {@link HookContext} instances from request data. * * @param key feature flag key * @param type flag value type @@ -17,39 +36,21 @@ public interface HookContext { * @param defaultValue Fallback value * @param type that the flag is evaluating against * @return resulting context for hook - * @deprecated this should not be instantiated outside the SDK anymore */ - @Deprecated - static HookContext from( + public static HookContext from( String key, FlagValueType type, ClientMetadata clientMetadata, Metadata providerMetadata, EvaluationContext ctx, T defaultValue) { - return new HookContextWithoutData<>(key, type, defaultValue, ctx, clientMetadata, providerMetadata); - } - - /** - * Returns a builder for our default HookContext object. - */ - static HookContextWithoutDataBuilder builder() { - return HookContextWithoutData.builder(); - } - - String getFlagKey(); - - FlagValueType getType(); - - T getDefaultValue(); - - EvaluationContext getCtx(); - - ClientMetadata getClientMetadata(); - - Metadata getProviderMetadata(); - - default HookData getHookData() { - return null; + return HookContext.builder() + .flagKey(key) + .type(type) + .clientMetadata(clientMetadata) + .providerMetadata(providerMetadata) + .ctx(ctx) + .defaultValue(defaultValue) + .build(); } } diff --git a/src/main/java/dev/openfeature/sdk/HookContextWithData.java b/src/main/java/dev/openfeature/sdk/HookContextWithData.java deleted file mode 100644 index 137477c11..000000000 --- a/src/main/java/dev/openfeature/sdk/HookContextWithData.java +++ /dev/null @@ -1,50 +0,0 @@ -package dev.openfeature.sdk; - -class HookContextWithData implements HookContext { - private final HookContext context; - private final HookData data; - - private HookContextWithData(HookContext context, HookData data) { - this.context = context; - this.data = data; - } - - public static HookContextWithData of(HookContext context, HookData data) { - return new HookContextWithData<>(context, data); - } - - @Override - public String getFlagKey() { - return context.getFlagKey(); - } - - @Override - public FlagValueType getType() { - return context.getType(); - } - - @Override - public T getDefaultValue() { - return context.getDefaultValue(); - } - - @Override - public EvaluationContext getCtx() { - return context.getCtx(); - } - - @Override - public ClientMetadata getClientMetadata() { - return context.getClientMetadata(); - } - - @Override - public Metadata getProviderMetadata() { - return context.getProviderMetadata(); - } - - @Override - public HookData getHookData() { - return data; - } -} diff --git a/src/main/java/dev/openfeature/sdk/HookContextWithoutData.java b/src/main/java/dev/openfeature/sdk/HookContextWithoutData.java deleted file mode 100644 index df1ed6ad1..000000000 --- a/src/main/java/dev/openfeature/sdk/HookContextWithoutData.java +++ /dev/null @@ -1,55 +0,0 @@ -package dev.openfeature.sdk; - -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Data; -import lombok.NonNull; -import lombok.Setter; -import lombok.With; - -/** - * A data class to hold immutable context that {@link Hook} instances use. - * - * @param the type for the flag being evaluated - */ -@Data -@Builder -@With -@Setter(AccessLevel.PRIVATE) -class HookContextWithoutData implements HookContext { - @NonNull String flagKey; - - @NonNull FlagValueType type; - - @NonNull T defaultValue; - - @Setter(AccessLevel.PACKAGE) - @NonNull EvaluationContext ctx; - - ClientMetadata clientMetadata; - Metadata providerMetadata; - - /** - * Builds a {@link HookContextWithoutData} instances from request data. - * - * @param key feature flag key - * @param type flag value type - * @param clientMetadata info on which client is calling - * @param providerMetadata info on the provider - * @param defaultValue Fallback value - * @param type that the flag is evaluating against - * @return resulting context for hook - */ - static HookContextWithoutData from( - String key, FlagValueType type, ClientMetadata clientMetadata, Metadata providerMetadata, T defaultValue) { - return new HookContextWithoutData<>( - key, type, defaultValue, ImmutableContext.EMPTY, clientMetadata, providerMetadata); - } - - /** - * Make the builder visible for javadocs. - * - * @param flag value type - */ - public static class HookContextWithoutDataBuilder {} -} diff --git a/src/main/java/dev/openfeature/sdk/HookData.java b/src/main/java/dev/openfeature/sdk/HookData.java deleted file mode 100644 index c7c644a93..000000000 --- a/src/main/java/dev/openfeature/sdk/HookData.java +++ /dev/null @@ -1,81 +0,0 @@ -package dev.openfeature.sdk; - -import java.util.HashMap; -import java.util.Map; - -/** - * Hook data provides a way for hooks to maintain state across their execution stages. - * Each hook instance gets its own isolated data store that persists only for the duration - * of a single flag evaluation. - */ -public interface HookData { - - /** - * Sets a value for the given key. - * - * @param key the key to store the value under - * @param value the value to store - */ - void set(String key, Object value); - - /** - * Gets the value for the given key. - * - * @param key the key to retrieve the value for - * @return the value, or null if not found - */ - Object get(String key); - - /** - * Gets the value for the given key, cast to the specified type. - * - * @param the type to cast to - * @param key the key to retrieve the value for - * @param type the class to cast to - * @return the value cast to the specified type, or null if not found - * @throws ClassCastException if the value cannot be cast to the specified type - */ - T get(String key, Class type); - - /** - * Default implementation uses a HashMap. - */ - static HookData create() { - return new DefaultHookData(); - } - - /** - * Default implementation of HookData. - */ - class DefaultHookData implements HookData { - private Map data; - - @Override - public void set(String key, Object value) { - if (data == null) { - data = new HashMap<>(); - } - data.put(key, value); - } - - @Override - public Object get(String key) { - if (data == null) { - return null; - } - return data.get(key); - } - - @Override - public T get(String key, Class type) { - Object value = get(key); - if (value == null) { - return null; - } - if (!type.isInstance(value)) { - throw new ClassCastException("Value for key '" + key + "' is not of type " + type.getName()); - } - return type.cast(value); - } - } -} diff --git a/src/main/java/dev/openfeature/sdk/HookSupport.java b/src/main/java/dev/openfeature/sdk/HookSupport.java index e9ebbbe58..73518ee8e 100644 --- a/src/main/java/dev/openfeature/sdk/HookSupport.java +++ b/src/main/java/dev/openfeature/sdk/HookSupport.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.function.BiConsumer; +import java.util.function.Consumer; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -15,81 +15,52 @@ class HookSupport { public EvaluationContext beforeHooks( - FlagValueType flagValueType, - HookContext hookCtx, - List> hookDataPairs, - Map hints) { - return callBeforeHooks(flagValueType, hookCtx, hookDataPairs, hints); + FlagValueType flagValueType, HookContext hookCtx, List hooks, Map hints) { + return callBeforeHooks(flagValueType, hookCtx, hooks, hints); } public void afterHooks( FlagValueType flagValueType, HookContext hookContext, FlagEvaluationDetails details, - List> hookDataPairs, + List hooks, Map hints) { - executeHooksUnchecked( - flagValueType, hookDataPairs, hookContext, (hook, ctx) -> hook.after(ctx, details, hints)); + executeHooksUnchecked(flagValueType, hooks, hook -> hook.after(hookContext, details, hints)); } public void afterAllHooks( FlagValueType flagValueType, HookContext hookCtx, FlagEvaluationDetails details, - List> hookDataPairs, + List hooks, Map hints) { - executeHooks( - flagValueType, - hookDataPairs, - hookCtx, - "finally", - (hook, ctx) -> hook.finallyAfter(ctx, details, hints)); + executeHooks(flagValueType, hooks, "finally", hook -> hook.finallyAfter(hookCtx, details, hints)); } public void errorHooks( FlagValueType flagValueType, HookContext hookCtx, Exception e, - List> hookDataPairs, + List hooks, Map hints) { - executeHooks(flagValueType, hookDataPairs, hookCtx, "error", (hook, ctx) -> hook.error(ctx, e, hints)); - } - - public List> getHookDataPairs(List hooks, FlagValueType flagValueType) { - var pairs = new ArrayList>(); - for (Hook hook : hooks) { - if (hook.supportsFlagValueType(flagValueType)) { - pairs.add(Pair.of(hook, HookData.create())); - } - } - return pairs; + executeHooks(flagValueType, hooks, "error", hook -> hook.error(hookCtx, e, hints)); } private void executeHooks( - FlagValueType flagValueType, - List> hookDataPairs, - HookContext hookContext, - String hookMethod, - BiConsumer, HookContext> hookCode) { - if (hookDataPairs != null) { - for (Pair hookDataPair : hookDataPairs) { - Hook hook = hookDataPair.getLeft(); - HookData hookData = hookDataPair.getRight(); - executeChecked(hook, hookData, hookContext, hookCode, hookMethod); + FlagValueType flagValueType, List hooks, String hookMethod, Consumer> hookCode) { + if (hooks != null) { + for (Hook hook : hooks) { + if (hook.supportsFlagValueType(flagValueType)) { + executeChecked(hook, hookCode, hookMethod); + } } } } // before, error, and finally hooks shouldn't throw - private void executeChecked( - Hook hook, - HookData hookData, - HookContext hookContext, - BiConsumer, HookContext> hookCode, - String hookMethod) { + private void executeChecked(Hook hook, Consumer> hookCode, String hookMethod) { try { - var hookCtxWithData = HookContextWithData.of(hookContext, hookData); - hookCode.accept(hook, hookCtxWithData); + hookCode.accept(hook); } catch (Exception exception) { log.error( "Unhandled exception when running {} hook {} (only 'after' hooks should throw)", @@ -100,41 +71,29 @@ private void executeChecked( } // after hooks can throw in order to do validation - private void executeHooksUnchecked( - FlagValueType flagValueType, - List> hookDataPairs, - HookContext hookContext, - BiConsumer, HookContext> hookCode) { - if (hookDataPairs != null) { - for (Pair hookDataPair : hookDataPairs) { - Hook hook = hookDataPair.getLeft(); - HookData hookData = hookDataPair.getRight(); - var hookCtxWithData = HookContextWithData.of(hookContext, hookData); - hookCode.accept(hook, hookCtxWithData); + private void executeHooksUnchecked(FlagValueType flagValueType, List hooks, Consumer> hookCode) { + if (hooks != null) { + for (Hook hook : hooks) { + if (hook.supportsFlagValueType(flagValueType)) { + hookCode.accept(hook); + } } } } private EvaluationContext callBeforeHooks( - FlagValueType flagValueType, - HookContext hookCtx, - List> hookDataPairs, - Map hints) { + FlagValueType flagValueType, HookContext hookCtx, List hooks, Map hints) { // These traverse backwards from normal. - List> reversedHooks = new ArrayList<>(hookDataPairs); + List reversedHooks = new ArrayList<>(hooks); Collections.reverse(reversedHooks); EvaluationContext context = hookCtx.getCtx(); - - for (Pair hookDataPair : reversedHooks) { - Hook hook = hookDataPair.getLeft(); - HookData hookData = hookDataPair.getRight(); - - // Create a new context with this hook's data - HookContext contextWithHookData = HookContextWithData.of(hookCtx, hookData); - Optional optional = - Optional.ofNullable(hook.before(contextWithHookData, hints)).orElse(Optional.empty()); - if (optional.isPresent()) { - context = context.merge(optional.get()); + for (Hook hook : reversedHooks) { + if (hook.supportsFlagValueType(flagValueType)) { + Optional optional = + Optional.ofNullable(hook.before(hookCtx, hints)).orElse(Optional.empty()); + if (optional.isPresent()) { + context = context.merge(optional.get()); + } } } return context; diff --git a/src/main/java/dev/openfeature/sdk/ImmutableContext.java b/src/main/java/dev/openfeature/sdk/ImmutableContext.java index e4916dfca..8560c369e 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableContext.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableContext.java @@ -20,8 +20,6 @@ @SuppressWarnings("PMD.BeanMembersShouldSerialize") public final class ImmutableContext implements EvaluationContext { - public static final ImmutableContext EMPTY = new ImmutableContext(); - @Delegate(excludes = DelegateExclusions.class) private final ImmutableStructure structure; diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index 10c359e3e..b5522b66a 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -164,27 +164,32 @@ private FlagEvaluationDetails evaluateFlag( var hints = Collections.unmodifiableMap(flagOptions.getHookHints()); FlagEvaluationDetails details = null; - List mergedHooks; - List> hookDataPairs = null; - HookContextWithoutData hookContext = null; + List mergedHooks = null; + HookContext afterHookContext = null; try { - final var stateManager = openfeatureApi.getFeatureProviderStateManager(this.domain); + var stateManager = openfeatureApi.getFeatureProviderStateManager(this.domain); // provider must be accessed once to maintain a consistent reference - final var provider = stateManager.getProvider(); - final var state = stateManager.getState(); - hookContext = - HookContextWithoutData.from(key, type, this.getMetadata(), provider.getMetadata(), defaultValue); - - // we are setting the evaluation context one after the other, so that we have a hook context in each - // possible exception case. - hookContext.setCtx(mergeEvaluationContext(ctx)); + var provider = stateManager.getProvider(); + var state = stateManager.getState(); mergedHooks = ObjectUtils.merge( provider.getProviderHooks(), flagOptions.getHooks(), clientHooks, openfeatureApi.getMutableHooks()); - hookDataPairs = hookSupport.getHookDataPairs(mergedHooks, type); - var mergedCtx = hookSupport.beforeHooks(type, hookContext, hookDataPairs, hints); - hookContext.setCtx(mergedCtx); + + var mergedCtx = hookSupport.beforeHooks( + type, + HookContext.from( + key, + type, + this.getMetadata(), + provider.getMetadata(), + mergeEvaluationContext(ctx), + defaultValue), + mergedHooks, + hints); + + 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)) { @@ -202,9 +207,9 @@ private FlagEvaluationDetails evaluateFlag( var error = ExceptionUtils.instantiateErrorByErrorCode(details.getErrorCode(), details.getErrorMessage()); enrichDetailsWithErrorDefaults(defaultValue, details); - hookSupport.errorHooks(type, hookContext, error, hookDataPairs, hints); + hookSupport.errorHooks(type, afterHookContext, error, mergedHooks, hints); } else { - hookSupport.afterHooks(type, hookContext, details, hookDataPairs, hints); + hookSupport.afterHooks(type, afterHookContext, details, mergedHooks, hints); } } catch (Exception e) { if (details == null) { @@ -217,9 +222,9 @@ private FlagEvaluationDetails evaluateFlag( } details.setErrorMessage(e.getMessage()); enrichDetailsWithErrorDefaults(defaultValue, details); - hookSupport.errorHooks(type, hookContext, e, hookDataPairs, hints); + hookSupport.errorHooks(type, afterHookContext, e, mergedHooks, hints); } finally { - hookSupport.afterAllHooks(type, hookContext, details, hookDataPairs, hints); + hookSupport.afterAllHooks(type, afterHookContext, details, mergedHooks, hints); } return details; diff --git a/src/main/java/dev/openfeature/sdk/Pair.java b/src/main/java/dev/openfeature/sdk/Pair.java deleted file mode 100644 index bc6614093..000000000 --- a/src/main/java/dev/openfeature/sdk/Pair.java +++ /dev/null @@ -1,28 +0,0 @@ -package dev.openfeature.sdk; - -class Pair { - private final K key; - private final V value; - - private Pair(K key, V value) { - this.key = key; - this.value = value; - } - - public K getLeft() { - return key; - } - - public V getRight() { - return value; - } - - @Override - public String toString() { - return "Pair{" + "key=" + key + ", value=" + value + '}'; - } - - public static Pair of(K key, V value) { - return new Pair<>(key, value); - } -} diff --git a/src/test/java/dev/openfeature/sdk/HookContextTest.java b/src/test/java/dev/openfeature/sdk/HookContextTest.java index 123052b7d..2196b8b1f 100644 --- a/src/test/java/dev/openfeature/sdk/HookContextTest.java +++ b/src/test/java/dev/openfeature/sdk/HookContextTest.java @@ -1,6 +1,6 @@ package dev.openfeature.sdk; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; import org.junit.jupiter.api.Test; @@ -29,46 +29,4 @@ void metadata_field_is_type_metadata() { "The before stage MUST run before flag resolution occurs. It accepts a hook context (required) and hook hints (optional) as parameters. It has no return value.") @Test void not_applicable_for_dynamic_context() {} - - @Test - void shouldCreateHookContextWithHookData() { - HookData hookData = HookData.create(); - hookData.set("test", "value"); - - HookContextWithData context = HookContextWithData.of(mock(HookContext.class), hookData); - - assertNotNull(context.getHookData()); - assertEquals("value", context.getHookData().get("test")); - } - - @Test - void shouldCreateHookContextWithoutHookData() { - HookContext context = HookContext.builder() - .flagKey("test-flag") - .type(FlagValueType.STRING) - .defaultValue("default") - .ctx(new ImmutableContext()) - .build(); - - assertNull(context.getHookData()); - } - - @Test - void shouldCreateHookContextWithHookDataUsingWith() { - HookContext originalContext = HookContext.builder() - .flagKey("test-flag") - .type(FlagValueType.STRING) - .defaultValue("default") - .ctx(new ImmutableContext()) - .build(); - - HookData hookData = HookData.create(); - hookData.set("timing", System.currentTimeMillis()); - - HookContext contextWithHookData = HookContextWithData.of(originalContext, hookData); - - assertNull(originalContext.getHookData()); - assertNotNull(contextWithHookData.getHookData()); - assertNotNull(contextWithHookData.getHookData().get("timing")); - } } diff --git a/src/test/java/dev/openfeature/sdk/HookDataTest.java b/src/test/java/dev/openfeature/sdk/HookDataTest.java deleted file mode 100644 index eacbeeb78..000000000 --- a/src/test/java/dev/openfeature/sdk/HookDataTest.java +++ /dev/null @@ -1,79 +0,0 @@ -package dev.openfeature.sdk; - -import static org.junit.jupiter.api.Assertions.*; - -import org.junit.jupiter.api.Test; - -class HookDataTest { - - @Test - void shouldStoreAndRetrieveValues() { - HookData hookData = HookData.create(); - - hookData.set("key1", "value1"); - hookData.set("key2", 42); - hookData.set("key3", true); - - assertEquals("value1", hookData.get("key1")); - assertEquals(42, hookData.get("key2")); - assertEquals(true, hookData.get("key3")); - } - - @Test - void shouldReturnNullForMissingKeys() { - HookData hookData = HookData.create(); - - assertNull(hookData.get("nonexistent")); - } - - @Test - void shouldSupportTypeSafeRetrieval() { - HookData hookData = HookData.create(); - - hookData.set("string", "hello"); - hookData.set("integer", 123); - hookData.set("boolean", false); - - assertEquals("hello", hookData.get("string", String.class)); - assertEquals(Integer.valueOf(123), hookData.get("integer", Integer.class)); - assertEquals(Boolean.FALSE, hookData.get("boolean", Boolean.class)); - } - - @Test - void shouldReturnNullForMissingKeysWithType() { - HookData hookData = HookData.create(); - - assertNull(hookData.get("missing", String.class)); - } - - @Test - void shouldThrowClassCastExceptionForWrongType() { - HookData hookData = HookData.create(); - - hookData.set("string", "not a number"); - - assertThrows(ClassCastException.class, () -> { - hookData.get("string", Integer.class); - }); - } - - @Test - void shouldOverwriteExistingValues() { - HookData hookData = HookData.create(); - - hookData.set("key", "original"); - assertEquals("original", hookData.get("key")); - - hookData.set("key", "updated"); - assertEquals("updated", hookData.get("key")); - } - - @Test - void shouldSupportNullValues() { - HookData hookData = HookData.create(); - - hookData.set("nullKey", null); - assertNull(hookData.get("nullKey")); - assertNull(hookData.get("nullKey", String.class)); - } -} diff --git a/src/test/java/dev/openfeature/sdk/HookSupportTest.java b/src/test/java/dev/openfeature/sdk/HookSupportTest.java index 67ec03d94..02a8ff90c 100644 --- a/src/test/java/dev/openfeature/sdk/HookSupportTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSupportTest.java @@ -9,7 +9,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Optional; import org.junit.jupiter.api.DisplayName; @@ -24,15 +23,8 @@ void shouldMergeEvaluationContextsOnBeforeHooksCorrectly() { Map attributes = new HashMap<>(); attributes.put("baseKey", new Value("baseValue")); EvaluationContext baseContext = new ImmutableContext(attributes); - FlagValueType valueType = FlagValueType.STRING; - HookContext hookContext = HookContextWithoutData.builder() - .flagKey("flagKey") - .type(valueType) - .defaultValue("defaultValue") - .ctx(baseContext) - .clientMetadata(() -> "client") - .providerMetadata(() -> "provider") - .build(); + HookContext hookContext = new HookContext<>( + "flagKey", FlagValueType.STRING, "defaultValue", baseContext, () -> "client", () -> "provider"); Hook hook1 = mockStringHook(); Hook hook2 = mockStringHook(); when(hook1.before(any(), any())).thenReturn(Optional.of(evaluationContextWithValue("bla", "blubber"))); @@ -40,10 +32,7 @@ void shouldMergeEvaluationContextsOnBeforeHooksCorrectly() { HookSupport hookSupport = new HookSupport(); EvaluationContext result = hookSupport.beforeHooks( - valueType, - hookContext, - hookSupport.getHookDataPairs(Arrays.asList(hook1, hook2), valueType), - Collections.emptyMap()); + FlagValueType.STRING, hookContext, Arrays.asList(hook1, hook2), Collections.emptyMap()); assertThat(result.getValue("bla").asString()).isEqualTo("blubber"); assertThat(result.getValue("foo").asString()).isEqualTo("bar"); @@ -56,32 +45,36 @@ void shouldMergeEvaluationContextsOnBeforeHooksCorrectly() { void shouldAlwaysCallGenericHook(FlagValueType flagValueType) { Hook genericHook = mockGenericHook(); HookSupport hookSupport = new HookSupport(); - var hookDataPairs = hookSupport.getHookDataPairs(Collections.singletonList(genericHook), flagValueType); EvaluationContext baseContext = new ImmutableContext(); IllegalStateException expectedException = new IllegalStateException("All fine, just a test"); - HookContext hookContext = HookContext.builder() - .flagKey("flagKey") - .type(flagValueType) - .defaultValue(createDefaultValue(flagValueType)) - .ctx(baseContext) - .clientMetadata(() -> "client") - .providerMetadata(() -> "provider") - .build(); + HookContext hookContext = new HookContext<>( + "flagKey", + flagValueType, + createDefaultValue(flagValueType), + baseContext, + () -> "client", + () -> "provider"); - hookSupport.beforeHooks(flagValueType, hookContext, hookDataPairs, Collections.emptyMap()); + hookSupport.beforeHooks( + flagValueType, hookContext, Collections.singletonList(genericHook), Collections.emptyMap()); hookSupport.afterHooks( flagValueType, hookContext, FlagEvaluationDetails.builder().build(), - hookDataPairs, + Collections.singletonList(genericHook), Collections.emptyMap()); hookSupport.afterAllHooks( flagValueType, hookContext, FlagEvaluationDetails.builder().build(), - hookDataPairs, + Collections.singletonList(genericHook), + Collections.emptyMap()); + hookSupport.errorHooks( + flagValueType, + hookContext, + expectedException, + Collections.singletonList(genericHook), Collections.emptyMap()); - hookSupport.errorHooks(flagValueType, hookContext, expectedException, hookDataPairs, Collections.emptyMap()); verify(genericHook).before(any(), any()); verify(genericHook).after(any(), any(), any()); @@ -89,101 +82,6 @@ void shouldAlwaysCallGenericHook(FlagValueType flagValueType) { verify(genericHook).error(any(), any(), any()); } - @ParameterizedTest - @EnumSource(value = FlagValueType.class) - @DisplayName("should allow hooks to store and retrieve data across stages") - void shouldPassDataAcrossStages(FlagValueType flagValueType) { - HookSupport hookSupport = new HookSupport(); - HookContext hookContext = getObjectHookContext(flagValueType); - - TestHookWithData testHook = new TestHookWithData("test-key", "value"); - var pairs = hookSupport.getHookDataPairs(List.of(testHook), flagValueType); - - callAllHooks(flagValueType, hookSupport, hookContext, testHook); - - assertHookData(testHook, "value"); - } - - @ParameterizedTest - @EnumSource(value = FlagValueType.class) - @DisplayName("should isolate data between different hook instances") - void shouldIsolateDataBetweenHooks(FlagValueType flagValueType) { - HookSupport hookSupport = new HookSupport(); - HookContext hookContext = getObjectHookContext(flagValueType); - - TestHookWithData testHook1 = new TestHookWithData("test-key", "value-1"); - TestHookWithData testHook2 = new TestHookWithData("test-key", "value-2"); - var pairs = hookSupport.getHookDataPairs(List.of(testHook1, testHook2), flagValueType); - - callAllHooks(flagValueType, hookSupport, hookContext, pairs); - - assertHookData(testHook1, "value-1"); - assertHookData(testHook2, "value-2"); - } - - @ParameterizedTest - @EnumSource(value = FlagValueType.class) - @DisplayName("should isolate data between the same hook instances") - void shouldIsolateDataBetweenSameHooks(FlagValueType flagValueType) { - - HookSupport hookSupport = new HookSupport(); - HookContext hookContext = getObjectHookContext(flagValueType); - - TestHookWithData testHook = new TestHookWithData("test-key", "value-1"); - - // run hooks first time - callAllHooks(flagValueType, hookSupport, hookContext, testHook); - assertHookData(testHook, "value-1"); - - // re-run with different value, will throw if HookData contains already data - testHook.value = "value-2"; - callAllHooks(flagValueType, hookSupport, hookContext, testHook); - - assertHookData(testHook, "value-2"); - } - - private HookContext getObjectHookContext(FlagValueType flagValueType) { - EvaluationContext baseContext = new ImmutableContext(); - HookContext hookContext = HookContext.builder() - .flagKey("flagKey") - .type(flagValueType) - .defaultValue(createDefaultValue(flagValueType)) - .ctx(baseContext) - .clientMetadata(() -> "client") - .providerMetadata(() -> "provider") - .build(); - return hookContext; - } - - private static void assertHookData(TestHookWithData testHook1, String expected) { - assertThat(testHook1.onBeforeValue).isEqualTo(expected); - assertThat(testHook1.onFinallyAfterValue).isEqualTo(expected); - assertThat(testHook1.onAfterValue).isEqualTo(expected); - assertThat(testHook1.onErrorValue).isEqualTo(expected); - } - - private static void callAllHooks( - FlagValueType flagValueType, - HookSupport hookSupport, - HookContext hookContext, - TestHookWithData testHook) { - var pairs = hookSupport.getHookDataPairs(List.of(testHook), flagValueType); - callAllHooks(flagValueType, hookSupport, hookContext, pairs); - } - - private static void callAllHooks( - FlagValueType flagValueType, - HookSupport hookSupport, - HookContext hookContext, - List> pairs) { - hookSupport.beforeHooks(flagValueType, hookContext, pairs, Collections.emptyMap()); - hookSupport.afterHooks( - flagValueType, hookContext, new FlagEvaluationDetails<>(), pairs, Collections.emptyMap()); - hookSupport.errorHooks(flagValueType, hookContext, new Exception(), pairs, Collections.emptyMap()); - hookSupport.afterAllHooks( - flagValueType, hookContext, new FlagEvaluationDetails<>(), pairs, Collections.emptyMap()); - } - private Object createDefaultValue(FlagValueType flagValueType) { switch (flagValueType) { case INTEGER: @@ -207,46 +105,4 @@ private EvaluationContext evaluationContextWithValue(String key, String value) { EvaluationContext baseContext = new ImmutableContext(attributes); return baseContext; } - - private class TestHookWithData implements Hook { - - private final String key; - Object value; - - Object onBeforeValue; - Object onAfterValue; - Object onErrorValue; - Object onFinallyAfterValue; - - TestHookWithData(String key, Object value) { - this.key = key; - this.value = value; - } - - @Override - public Optional before(HookContext ctx, Map hints) { - var storedValue = ctx.getHookData().get(key); - if (storedValue != null) { - throw new Error("Hook data isolation violated! Data is already set."); - } - ctx.getHookData().set(key, value); - onBeforeValue = ctx.getHookData().get(key); - return Optional.empty(); - } - - @Override - public void after(HookContext ctx, FlagEvaluationDetails details, Map hints) { - onAfterValue = ctx.getHookData().get(key); - } - - @Override - public void error(HookContext ctx, Exception error, Map hints) { - onErrorValue = ctx.getHookData().get(key); - } - - @Override - public void finallyAfter(HookContext ctx, FlagEvaluationDetails details, Map hints) { - onFinallyAfterValue = ctx.getHookData().get(key); - } - } } diff --git a/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java b/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java index 9fe043722..5bc89d03d 100644 --- a/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java +++ b/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java @@ -54,30 +54,6 @@ public Optional before(HookContext ctx, Map() { - @Override - public Optional before(HookContext ctx, Map hints) { - return Optional.ofNullable(new ImmutableContext()); - } - }); - client.addHooks(new Hook() { - @Override - public Optional before(HookContext ctx, Map hints) { - return Optional.ofNullable(new ImmutableContext()); - } - }); - client.addHooks(new Hook() { - @Override - public Optional before(HookContext ctx, Map hints) { - return Optional.ofNullable(new ImmutableContext()); - } - }); - client.addHooks(new Hook() { - @Override - public Optional before(HookContext ctx, Map hints) { - return Optional.ofNullable(new ImmutableContext()); - } - }); Map invocationAttrs = new HashMap<>(); invocationAttrs.put("invoke", new Value(3)); From fa23e960ff9dc52b5c44b56e521485ca03e0e650 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Sep 2025 16:36:59 +0000 Subject: [PATCH 397/745] chore(deps): update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.6.0 (#1612) 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 07c0e23a7..641d2e894 100644 --- a/pom.xml +++ b/pom.xml @@ -457,7 +457,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.9.5.0 + 4.9.6.0 spotbugs-exclusions.xml From fbf2a752647817d3e25d4f8b67893ba5e8f89b7a Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Wed, 17 Sep 2025 12:40:39 -0400 Subject: [PATCH 398/745] chore: fix checkout (#1614) * chore: checkout Signed-off-by: Todd Baert * Update pullrequest.yml Signed-off-by: Todd Baert * Update release.yml Signed-off-by: Todd Baert --------- Signed-off-by: Todd Baert --- .github/workflows/merge.yml | 3 +++ .github/workflows/pullrequest.yml | 3 +++ .github/workflows/release.yml | 3 +++ 3 files changed, 9 insertions(+) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index a7e2b1bc3..bc01938d8 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -22,6 +22,9 @@ jobs: steps: - uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 + with: + fetch-depth: 0 + submodules: recursive - name: Set up JDK 17 uses: actions/setup-java@ead9eaa3cfe0b0fc2fa749519ae09c3d4f4080b0 with: diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 819d0eac2..a1a112d7b 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -20,6 +20,9 @@ jobs: steps: - name: Check out the code uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 + with: + fetch-depth: 0 + submodules: recursive - name: Set up JDK ${{ matrix.build.java }} uses: actions/setup-java@ead9eaa3cfe0b0fc2fa749519ae09c3d4f4080b0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c6104f125..c07ff847e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,6 +38,9 @@ jobs: steps: - name: Checkout Repository uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 + with: + fetch-depth: 0 + submodules: recursive - name: Set up JDK 17 uses: actions/setup-java@ead9eaa3cfe0b0fc2fa749519ae09c3d4f4080b0 From 69c5a1244283d22af0119f534270726a8c520367 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Wed, 17 Sep 2025 12:58:02 -0400 Subject: [PATCH 399/745] chore: relax coverage Signed-off-by: Todd Baert --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 641d2e894..cfc16648b 100644 --- a/pom.xml +++ b/pom.xml @@ -444,7 +444,7 @@ LINE COVEREDRATIO - 0.80 + 0.70 From 9ff13e2f523a948ef954202e47af999e145ff3e0 Mon Sep 17 00:00:00 2001 From: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> Date: Wed, 17 Sep 2025 13:21:53 -0400 Subject: [PATCH 400/745] chore(main): release 1.18.1 (#1602) * chore(main): release 1.19.0 Signed-off-by: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> * Update .release-please-manifest.json Signed-off-by: Todd Baert * Update CHANGELOG.md 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 * Update version.txt Signed-off-by: Todd Baert --------- Signed-off-by: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> Signed-off-by: Todd Baert Co-authored-by: Todd Baert --- .release-please-manifest.json | 2 +- CHANGELOG.md | 20 ++++++++++++++++++++ README.md | 8 ++++---- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index b0c190560..0ddd8a814 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"1.18.0"} +{".":"1.18.1"} diff --git a/CHANGELOG.md b/CHANGELOG.md index dafacd904..a241abad6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## [1.18.1](https://github.com/open-feature/java-sdk/compare/v1.18.0...v1.18.1) (2025-09-17) + + +### 🐛 Bug Fixes + +* **deps:** update dependency com.fasterxml.jackson:jackson-bom to v2.20.0 ([#1604](https://github.com/open-feature/java-sdk/issues/1604)) ([b693390](https://github.com/open-feature/java-sdk/commit/b69339067a75a524911dded9798a06e58d628bce)) +* **deps:** update dependency com.github.spotbugs:spotbugs to v4.9.6 ([#1609](https://github.com/open-feature/java-sdk/issues/1609)) ([45ff89f](https://github.com/open-feature/java-sdk/commit/45ff89f530e8c73636618676b9db46c61235df57)) +* revert hook data to resolve bytecode incompatibility ([#1613](https://github.com/open-feature/java-sdk/issues/1613)) ([9845601](https://github.com/open-feature/java-sdk/commit/984560196d4a34fb21c8946d1dc675cf6565e90f)) + + +### 🧹 Chore + +* **deps:** update actions/setup-java digest to ead9eaa ([#1608](https://github.com/open-feature/java-sdk/issues/1608)) ([a40667e](https://github.com/open-feature/java-sdk/commit/a40667e9cb635f9ba31f6975ba72bc5932fca094)) +* **deps:** update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.6.0 ([#1612](https://github.com/open-feature/java-sdk/issues/1612)) ([fa23e96](https://github.com/open-feature/java-sdk/commit/fa23e960ff9dc52b5c44b56e521485ca03e0e650)) +* **deps:** update dependency com.vmlens:vmlens-maven-plugin to v1.2.14 ([#1606](https://github.com/open-feature/java-sdk/issues/1606)) ([a92a367](https://github.com/open-feature/java-sdk/commit/a92a367fef71cc9ec26f6b1b6609fb8e6b2543bc)) +* **deps:** update dependency dev.cel:cel to v0.11.0 ([#1603](https://github.com/open-feature/java-sdk/issues/1603)) ([e792221](https://github.com/open-feature/java-sdk/commit/e7922212d8cd964a8a24dacc518ff31c77fcfae6)) +* **deps:** update github/codeql-action digest to 573acd9 ([#1600](https://github.com/open-feature/java-sdk/issues/1600)) ([6fb139f](https://github.com/open-feature/java-sdk/commit/6fb139f8425fb76368b1e1baa745aa182f8c13f7)) +* fix checkout ([#1614](https://github.com/open-feature/java-sdk/issues/1614)) ([fbf2a75](https://github.com/open-feature/java-sdk/commit/fbf2a752647817d3e25d4f8b67893ba5e8f89b7a)) +* relax coverage ([69c5a12](https://github.com/open-feature/java-sdk/commit/69c5a1244283d22af0119f534270726a8c520367)) + ## [1.18.0](https://github.com/open-feature/java-sdk/compare/v1.17.0...v1.18.0) (2025-09-16) diff --git a/README.md b/README.md index 39f558f8f..58f586478 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.18.0 + 1.18.1 ``` @@ -84,7 +84,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:1.18.0' + implementation 'dev.openfeature:sdk:1.18.1' } ``` diff --git a/pom.xml b/pom.xml index cfc16648b..ea6e22a11 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ dev.openfeature sdk - 1.18.0 + 1.18.1 [17,) diff --git a/version.txt b/version.txt index 84cc52946..ec6d649be 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.18.0 +1.18.1 From 6dcd21f559477c1b473cd30e459ca7241c4f7210 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Sep 2025 08:29:55 +0200 Subject: [PATCH 401/745] fix(deps): update dependency org.projectlombok:lombok to v1.18.42 (#1616) 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 ea6e22a11..d257c7f09 100644 --- a/pom.xml +++ b/pom.xml @@ -52,7 +52,7 @@ org.projectlombok lombok - 1.18.40 + 1.18.42 provided From 17d0e487f31864facc0e69ee76352cab82b6b6b7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Sep 2025 02:34:18 +0000 Subject: [PATCH 402/745] chore(deps): update github/codeql-action digest to 12dda79 (#1618) 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 a1a112d7b..46e415359 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@573acd9552f33577783abde4acb66a1058e762e5 + uses: github/codeql-action/init@12dda79905a80126f2c9e61d8c032085742e7893 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@573acd9552f33577783abde4acb66a1058e762e5 + uses: github/codeql-action/analyze@12dda79905a80126f2c9e61d8c032085742e7893 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 2ab9903d2..1fe5726c3 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@573acd9552f33577783abde4acb66a1058e762e5 + uses: github/codeql-action/init@12dda79905a80126f2c9e61d8c032085742e7893 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@573acd9552f33577783abde4acb66a1058e762e5 + uses: github/codeql-action/autobuild@12dda79905a80126f2c9e61d8c032085742e7893 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@573acd9552f33577783abde4acb66a1058e762e5 + uses: github/codeql-action/analyze@12dda79905a80126f2c9e61d8c032085742e7893 From d4beca71bb60359b88e739153ff96ffc11aa74ef Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Sep 2025 05:09:52 +0000 Subject: [PATCH 403/745] chore(deps): update dependency org.assertj:assertj-core to v3.27.5 (#1619) 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 d257c7f09..a91de564a 100644 --- a/pom.xml +++ b/pom.xml @@ -88,7 +88,7 @@ org.assertj assertj-core - 3.27.4 + 3.27.5 test From 3ef41f5225b93ca9d4b975c265d4ec41dbd91717 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Sep 2025 07:28:40 +0200 Subject: [PATCH 404/745] chore(deps): update dependency com.google.guava:guava to v33.5.0-jre (#1615) 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 a91de564a..7e23294e8 100644 --- a/pom.xml +++ b/pom.xml @@ -150,7 +150,7 @@ com.google.guava guava - 33.4.8-jre + 33.5.0-jre test From 6cf64d6b0c0ae351a707d70257380f2bce81a82e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 20 Sep 2025 01:51:15 +0000 Subject: [PATCH 405/745] chore(deps): update github/codeql-action digest to 0337c4c (#1621) 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 46e415359..5893ad69b 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@12dda79905a80126f2c9e61d8c032085742e7893 + uses: github/codeql-action/init@0337c4c06e7e00d0d6e64396c13b9dc18dd6d8c5 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@12dda79905a80126f2c9e61d8c032085742e7893 + uses: github/codeql-action/analyze@0337c4c06e7e00d0d6e64396c13b9dc18dd6d8c5 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 1fe5726c3..a821027a2 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@12dda79905a80126f2c9e61d8c032085742e7893 + uses: github/codeql-action/init@0337c4c06e7e00d0d6e64396c13b9dc18dd6d8c5 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@12dda79905a80126f2c9e61d8c032085742e7893 + uses: github/codeql-action/autobuild@0337c4c06e7e00d0d6e64396c13b9dc18dd6d8c5 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@12dda79905a80126f2c9e61d8c032085742e7893 + uses: github/codeql-action/analyze@0337c4c06e7e00d0d6e64396c13b9dc18dd6d8c5 From 857fb9d78c509ee9c1087c355eb0fdb4ffdb668e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 20 Sep 2025 12:37:26 +0000 Subject: [PATCH 406/745] chore(deps): update dependency org.mockito:mockito-core to v5.20.0 (#1622) 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 7e23294e8..faeb6c367 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ UTF-8 11 ${maven.compiler.source} - 5.19.0 + 5.20.0 **/e2e/*.java ${project.groupId}.${project.artifactId} From 99a997dcc594e06662cc3509e9c8698611893567 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 06:01:11 +0000 Subject: [PATCH 407/745] chore(deps): update github/codeql-action digest to e4b85ab (#1626) 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 5893ad69b..2cf73b0e6 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@0337c4c06e7e00d0d6e64396c13b9dc18dd6d8c5 + uses: github/codeql-action/init@e4b85ab654a244f420e4d9a9ca6305cf2d3fdc90 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0337c4c06e7e00d0d6e64396c13b9dc18dd6d8c5 + uses: github/codeql-action/analyze@e4b85ab654a244f420e4d9a9ca6305cf2d3fdc90 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index a821027a2..7c19f6510 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@0337c4c06e7e00d0d6e64396c13b9dc18dd6d8c5 + uses: github/codeql-action/init@e4b85ab654a244f420e4d9a9ca6305cf2d3fdc90 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@0337c4c06e7e00d0d6e64396c13b9dc18dd6d8c5 + uses: github/codeql-action/autobuild@e4b85ab654a244f420e4d9a9ca6305cf2d3fdc90 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0337c4c06e7e00d0d6e64396c13b9dc18dd6d8c5 + uses: github/codeql-action/analyze@e4b85ab654a244f420e4d9a9ca6305cf2d3fdc90 From d0f9647fd09a8602ee47aae7778dbf7534c3fbd5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 08:14:46 +0200 Subject: [PATCH 408/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.29.0 (#1624) 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 faeb6c367..2b4ed32ed 100644 --- a/pom.xml +++ b/pom.xml @@ -234,7 +234,7 @@ io.cucumber cucumber-bom - 7.28.2 + 7.29.0 pom import From c1944d2b1c1a85efb3b4f76a5836dfc0e1c9124b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 06:21:37 +0000 Subject: [PATCH 409/745] chore(deps): update actions/cache digest to 0057852 (#1631) 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 bc01938d8..d39980b71 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -36,7 +36,7 @@ jobs: server-password: ${{ secrets.CENTRAL_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@638ed79f9dc94c1de1baef91bcab5edaa19451f4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 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 2cf73b0e6..66c01ab0d 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -37,7 +37,7 @@ jobs: languages: java - name: Cache local Maven repository - uses: actions/cache@638ed79f9dc94c1de1baef91bcab5edaa19451f4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 with: path: ~/.m2/repository key: ${{ runner.os }}${{ matrix.build.java }}-maven-${{ hashFiles('**/pom.xml') }} From eeda09980cc85a538f0c41fef10bf285b0829761 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 06:28:21 +0000 Subject: [PATCH 410/745] chore(deps): update dependency org.apache.maven.plugins:maven-javadoc-plugin to v3.12.0 (#1623) 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 2b4ed32ed..f34d89d0a 100644 --- a/pom.xml +++ b/pom.xml @@ -580,7 +580,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.11.3 + 3.12.0 true all,-missing From 14f550fd4ff9223437cc36d6cc1b248125a68e3c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 06:35:01 +0000 Subject: [PATCH 411/745] chore(deps): update dependency org.assertj:assertj-core to v3.27.6 (#1627) 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 f34d89d0a..baa6cc863 100644 --- a/pom.xml +++ b/pom.xml @@ -88,7 +88,7 @@ org.assertj assertj-core - 3.27.5 + 3.27.6 test From 0596adac7dde1d9b5bf0da3763799d965870e828 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 10:02:08 +0200 Subject: [PATCH 412/745] chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3 (#1632) 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 baa6cc863..a66bdbf7d 100644 --- a/pom.xml +++ b/pom.xml @@ -517,7 +517,7 @@ com.diffplug.spotless spotless-maven-plugin - 2.46.1 + 3.0.0 From 014e82af10ae478596c65c80d2cf92fc843339ed Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 08:08:26 +0000 Subject: [PATCH 413/745] chore(deps): update dependency org.sonatype.central:central-publishing-maven-plugin to v0.9.0 (#1630) 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 a66bdbf7d..f4e17f484 100644 --- a/pom.xml +++ b/pom.xml @@ -611,7 +611,7 @@ org.sonatype.central central-publishing-maven-plugin - 0.8.0 + 0.9.0 true central From 55c344a8323fa94f4b890d5a119976e879bbb43c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 08:14:37 +0000 Subject: [PATCH 414/745] chore(deps): update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.14.1 (#1625) 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 f4e17f484..72ac3debc 100644 --- a/pom.xml +++ b/pom.xml @@ -291,7 +291,7 @@ maven-compiler-plugin - 3.14.0 + 3.14.1 @@ -743,7 +743,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.14.0 + 3.14.1 default-testCompile From fb3144a0b5e2f02e8af33d746fb6c426724adede Mon Sep 17 00:00:00 2001 From: ThomasKrieger Date: Thu, 25 Sep 2025 10:45:54 +0200 Subject: [PATCH 415/745] fix: improve vmlens handling (#1628) * fix: for #1611 Only execute concurrent tests with VMLens VMLens test run now takes 4s and there is no risk of hanging tests. The hanging tests was during executing ArchUnitTests with VMLens. Renamed VmLensTest to VmLensCT and added a filter in the VMlens plugin. increased timeout for gherkin tests to 30s from 10s Signed-off-by: ThomasKrieger * added await in ProviderSteps and removed Awaitility.await() since it is not needed anymore since we wait during the setting of the states Signed-off-by: ThomasKrieger --------- Signed-off-by: ThomasKrieger --- pom.xml | 9 ++++++--- .../openfeature/sdk/e2e/steps/ProviderSteps.java | 13 ++++--------- .../sdk/vmlens/{VmLensTest.java => VmLensCT.java} | 2 +- 3 files changed, 11 insertions(+), 13 deletions(-) rename src/test/java/dev/openfeature/sdk/vmlens/{VmLensTest.java => VmLensCT.java} (99%) diff --git a/pom.xml b/pom.xml index 72ac3debc..c53541731 100644 --- a/pom.xml +++ b/pom.xml @@ -196,7 +196,7 @@ com.vmlens api - 1.2.13 + 1.2.14 test @@ -348,7 +348,7 @@ - + maven-dependency-plugin 3.8.1 diff --git a/src/test/java/dev/openfeature/sdk/e2e/steps/ProviderSteps.java b/src/test/java/dev/openfeature/sdk/e2e/steps/ProviderSteps.java index d9dde3c2b..f22a0811a 100644 --- a/src/test/java/dev/openfeature/sdk/e2e/steps/ProviderSteps.java +++ b/src/test/java/dev/openfeature/sdk/e2e/steps/ProviderSteps.java @@ -26,7 +26,6 @@ import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import java.util.Map; -import org.awaitility.Awaitility; public class ProviderSteps { private final State state; @@ -113,19 +112,15 @@ private void setupMockProvider(ErrorCode errorCode, String errorMessage, Provide switch (providerState) { case FATAL: case ERROR: - mockProvider.emitProviderReady(details); - mockProvider.emitProviderError(details); + mockProvider.emitProviderReady(details).await(); + mockProvider.emitProviderError(details).await(); break; case STALE: - mockProvider.emitProviderReady(details); - mockProvider.emitProviderStale(details); + mockProvider.emitProviderReady(details).await(); + mockProvider.emitProviderStale(details).await(); break; default: } - Awaitility.await().until(() -> { - ProviderState providerState1 = client.getProviderState(); - return providerState1 == providerState; - }); } private void configureMockEvaluations(FeatureProvider mockProvider, ErrorCode errorCode, String errorMessage) { diff --git a/src/test/java/dev/openfeature/sdk/vmlens/VmLensTest.java b/src/test/java/dev/openfeature/sdk/vmlens/VmLensCT.java similarity index 99% rename from src/test/java/dev/openfeature/sdk/vmlens/VmLensTest.java rename to src/test/java/dev/openfeature/sdk/vmlens/VmLensCT.java index 136c35965..c09e254e6 100644 --- a/src/test/java/dev/openfeature/sdk/vmlens/VmLensTest.java +++ b/src/test/java/dev/openfeature/sdk/vmlens/VmLensCT.java @@ -18,7 +18,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -class VmLensTest { +class VmLensCT { final OpenFeatureAPI api = OpenFeatureAPITestUtil.createAPI(); @BeforeEach From 9bffa0a45aaea6fb5ecf7b489c02cd502fc2d93c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 18:36:14 +0000 Subject: [PATCH 416/745] chore(deps): update dependency com.vmlens:api to v1.2.15 (#1636) 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 c53541731..334e0a36c 100644 --- a/pom.xml +++ b/pom.xml @@ -196,7 +196,7 @@ com.vmlens api - 1.2.14 + 1.2.15 test From 139c9b21b73717e52fde4970561009cbd27addaa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Sep 2025 22:46:38 +0000 Subject: [PATCH 417/745] chore(deps): update dependency com.vmlens:vmlens-maven-plugin to v1.2.15 (#1637) 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 334e0a36c..5d9456a33 100644 --- a/pom.xml +++ b/pom.xml @@ -351,7 +351,7 @@ com.vmlens vmlens-maven-plugin - 1.2.14 + 1.2.15 test From f9796e8e1623bdac0ec52b7102e11759d3e449d8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 26 Sep 2025 02:48:47 +0000 Subject: [PATCH 418/745] chore(deps): update github/codeql-action digest to 94a9b7a (#1635) 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 66c01ab0d..a8f9d79d6 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@e4b85ab654a244f420e4d9a9ca6305cf2d3fdc90 + uses: github/codeql-action/init@94a9b7a1101a1320dcadcbda5e7fd9a1e6abaaca with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e4b85ab654a244f420e4d9a9ca6305cf2d3fdc90 + uses: github/codeql-action/analyze@94a9b7a1101a1320dcadcbda5e7fd9a1e6abaaca diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 7c19f6510..6b1184be9 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@e4b85ab654a244f420e4d9a9ca6305cf2d3fdc90 + uses: github/codeql-action/init@94a9b7a1101a1320dcadcbda5e7fd9a1e6abaaca with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@e4b85ab654a244f420e4d9a9ca6305cf2d3fdc90 + uses: github/codeql-action/autobuild@94a9b7a1101a1320dcadcbda5e7fd9a1e6abaaca - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e4b85ab654a244f420e4d9a9ca6305cf2d3fdc90 + uses: github/codeql-action/analyze@94a9b7a1101a1320dcadcbda5e7fd9a1e6abaaca From 58b6575410b75760d5402f3f927dc8a2e62e9654 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 26 Sep 2025 22:32:45 +0000 Subject: [PATCH 419/745] chore(deps): update github/codeql-action digest to 6a87ebe (#1639) 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 a8f9d79d6..e76566f4c 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@94a9b7a1101a1320dcadcbda5e7fd9a1e6abaaca + uses: github/codeql-action/init@6a87ebe42bbd3423c818b3d15ce9803ba45bd522 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@94a9b7a1101a1320dcadcbda5e7fd9a1e6abaaca + uses: github/codeql-action/analyze@6a87ebe42bbd3423c818b3d15ce9803ba45bd522 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 6b1184be9..ac65ff01f 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@94a9b7a1101a1320dcadcbda5e7fd9a1e6abaaca + uses: github/codeql-action/init@6a87ebe42bbd3423c818b3d15ce9803ba45bd522 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@94a9b7a1101a1320dcadcbda5e7fd9a1e6abaaca + uses: github/codeql-action/autobuild@6a87ebe42bbd3423c818b3d15ce9803ba45bd522 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@94a9b7a1101a1320dcadcbda5e7fd9a1e6abaaca + uses: github/codeql-action/analyze@6a87ebe42bbd3423c818b3d15ce9803ba45bd522 From b686932fa86138e02bddaab0be79d61f39946a02 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 28 Sep 2025 21:50:11 +0000 Subject: [PATCH 420/745] chore(deps): update dependency com.puppycrawl.tools:checkstyle to v11.1.0 (#1640) 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 5d9456a33..ff136ee30 100644 --- a/pom.xml +++ b/pom.xml @@ -504,7 +504,7 @@ com.puppycrawl.tools checkstyle - 11.0.1 + 11.1.0 From 69a87a81e8f4796c5d4a895b9379c0103765ba3d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 01:28:40 +0000 Subject: [PATCH 421/745] chore(deps): update dependency maven-wrapper to v3.3.4 (#1638) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- mvnw | 2 +- mvnw.cmd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mvnw b/mvnw index e9cf8d330..bd8896bf2 100644 --- a/mvnw +++ b/mvnw @@ -19,7 +19,7 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Apache Maven Wrapper startup batch script, version 3.3.3 +# Apache Maven Wrapper startup batch script, version 3.3.4 # # Optional ENV vars # ----------------- diff --git a/mvnw.cmd b/mvnw.cmd index 3fd2be860..5761d9489 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -19,7 +19,7 @@ @REM ---------------------------------------------------------------------------- @REM ---------------------------------------------------------------------------- -@REM Apache Maven Wrapper startup batch script, version 3.3.3 +@REM Apache Maven Wrapper startup batch script, version 3.3.4 @REM @REM Optional ENV vars @REM MVNW_REPOURL - repo url base for downloading maven distribution From f6cb98556be3dacdb4e8d7770014dc2e7df65b6b Mon Sep 17 00:00:00 2001 From: ThomasKrieger Date: Mon, 29 Sep 2025 15:41:27 +0200 Subject: [PATCH 422/745] fix: deployment failure because no tests were run by VMLens (#1634) new VMLens version to fix the deployment failure fix: for #1611 Signed-off-by: ThomasKrieger From 4c18cc4ee502030935796e98272fd45b6c394c11 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 16:55:21 +0200 Subject: [PATCH 423/745] chore(deps): update dependency com.vmlens:api to v1.2.16 (#1642) 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 ff136ee30..61a22d0dc 100644 --- a/pom.xml +++ b/pom.xml @@ -196,7 +196,7 @@ com.vmlens api - 1.2.15 + 1.2.16 test From 2155cc94371a0147fafc3246e7d4e4b9d9b7a5a3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 15:02:20 +0000 Subject: [PATCH 424/745] chore(deps): update github/codeql-action digest to 36adfa7 (#1641) 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 e76566f4c..f014235cb 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@6a87ebe42bbd3423c818b3d15ce9803ba45bd522 + uses: github/codeql-action/init@36adfa7b0f5334b69b6ccdc55e94eefc75cd3279 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6a87ebe42bbd3423c818b3d15ce9803ba45bd522 + uses: github/codeql-action/analyze@36adfa7b0f5334b69b6ccdc55e94eefc75cd3279 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index ac65ff01f..fbb7fbde1 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@6a87ebe42bbd3423c818b3d15ce9803ba45bd522 + uses: github/codeql-action/init@36adfa7b0f5334b69b6ccdc55e94eefc75cd3279 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@6a87ebe42bbd3423c818b3d15ce9803ba45bd522 + uses: github/codeql-action/autobuild@36adfa7b0f5334b69b6ccdc55e94eefc75cd3279 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6a87ebe42bbd3423c818b3d15ce9803ba45bd522 + uses: github/codeql-action/analyze@36adfa7b0f5334b69b6ccdc55e94eefc75cd3279 From 6b922a2a6107cff7f951dcaf9e1c09609aeade83 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 17:35:26 +0000 Subject: [PATCH 425/745] chore(deps): update github/codeql-action digest to 80cb6b5 (#1644) 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 f014235cb..899f3815b 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@36adfa7b0f5334b69b6ccdc55e94eefc75cd3279 + uses: github/codeql-action/init@80cb6b56b93de3e779c7d476d9100d06fb87c877 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@36adfa7b0f5334b69b6ccdc55e94eefc75cd3279 + uses: github/codeql-action/analyze@80cb6b56b93de3e779c7d476d9100d06fb87c877 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index fbb7fbde1..fb4c48f81 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@36adfa7b0f5334b69b6ccdc55e94eefc75cd3279 + uses: github/codeql-action/init@80cb6b56b93de3e779c7d476d9100d06fb87c877 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@36adfa7b0f5334b69b6ccdc55e94eefc75cd3279 + uses: github/codeql-action/autobuild@80cb6b56b93de3e779c7d476d9100d06fb87c877 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@36adfa7b0f5334b69b6ccdc55e94eefc75cd3279 + uses: github/codeql-action/analyze@80cb6b56b93de3e779c7d476d9100d06fb87c877 From 01ce26afc9b8a4bc098dc3406e65c483fd940d15 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 20:38:37 +0000 Subject: [PATCH 426/745] chore(deps): update dependency com.vmlens:vmlens-maven-plugin to v1.2.16 (#1643) 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 61a22d0dc..5edf029c7 100644 --- a/pom.xml +++ b/pom.xml @@ -351,7 +351,7 @@ com.vmlens vmlens-maven-plugin - 1.2.15 + 1.2.16 test From 2da33d60bc51ff9adadc3113d53106162e42f4b7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Sep 2025 14:17:09 +0200 Subject: [PATCH 427/745] fix(deps): update dependency org.junit:junit-bom to v5.14.0 (#1646) 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 5edf029c7..8cf5c7592 100644 --- a/pom.xml +++ b/pom.xml @@ -242,7 +242,7 @@ org.junit junit-bom - 5.13.4 + 5.14.0 pom import From 261ea5dfa6b73d6e538388315719b0f06f417927 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Sep 2025 17:28:34 +0000 Subject: [PATCH 428/745] chore(deps): update dependency org.codehaus.mojo:exec-maven-plugin to v3.6.0 (#1645) 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 8cf5c7592..244373ae6 100644 --- a/pom.xml +++ b/pom.xml @@ -668,7 +668,7 @@ org.codehaus.mojo exec-maven-plugin - 3.5.1 + 3.6.0 update-test-harness-submodule From 8893bf3817053e416d0d8656890441095357411b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 Oct 2025 08:31:08 +0200 Subject: [PATCH 429/745] fix(deps): update dependency org.junit:junit-bom to v6 (#1647) 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 244373ae6..4307474bc 100644 --- a/pom.xml +++ b/pom.xml @@ -242,7 +242,7 @@ org.junit junit-bom - 5.14.0 + 6.0.0 pom import From badac4f6aaf8fb1a71f4a50f906b4c74603f10ae Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 Oct 2025 08:56:02 +0200 Subject: [PATCH 430/745] chore(deps): update amannn/action-semantic-pull-request digest to e49f57c (#1648) 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 7629cb0c7..707faef76 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@e7d011b07ef37e089bea6539210f6a0d360d8af9 + - uses: amannn/action-semantic-pull-request@e49f57ce06c1747542fce2243c7a98682384bc0e env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 07bda4a99127e2c35d1e5323516c59f5beed20f8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 2 Oct 2025 02:09:07 +0000 Subject: [PATCH 431/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.30.0 (#1649) 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 4307474bc..153ac1d09 100644 --- a/pom.xml +++ b/pom.xml @@ -234,7 +234,7 @@ io.cucumber cucumber-bom - 7.29.0 + 7.30.0 pom import From 1de446d38ee2abdc3149f8eff374c617c26462fb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 2 Oct 2025 20:39:52 +0000 Subject: [PATCH 432/745] chore(deps): update github/codeql-action digest to 21a7ba3 (#1650) 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 899f3815b..d6557e11f 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@80cb6b56b93de3e779c7d476d9100d06fb87c877 + uses: github/codeql-action/init@21a7ba37dd3a3acab11343f27c466aae7dfef4c7 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@80cb6b56b93de3e779c7d476d9100d06fb87c877 + uses: github/codeql-action/analyze@21a7ba37dd3a3acab11343f27c466aae7dfef4c7 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index fb4c48f81..8038c2cf9 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@80cb6b56b93de3e779c7d476d9100d06fb87c877 + uses: github/codeql-action/init@21a7ba37dd3a3acab11343f27c466aae7dfef4c7 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@80cb6b56b93de3e779c7d476d9100d06fb87c877 + uses: github/codeql-action/autobuild@21a7ba37dd3a3acab11343f27c466aae7dfef4c7 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@80cb6b56b93de3e779c7d476d9100d06fb87c877 + uses: github/codeql-action/analyze@21a7ba37dd3a3acab11343f27c466aae7dfef4c7 From bb4218456e87391ae4ad96999e6cb49f78eab0aa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 2 Oct 2025 14:22:10 -0700 Subject: [PATCH 433/745] chore(deps): update dependency org.apache.maven.plugins:maven-dependency-plugin to v3.9.0 (#1651) 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 153ac1d09..b1eeb91cb 100644 --- a/pom.xml +++ b/pom.xml @@ -369,7 +369,7 @@ maven-dependency-plugin - 3.8.1 + 3.9.0 verify From fe44e519c9de5dbc00b25aeaa6f1bf31809688f0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Oct 2025 16:41:32 +0000 Subject: [PATCH 434/745] chore(deps): update github/codeql-action digest to 065c6cf (#1652) 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 d6557e11f..ef6d4b2ca 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@21a7ba37dd3a3acab11343f27c466aae7dfef4c7 + uses: github/codeql-action/init@065c6cfb7809de8db2167a953b5b622491cda914 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@21a7ba37dd3a3acab11343f27c466aae7dfef4c7 + uses: github/codeql-action/analyze@065c6cfb7809de8db2167a953b5b622491cda914 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 8038c2cf9..2480aef2b 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@21a7ba37dd3a3acab11343f27c466aae7dfef4c7 + uses: github/codeql-action/init@065c6cfb7809de8db2167a953b5b622491cda914 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@21a7ba37dd3a3acab11343f27c466aae7dfef4c7 + uses: github/codeql-action/autobuild@065c6cfb7809de8db2167a953b5b622491cda914 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@21a7ba37dd3a3acab11343f27c466aae7dfef4c7 + uses: github/codeql-action/analyze@065c6cfb7809de8db2167a953b5b622491cda914 From 71dfb08a096a03fb02e44be4ada796e99b053cf0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 Oct 2025 00:52:46 +0000 Subject: [PATCH 435/745] chore(deps): update dependency org.codehaus.mojo:exec-maven-plugin to v3.6.1 (#1653) 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 b1eeb91cb..5917d41bd 100644 --- a/pom.xml +++ b/pom.xml @@ -668,7 +668,7 @@ org.codehaus.mojo exec-maven-plugin - 3.6.0 + 3.6.1 update-test-harness-submodule From 52c7f9906672320d08ad6e840dbaf4978d5fb6e2 Mon Sep 17 00:00:00 2001 From: alexandraoberaigner <82218944+alexandraoberaigner@users.noreply.github.com> Date: Mon, 6 Oct 2025 08:43:08 +0200 Subject: [PATCH 436/745] feat: add hook data support (#1620) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add hook data support Signed-off-by: Alexandra Oberaigner * feat: gemini suggestions Signed-off-by: Alexandra Oberaigner * feat: hook executor impl (WIP) Signed-off-by: Alexandra Oberaigner * Use shared hook context Signed-off-by: Guido Breitenhuber * Split HookData interface and implementation Signed-off-by: Guido Breitenhuber * Atopted tests Signed-off-by: Guido Breitenhuber * Remove obsolete test Signed-off-by: Guido Breitenhuber * HookSupport improvements: rename back to old name, move code from static factory method to ctor Signed-off-by: Alexandra Oberaigner * PR suggestion: use concrete hooks Signed-off-by: Alexandra Oberaigner * PR suggestions: DefaultHookData access modifier, no star imports Signed-off-by: Alexandra Oberaigner * feat: separate hook support data from logic, PR suggestions Signed-off-by: Alexandra Oberaigner * Update DefaultHookDataTest.java spotless Signed-off-by: Alexandra Oberaigner * fix tests, spotless apply Signed-off-by: Alexandra Oberaigner * exclude lombok generated functions from codecov Signed-off-by: Alexandra Oberaigner * replace init function with setters Signed-off-by: Alexandra Oberaigner * pr suggestion: replace Generated annotation with more descriptive ExcludeFromGeneratedCoverageReport, replace delomboked functions with lombok annotations Signed-off-by: Alexandra Oberaigner * PR suggestion: make HookSupportData a real POJO Signed-off-by: Alexandra Oberaigner * gemini suggestions Signed-off-by: Alexandra Oberaigner * PR suggestion: call hooks as early as possible Signed-off-by: Alexandra Oberaigner * PR suggestions: integration test hook data usage in client, set pair value Signed-off-by: Alexandra Oberaigner * add hook data spec test Signed-off-by: Alexandra Oberaigner --------- Signed-off-by: Alexandra Oberaigner Signed-off-by: Guido Breitenhuber Co-authored-by: Guido Breitenhuber --- .../dev/openfeature/sdk/DefaultHookData.java | 39 ++ .../java/dev/openfeature/sdk/HookContext.java | 338 +++++++++++++++++- .../java/dev/openfeature/sdk/HookData.java | 35 ++ .../java/dev/openfeature/sdk/HookSupport.java | 161 +++++---- .../dev/openfeature/sdk/HookSupportData.java | 18 + .../dev/openfeature/sdk/ImmutableContext.java | 2 + .../java/dev/openfeature/sdk/ObjectHook.java | 15 + .../openfeature/sdk/OpenFeatureClient.java | 62 ++-- src/main/java/dev/openfeature/sdk/Pair.java | 29 ++ .../openfeature/sdk/SharedHookContext.java | 32 ++ .../openfeature/sdk/DefaultHookDataTest.java | 81 +++++ .../dev/openfeature/sdk/HookContextTest.java | 2 +- .../dev/openfeature/sdk/HookSpecTest.java | 25 ++ .../dev/openfeature/sdk/HookSupportTest.java | 138 ++++--- .../sdk/OpenFeatureClientTest.java | 32 ++ .../dev/openfeature/sdk/TestHookWithData.java | 42 +++ .../sdk/benchmark/AllocationBenchmark.java | 34 +- 17 files changed, 926 insertions(+), 159 deletions(-) create mode 100644 src/main/java/dev/openfeature/sdk/DefaultHookData.java create mode 100644 src/main/java/dev/openfeature/sdk/HookData.java create mode 100644 src/main/java/dev/openfeature/sdk/HookSupportData.java create mode 100644 src/main/java/dev/openfeature/sdk/ObjectHook.java create mode 100644 src/main/java/dev/openfeature/sdk/Pair.java create mode 100644 src/main/java/dev/openfeature/sdk/SharedHookContext.java create mode 100644 src/test/java/dev/openfeature/sdk/DefaultHookDataTest.java create mode 100644 src/test/java/dev/openfeature/sdk/TestHookWithData.java diff --git a/src/main/java/dev/openfeature/sdk/DefaultHookData.java b/src/main/java/dev/openfeature/sdk/DefaultHookData.java new file mode 100644 index 000000000..d0efe49d0 --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/DefaultHookData.java @@ -0,0 +1,39 @@ +package dev.openfeature.sdk; + +import java.util.HashMap; +import java.util.Map; + +/** + * Default implementation of HookData. + */ +public class DefaultHookData implements HookData { + private Map data; + + @Override + public void set(String key, Object value) { + if (data == null) { + data = new HashMap<>(); + } + data.put(key, value); + } + + @Override + public Object get(String key) { + if (data == null) { + return null; + } + return data.get(key); + } + + @Override + public T get(String key, Class type) { + Object value = get(key); + if (value == null) { + return null; + } + if (!type.isInstance(value)) { + throw new ClassCastException("Value for key '" + key + "' is not of type " + type.getName()); + } + return type.cast(value); + } +} diff --git a/src/main/java/dev/openfeature/sdk/HookContext.java b/src/main/java/dev/openfeature/sdk/HookContext.java index e14eeb643..8d4d2e13a 100644 --- a/src/main/java/dev/openfeature/sdk/HookContext.java +++ b/src/main/java/dev/openfeature/sdk/HookContext.java @@ -1,32 +1,56 @@ package dev.openfeature.sdk; -import lombok.Builder; +import dev.openfeature.sdk.internal.ExcludeFromGeneratedCoverageReport; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import java.util.Objects; +import lombok.EqualsAndHashCode; import lombok.NonNull; -import lombok.Value; -import lombok.With; +import lombok.ToString; /** * A data class to hold immutable context that {@link Hook} instances use. * * @param the type for the flag being evaluated */ -@Value -@Builder -@With -public class HookContext { - @NonNull String flagKey; +@EqualsAndHashCode +@ToString +public final class HookContext { + private final SharedHookContext sharedContext; + private EvaluationContext ctx; + private final HookData hookData; - @NonNull FlagValueType type; - - @NonNull T defaultValue; - - @NonNull EvaluationContext ctx; + HookContext(@NonNull SharedHookContext sharedContext, EvaluationContext evaluationContext, HookData hookData) { + this.sharedContext = sharedContext; + ctx = evaluationContext; + this.hookData = hookData; + } - ClientMetadata clientMetadata; - Metadata providerMetadata; + /** + * Obsolete constructor. + * This constructor is retained for binary compatibility but is no longer part of the public API. + * + * @param flagKey feature flag key + * @param type flag value type + * @param clientMetadata info on which client is calling + * @param providerMetadata info on the provider + * @param ctx Evaluation Context for the request + * @param defaultValue Fallback value + * @deprecated HookContext is initialized by the SDK and passed to hooks. Users should not create new instances. + */ + @Deprecated + HookContext( + @NonNull String flagKey, + @NonNull FlagValueType type, + @NonNull T defaultValue, + @NonNull EvaluationContext ctx, + ClientMetadata clientMetadata, + Metadata providerMetadata, + HookData hookData) { + this(new SharedHookContext<>(flagKey, type, clientMetadata, providerMetadata, defaultValue), ctx, hookData); + } /** - * Builds a {@link HookContext} instances from request data. + * Builds {@link HookContext} instances from request data. * * @param key feature flag key * @param type flag value type @@ -36,7 +60,9 @@ public class HookContext { * @param defaultValue Fallback value * @param type that the flag is evaluating against * @return resulting context for hook + * @deprecated HookContext is initialized by the SDK and passed to hooks. Users should not create new instances. */ + @Deprecated public static HookContext from( String key, FlagValueType type, @@ -51,6 +77,286 @@ public static HookContext from( .providerMetadata(providerMetadata) .ctx(ctx) .defaultValue(defaultValue) + .hookData(null) .build(); } + + /** + * Creates a new builder for {@link HookContext}. + * + * @param the type for the flag being evaluated + * @return a new builder + * @deprecated HookContext is initialized by the SDK and passed to hooks. Users should not create new instances. + */ + @Deprecated + public static HookContextBuilder builder() { + return new HookContextBuilder(); + } + + public @NonNull String getFlagKey() { + return sharedContext.getFlagKey(); + } + + public @NonNull FlagValueType getType() { + return sharedContext.getType(); + } + + public @NonNull T getDefaultValue() { + return sharedContext.getDefaultValue(); + } + + public @NonNull EvaluationContext getCtx() { + return this.ctx; + } + + public ClientMetadata getClientMetadata() { + return sharedContext.getClientMetadata(); + } + + public Metadata getProviderMetadata() { + return sharedContext.getProviderMetadata(); + } + + @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "Intentional exposure of hookData") + public HookData getHookData() { + return this.hookData; + } + + void setCtx(@NonNull EvaluationContext ctx) { + this.ctx = ctx; + } + + /** + * Returns a new HookContext with the provided flagKey if it is different from the current one. + * + * @param flagKey new flag key + * @return new HookContext with updated flagKey or the same instance if unchanged + * @deprecated HookContext is initialized by the SDK and passed to hooks. Users should not create new instances. + */ + @ExcludeFromGeneratedCoverageReport + @Deprecated + public HookContext withFlagKey(@NonNull String flagKey) { + return Objects.equals(this.getFlagKey(), flagKey) + ? this + : new HookContext( + flagKey, + this.getType(), + this.getDefaultValue(), + this.getCtx(), + this.getClientMetadata(), + this.getProviderMetadata(), + this.hookData); + } + + /** + * Returns a new HookContext with the provided type if it is different from the current one. + * + * @param type new flag value type + * @return new HookContext with updated type or the same instance if unchanged + * @deprecated HookContext is initialized by the SDK and passed to hooks. Users should not create new instances. + */ + @ExcludeFromGeneratedCoverageReport + @Deprecated + public HookContext withType(@NonNull FlagValueType type) { + return this.getType() == type + ? this + : new HookContext( + this.getFlagKey(), + type, + this.getDefaultValue(), + this.getCtx(), + this.getClientMetadata(), + this.getProviderMetadata(), + this.hookData); + } + + /** + * Returns a new HookContext with the provided defaultValue if it is different from the current one. + * + * @param defaultValue new default value + * @return new HookContext with updated defaultValue or the same instance if unchanged + * @deprecated HookContext is initialized by the SDK and passed to hooks. Users should not create new instances. + */ + @ExcludeFromGeneratedCoverageReport + @Deprecated + public HookContext withDefaultValue(@NonNull T defaultValue) { + return this.getDefaultValue() == defaultValue + ? this + : new HookContext( + this.getFlagKey(), + this.getType(), + defaultValue, + this.getCtx(), + this.getClientMetadata(), + this.getProviderMetadata(), + this.hookData); + } + + /** + * Returns a new HookContext with the provided ctx if it is different from the current one. + * + * @param ctx new evaluation context + * @return new HookContext with updated ctx or the same instance if unchanged + * @deprecated HookContext is initialized by the SDK and passed to hooks. Users should not create new instances. + */ + @ExcludeFromGeneratedCoverageReport + @Deprecated + public HookContext withCtx(@NonNull EvaluationContext ctx) { + return this.ctx == ctx + ? this + : new HookContext( + this.getFlagKey(), + this.getType(), + this.getDefaultValue(), + ctx, + this.getClientMetadata(), + this.getProviderMetadata(), + this.hookData); + } + + /** + * Returns a new HookContext with the provided clientMetadata if it is different from the current one. + * + * @param clientMetadata new client metadata + * @return new HookContext with updated clientMetadata or the same instance if unchanged + * @deprecated HookContext is initialized by the SDK and passed to hooks. Users should not create new instances. + */ + @ExcludeFromGeneratedCoverageReport + @Deprecated + public HookContext withClientMetadata(ClientMetadata clientMetadata) { + return this.getClientMetadata() == clientMetadata + ? this + : new HookContext( + this.getFlagKey(), + this.getType(), + this.getDefaultValue(), + this.getCtx(), + clientMetadata, + this.getProviderMetadata(), + this.hookData); + } + + /** + * Returns a new HookContext with the provided providerMetadata if it is different from the current one. + * + * @param providerMetadata new provider metadata + * @return new HookContext with updated providerMetadata or the same instance if unchanged + * @deprecated HookContext is initialized by the SDK and passed to hooks. Users should not create new instances. + */ + @ExcludeFromGeneratedCoverageReport + @Deprecated + public HookContext withProviderMetadata(Metadata providerMetadata) { + return this.getProviderMetadata() == providerMetadata + ? this + : new HookContext( + this.getFlagKey(), + this.getType(), + this.getDefaultValue(), + this.getCtx(), + this.getClientMetadata(), + providerMetadata, + this.hookData); + } + + /** + * Returns a new HookContext with the provided hookData if it is different from the current one. + * + * @param hookData new hook data + * @return new HookContext with updated hookData or the same instance if unchanged + * @deprecated HookContext is initialized by the SDK and passed to hooks. Users should not create new instances. + */ + @ExcludeFromGeneratedCoverageReport + @Deprecated + public HookContext withHookData(HookData hookData) { + return this.hookData == hookData + ? this + : new HookContext( + this.getFlagKey(), + this.getType(), + this.getDefaultValue(), + this.getCtx(), + this.getClientMetadata(), + this.getProviderMetadata(), + hookData); + } + + /** + * Builder for HookContext. + * + * @param The flag type. + * @deprecated HookContext is initialized by the SDK and passed to hooks. Users should not create new instances. + */ + @Deprecated + @ToString + public static class HookContextBuilder { + private String flagKey; + private FlagValueType type; + private T defaultValue; + private EvaluationContext ctx; + private ClientMetadata clientMetadata; + private Metadata providerMetadata; + private HookData hookData; + + HookContextBuilder() {} + + @ExcludeFromGeneratedCoverageReport + public HookContextBuilder flagKey(@NonNull String flagKey) { + this.flagKey = flagKey; + return this; + } + + @ExcludeFromGeneratedCoverageReport + public HookContextBuilder type(@NonNull FlagValueType type) { + this.type = type; + return this; + } + + @ExcludeFromGeneratedCoverageReport + public HookContextBuilder defaultValue(@NonNull T defaultValue) { + this.defaultValue = defaultValue; + return this; + } + + @ExcludeFromGeneratedCoverageReport + public HookContextBuilder ctx(@NonNull EvaluationContext ctx) { + this.ctx = ctx; + return this; + } + + @ExcludeFromGeneratedCoverageReport + public HookContextBuilder clientMetadata(ClientMetadata clientMetadata) { + this.clientMetadata = clientMetadata; + return this; + } + + @ExcludeFromGeneratedCoverageReport + public HookContextBuilder providerMetadata(Metadata providerMetadata) { + this.providerMetadata = providerMetadata; + return this; + } + + @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "Intentional exposure of hookData") + @ExcludeFromGeneratedCoverageReport + public HookContextBuilder hookData(HookData hookData) { + this.hookData = hookData; + return this; + } + + /** + * Builds the HookContext instance. + * + * @return a new HookContext + */ + @ExcludeFromGeneratedCoverageReport + public HookContext build() { + return new HookContext( + this.flagKey, + this.type, + this.defaultValue, + this.ctx, + this.clientMetadata, + this.providerMetadata, + this.hookData); + } + } } diff --git a/src/main/java/dev/openfeature/sdk/HookData.java b/src/main/java/dev/openfeature/sdk/HookData.java new file mode 100644 index 000000000..bd2c5dba9 --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/HookData.java @@ -0,0 +1,35 @@ +package dev.openfeature.sdk; + +/** + * Hook data provides a way for hooks to maintain state across their execution stages. + * Each hook instance gets its own isolated data store that persists only for the duration + * of a single flag evaluation. + */ +public interface HookData { + /** + * Sets a value for the given key. + * + * @param key the key to store the value under + * @param value the value to store + */ + void set(String key, Object value); + + /** + * Gets the value for the given key. + * + * @param key the key to retrieve the value for + * @return the value, or null if not found + */ + Object get(String key); + + /** + * Gets the value for the given key, cast to the specified type. + * + * @param the type to cast to + * @param key the key to retrieve the value for + * @param type the class to cast to + * @return the value cast to the specified type, or null if not found + * @throws ClassCastException if the value cannot be cast to the specified type + */ + T get(String key, Class type); +} diff --git a/src/main/java/dev/openfeature/sdk/HookSupport.java b/src/main/java/dev/openfeature/sdk/HookSupport.java index 73518ee8e..c7a7630da 100644 --- a/src/main/java/dev/openfeature/sdk/HookSupport.java +++ b/src/main/java/dev/openfeature/sdk/HookSupport.java @@ -3,99 +3,124 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.Optional; -import java.util.function.Consumer; -import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +/** + * Helper class to run hooks. Initialize {@link HookSupportData} by calling setHooks, setHookContexts + * & updateEvaluationContext in this exact order. + */ @Slf4j -@RequiredArgsConstructor -@SuppressWarnings({"unchecked", "rawtypes"}) class HookSupport { - public EvaluationContext beforeHooks( - FlagValueType flagValueType, HookContext hookCtx, List hooks, Map hints) { - return callBeforeHooks(flagValueType, hookCtx, hooks, hints); + /** + * Sets the {@link Hook}-{@link HookContext}-{@link Pair} list in the given data object with {@link HookContext} + * set to null. Filters hooks by supported {@link FlagValueType}. + * + * @param hookSupportData the data object to modify + * @param hooks the hooks to set + * @param type the flag value type to filter unsupported hooks + */ + public void setHooks(HookSupportData hookSupportData, List hooks, FlagValueType type) { + List> hookContextPairs = new ArrayList<>(); + for (Hook hook : hooks) { + if (hook.supportsFlagValueType(type)) { + hookContextPairs.add(Pair.of(hook, null)); + } + } + hookSupportData.hooks = hookContextPairs; } - public void afterHooks( - FlagValueType flagValueType, - HookContext hookContext, - FlagEvaluationDetails details, - List hooks, - Map hints) { - executeHooksUnchecked(flagValueType, hooks, hook -> hook.after(hookContext, details, hints)); + /** + * Creates & sets a {@link HookContext} for every {@link Hook}-{@link HookContext}-{@link Pair} + * in the given data object with a new {@link HookData} instance. + * + * @param hookSupportData the data object to modify + * @param sharedContext the shared context from which the new {@link HookContext} is created + */ + public void setHookContexts(HookSupportData hookSupportData, SharedHookContext sharedContext) { + for (int i = 0; i < hookSupportData.hooks.size(); i++) { + Pair hookContextPair = hookSupportData.hooks.get(i); + HookContext curHookContext = sharedContext.hookContextFor(null, new DefaultHookData()); + hookContextPair.setValue(curHookContext); + } } - public void afterAllHooks( - FlagValueType flagValueType, - HookContext hookCtx, - FlagEvaluationDetails details, - List hooks, - Map hints) { - executeHooks(flagValueType, hooks, "finally", hook -> hook.finallyAfter(hookCtx, details, hints)); + /** + * Updates the evaluation context in the given data object's eval context and each hooks eval context. + * + * @param hookSupportData the data object to modify + * @param evaluationContext the new context to set + */ + public void updateEvaluationContext(HookSupportData hookSupportData, EvaluationContext evaluationContext) { + hookSupportData.evaluationContext = evaluationContext; + if (hookSupportData.hooks != null) { + for (Pair hookContextPair : hookSupportData.hooks) { + var curHookContext = hookContextPair.getValue(); + if (curHookContext != null) { + curHookContext.setCtx(evaluationContext); + } + } + } } - public void errorHooks( - FlagValueType flagValueType, - HookContext hookCtx, - Exception e, - List hooks, - Map hints) { - executeHooks(flagValueType, hooks, "error", hook -> hook.error(hookCtx, e, hints)); - } + public void executeBeforeHooks(HookSupportData data) { + // These traverse backwards from normal. + List> reversedHooks = new ArrayList<>(data.getHooks()); + Collections.reverse(reversedHooks); - private void executeHooks( - FlagValueType flagValueType, List hooks, String hookMethod, Consumer> hookCode) { - if (hooks != null) { - for (Hook hook : hooks) { - if (hook.supportsFlagValueType(flagValueType)) { - executeChecked(hook, hookCode, hookMethod); - } + for (Pair hookContextPair : reversedHooks) { + var hook = hookContextPair.getKey(); + var hookContext = hookContextPair.getValue(); + + Optional returnedEvalContext = Optional.ofNullable( + hook.before(hookContext, data.getHints())) + .orElse(Optional.empty()); + if (returnedEvalContext.isPresent()) { + // update shared evaluation context for all hooks + updateEvaluationContext(data, data.getEvaluationContext().merge(returnedEvalContext.get())); } } } - // 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); + public void executeErrorHooks(HookSupportData data, Exception error) { + for (Pair hookContextPair : data.getHooks()) { + var hook = hookContextPair.getKey(); + var hookContext = hookContextPair.getValue(); + try { + hook.error(hookContext, error, data.getHints()); + } catch (Exception e) { + log.error( + "Unhandled exception when running {} hook {} (only 'after' hooks should throw)", + "error", + hook.getClass(), + e); + } } } // after hooks can throw in order to do validation - private void executeHooksUnchecked(FlagValueType flagValueType, List hooks, Consumer> hookCode) { - if (hooks != null) { - for (Hook hook : hooks) { - if (hook.supportsFlagValueType(flagValueType)) { - hookCode.accept(hook); - } - } + public void executeAfterHooks(HookSupportData data, FlagEvaluationDetails details) { + for (Pair hookContextPair : data.getHooks()) { + var hook = hookContextPair.getKey(); + var hookContext = hookContextPair.getValue(); + hook.after(hookContext, details, data.getHints()); } } - private EvaluationContext callBeforeHooks( - FlagValueType flagValueType, HookContext hookCtx, List hooks, Map hints) { - // These traverse backwards from normal. - List reversedHooks = new ArrayList<>(hooks); - Collections.reverse(reversedHooks); - EvaluationContext context = hookCtx.getCtx(); - for (Hook hook : reversedHooks) { - if (hook.supportsFlagValueType(flagValueType)) { - Optional optional = - Optional.ofNullable(hook.before(hookCtx, hints)).orElse(Optional.empty()); - if (optional.isPresent()) { - context = context.merge(optional.get()); - } + public void executeAfterAllHooks(HookSupportData data, FlagEvaluationDetails details) { + for (Pair hookContextPair : data.getHooks()) { + var hook = hookContextPair.getKey(); + var hookContext = hookContextPair.getValue(); + try { + hook.finallyAfter(hookContext, details, data.getHints()); + } catch (Exception e) { + log.error( + "Unhandled exception when running {} hook {} (only 'after' hooks should throw)", + "finally", + hook.getClass(), + e); } } - return context; } } diff --git a/src/main/java/dev/openfeature/sdk/HookSupportData.java b/src/main/java/dev/openfeature/sdk/HookSupportData.java new file mode 100644 index 000000000..2d3346ba1 --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/HookSupportData.java @@ -0,0 +1,18 @@ +package dev.openfeature.sdk; + +import java.util.List; +import java.util.Map; +import lombok.Getter; + +/** + * Encapsulates data for hook execution per flag evaluation. + */ +@Getter +class HookSupportData { + + List> hooks; + EvaluationContext evaluationContext; + Map hints; + + HookSupportData() {} +} diff --git a/src/main/java/dev/openfeature/sdk/ImmutableContext.java b/src/main/java/dev/openfeature/sdk/ImmutableContext.java index 8560c369e..e4916dfca 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableContext.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableContext.java @@ -20,6 +20,8 @@ @SuppressWarnings("PMD.BeanMembersShouldSerialize") public final class ImmutableContext implements EvaluationContext { + public static final ImmutableContext EMPTY = new ImmutableContext(); + @Delegate(excludes = DelegateExclusions.class) private final ImmutableStructure structure; diff --git a/src/main/java/dev/openfeature/sdk/ObjectHook.java b/src/main/java/dev/openfeature/sdk/ObjectHook.java new file mode 100644 index 000000000..ad3af6444 --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/ObjectHook.java @@ -0,0 +1,15 @@ +package dev.openfeature.sdk; + +/** + * 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 ObjectHook extends Hook { + + @Override + default boolean supportsFlagValueType(FlagValueType flagValueType) { + return FlagValueType.OBJECT == flagValueType; + } +} diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index b5522b66a..614bc1e34 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -48,9 +48,10 @@ public class OpenFeatureClient implements Client { private final String version; private final ConcurrentLinkedQueue clientHooks; - private final HookSupport hookSupport; private final AtomicReference evaluationContext = new AtomicReference<>(); + private final HookSupport hookSupport; + /** * Deprecated public constructor. Use OpenFeature.API.getClient() instead. * @@ -67,8 +68,8 @@ public OpenFeatureClient(OpenFeatureAPI openFeatureAPI, String domain, String ve this.openfeatureApi = openFeatureAPI; this.domain = domain; this.version = version; - this.clientHooks = new ConcurrentLinkedQueue<>(); this.hookSupport = new HookSupport(); + this.clientHooks = new ConcurrentLinkedQueue<>(); } /** @@ -159,37 +160,32 @@ public EvaluationContext getEvaluationContext() { + "Instead, we return an evaluation result with the appropriate error code.") private FlagEvaluationDetails evaluateFlag( FlagValueType type, String key, T defaultValue, EvaluationContext ctx, FlagEvaluationOptions options) { + FlagEvaluationDetails details = null; + HookSupportData hookSupportData = new HookSupportData(); + var flagOptions = ObjectUtils.defaultIfNull( options, () -> FlagEvaluationOptions.builder().build()); - var hints = Collections.unmodifiableMap(flagOptions.getHookHints()); - - FlagEvaluationDetails details = null; - List mergedHooks = null; - HookContext afterHookContext = null; + hookSupportData.hints = Collections.unmodifiableMap(flagOptions.getHookHints()); try { - var stateManager = openfeatureApi.getFeatureProviderStateManager(this.domain); + final var stateManager = openfeatureApi.getFeatureProviderStateManager(this.domain); // provider must be accessed once to maintain a consistent reference - var provider = stateManager.getProvider(); - var state = stateManager.getState(); + final var provider = stateManager.getProvider(); + final var state = stateManager.getState(); - mergedHooks = ObjectUtils.merge( + // Hooks are initialized as early as possible to enable the execution of error stages + var mergedHooks = ObjectUtils.merge( provider.getProviderHooks(), flagOptions.getHooks(), clientHooks, openfeatureApi.getMutableHooks()); + hookSupport.setHooks(hookSupportData, mergedHooks, type); + + var sharedHookContext = + new SharedHookContext(key, type, this.getMetadata(), provider.getMetadata(), defaultValue); + hookSupport.setHookContexts(hookSupportData, sharedHookContext); - var mergedCtx = hookSupport.beforeHooks( - type, - HookContext.from( - key, - type, - this.getMetadata(), - provider.getMetadata(), - mergeEvaluationContext(ctx), - defaultValue), - mergedHooks, - hints); - - afterHookContext = - HookContext.from(key, type, this.getMetadata(), provider.getMetadata(), mergedCtx, defaultValue); + var evalContext = mergeEvaluationContext(ctx); + hookSupport.updateEvaluationContext(hookSupportData, evalContext); + + hookSupport.executeBeforeHooks(hookSupportData); // "short circuit" if the provider is in NOT_READY or FATAL state if (ProviderState.NOT_READY.equals(state)) { @@ -199,17 +195,17 @@ private FlagEvaluationDetails evaluateFlag( throw new FatalError("Provider is in an irrecoverable error state"); } - var providerEval = - (ProviderEvaluation) createProviderEvaluation(type, key, defaultValue, provider, mergedCtx); + var providerEval = (ProviderEvaluation) + createProviderEvaluation(type, key, defaultValue, provider, hookSupportData.getEvaluationContext()); details = FlagEvaluationDetails.from(providerEval, key); if (details.getErrorCode() != null) { var error = ExceptionUtils.instantiateErrorByErrorCode(details.getErrorCode(), details.getErrorMessage()); enrichDetailsWithErrorDefaults(defaultValue, details); - hookSupport.errorHooks(type, afterHookContext, error, mergedHooks, hints); + hookSupport.executeErrorHooks(hookSupportData, error); } else { - hookSupport.afterHooks(type, afterHookContext, details, mergedHooks, hints); + hookSupport.executeAfterHooks(hookSupportData, details); } } catch (Exception e) { if (details == null) { @@ -222,9 +218,13 @@ private FlagEvaluationDetails evaluateFlag( } details.setErrorMessage(e.getMessage()); enrichDetailsWithErrorDefaults(defaultValue, details); - hookSupport.errorHooks(type, afterHookContext, e, mergedHooks, hints); + if (hookSupportData.getHooks() != null) { + hookSupport.executeErrorHooks(hookSupportData, e); + } } finally { - hookSupport.afterAllHooks(type, afterHookContext, details, mergedHooks, hints); + if (hookSupportData.getHooks() != null) { + hookSupport.executeAfterAllHooks(hookSupportData, details); + } } return details; diff --git a/src/main/java/dev/openfeature/sdk/Pair.java b/src/main/java/dev/openfeature/sdk/Pair.java new file mode 100644 index 000000000..765be9f2d --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/Pair.java @@ -0,0 +1,29 @@ +package dev.openfeature.sdk; + +import lombok.Setter; +import lombok.ToString; + +@ToString +class Pair { + private final K key; + + @Setter + private V value; + + private Pair(K key, V value) { + this.key = key; + this.value = value; + } + + public K getKey() { + return key; + } + + public V getValue() { + return value; + } + + public static Pair of(K key, V value) { + return new Pair<>(key, value); + } +} diff --git a/src/main/java/dev/openfeature/sdk/SharedHookContext.java b/src/main/java/dev/openfeature/sdk/SharedHookContext.java new file mode 100644 index 000000000..8faab37b2 --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/SharedHookContext.java @@ -0,0 +1,32 @@ +package dev.openfeature.sdk; + +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@Getter +@EqualsAndHashCode +class SharedHookContext { + + private final String flagKey; + private final FlagValueType type; + private final ClientMetadata clientMetadata; + private final Metadata providerMetadata; + private final T defaultValue; + + public SharedHookContext( + String flagKey, + FlagValueType type, + ClientMetadata clientMetadata, + Metadata providerMetadata, + T defaultValue) { + this.flagKey = flagKey; + this.type = type; + this.clientMetadata = clientMetadata; + this.providerMetadata = providerMetadata; + this.defaultValue = defaultValue; + } + + public HookContext hookContextFor(EvaluationContext evaluationContext, HookData hookData) { + return new HookContext<>(this, evaluationContext, hookData); + } +} diff --git a/src/test/java/dev/openfeature/sdk/DefaultHookDataTest.java b/src/test/java/dev/openfeature/sdk/DefaultHookDataTest.java new file mode 100644 index 000000000..ac50988ea --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/DefaultHookDataTest.java @@ -0,0 +1,81 @@ +package dev.openfeature.sdk; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +class DefaultHookDataTest { + + @Test + void shouldStoreAndRetrieveValues() { + var hookData = new DefaultHookData(); + + hookData.set("key1", "value1"); + hookData.set("key2", 42); + hookData.set("key3", true); + + assertEquals("value1", hookData.get("key1")); + assertEquals(42, hookData.get("key2")); + assertEquals(true, hookData.get("key3")); + } + + @Test + void shouldReturnNullForMissingKeys() { + var hookData = new DefaultHookData(); + + assertNull(hookData.get("nonexistent")); + } + + @Test + void shouldSupportTypeSafeRetrieval() { + var hookData = new DefaultHookData(); + + hookData.set("string", "hello"); + hookData.set("integer", 123); + hookData.set("boolean", false); + + assertEquals("hello", hookData.get("string", String.class)); + assertEquals(Integer.valueOf(123), hookData.get("integer", Integer.class)); + assertEquals(Boolean.FALSE, hookData.get("boolean", Boolean.class)); + } + + @Test + void shouldReturnNullForMissingKeysWithType() { + var hookData = new DefaultHookData(); + + assertNull(hookData.get("missing", String.class)); + } + + @Test + void shouldThrowClassCastExceptionForWrongType() { + var hookData = new DefaultHookData(); + + hookData.set("string", "not a number"); + + assertThrows(ClassCastException.class, () -> { + hookData.get("string", Integer.class); + }); + } + + @Test + void shouldOverwriteExistingValues() { + var hookData = new DefaultHookData(); + + hookData.set("key", "original"); + assertEquals("original", hookData.get("key")); + + hookData.set("key", "updated"); + assertEquals("updated", hookData.get("key")); + } + + @Test + void shouldSupportNullValues() { + var hookData = new DefaultHookData(); + + hookData.set("nullKey", null); + assertNull(hookData.get("nullKey")); + assertNull(hookData.get("nullKey", String.class)); + } +} diff --git a/src/test/java/dev/openfeature/sdk/HookContextTest.java b/src/test/java/dev/openfeature/sdk/HookContextTest.java index 2196b8b1f..a37ade9d5 100644 --- a/src/test/java/dev/openfeature/sdk/HookContextTest.java +++ b/src/test/java/dev/openfeature/sdk/HookContextTest.java @@ -1,6 +1,6 @@ package dev.openfeature.sdk; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; import org.junit.jupiter.api.Test; diff --git a/src/test/java/dev/openfeature/sdk/HookSpecTest.java b/src/test/java/dev/openfeature/sdk/HookSpecTest.java index 3a953d18a..56d88dfba 100644 --- a/src/test/java/dev/openfeature/sdk/HookSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSpecTest.java @@ -6,6 +6,7 @@ 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 static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doThrow; @@ -801,4 +802,28 @@ void doesnt_use_finally() { Hook.class.getMethod("finallyAfter", HookContext.class, FlagEvaluationDetails.class, Map.class)) .doesNotThrowAnyException(); } + + @Specification( + number = "4.6.1", + text = "hook data MUST be a structure supporting the definition of arbitrary " + + "properties, with keys of type string, and values of any type.") + @Test + void hook_data_structure() { + // Arrange + HookData hookData = new DefaultHookData(); + + // Act - Add arbitrary properties to hook data + hookData.set("stringKey", "StringValue"); // String value + hookData.set("intKey", 42); // Integer value + hookData.set("doubleKey", 3.14); // Double value + hookData.set("objectKey", new Object()); // Object value + hookData.set("nullKey", null); // Null value + + // Assert - Retrieve and validate the properties + assertEquals("StringValue", hookData.get("stringKey")); + assertEquals(42, hookData.get("intKey")); + assertEquals(3.14, hookData.get("doubleKey")); + assertNotNull(hookData.get("objectKey")); + assertNull(hookData.get("nullKey")); + } } diff --git a/src/test/java/dev/openfeature/sdk/HookSupportTest.java b/src/test/java/dev/openfeature/sdk/HookSupportTest.java index 02a8ff90c..b1bb70ba1 100644 --- a/src/test/java/dev/openfeature/sdk/HookSupportTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSupportTest.java @@ -2,13 +2,14 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import dev.openfeature.sdk.fixtures.HookFixtures; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Optional; import org.junit.jupiter.api.DisplayName; @@ -17,22 +18,30 @@ import org.junit.jupiter.params.provider.EnumSource; class HookSupportTest implements HookFixtures { + + private static final HookSupport hookSupport = new HookSupport(); + @Test @DisplayName("should merge EvaluationContexts on before hooks correctly") void shouldMergeEvaluationContextsOnBeforeHooksCorrectly() { Map attributes = new HashMap<>(); attributes.put("baseKey", new Value("baseValue")); - EvaluationContext baseContext = new ImmutableContext(attributes); - HookContext hookContext = new HookContext<>( - "flagKey", FlagValueType.STRING, "defaultValue", baseContext, () -> "client", () -> "provider"); + EvaluationContext baseEvalContext = new ImmutableContext(attributes); + Hook hook1 = mockStringHook(); Hook hook2 = mockStringHook(); when(hook1.before(any(), any())).thenReturn(Optional.of(evaluationContextWithValue("bla", "blubber"))); when(hook2.before(any(), any())).thenReturn(Optional.of(evaluationContextWithValue("foo", "bar"))); - HookSupport hookSupport = new HookSupport(); - EvaluationContext result = hookSupport.beforeHooks( - FlagValueType.STRING, hookContext, Arrays.asList(hook1, hook2), Collections.emptyMap()); + var sharedContext = getBaseHookContextForType(FlagValueType.STRING); + var hookSupportData = new HookSupportData(); + hookSupport.setHooks(hookSupportData, Arrays.asList(hook1, hook2), FlagValueType.STRING); + hookSupport.setHookContexts(hookSupportData, sharedContext); + hookSupport.updateEvaluationContext(hookSupportData, baseEvalContext); + + hookSupport.executeBeforeHooks(hookSupportData); + + EvaluationContext result = hookSupportData.getEvaluationContext(); assertThat(result.getValue("bla").asString()).isEqualTo("blubber"); assertThat(result.getValue("foo").asString()).isEqualTo("bar"); @@ -44,37 +53,11 @@ void shouldMergeEvaluationContextsOnBeforeHooksCorrectly() { @DisplayName("should always call generic hook") void shouldAlwaysCallGenericHook(FlagValueType flagValueType) { Hook genericHook = mockGenericHook(); - HookSupport hookSupport = new HookSupport(); - EvaluationContext baseContext = new ImmutableContext(); - IllegalStateException expectedException = new IllegalStateException("All fine, just a test"); - HookContext hookContext = new HookContext<>( - "flagKey", - flagValueType, - createDefaultValue(flagValueType), - baseContext, - () -> "client", - () -> "provider"); - - hookSupport.beforeHooks( - flagValueType, hookContext, Collections.singletonList(genericHook), Collections.emptyMap()); - hookSupport.afterHooks( - flagValueType, - hookContext, - FlagEvaluationDetails.builder().build(), - Collections.singletonList(genericHook), - Collections.emptyMap()); - hookSupport.afterAllHooks( - flagValueType, - hookContext, - FlagEvaluationDetails.builder().build(), - Collections.singletonList(genericHook), - Collections.emptyMap()); - hookSupport.errorHooks( - flagValueType, - hookContext, - expectedException, - Collections.singletonList(genericHook), - Collections.emptyMap()); + + var hookSupportData = new HookSupportData(); + hookSupport.setHooks(hookSupportData, List.of(genericHook), flagValueType); + + callAllHooks(hookSupportData); verify(genericHook).before(any(), any()); verify(genericHook).after(any(), any(), any()); @@ -82,6 +65,82 @@ void shouldAlwaysCallGenericHook(FlagValueType flagValueType) { verify(genericHook).error(any(), any(), any()); } + @ParameterizedTest + @EnumSource(value = FlagValueType.class) + @DisplayName("should allow hooks to store and retrieve data across stages") + void shouldPassDataAcrossStages(FlagValueType flagValueType) { + var testHook = new TestHookWithData(); + var hookSupportData = new HookSupportData(); + hookSupport.setHooks(hookSupportData, List.of(testHook), flagValueType); + hookSupport.setHookContexts(hookSupportData, getBaseHookContextForType(flagValueType)); + + hookSupport.executeBeforeHooks(hookSupportData); + assertHookData(testHook, "before"); + + hookSupport.executeAfterHooks( + hookSupportData, FlagEvaluationDetails.builder().build()); + assertHookData(testHook, "before", "after"); + + hookSupport.executeAfterAllHooks( + hookSupportData, FlagEvaluationDetails.builder().build()); + assertHookData(testHook, "before", "after", "finallyAfter"); + + hookSupport.executeErrorHooks(hookSupportData, mock(Exception.class)); + assertHookData(testHook, "before", "after", "finallyAfter", "error"); + } + + @ParameterizedTest + @EnumSource(value = FlagValueType.class) + @DisplayName("should isolate data between different hook instances") + void shouldIsolateDataBetweenHooks(FlagValueType flagValueType) { + var testHook1 = new TestHookWithData(1); + var testHook2 = new TestHookWithData(2); + + var hookSupportData = new HookSupportData(); + hookSupport.setHooks(hookSupportData, List.of(testHook1, testHook2), flagValueType); + hookSupport.setHookContexts(hookSupportData, getBaseHookContextForType(flagValueType)); + + callAllHooks(hookSupportData); + + assertHookData(testHook1, 1, "before", "after", "finallyAfter", "error"); + assertHookData(testHook2, 2, "before", "after", "finallyAfter", "error"); + } + + private static void callAllHooks(HookSupportData hookSupportData) { + hookSupport.executeBeforeHooks(hookSupportData); + hookSupport.executeAfterHooks( + hookSupportData, FlagEvaluationDetails.builder().build()); + hookSupport.executeAfterAllHooks( + hookSupportData, FlagEvaluationDetails.builder().build()); + hookSupport.executeErrorHooks(hookSupportData, mock(Exception.class)); + } + + private static void assertHookData(TestHookWithData testHook, String... expectedKeys) { + for (String expectedKey : expectedKeys) { + assertThat(testHook.hookData.get(expectedKey)) + .withFailMessage("Expected key %s not present in hook data", expectedKey) + .isNotNull(); + } + } + + private static void assertHookData(TestHookWithData testHook, Object expectedValue, String... expectedKeys) { + for (String expectedKey : expectedKeys) { + assertThat(testHook.hookData.get(expectedKey)) + .withFailMessage("Expected key '%s' not present in hook data", expectedKey) + .isNotNull(); + assertThat(testHook.hookData.get(expectedKey)) + .withFailMessage( + "Expected key '%s' not containing expected value. Expected '%s' but found '%s'", + expectedKey, expectedValue, testHook.hookData.get(expectedKey)) + .isEqualTo(expectedValue); + } + } + + private SharedHookContext getBaseHookContextForType(FlagValueType flagValueType) { + return new SharedHookContext<>( + "flagKey", flagValueType, () -> "client", () -> "provider", createDefaultValue(flagValueType)); + } + private Object createDefaultValue(FlagValueType flagValueType) { switch (flagValueType) { case INTEGER: @@ -102,7 +161,6 @@ private Object createDefaultValue(FlagValueType flagValueType) { private EvaluationContext evaluationContextWithValue(String key, String value) { Map attributes = new HashMap<>(); attributes.put(key, new Value(value)); - EvaluationContext baseContext = new ImmutableContext(attributes); - return baseContext; + return new ImmutableContext(attributes); } } diff --git a/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java b/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java index 97a1417a1..88ebfaf9d 100644 --- a/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java +++ b/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java @@ -16,6 +16,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.mockito.Mockito; import org.simplify4u.slf4jmock.LoggerMock; import org.slf4j.Logger; @@ -104,4 +106,34 @@ void shouldNotCallEvaluationMethodsWhenProviderIsInNotReadyState() { assertThat(details.getErrorCode()).isEqualTo(ErrorCode.PROVIDER_NOT_READY); } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + @DisplayName("Should support usage of HookData with/without error") + void shouldSupportUsageOfHookData(boolean isError) { + OpenFeatureAPI api = new OpenFeatureAPI(); + FeatureProvider provider; + if (isError) { + provider = new AlwaysBrokenWithExceptionProvider(); + } else { + provider = new DoSomethingProvider(); + } + api.setProviderAndWait("shouldSupportUsageOfHookData", provider); + + var testHook = new TestHookWithData("test-data"); + api.addHooks(testHook); + + Client client = api.getClient("shouldSupportUsageOfHookData"); + client.getBooleanDetails("key", true); + + assertThat(testHook.hookData.get("before")).isEqualTo("test-data"); + assertThat(testHook.hookData.get("finallyAfter")).isEqualTo("test-data"); + if (isError) { + assertThat(testHook.hookData.get("after")).isEqualTo(null); + assertThat(testHook.hookData.get("error")).isEqualTo("test-data"); + } else { + assertThat(testHook.hookData.get("after")).isEqualTo("test-data"); + assertThat(testHook.hookData.get("error")).isEqualTo(null); + } + } } diff --git a/src/test/java/dev/openfeature/sdk/TestHookWithData.java b/src/test/java/dev/openfeature/sdk/TestHookWithData.java new file mode 100644 index 000000000..dc415fa16 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/TestHookWithData.java @@ -0,0 +1,42 @@ +package dev.openfeature.sdk; + +import java.util.Map; +import java.util.Optional; + +class TestHookWithData implements Hook { + private final Object value; + HookData hookData = null; + + public TestHookWithData(Object value) { + this.value = value; + } + + public TestHookWithData() { + this("test"); + } + + @Override + public Optional before(HookContext ctx, Map hints) { + ctx.getHookData().set("before", value); + hookData = ctx.getHookData(); + return Optional.empty(); + } + + @Override + public void after(HookContext ctx, FlagEvaluationDetails details, Map hints) { + ctx.getHookData().set("after", value); + hookData = ctx.getHookData(); + } + + @Override + public void error(HookContext ctx, Exception error, Map hints) { + ctx.getHookData().set("error", value); + hookData = ctx.getHookData(); + } + + @Override + public void finallyAfter(HookContext ctx, FlagEvaluationDetails details, Map hints) { + ctx.getHookData().set("finallyAfter", value); + hookData = ctx.getHookData(); + } +} diff --git a/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java b/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java index 5bc89d03d..d6a03efd6 100644 --- a/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java +++ b/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java @@ -6,14 +6,18 @@ import static dev.openfeature.sdk.testutils.TestFlagsUtils.OBJECT_FLAG_KEY; import static dev.openfeature.sdk.testutils.TestFlagsUtils.STRING_FLAG_KEY; +import dev.openfeature.sdk.BooleanHook; import dev.openfeature.sdk.Client; +import dev.openfeature.sdk.DoubleHook; import dev.openfeature.sdk.EvaluationContext; -import dev.openfeature.sdk.Hook; import dev.openfeature.sdk.HookContext; import dev.openfeature.sdk.ImmutableContext; import dev.openfeature.sdk.ImmutableStructure; +import dev.openfeature.sdk.IntegerHook; import dev.openfeature.sdk.NoOpProvider; +import dev.openfeature.sdk.ObjectHook; import dev.openfeature.sdk.OpenFeatureAPI; +import dev.openfeature.sdk.StringHook; import dev.openfeature.sdk.Value; import java.util.HashMap; import java.util.Map; @@ -25,7 +29,7 @@ /** * Runs a large volume of flag evaluations on a VM with 1G memory and GC - * completely disabled so we can take a heap-dump. + * completely disabled, so we can take a heap-dump. */ public class AllocationBenchmark { @@ -48,12 +52,36 @@ public void run() { Map clientAttrs = new HashMap<>(); clientAttrs.put("client", new Value(2)); client.setEvaluationContext(new ImmutableContext(clientAttrs)); - client.addHooks(new Hook() { + client.addHooks(new ObjectHook() { @Override public Optional before(HookContext ctx, Map hints) { return Optional.ofNullable(new ImmutableContext()); } }); + client.addHooks(new StringHook() { + @Override + public Optional before(HookContext ctx, Map hints) { + return Optional.ofNullable(new ImmutableContext()); + } + }); + client.addHooks(new BooleanHook() { + @Override + public Optional before(HookContext ctx, Map hints) { + return Optional.ofNullable(new ImmutableContext()); + } + }); + client.addHooks(new IntegerHook() { + @Override + public Optional before(HookContext ctx, Map hints) { + return Optional.ofNullable(new ImmutableContext()); + } + }); + client.addHooks(new DoubleHook() { + @Override + public Optional before(HookContext ctx, Map hints) { + return Optional.ofNullable(new ImmutableContext()); + } + }); Map invocationAttrs = new HashMap<>(); invocationAttrs.put("invoke", new Value(3)); From 461b4154852809af34010da6b2ed7715d0bb7e04 Mon Sep 17 00:00:00 2001 From: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> Date: Mon, 6 Oct 2025 07:08:53 -0400 Subject: [PATCH 437/745] chore(main): release 1.18.2 (#1617) * chore(main): release 1.19.0 Signed-off-by: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> * change pr to release 1.18.2 instead of 1.19.0 Signed-off-by: christian.lutnik --------- Signed-off-by: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> Signed-off-by: christian.lutnik Co-authored-by: christian.lutnik --- .release-please-manifest.json | 2 +- CHANGELOG.md | 51 +++++++++++++++++++++++++++++++++++ README.md | 8 +++--- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 58 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 0ddd8a814..f386789e1 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"1.18.1"} +{".":"1.18.2"} diff --git a/CHANGELOG.md b/CHANGELOG.md index a241abad6..cbb4c6135 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,56 @@ # Changelog +## [1.18.2](https://github.com/open-feature/java-sdk/compare/v1.18.1...v1.18.2) (2025-10-06) + + +### 🐛 Bug Fixes + +* deployment failure because no tests were run by VMLens ([#1634](https://github.com/open-feature/java-sdk/issues/1634)) ([f6cb985](https://github.com/open-feature/java-sdk/commit/f6cb98556be3dacdb4e8d7770014dc2e7df65b6b)) +* **deps:** update dependency io.cucumber:cucumber-bom to v7.29.0 ([#1624](https://github.com/open-feature/java-sdk/issues/1624)) ([d0f9647](https://github.com/open-feature/java-sdk/commit/d0f9647fd09a8602ee47aae7778dbf7534c3fbd5)) +* **deps:** update dependency io.cucumber:cucumber-bom to v7.30.0 ([#1649](https://github.com/open-feature/java-sdk/issues/1649)) ([07bda4a](https://github.com/open-feature/java-sdk/commit/07bda4a99127e2c35d1e5323516c59f5beed20f8)) +* **deps:** update dependency org.junit:junit-bom to v5.14.0 ([#1646](https://github.com/open-feature/java-sdk/issues/1646)) ([2da33d6](https://github.com/open-feature/java-sdk/commit/2da33d60bc51ff9adadc3113d53106162e42f4b7)) +* **deps:** update dependency org.junit:junit-bom to v6 ([#1647](https://github.com/open-feature/java-sdk/issues/1647)) ([8893bf3](https://github.com/open-feature/java-sdk/commit/8893bf3817053e416d0d8656890441095357411b)) +* **deps:** update dependency org.projectlombok:lombok to v1.18.42 ([#1616](https://github.com/open-feature/java-sdk/issues/1616)) ([6dcd21f](https://github.com/open-feature/java-sdk/commit/6dcd21f559477c1b473cd30e459ca7241c4f7210)) +* for [#1611](https://github.com/open-feature/java-sdk/issues/1611) ([f6cb985](https://github.com/open-feature/java-sdk/commit/f6cb98556be3dacdb4e8d7770014dc2e7df65b6b)) +* improve vmlens handling ([#1628](https://github.com/open-feature/java-sdk/issues/1628)) ([fb3144a](https://github.com/open-feature/java-sdk/commit/fb3144a0b5e2f02e8af33d746fb6c426724adede)) + + +### ✨ New Features + +* add hook data support ([#1620](https://github.com/open-feature/java-sdk/issues/1620)) ([52c7f99](https://github.com/open-feature/java-sdk/commit/52c7f9906672320d08ad6e840dbaf4978d5fb6e2)) + + +### 🧹 Chore + +* **deps:** update actions/cache digest to 0057852 ([#1631](https://github.com/open-feature/java-sdk/issues/1631)) ([c1944d2](https://github.com/open-feature/java-sdk/commit/c1944d2b1c1a85efb3b4f76a5836dfc0e1c9124b)) +* **deps:** update amannn/action-semantic-pull-request digest to e49f57c ([#1648](https://github.com/open-feature/java-sdk/issues/1648)) ([badac4f](https://github.com/open-feature/java-sdk/commit/badac4f6aaf8fb1a71f4a50f906b4c74603f10ae)) +* **deps:** update dependency com.diffplug.spotless:spotless-maven-plugin to v3 ([#1632](https://github.com/open-feature/java-sdk/issues/1632)) ([0596ada](https://github.com/open-feature/java-sdk/commit/0596adac7dde1d9b5bf0da3763799d965870e828)) +* **deps:** update dependency com.google.guava:guava to v33.5.0-jre ([#1615](https://github.com/open-feature/java-sdk/issues/1615)) ([3ef41f5](https://github.com/open-feature/java-sdk/commit/3ef41f5225b93ca9d4b975c265d4ec41dbd91717)) +* **deps:** update dependency com.puppycrawl.tools:checkstyle to v11.1.0 ([#1640](https://github.com/open-feature/java-sdk/issues/1640)) ([b686932](https://github.com/open-feature/java-sdk/commit/b686932fa86138e02bddaab0be79d61f39946a02)) +* **deps:** update dependency com.vmlens:api to v1.2.15 ([#1636](https://github.com/open-feature/java-sdk/issues/1636)) ([9bffa0a](https://github.com/open-feature/java-sdk/commit/9bffa0a45aaea6fb5ecf7b489c02cd502fc2d93c)) +* **deps:** update dependency com.vmlens:api to v1.2.16 ([#1642](https://github.com/open-feature/java-sdk/issues/1642)) ([4c18cc4](https://github.com/open-feature/java-sdk/commit/4c18cc4ee502030935796e98272fd45b6c394c11)) +* **deps:** update dependency com.vmlens:vmlens-maven-plugin to v1.2.15 ([#1637](https://github.com/open-feature/java-sdk/issues/1637)) ([139c9b2](https://github.com/open-feature/java-sdk/commit/139c9b21b73717e52fde4970561009cbd27addaa)) +* **deps:** update dependency com.vmlens:vmlens-maven-plugin to v1.2.16 ([#1643](https://github.com/open-feature/java-sdk/issues/1643)) ([01ce26a](https://github.com/open-feature/java-sdk/commit/01ce26afc9b8a4bc098dc3406e65c483fd940d15)) +* **deps:** update dependency maven-wrapper to v3.3.4 ([#1638](https://github.com/open-feature/java-sdk/issues/1638)) ([69a87a8](https://github.com/open-feature/java-sdk/commit/69a87a81e8f4796c5d4a895b9379c0103765ba3d)) +* **deps:** update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.14.1 ([#1625](https://github.com/open-feature/java-sdk/issues/1625)) ([55c344a](https://github.com/open-feature/java-sdk/commit/55c344a8323fa94f4b890d5a119976e879bbb43c)) +* **deps:** update dependency org.apache.maven.plugins:maven-dependency-plugin to v3.9.0 ([#1651](https://github.com/open-feature/java-sdk/issues/1651)) ([bb42184](https://github.com/open-feature/java-sdk/commit/bb4218456e87391ae4ad96999e6cb49f78eab0aa)) +* **deps:** update dependency org.apache.maven.plugins:maven-javadoc-plugin to v3.12.0 ([#1623](https://github.com/open-feature/java-sdk/issues/1623)) ([eeda099](https://github.com/open-feature/java-sdk/commit/eeda09980cc85a538f0c41fef10bf285b0829761)) +* **deps:** update dependency org.assertj:assertj-core to v3.27.5 ([#1619](https://github.com/open-feature/java-sdk/issues/1619)) ([d4beca7](https://github.com/open-feature/java-sdk/commit/d4beca71bb60359b88e739153ff96ffc11aa74ef)) +* **deps:** update dependency org.assertj:assertj-core to v3.27.6 ([#1627](https://github.com/open-feature/java-sdk/issues/1627)) ([14f550f](https://github.com/open-feature/java-sdk/commit/14f550fd4ff9223437cc36d6cc1b248125a68e3c)) +* **deps:** update dependency org.codehaus.mojo:exec-maven-plugin to v3.6.0 ([#1645](https://github.com/open-feature/java-sdk/issues/1645)) ([261ea5d](https://github.com/open-feature/java-sdk/commit/261ea5dfa6b73d6e538388315719b0f06f417927)) +* **deps:** update dependency org.codehaus.mojo:exec-maven-plugin to v3.6.1 ([#1653](https://github.com/open-feature/java-sdk/issues/1653)) ([71dfb08](https://github.com/open-feature/java-sdk/commit/71dfb08a096a03fb02e44be4ada796e99b053cf0)) +* **deps:** update dependency org.mockito:mockito-core to v5.20.0 ([#1622](https://github.com/open-feature/java-sdk/issues/1622)) ([857fb9d](https://github.com/open-feature/java-sdk/commit/857fb9d78c509ee9c1087c355eb0fdb4ffdb668e)) +* **deps:** update dependency org.sonatype.central:central-publishing-maven-plugin to v0.9.0 ([#1630](https://github.com/open-feature/java-sdk/issues/1630)) ([014e82a](https://github.com/open-feature/java-sdk/commit/014e82af10ae478596c65c80d2cf92fc843339ed)) +* **deps:** update github/codeql-action digest to 0337c4c ([#1621](https://github.com/open-feature/java-sdk/issues/1621)) ([6cf64d6](https://github.com/open-feature/java-sdk/commit/6cf64d6b0c0ae351a707d70257380f2bce81a82e)) +* **deps:** update github/codeql-action digest to 065c6cf ([#1652](https://github.com/open-feature/java-sdk/issues/1652)) ([fe44e51](https://github.com/open-feature/java-sdk/commit/fe44e519c9de5dbc00b25aeaa6f1bf31809688f0)) +* **deps:** update github/codeql-action digest to 12dda79 ([#1618](https://github.com/open-feature/java-sdk/issues/1618)) ([17d0e48](https://github.com/open-feature/java-sdk/commit/17d0e487f31864facc0e69ee76352cab82b6b6b7)) +* **deps:** update github/codeql-action digest to 21a7ba3 ([#1650](https://github.com/open-feature/java-sdk/issues/1650)) ([1de446d](https://github.com/open-feature/java-sdk/commit/1de446d38ee2abdc3149f8eff374c617c26462fb)) +* **deps:** update github/codeql-action digest to 36adfa7 ([#1641](https://github.com/open-feature/java-sdk/issues/1641)) ([2155cc9](https://github.com/open-feature/java-sdk/commit/2155cc94371a0147fafc3246e7d4e4b9d9b7a5a3)) +* **deps:** update github/codeql-action digest to 6a87ebe ([#1639](https://github.com/open-feature/java-sdk/issues/1639)) ([58b6575](https://github.com/open-feature/java-sdk/commit/58b6575410b75760d5402f3f927dc8a2e62e9654)) +* **deps:** update github/codeql-action digest to 80cb6b5 ([#1644](https://github.com/open-feature/java-sdk/issues/1644)) ([6b922a2](https://github.com/open-feature/java-sdk/commit/6b922a2a6107cff7f951dcaf9e1c09609aeade83)) +* **deps:** update github/codeql-action digest to 94a9b7a ([#1635](https://github.com/open-feature/java-sdk/issues/1635)) ([f9796e8](https://github.com/open-feature/java-sdk/commit/f9796e8e1623bdac0ec52b7102e11759d3e449d8)) +* **deps:** update github/codeql-action digest to e4b85ab ([#1626](https://github.com/open-feature/java-sdk/issues/1626)) ([99a997d](https://github.com/open-feature/java-sdk/commit/99a997dcc594e06662cc3509e9c8698611893567)) + ## [1.18.1](https://github.com/open-feature/java-sdk/compare/v1.18.0...v1.18.1) (2025-09-17) diff --git a/README.md b/README.md index 58f586478..70b131e9a 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.18.1 + 1.18.2 ``` @@ -84,7 +84,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:1.18.1' + implementation 'dev.openfeature:sdk:1.18.2' } ``` diff --git a/pom.xml b/pom.xml index 5917d41bd..33a98de7a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ dev.openfeature sdk - 1.18.1 + 1.18.2 [17,) diff --git a/version.txt b/version.txt index ec6d649be..b57fc7228 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.18.1 +1.18.2 From ab0553b31c1afe3a448a58c2df231851f4453f30 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 01:04:11 +0000 Subject: [PATCH 438/745] chore(deps): update github/codeql-action digest to 5528384 (#1654) 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 ef6d4b2ca..a94de73da 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@065c6cfb7809de8db2167a953b5b622491cda914 + uses: github/codeql-action/init@55283843ca9b4d67ebda238e93f97913b6d527ca with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@065c6cfb7809de8db2167a953b5b622491cda914 + uses: github/codeql-action/analyze@55283843ca9b4d67ebda238e93f97913b6d527ca diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 2480aef2b..9c1b0962a 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@065c6cfb7809de8db2167a953b5b622491cda914 + uses: github/codeql-action/init@55283843ca9b4d67ebda238e93f97913b6d527ca with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@065c6cfb7809de8db2167a953b5b622491cda914 + uses: github/codeql-action/autobuild@55283843ca9b4d67ebda238e93f97913b6d527ca - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@065c6cfb7809de8db2167a953b5b622491cda914 + uses: github/codeql-action/analyze@55283843ca9b4d67ebda238e93f97913b6d527ca From 1266940ddb4347fe54b8ef26de85d7a88daa3815 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 12:46:23 +0200 Subject: [PATCH 439/745] chore(deps): update github/codeql-action digest to 239d7b2 (#1656) 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 a94de73da..375ce689d 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@55283843ca9b4d67ebda238e93f97913b6d527ca + uses: github/codeql-action/init@239d7b286f1cc525f01e99e2f7039bcfe5cf3919 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@55283843ca9b4d67ebda238e93f97913b6d527ca + uses: github/codeql-action/analyze@239d7b286f1cc525f01e99e2f7039bcfe5cf3919 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 9c1b0962a..fc461c700 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@55283843ca9b4d67ebda238e93f97913b6d527ca + uses: github/codeql-action/init@239d7b286f1cc525f01e99e2f7039bcfe5cf3919 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@55283843ca9b4d67ebda238e93f97913b6d527ca + uses: github/codeql-action/autobuild@239d7b286f1cc525f01e99e2f7039bcfe5cf3919 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@55283843ca9b4d67ebda238e93f97913b6d527ca + uses: github/codeql-action/analyze@239d7b286f1cc525f01e99e2f7039bcfe5cf3919 From 0ab5832fec1df40a54c9856b3841484ace8118b4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 12:55:56 +0200 Subject: [PATCH 440/745] chore(deps): update github/codeql-action digest to 2f11c17 (#1658) 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 375ce689d..ebb554154 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@239d7b286f1cc525f01e99e2f7039bcfe5cf3919 + uses: github/codeql-action/init@2f11c17b09609f544685db8f691ba3176174beb4 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@239d7b286f1cc525f01e99e2f7039bcfe5cf3919 + uses: github/codeql-action/analyze@2f11c17b09609f544685db8f691ba3176174beb4 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index fc461c700..0558a7943 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@239d7b286f1cc525f01e99e2f7039bcfe5cf3919 + uses: github/codeql-action/init@2f11c17b09609f544685db8f691ba3176174beb4 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@239d7b286f1cc525f01e99e2f7039bcfe5cf3919 + uses: github/codeql-action/autobuild@2f11c17b09609f544685db8f691ba3176174beb4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@239d7b286f1cc525f01e99e2f7039bcfe5cf3919 + uses: github/codeql-action/analyze@2f11c17b09609f544685db8f691ba3176174beb4 From 490eeac9b06302359f5af0c3eb79f41562e53c5b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 11:03:05 +0000 Subject: [PATCH 441/745] chore(deps): update dependency com.vmlens:vmlens-maven-plugin to v1.2.17 (#1659) 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 33a98de7a..478f7de3f 100644 --- a/pom.xml +++ b/pom.xml @@ -351,7 +351,7 @@ com.vmlens vmlens-maven-plugin - 1.2.16 + 1.2.17 test From 354632084a2978db17a0d7791253c9442e843c33 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 11:11:44 +0000 Subject: [PATCH 442/745] chore(deps): update dependency com.vmlens:api to v1.2.17 (#1657) 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 478f7de3f..eb62abc70 100644 --- a/pom.xml +++ b/pom.xml @@ -196,7 +196,7 @@ com.vmlens api - 1.2.16 + 1.2.17 test From 59fa1e28602ba2a485323882cfbd7872280ec683 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 8 Oct 2025 02:54:51 +0000 Subject: [PATCH 443/745] chore(deps): update github/codeql-action digest to 8a6b62b (#1660) 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 ebb554154..e356961bb 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@2f11c17b09609f544685db8f691ba3176174beb4 + uses: github/codeql-action/init@8a6b62bc2dc4eb1fbb471c60b48b640bbdac8575 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@2f11c17b09609f544685db8f691ba3176174beb4 + uses: github/codeql-action/analyze@8a6b62bc2dc4eb1fbb471c60b48b640bbdac8575 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 0558a7943..6131c8253 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@2f11c17b09609f544685db8f691ba3176174beb4 + uses: github/codeql-action/init@8a6b62bc2dc4eb1fbb471c60b48b640bbdac8575 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@2f11c17b09609f544685db8f691ba3176174beb4 + uses: github/codeql-action/autobuild@8a6b62bc2dc4eb1fbb471c60b48b640bbdac8575 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@2f11c17b09609f544685db8f691ba3176174beb4 + uses: github/codeql-action/analyze@8a6b62bc2dc4eb1fbb471c60b48b640bbdac8575 From 2889ca601ed7fe6c10d1b93a4fd2c197e9b8d516 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 8 Oct 2025 18:02:06 +0000 Subject: [PATCH 444/745] chore(deps): update github/codeql-action digest to 6fd4ceb (#1662) 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 e356961bb..b8983a723 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@8a6b62bc2dc4eb1fbb471c60b48b640bbdac8575 + uses: github/codeql-action/init@6fd4ceb7bbb8ec2746fd4d3a64b77787dffd9afc with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@8a6b62bc2dc4eb1fbb471c60b48b640bbdac8575 + uses: github/codeql-action/analyze@6fd4ceb7bbb8ec2746fd4d3a64b77787dffd9afc diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 6131c8253..ee5826037 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@8a6b62bc2dc4eb1fbb471c60b48b640bbdac8575 + uses: github/codeql-action/init@6fd4ceb7bbb8ec2746fd4d3a64b77787dffd9afc with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@8a6b62bc2dc4eb1fbb471c60b48b640bbdac8575 + uses: github/codeql-action/autobuild@6fd4ceb7bbb8ec2746fd4d3a64b77787dffd9afc - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@8a6b62bc2dc4eb1fbb471c60b48b640bbdac8575 + uses: github/codeql-action/analyze@6fd4ceb7bbb8ec2746fd4d3a64b77787dffd9afc From e3f2e422df793044682328cb8f7835fec9607cb1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 9 Oct 2025 05:10:25 +0000 Subject: [PATCH 445/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.17.8 (#1663) 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 eb62abc70..1f4a6d5da 100644 --- a/pom.xml +++ b/pom.xml @@ -211,7 +211,7 @@ net.bytebuddy byte-buddy - 1.17.7 + 1.17.8 test From e264a7a600229b380ce1d63459990718a2f427e4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 9 Oct 2025 08:48:39 +0000 Subject: [PATCH 446/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.17.8 (#1664) 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 1f4a6d5da..f8099007b 100644 --- a/pom.xml +++ b/pom.xml @@ -218,7 +218,7 @@ net.bytebuddy byte-buddy-agent - 1.17.7 + 1.17.8 test From 7aa3445802ee7a64804497b7ed2d407cd0544ce7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 10 Oct 2025 13:47:31 +0000 Subject: [PATCH 447/745] chore(deps): update dependency com.vmlens:api to v1.2.18 (#1666) 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 f8099007b..176aeed4f 100644 --- a/pom.xml +++ b/pom.xml @@ -196,7 +196,7 @@ com.vmlens api - 1.2.17 + 1.2.18 test From 1a2d32437976651f582b33244173347938d8c3ad Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 10 Oct 2025 17:35:26 +0000 Subject: [PATCH 448/745] chore(deps): update dependency com.vmlens:vmlens-maven-plugin to v1.2.18 (#1667) 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 176aeed4f..53e90c67d 100644 --- a/pom.xml +++ b/pom.xml @@ -351,7 +351,7 @@ com.vmlens vmlens-maven-plugin - 1.2.17 + 1.2.18 test From 4cd6aeb21f2fe491320e1033674dd0db8ad72d5f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 10 Oct 2025 22:35:21 +0000 Subject: [PATCH 449/745] chore(deps): update github/codeql-action digest to 17783bf (#1668) 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 b8983a723..97fa5739f 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@6fd4ceb7bbb8ec2746fd4d3a64b77787dffd9afc + uses: github/codeql-action/init@17783bfb99b07f70fae080b654aed0c514057477 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6fd4ceb7bbb8ec2746fd4d3a64b77787dffd9afc + uses: github/codeql-action/analyze@17783bfb99b07f70fae080b654aed0c514057477 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index ee5826037..7d6aef28d 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@6fd4ceb7bbb8ec2746fd4d3a64b77787dffd9afc + uses: github/codeql-action/init@17783bfb99b07f70fae080b654aed0c514057477 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@6fd4ceb7bbb8ec2746fd4d3a64b77787dffd9afc + uses: github/codeql-action/autobuild@17783bfb99b07f70fae080b654aed0c514057477 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6fd4ceb7bbb8ec2746fd4d3a64b77787dffd9afc + uses: github/codeql-action/analyze@17783bfb99b07f70fae080b654aed0c514057477 From 4de637f716314ae99b26bf02e8a78c4a3c5c1940 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 15 Oct 2025 06:06:50 +0000 Subject: [PATCH 450/745] fix(deps): update dependency com.github.spotbugs:spotbugs to v4.9.7 (#1670) 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 53e90c67d..1a2bda168 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ com.github.spotbugs spotbugs - 4.9.6 + 4.9.7 provided @@ -476,7 +476,7 @@ com.github.spotbugs spotbugs - 4.9.6 + 4.9.7 From c5d54940bfe1e9671bd2dc2dc0f4a6f414fd6e36 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 15 Oct 2025 08:22:32 +0200 Subject: [PATCH 451/745] chore(deps): update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.7.0 (#1671) 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 1a2bda168..e5feb632d 100644 --- a/pom.xml +++ b/pom.xml @@ -460,7 +460,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.9.6.0 + 4.9.7.0 spotbugs-exclusions.xml From a9a5431676ea37f0de0270d19cc4e98065fb09b8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 15 Oct 2025 13:10:01 +0200 Subject: [PATCH 452/745] chore(deps): update dependency com.vmlens:api to v1.2.19 (#1672) 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 e5feb632d..97e8af1d6 100644 --- a/pom.xml +++ b/pom.xml @@ -196,7 +196,7 @@ com.vmlens api - 1.2.18 + 1.2.19 test From 060dd410fb5bf1fd2cc498e9b12ef0681667149f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 15 Oct 2025 11:17:07 +0000 Subject: [PATCH 453/745] chore(deps): update dependency com.vmlens:vmlens-maven-plugin to v1.2.19 (#1673) 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 97e8af1d6..8d3ff4897 100644 --- a/pom.xml +++ b/pom.xml @@ -351,7 +351,7 @@ com.vmlens vmlens-maven-plugin - 1.2.18 + 1.2.19 test From fdf69f9b366f5278eb3387ccd761ebb1c3f7805b Mon Sep 17 00:00:00 2001 From: chrfwow Date: Wed, 15 Oct 2025 16:49:57 +0200 Subject: [PATCH 454/745] chore: Extract vmlens version (#1610) Extract vmlens version Signed-off-by: christian.lutnik --- pom.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 8d3ff4897..65106c35f 100644 --- a/pom.xml +++ b/pom.xml @@ -13,6 +13,7 @@ 11 ${maven.compiler.source} 5.20.0 + 1.2.19 **/e2e/*.java ${project.groupId}.${project.artifactId} @@ -196,7 +197,7 @@ com.vmlens api - 1.2.19 + ${com.vmlens.version} test @@ -351,7 +352,7 @@ com.vmlens vmlens-maven-plugin - 1.2.19 + ${com.vmlens.version} test From e2d1bb63e5f42868422d510779ebbb33c74fe377 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 17 Oct 2025 03:05:31 +0000 Subject: [PATCH 455/745] chore(deps): update github/codeql-action digest to ee753b4 (#1674) 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 97fa5739f..252b06872 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@17783bfb99b07f70fae080b654aed0c514057477 + uses: github/codeql-action/init@ee753b4724a8022c6235aff6a88efbfd82155923 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@17783bfb99b07f70fae080b654aed0c514057477 + uses: github/codeql-action/analyze@ee753b4724a8022c6235aff6a88efbfd82155923 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 7d6aef28d..1c824ce05 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@17783bfb99b07f70fae080b654aed0c514057477 + uses: github/codeql-action/init@ee753b4724a8022c6235aff6a88efbfd82155923 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@17783bfb99b07f70fae080b654aed0c514057477 + uses: github/codeql-action/autobuild@ee753b4724a8022c6235aff6a88efbfd82155923 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@17783bfb99b07f70fae080b654aed0c514057477 + uses: github/codeql-action/analyze@ee753b4724a8022c6235aff6a88efbfd82155923 From e12d594002abe54eeb56a54e3e5d429609247717 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 17 Oct 2025 12:43:23 +0000 Subject: [PATCH 456/745] chore(deps): update com.vmlens.version to v1.2.20 (#1675) 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 65106c35f..9c15aef16 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ 11 ${maven.compiler.source} 5.20.0 - 1.2.19 + 1.2.20 **/e2e/*.java ${project.groupId}.${project.artifactId} From e0f1ab03d6694d2ae45ac10825d4fbc52a7c8b5a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 18 Oct 2025 03:10:09 +0000 Subject: [PATCH 457/745] chore(deps): update github/codeql-action digest to d88a554 (#1676) 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 252b06872..8faba4042 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@ee753b4724a8022c6235aff6a88efbfd82155923 + uses: github/codeql-action/init@d88a5540c3fd916f4e15b7744d287a124278e065 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ee753b4724a8022c6235aff6a88efbfd82155923 + uses: github/codeql-action/analyze@d88a5540c3fd916f4e15b7744d287a124278e065 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 1c824ce05..c65ca82a7 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@ee753b4724a8022c6235aff6a88efbfd82155923 + uses: github/codeql-action/init@d88a5540c3fd916f4e15b7744d287a124278e065 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@ee753b4724a8022c6235aff6a88efbfd82155923 + uses: github/codeql-action/autobuild@d88a5540c3fd916f4e15b7744d287a124278e065 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ee753b4724a8022c6235aff6a88efbfd82155923 + uses: github/codeql-action/analyze@d88a5540c3fd916f4e15b7744d287a124278e065 From b21c6745cfca313bd48d6c975929161f934be50d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 18 Oct 2025 21:50:42 +0000 Subject: [PATCH 458/745] fix(deps): update dependency com.github.spotbugs:spotbugs to v4.9.8 (#1677) 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 9c15aef16..0b1b9e319 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,7 @@ com.github.spotbugs spotbugs - 4.9.7 + 4.9.8 provided @@ -477,7 +477,7 @@ com.github.spotbugs spotbugs - 4.9.7 + 4.9.8 From 8c9b126e6b600bac9c9edbc63ad0d19e4bd9b5cf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 Oct 2025 03:22:02 +0000 Subject: [PATCH 459/745] chore(deps): update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.8.0 (#1678) 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 0b1b9e319..95aae6c2f 100644 --- a/pom.xml +++ b/pom.xml @@ -461,7 +461,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.9.7.0 + 4.9.8.0 spotbugs-exclusions.xml From d9563626b436961e3a4706280686d31952e42885 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 Oct 2025 13:34:56 +0000 Subject: [PATCH 460/745] chore(deps): update dependency org.codehaus.mojo:exec-maven-plugin to v3.6.2 (#1679) 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 95aae6c2f..b78e4c3f4 100644 --- a/pom.xml +++ b/pom.xml @@ -669,7 +669,7 @@ org.codehaus.mojo exec-maven-plugin - 3.6.1 + 3.6.2 update-test-harness-submodule From 110054faa099b44b2306f16cdf4ccbd33fa61fe0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 20 Oct 2025 05:48:29 +0000 Subject: [PATCH 461/745] chore(deps): update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.8.1 (#1680) 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 b78e4c3f4..f16854c8c 100644 --- a/pom.xml +++ b/pom.xml @@ -461,7 +461,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.9.8.0 + 4.9.8.1 spotbugs-exclusions.xml From d7dfc06c6616892a12c645a109ad0eeef3c18cf9 Mon Sep 17 00:00:00 2001 From: chrfwow Date: Mon, 20 Oct 2025 19:58:58 +0200 Subject: [PATCH 462/745] test: Consolidate test providers (#1661) * Consolidate test providers Signed-off-by: christian.lutnik * spotless Signed-off-by: christian.lutnik * fix errors on flag evaluation logic Signed-off-by: christian.lutnik --------- Signed-off-by: christian.lutnik --- spotbugs-exclusions.xml | 3 +- .../openfeature/sdk/ImmutableMetadata.java | 2 + .../sdk/AlwaysBrokenWithDetailsProvider.java | 52 --- .../AlwaysBrokenWithExceptionProvider.java | 39 -- .../sdk/ClientProviderMappingTest.java | 15 +- .../sdk/DeveloperExperienceTest.java | 36 +- .../openfeature/sdk/DoSomethingProvider.java | 64 --- .../java/dev/openfeature/sdk/EventsTest.java | 138 +++--- .../openfeature/sdk/FatalErrorProvider.java | 45 -- .../sdk/FlagEvaluationSpecTest.java | 164 +++++--- .../dev/openfeature/sdk/HookSpecTest.java | 90 ++-- .../openfeature/sdk/OpenFeatureAPITest.java | 21 +- .../sdk/OpenFeatureClientTest.java | 23 +- .../java/dev/openfeature/sdk/e2e/Flag.java | 14 +- .../sdk/testutils/TestEventsProvider.java | 127 ------ .../testProvider/FlagEvaluation.java | 16 + .../testutils/testProvider/TestProvider.java | 396 ++++++++++++++++++ 17 files changed, 694 insertions(+), 551 deletions(-) delete mode 100644 src/test/java/dev/openfeature/sdk/AlwaysBrokenWithDetailsProvider.java delete mode 100644 src/test/java/dev/openfeature/sdk/AlwaysBrokenWithExceptionProvider.java delete mode 100644 src/test/java/dev/openfeature/sdk/DoSomethingProvider.java delete mode 100644 src/test/java/dev/openfeature/sdk/FatalErrorProvider.java delete mode 100644 src/test/java/dev/openfeature/sdk/testutils/TestEventsProvider.java create mode 100644 src/test/java/dev/openfeature/sdk/testutils/testProvider/FlagEvaluation.java create mode 100644 src/test/java/dev/openfeature/sdk/testutils/testProvider/TestProvider.java diff --git a/spotbugs-exclusions.xml b/spotbugs-exclusions.xml index 66032ad08..b841bbad4 100644 --- a/spotbugs-exclusions.xml +++ b/spotbugs-exclusions.xml @@ -49,7 +49,6 @@ - @@ -58,4 +57,4 @@ - \ No newline at end of file + diff --git a/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java b/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java index f6c1d742e..945e0ea17 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java @@ -13,6 +13,8 @@ @Slf4j @EqualsAndHashCode public class ImmutableMetadata { + public static final ImmutableMetadata EMPTY = new ImmutableMetadata(Collections.emptyMap()); + private final Map metadata; private ImmutableMetadata(Map metadata) { diff --git a/src/test/java/dev/openfeature/sdk/AlwaysBrokenWithDetailsProvider.java b/src/test/java/dev/openfeature/sdk/AlwaysBrokenWithDetailsProvider.java deleted file mode 100644 index bd0ac2c21..000000000 --- a/src/test/java/dev/openfeature/sdk/AlwaysBrokenWithDetailsProvider.java +++ /dev/null @@ -1,52 +0,0 @@ -package dev.openfeature.sdk; - -public class AlwaysBrokenWithDetailsProvider implements FeatureProvider { - - private final String name = "always broken with details"; - - @Override - public Metadata getMetadata() { - return () -> name; - } - - @Override - public ProviderEvaluation getBooleanEvaluation(String key, Boolean defaultValue, EvaluationContext ctx) { - return ProviderEvaluation.builder() - .errorMessage(TestConstants.BROKEN_MESSAGE) - .errorCode(ErrorCode.FLAG_NOT_FOUND) - .build(); - } - - @Override - public ProviderEvaluation getStringEvaluation(String key, String defaultValue, EvaluationContext ctx) { - return ProviderEvaluation.builder() - .errorMessage(TestConstants.BROKEN_MESSAGE) - .errorCode(ErrorCode.FLAG_NOT_FOUND) - .build(); - } - - @Override - public ProviderEvaluation getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx) { - return ProviderEvaluation.builder() - .errorMessage(TestConstants.BROKEN_MESSAGE) - .errorCode(ErrorCode.FLAG_NOT_FOUND) - .build(); - } - - @Override - public ProviderEvaluation getDoubleEvaluation(String key, Double defaultValue, EvaluationContext ctx) { - return ProviderEvaluation.builder() - .errorMessage(TestConstants.BROKEN_MESSAGE) - .errorCode(ErrorCode.FLAG_NOT_FOUND) - .build(); - } - - @Override - public ProviderEvaluation getObjectEvaluation( - String key, Value defaultValue, EvaluationContext invocationContext) { - return ProviderEvaluation.builder() - .errorMessage(TestConstants.BROKEN_MESSAGE) - .errorCode(ErrorCode.FLAG_NOT_FOUND) - .build(); - } -} diff --git a/src/test/java/dev/openfeature/sdk/AlwaysBrokenWithExceptionProvider.java b/src/test/java/dev/openfeature/sdk/AlwaysBrokenWithExceptionProvider.java deleted file mode 100644 index 0ad09db29..000000000 --- a/src/test/java/dev/openfeature/sdk/AlwaysBrokenWithExceptionProvider.java +++ /dev/null @@ -1,39 +0,0 @@ -package dev.openfeature.sdk; - -import dev.openfeature.sdk.exceptions.FlagNotFoundError; - -public class AlwaysBrokenWithExceptionProvider implements FeatureProvider { - - private final String name = "always broken"; - - @Override - public Metadata getMetadata() { - return () -> name; - } - - @Override - public ProviderEvaluation getBooleanEvaluation(String key, Boolean defaultValue, EvaluationContext ctx) { - throw new FlagNotFoundError(TestConstants.BROKEN_MESSAGE); - } - - @Override - public ProviderEvaluation getStringEvaluation(String key, String defaultValue, EvaluationContext ctx) { - throw new FlagNotFoundError(TestConstants.BROKEN_MESSAGE); - } - - @Override - public ProviderEvaluation getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx) { - throw new FlagNotFoundError(TestConstants.BROKEN_MESSAGE); - } - - @Override - public ProviderEvaluation getDoubleEvaluation(String key, Double defaultValue, EvaluationContext ctx) { - throw new FlagNotFoundError(TestConstants.BROKEN_MESSAGE); - } - - @Override - public ProviderEvaluation getObjectEvaluation( - String key, Value defaultValue, EvaluationContext invocationContext) { - throw new FlagNotFoundError(TestConstants.BROKEN_MESSAGE); - } -} diff --git a/src/test/java/dev/openfeature/sdk/ClientProviderMappingTest.java b/src/test/java/dev/openfeature/sdk/ClientProviderMappingTest.java index beadf7aad..6bbb2e6c3 100644 --- a/src/test/java/dev/openfeature/sdk/ClientProviderMappingTest.java +++ b/src/test/java/dev/openfeature/sdk/ClientProviderMappingTest.java @@ -2,6 +2,7 @@ import static org.junit.jupiter.api.Assertions.*; +import dev.openfeature.sdk.testutils.testProvider.TestProvider; import org.junit.jupiter.api.Test; class ClientProviderMappingTest { @@ -10,13 +11,19 @@ class ClientProviderMappingTest { void clientProviderTest() { OpenFeatureAPI api = new OpenFeatureAPI(); - api.setProviderAndWait("client1", new DoSomethingProvider()); - api.setProviderAndWait("client2", new NoOpProvider()); + var provider1 = TestProvider.builder().initsToReady(); + var provider2 = TestProvider.builder().initsToReady(); + + api.setProviderAndWait("client1", provider1); + api.setProviderAndWait("client2", provider2); Client c1 = api.getClient("client1"); Client c2 = api.getClient("client2"); - assertTrue(c1.getBooleanValue("test", false)); - assertFalse(c2.getBooleanValue("test", false)); + c1.getBooleanValue("test", false); + c2.getBooleanValue("test", false); + + assertEquals(1, provider1.getFlagEvaluations().size()); + assertEquals(1, provider2.getFlagEvaluations().size()); } } diff --git a/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java b/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java index c954c8b19..19108bde5 100644 --- a/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java +++ b/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java @@ -8,7 +8,7 @@ import static org.mockito.Mockito.verify; import dev.openfeature.sdk.fixtures.HookFixtures; -import dev.openfeature.sdk.testutils.TestEventsProvider; +import dev.openfeature.sdk.testutils.testProvider.TestProvider; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -23,13 +23,13 @@ class DeveloperExperienceTest implements HookFixtures { private OpenFeatureAPI api; @BeforeEach - public void setUp() throws Exception { + void setUp() { api = new OpenFeatureAPI(); } @Test void simpleBooleanFlag() { - api.setProviderAndWait(new TestEventsProvider()); + api.setProviderAndWait(TestProvider.builder().initsToReady()); Client client = api.getClient(); Boolean retval = client.getBooleanValue(flagKey, false); assertFalse(retval); @@ -39,7 +39,7 @@ void simpleBooleanFlag() { void clientHooks() { Hook exampleHook = mockBooleanHook(); - api.setProviderAndWait(new TestEventsProvider()); + api.setProviderAndWait(TestProvider.builder().initsToReady()); Client client = api.getClient(); client.addHooks(exampleHook); Boolean retval = client.getBooleanValue(flagKey, false); @@ -52,7 +52,7 @@ void evalHooks() { Hook clientHook = mockBooleanHook(); Hook evalHook = mockBooleanHook(); - api.setProviderAndWait(new TestEventsProvider()); + api.setProviderAndWait(TestProvider.builder().initsToReady()); Client client = api.getClient(); client.addHooks(clientHook); Boolean retval = client.getBooleanValue( @@ -72,7 +72,7 @@ void evalHooks() { @Test void providingContext() { - api.setProviderAndWait(new TestEventsProvider()); + api.setProviderAndWait(TestProvider.builder().initsToReady()); Client client = api.getClient(); Map attributes = new HashMap<>(); List values = Arrays.asList(new Value(2), new Value(4)); @@ -88,7 +88,7 @@ void providingContext() { @Test void brokenProvider() { - api.setProviderAndWait(new AlwaysBrokenWithExceptionProvider()); + api.setProviderAndWait(TestProvider.builder().withExceptionOnFlagEvaluation()); Client client = api.getClient(); FlagEvaluationDetails retval = client.getBooleanDetails(flagKey, false); assertEquals(ErrorCode.FLAG_NOT_FOUND, retval.getErrorCode()); @@ -102,6 +102,8 @@ void providerLockedPerTransaction() { final String defaultValue = "string-value"; final OpenFeatureAPI api = new OpenFeatureAPI(); + var provider1 = TestProvider.builder().initsToReady(); + var provider2 = TestProvider.builder().initsToReady(); class MutatingHook implements Hook { @@ -110,31 +112,31 @@ 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) { - api.setProviderAndWait(TestEventsProvider.newInitializedTestEventsProvider()); + api.setProviderAndWait(provider2); return Optional.empty(); } } final Client client = api.getClient(); - api.setProviderAndWait(new DoSomethingProvider()); + api.setProviderAndWait(provider1); api.addHooks(new MutatingHook()); // if provider is changed during an evaluation transaction it should proceed with the original provider - String doSomethingValue = client.getStringValue("val", defaultValue); - assertEquals(new StringBuilder(defaultValue).reverse().toString(), doSomethingValue); + client.getStringValue("val", defaultValue); + assertEquals(1, provider1.getFlagEvaluations().size()); api.clearHooks(); // subsequent evaluations should now use new provider set by hook - String noOpValue = client.getStringValue("val", defaultValue); - assertEquals(noOpValue, defaultValue); + client.getStringValue("val", defaultValue); + assertEquals(1, provider2.getFlagEvaluations().size()); } @Test void setProviderAndWaitShouldPutTheProviderInReadyState() { String domain = "domain"; - api.setProviderAndWait(domain, new TestEventsProvider()); + api.setProviderAndWait(domain, TestProvider.builder().initsToReady()); Client client = api.getClient(domain); assertThat(client.getProviderState()).isEqualTo(ProviderState.READY); } @@ -146,7 +148,7 @@ void setProviderAndWaitShouldPutTheProviderInReadyState() { @Test void shouldPutTheProviderInStateErrorAfterEmittingErrorEvent() { String domain = "domain"; - TestEventsProvider provider = new TestEventsProvider(); + var provider = TestProvider.builder().initsToReady(); api.setProviderAndWait(domain, provider); Client client = api.getClient(domain); assertThat(client.getProviderState()).isEqualTo(ProviderState.READY); @@ -161,7 +163,7 @@ void shouldPutTheProviderInStateErrorAfterEmittingErrorEvent() { @Test void shouldPutTheProviderInStateStaleAfterEmittingStaleEvent() { String domain = "domain"; - TestEventsProvider provider = new TestEventsProvider(); + var provider = TestProvider.builder().initsToReady(); api.setProviderAndWait(domain, provider); Client client = api.getClient(domain); assertThat(client.getProviderState()).isEqualTo(ProviderState.READY); @@ -176,7 +178,7 @@ void shouldPutTheProviderInStateStaleAfterEmittingStaleEvent() { @Test void shouldPutTheProviderInStateReadyAfterEmittingReadyEvent() { String domain = "domain"; - TestEventsProvider provider = new TestEventsProvider(); + var provider = TestProvider.builder().initsToReady(); api.setProviderAndWait(domain, provider); Client client = api.getClient(domain); assertThat(client.getProviderState()).isEqualTo(ProviderState.READY); diff --git a/src/test/java/dev/openfeature/sdk/DoSomethingProvider.java b/src/test/java/dev/openfeature/sdk/DoSomethingProvider.java deleted file mode 100644 index 0477a725b..000000000 --- a/src/test/java/dev/openfeature/sdk/DoSomethingProvider.java +++ /dev/null @@ -1,64 +0,0 @@ -package dev.openfeature.sdk; - -class DoSomethingProvider implements FeatureProvider { - - static final String name = "Something"; - // Flag evaluation metadata - static final ImmutableMetadata DEFAULT_METADATA = - ImmutableMetadata.builder().build(); - private ImmutableMetadata flagMetadata; - - public DoSomethingProvider() { - this.flagMetadata = DEFAULT_METADATA; - } - - public DoSomethingProvider(ImmutableMetadata flagMetadata) { - this.flagMetadata = flagMetadata; - } - - @Override - public Metadata getMetadata() { - return () -> name; - } - - @Override - public ProviderEvaluation getBooleanEvaluation(String key, Boolean defaultValue, EvaluationContext ctx) { - return ProviderEvaluation.builder() - .value(!defaultValue) - .flagMetadata(flagMetadata) - .build(); - } - - @Override - public ProviderEvaluation getStringEvaluation(String key, String defaultValue, EvaluationContext ctx) { - return ProviderEvaluation.builder() - .value(new StringBuilder(defaultValue).reverse().toString()) - .flagMetadata(flagMetadata) - .build(); - } - - @Override - public ProviderEvaluation getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx) { - return ProviderEvaluation.builder() - .value(defaultValue * 100) - .flagMetadata(flagMetadata) - .build(); - } - - @Override - public ProviderEvaluation getDoubleEvaluation(String key, Double defaultValue, EvaluationContext ctx) { - return ProviderEvaluation.builder() - .value(defaultValue * 100) - .flagMetadata(flagMetadata) - .build(); - } - - @Override - public ProviderEvaluation getObjectEvaluation( - String key, Value defaultValue, EvaluationContext invocationContext) { - return ProviderEvaluation.builder() - .value(null) - .flagMetadata(flagMetadata) - .build(); - } -} diff --git a/src/test/java/dev/openfeature/sdk/EventsTest.java b/src/test/java/dev/openfeature/sdk/EventsTest.java index b232f1177..b3cd2a05d 100644 --- a/src/test/java/dev/openfeature/sdk/EventsTest.java +++ b/src/test/java/dev/openfeature/sdk/EventsTest.java @@ -4,9 +4,14 @@ import static org.awaitility.Awaitility.await; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Mockito.*; - -import dev.openfeature.sdk.testutils.TestEventsProvider; +import static org.mockito.Mockito.after; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.verify; + +import dev.openfeature.sdk.testutils.testProvider.TestProvider; import java.util.Arrays; import java.util.List; import java.util.function.Consumer; @@ -49,7 +54,8 @@ void apiInitReady() { final Consumer handler = mockHandler(); final String name = "apiInitReady"; - TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); + var provider = + TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); api.onProviderReady(handler); api.setProviderAndWait(name, provider); verify(handler, timeout(TIMEOUT).atLeastOnce()).accept(any()); @@ -64,14 +70,15 @@ void apiInitReady() { void apiInitError() { final Consumer handler = mockHandler(); final String name = "apiInitError"; - final String errMessage = "oh no!"; - TestEventsProvider provider = new TestEventsProvider(INIT_DELAY, true, errMessage); + var provider = TestProvider.builder() + .withName(name) + .initWaitsFor(INIT_DELAY) + .initsToError(); api.onProviderError(handler); api.setProvider(name, provider); - verify(handler, timeout(TIMEOUT)).accept(argThat(details -> { - return errMessage.equals(details.getMessage()); - })); + verify(handler, timeout(TIMEOUT)) + .accept(argThat(details -> name.equals(details.getProviderName()))); } } @@ -89,11 +96,12 @@ void apiShouldPropagateEvents() { final Consumer handler = mockHandler(); final String name = "apiShouldPropagateEvents"; - TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); + var provider = + TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); api.setProviderAndWait(name, provider); api.onProviderConfigurationChanged(handler); - provider.mockEvent( + provider.emit( ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, EventDetails.builder().build()); verify(handler, timeout(TIMEOUT)).accept(any()); @@ -118,7 +126,8 @@ void apiShouldSupportAllEventTypes() { final Consumer handler3 = mockHandler(); final Consumer handler4 = mockHandler(); - TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); + var provider = + TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); api.setProviderAndWait(name, provider); api.onProviderReady(handler1); @@ -127,8 +136,7 @@ void apiShouldSupportAllEventTypes() { api.onProviderError(handler4); Arrays.asList(ProviderEvent.values()).stream().forEach(eventType -> { - provider.mockEvent( - eventType, ProviderEventDetails.builder().build()); + provider.emit(eventType, ProviderEventDetails.builder().build()); }); verify(handler1, timeout(TIMEOUT).atLeastOnce()).accept(any()); @@ -161,13 +169,14 @@ class ProviderEvents { void shouldPropagateDefaultAndAnon() { final Consumer handler = mockHandler(); - TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); + var provider = + TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); // set provider before getting a client api.setProviderAndWait(provider); Client client = api.getClient(); client.onProviderStale(handler); - provider.mockEvent( + provider.emit( ProviderEvent.PROVIDER_STALE, EventDetails.builder().build()); verify(handler, timeout(TIMEOUT)).accept(any()); } @@ -182,13 +191,14 @@ void shouldPropagateDefaultAndNamed() { final Consumer handler = mockHandler(); final String name = "shouldPropagateDefaultAndNamed"; - TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); + var provider = + TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); // set provider before getting a client api.setProviderAndWait(provider); Client client = api.getClient(name); client.onProviderStale(handler); - provider.mockEvent( + provider.emit( ProviderEvent.PROVIDER_STALE, EventDetails.builder().build()); verify(handler, timeout(TIMEOUT)).accept(any()); } @@ -213,7 +223,7 @@ void initReadyProviderBefore() { final Consumer handler = mockHandler(); final String name = "initReadyProviderBefore"; - TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); + var provider = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); Client client = api.getClient(name); client.onProviderReady(handler); // set provider after getting a client @@ -232,7 +242,7 @@ void initReadyProviderAfter() { final Consumer handler = mockHandler(); final String name = "initReadyProviderAfter"; - TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); + var provider = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); // set provider before getting a client api.setProviderAndWait(name, provider); Client client = api.getClient(name); @@ -250,16 +260,13 @@ void initReadyProviderAfter() { void initErrorProviderAfter() { final Consumer handler = mockHandler(); final String name = "initErrorProviderAfter"; - final String errMessage = "oh no!"; - TestEventsProvider provider = new TestEventsProvider(INIT_DELAY, true, errMessage); + var provider = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToError(); Client client = api.getClient(name); client.onProviderError(handler); // set provider after getting a client api.setProvider(name, provider); - verify(handler, timeout(TIMEOUT)).accept(argThat(details -> { - return name.equals(details.getDomain()) && errMessage.equals(details.getMessage()); - })); + verify(handler, timeout(TIMEOUT)).accept(argThat(details -> name.equals(details.getDomain()))); } @Test @@ -271,15 +278,14 @@ void initErrorProviderAfter() { void initErrorProviderBefore() { final Consumer handler = mockHandler(); final String name = "initErrorProviderBefore"; - final String errMessage = "oh no!"; - TestEventsProvider provider = new TestEventsProvider(INIT_DELAY, true, errMessage); + var provider = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToError(); // set provider after getting a client 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()); + return name.equals(details.getDomain()); })); } } @@ -298,13 +304,13 @@ void shouldPropagateBefore() { final Consumer handler = mockHandler(); final String name = "shouldPropagateBefore"; - TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); + var provider = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); // set provider before getting a client api.setProviderAndWait(name, provider); Client client = api.getClient(name); client.onProviderConfigurationChanged(handler); - provider.mockEvent( + provider.emit( ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, EventDetails.builder().build()); verify(handler, timeout(TIMEOUT)) @@ -322,13 +328,13 @@ void shouldPropagateAfter() { final Consumer handler = mockHandler(); final String name = "shouldPropagateAfter"; - TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); + var provider = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); Client client = api.getClient(name); client.onProviderConfigurationChanged(handler); // set provider after getting a client api.setProviderAndWait(name, provider); - provider.mockEvent( + provider.emit( ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, EventDetails.builder().build()); verify(handler, timeout(TIMEOUT)) @@ -354,7 +360,7 @@ void shouldSupportAllEventTypes() { final Consumer handler3 = mockHandler(); final Consumer handler4 = mockHandler(); - TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); + var provider = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); api.setProviderAndWait(name, provider); Client client = api.getClient(name); @@ -364,7 +370,7 @@ void shouldSupportAllEventTypes() { client.onProviderError(handler4); Arrays.asList(ProviderEvent.values()).stream().forEach(eventType -> { - provider.mockEvent(eventType, ProviderEventDetails.builder().build()); + provider.emit(eventType, ProviderEventDetails.builder().build()); }); ArgumentMatcher nameMatches = (EventDetails details) -> details.getDomain().equals(name); @@ -383,8 +389,8 @@ void shouldNotRunHandlers() { final Consumer handler2 = mockHandler(); final String name = "shouldNotRunHandlers"; - TestEventsProvider provider1 = new TestEventsProvider(INIT_DELAY); - TestEventsProvider provider2 = new TestEventsProvider(INIT_DELAY); + var provider1 = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); + var provider2 = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); api.setProviderAndWait(name, provider1); Client client = api.getClient(name); @@ -395,12 +401,17 @@ void shouldNotRunHandlers() { api.setProviderAndWait(name, provider2); // wait for the new provider to be ready and make sure things are cleaned up. - await().until(() -> provider1.isShutDown()); + await().until(provider1::isShutdown); // fire old event - provider1.mockEvent( - ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, - EventDetails.builder().build()); + try { + provider1.emit( + ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, + EventDetails.builder().build()); + } catch (Exception e) { + // ignore this exception. When the provider is shutdown, so is the underlying ExecutorService. If new tasks + // are scheduled, they will be rejected and an exception will be thrown. + } // a bit of waiting here, but we want to make sure these are indeed never // called. @@ -420,8 +431,9 @@ void otherClientHandlersShouldNotRun() { final Consumer handlerToRun = mockHandler(); final Consumer handlerNotToRun = mockHandler(); - TestEventsProvider provider1 = new TestEventsProvider(INIT_DELAY); - TestEventsProvider provider2 = new TestEventsProvider(INIT_DELAY); + var provider1 = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); + var provider2 = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); + api.setProviderAndWait(name1, provider1); api.setProviderAndWait(name2, provider2); @@ -431,7 +443,7 @@ void otherClientHandlersShouldNotRun() { client1.onProviderConfigurationChanged(handlerToRun); client2.onProviderConfigurationChanged(handlerNotToRun); - provider1.mockEvent( + provider1.emit( ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, ProviderEventDetails.builder().build()); @@ -449,8 +461,8 @@ void boundShouldNotRunWithDefault() { final String name = "boundShouldNotRunWithDefault"; final Consumer handlerNotToRun = mockHandler(); - TestEventsProvider namedProvider = new TestEventsProvider(INIT_DELAY); - TestEventsProvider defaultProvider = new TestEventsProvider(INIT_DELAY); + var namedProvider = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); + var defaultProvider = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); api.setProviderAndWait(defaultProvider); Client client = api.getClient(name); @@ -458,10 +470,10 @@ void boundShouldNotRunWithDefault() { api.setProviderAndWait(name, namedProvider); // await the new provider to make sure the old one is shut down - await().until(() -> namedProvider.getState().equals(ProviderState.READY)); + await().until(() -> ProviderState.READY.equals(client.getProviderState())); // fire event on default provider - defaultProvider.mockEvent( + defaultProvider.emit( ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, ProviderEventDetails.builder().build()); @@ -479,17 +491,17 @@ void unboundShouldRunWithDefault() { final String name = "unboundShouldRunWithDefault"; final Consumer handlerToRun = mockHandler(); - TestEventsProvider defaultProvider = new TestEventsProvider(INIT_DELAY); + var defaultProvider = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); api.setProviderAndWait(defaultProvider); Client client = api.getClient(name); client.onProviderConfigurationChanged(handlerToRun); // await the new provider to make sure the old one is shut down - await().until(() -> defaultProvider.getState().equals(ProviderState.READY)); + await().until(() -> ProviderState.READY.equals(client.getProviderState())); // fire event on default provider - defaultProvider.mockEvent( + defaultProvider.emit( ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, ProviderEventDetails.builder().build()); @@ -509,7 +521,7 @@ void handlersRunIfOneThrows() { final Consumer nextHandler = mockHandler(); final Consumer lastHandler = mockHandler(); - TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); + var provider = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); api.setProviderAndWait(name, provider); Client client1 = api.getClient(name); @@ -518,7 +530,7 @@ void handlersRunIfOneThrows() { client1.onProviderConfigurationChanged(nextHandler); client1.onProviderConfigurationChanged(lastHandler); - provider.mockEvent( + provider.emit( ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, ProviderEventDetails.builder().build()); verify(errorHandler, timeout(TIMEOUT)).accept(any()); @@ -537,7 +549,7 @@ void shouldHaveAllProperties() { final Consumer handler2 = mockHandler(); final String name = "shouldHaveAllProperties"; - TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); + var provider = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); api.setProviderAndWait(name, provider); Client client = api.getClient(name); @@ -555,7 +567,7 @@ void shouldHaveAllProperties() { .message(message) .build(); - provider.mockEvent(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, details); + provider.emit(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, details); // both global and client handler should have all the fields. verify(handler1, timeout(TIMEOUT)).accept(argThat((EventDetails eventDetails) -> { @@ -582,7 +594,7 @@ void matchingReadyEventsMustRunImmediately() { final Consumer handler = mockHandler(); // provider which is already ready - TestEventsProvider provider = new TestEventsProvider(); + var provider = TestProvider.builder().initsToReady(); api.setProviderAndWait(name, provider); // should run even thought handler was added after ready @@ -601,7 +613,7 @@ void matchingStaleEventsMustRunImmediately() { final Consumer handler = mockHandler(); // provider which is already stale - TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); + var provider = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); Client client = api.getClient(name); api.setProviderAndWait(name, provider); provider.emitProviderStale(ProviderEventDetails.builder().build()).await(); @@ -622,7 +634,7 @@ void matchingErrorEventsMustRunImmediately() { final Consumer handler = mockHandler(); // provider which is already in error - TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); + var provider = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); Client client = api.getClient(name); api.setProviderAndWait(name, provider); provider.emitProviderError(ProviderEventDetails.builder().build()).await(); @@ -641,14 +653,14 @@ void mustPersistAcrossChanges() { final String name = "mustPersistAcrossChanges"; final Consumer handler = mockHandler(); - TestEventsProvider provider1 = new TestEventsProvider(INIT_DELAY); - TestEventsProvider provider2 = new TestEventsProvider(INIT_DELAY); + var provider1 = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); + var provider2 = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); api.setProviderAndWait(name, provider1); Client client = api.getClient(name); client.onProviderConfigurationChanged(handler); - provider1.mockEvent( + provider1.emit( ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, ProviderEventDetails.builder().build()); ArgumentMatcher nameMatches = @@ -661,7 +673,7 @@ void mustPersistAcrossChanges() { // verify that with the new provider under the same name, the handler is called // again. - provider2.mockEvent( + provider2.emit( ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, ProviderEventDetails.builder().build()); verify(handler, timeout(TIMEOUT).times(2)).accept(argThat(nameMatches)); @@ -680,7 +692,7 @@ void removedEventsShouldNotRun() { final Consumer handler1 = mockHandler(); final Consumer handler2 = mockHandler(); - TestEventsProvider provider = new TestEventsProvider(INIT_DELAY); + var provider = TestProvider.builder().initWaitsFor(INIT_DELAY).initsToReady(); api.setProviderAndWait(name, provider); Client client = api.getClient(name); @@ -692,7 +704,7 @@ void removedEventsShouldNotRun() { client.removeHandler(ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, handler2); // emit event - provider.mockEvent( + provider.emit( ProviderEvent.PROVIDER_CONFIGURATION_CHANGED, ProviderEventDetails.builder().build()); diff --git a/src/test/java/dev/openfeature/sdk/FatalErrorProvider.java b/src/test/java/dev/openfeature/sdk/FatalErrorProvider.java deleted file mode 100644 index 9ebd24758..000000000 --- a/src/test/java/dev/openfeature/sdk/FatalErrorProvider.java +++ /dev/null @@ -1,45 +0,0 @@ -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/FlagEvaluationSpecTest.java b/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java index 3b02b172d..82aa4e3cc 100644 --- a/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java @@ -1,15 +1,24 @@ package dev.openfeature.sdk; -import static dev.openfeature.sdk.DoSomethingProvider.DEFAULT_METADATA; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import dev.openfeature.sdk.e2e.Flag; import dev.openfeature.sdk.exceptions.GeneralError; import dev.openfeature.sdk.fixtures.HookFixtures; -import dev.openfeature.sdk.testutils.TestEventsProvider; +import dev.openfeature.sdk.testutils.testProvider.TestProvider; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -34,7 +43,7 @@ private Client _client() { @SneakyThrows private Client _initializedClient() { - TestEventsProvider provider = new TestEventsProvider(); + var provider = TestProvider.builder().initsToReady(); provider.initialize(null); api.setProviderAndWait(provider); return api.getClient(); @@ -74,12 +83,12 @@ void provider() { "The API SHOULD provide functions to set a provider and wait for the initialize function to return or throw.") @Test void providerAndWait() { - FeatureProvider provider = new TestEventsProvider(500); + var provider = TestProvider.builder().initWaitsFor(500).initsToReady(); api.setProviderAndWait(provider); Client client = api.getClient(); assertThat(client.getProviderState()).isEqualTo(ProviderState.READY); - provider = new TestEventsProvider(500); + provider = TestProvider.builder().initWaitsFor(500).initsToReady(); String providerName = "providerAndWait"; api.setProviderAndWait(providerName, provider); Client client2 = api.getClient(providerName); @@ -93,10 +102,10 @@ void providerAndWait() { "The API SHOULD provide functions to set a provider and wait for the initialize function to return or throw.") @Test void providerAndWaitError() { - FeatureProvider provider1 = new TestEventsProvider(500, true, "fake error"); + var provider1 = TestProvider.builder().initWaitsFor(500).initsToError(); assertThrows(GeneralError.class, () -> api.setProviderAndWait(provider1)); - FeatureProvider provider2 = new TestEventsProvider(500, true, "fake error"); + var provider2 = TestProvider.builder().initWaitsFor(500).initsToError(); String providerName = "providerAndWaitError"; assertThrows(GeneralError.class, () -> api.setProviderAndWait(providerName, provider2)); } @@ -107,7 +116,7 @@ void providerAndWaitError() { "The provider SHOULD indicate an error if flag resolution is attempted before the provider is ready.") @Test void shouldReturnNotReadyIfNotInitialized() { - FeatureProvider provider = new TestEventsProvider(100); + var provider = TestProvider.builder().initWaitsFor(500).initsToReady(); String providerName = "shouldReturnNotReadyIfNotInitialized"; api.setProvider(providerName, provider); Client client = api.getClient(providerName); @@ -121,8 +130,9 @@ void shouldReturnNotReadyIfNotInitialized() { text = "The API MUST provide a function for retrieving the metadata field of the configured provider.") @Test void provider_metadata() { - api.setProviderAndWait(new DoSomethingProvider()); - assertThat(api.getProviderMetadata().getName()).isEqualTo(DoSomethingProvider.name); + var name = "name"; + api.setProviderAndWait(TestProvider.builder().withName(name).initsToReady()); + assertThat(api.getProviderMetadata().getName()).isEqualTo(name); } @Specification( @@ -183,57 +193,63 @@ void hookRegistration() { "The client SHOULD provide functions for floating-point numbers and integers, consistent with language idioms.") @Test void value_flags() { - api.setProviderAndWait(new DoSomethingProvider()); + api.setProviderAndWait(TestProvider.builder() + .withFlags( + new Flag(FlagValueType.BOOLEAN.name(), "boolean", true), + new Flag(FlagValueType.STRING.name(), "string", "default"), + new Flag(FlagValueType.INTEGER.name(), "int", 400), + new Flag(FlagValueType.DOUBLE.name(), "double", 40.0), + new Flag(FlagValueType.OBJECT.name(), "obj", new Value())) + .initsToReady()); Client c = api.getClient(); - String key = "key"; - assertEquals(true, c.getBooleanValue(key, false)); - assertEquals(true, c.getBooleanValue(key, false, new ImmutableContext())); + assertEquals(true, c.getBooleanValue("boolean", false)); + assertEquals(true, c.getBooleanValue("boolean", false, new ImmutableContext())); assertEquals( true, c.getBooleanValue( - key, + "boolean", false, new ImmutableContext(), FlagEvaluationOptions.builder().build())); - assertEquals("gnirts-ym", c.getStringValue(key, "my-string")); - assertEquals("gnirts-ym", c.getStringValue(key, "my-string", new ImmutableContext())); + assertEquals("default", c.getStringValue("string", "my-string")); + assertEquals("default", c.getStringValue("string", "my-string", new ImmutableContext())); assertEquals( - "gnirts-ym", + "default", c.getStringValue( - key, + "string", "my-string", new ImmutableContext(), FlagEvaluationOptions.builder().build())); - assertEquals(400, c.getIntegerValue(key, 4)); - assertEquals(400, c.getIntegerValue(key, 4, new ImmutableContext())); + assertEquals(400, c.getIntegerValue("int", 3)); + assertEquals(400, c.getIntegerValue("int", 3, new ImmutableContext())); assertEquals( 400, c.getIntegerValue( - key, + "int", 4, new ImmutableContext(), FlagEvaluationOptions.builder().build())); - assertEquals(40.0, c.getDoubleValue(key, .4)); - assertEquals(40.0, c.getDoubleValue(key, .4, new ImmutableContext())); + assertEquals(40.0, c.getDoubleValue("double", .4)); + assertEquals(40.0, c.getDoubleValue("double", .4, new ImmutableContext())); assertEquals( 40.0, c.getDoubleValue( - key, + "double", .4, new ImmutableContext(), FlagEvaluationOptions.builder().build())); - assertEquals(null, c.getObjectValue(key, new Value())); - assertEquals(null, c.getObjectValue(key, new Value(), new ImmutableContext())); + assertEquals(new Value(), c.getObjectValue("obj", new Value())); + assertEquals(new Value(), c.getObjectValue("obj", new Value(), new ImmutableContext())); assertEquals( - null, + new Value(), c.getObjectValue( - key, + "obj", new Value(), new ImmutableContext(), FlagEvaluationOptions.builder().build())); @@ -264,68 +280,80 @@ 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() { - api.setProviderAndWait(new DoSomethingProvider()); + api.setProviderAndWait(TestProvider.builder() + .withFlags( + new Flag(FlagValueType.BOOLEAN.name(), "boolean", true), + new Flag(FlagValueType.STRING.name(), "string", "default"), + new Flag(FlagValueType.INTEGER.name(), "int", 400), + new Flag(FlagValueType.DOUBLE.name(), "double", 40.0), + new Flag(FlagValueType.OBJECT.name(), "obj", new Value())) + .initsToReady()); Client c = api.getClient(); - String key = "key"; FlagEvaluationDetails bd = FlagEvaluationDetails.builder() - .flagKey(key) - .value(false) - .variant(null) - .flagMetadata(DEFAULT_METADATA) + .flagKey("boolean") + .value(true) + .variant(TestProvider.DEFAULT_VARIANT) + .flagMetadata(ImmutableMetadata.EMPTY) + .reason(Reason.STATIC.name()) .build(); - assertEquals(bd, c.getBooleanDetails(key, true)); - assertEquals(bd, c.getBooleanDetails(key, true, new ImmutableContext())); + assertEquals(bd, c.getBooleanDetails("boolean", false)); + assertEquals(bd, c.getBooleanDetails("boolean", false, new ImmutableContext())); assertEquals( bd, c.getBooleanDetails( - key, - true, + "boolean", + false, new ImmutableContext(), FlagEvaluationOptions.builder().build())); FlagEvaluationDetails sd = FlagEvaluationDetails.builder() - .flagKey(key) - .value("tset") - .variant(null) - .flagMetadata(DEFAULT_METADATA) + .flagKey("string") + .value("default") + .variant(TestProvider.DEFAULT_VARIANT) + .flagMetadata(ImmutableMetadata.EMPTY) + .reason(Reason.STATIC.name()) .build(); - assertEquals(sd, c.getStringDetails(key, "test")); - assertEquals(sd, c.getStringDetails(key, "test", new ImmutableContext())); + assertEquals(sd, c.getStringDetails("string", "test")); + assertEquals(sd, c.getStringDetails("string", "test", new ImmutableContext())); assertEquals( sd, c.getStringDetails( - key, + "string", "test", new ImmutableContext(), FlagEvaluationOptions.builder().build())); FlagEvaluationDetails id = FlagEvaluationDetails.builder() - .flagKey(key) + .flagKey("int") .value(400) - .flagMetadata(DEFAULT_METADATA) + .flagMetadata(ImmutableMetadata.EMPTY) + .reason(Reason.STATIC.name()) + .variant(TestProvider.DEFAULT_VARIANT) .build(); - assertEquals(id, c.getIntegerDetails(key, 4)); - assertEquals(id, c.getIntegerDetails(key, 4, new ImmutableContext())); + assertEquals(id, c.getIntegerDetails("int", 4)); + assertEquals(id, c.getIntegerDetails("int", 4, new ImmutableContext())); assertEquals( id, c.getIntegerDetails( - key, + "int", 4, new ImmutableContext(), FlagEvaluationOptions.builder().build())); FlagEvaluationDetails dd = FlagEvaluationDetails.builder() - .flagKey(key) + .flagKey("double") .value(40.0) - .flagMetadata(DEFAULT_METADATA) + .flagMetadata(ImmutableMetadata.EMPTY) + .reason(Reason.STATIC.name()) + .variant(TestProvider.DEFAULT_VARIANT) .build(); - assertEquals(dd, c.getDoubleDetails(key, .4)); - assertEquals(dd, c.getDoubleDetails(key, .4, new ImmutableContext())); + assertEquals(dd, c.getDoubleDetails("double", .4)); + assertEquals(dd, c.getDoubleDetails("double", .4, new ImmutableContext())); assertEquals( dd, c.getDoubleDetails( - key, + "double", .4, new ImmutableContext(), FlagEvaluationOptions.builder().build())); @@ -371,7 +399,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() { - api.setProviderAndWait(new AlwaysBrokenWithExceptionProvider()); + api.setProviderAndWait(TestProvider.builder().withExceptionOnFlagEvaluation()); Client c = api.getClient(); boolean defaultValue = false; assertFalse(c.getBooleanValue("key", defaultValue)); @@ -400,7 +428,7 @@ void broken_provider() { "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() throws InterruptedException { - api.setProviderAndWait(new AlwaysBrokenWithDetailsProvider()); + api.setProviderAndWait(TestProvider.builder().withExceptionOnFlagEvaluation()); Client c = api.getClient(); boolean defaultValue = false; assertFalse(c.getBooleanValue("key", defaultValue)); @@ -416,7 +444,7 @@ void broken_provider_withDetails() throws InterruptedException { text = "Methods, functions, or operations on the client SHOULD NOT write log messages.") @Test void log_on_error() throws NotImplementedException { - api.setProviderAndWait(new AlwaysBrokenWithExceptionProvider()); + api.setProviderAndWait(TestProvider.builder().withExceptionOnFlagEvaluation()); Client c = api.getClient(); FlagEvaluationDetails result = c.getBooleanDetails("test", false); @@ -435,7 +463,7 @@ void clientMetadata() { assertNull(c.getMetadata().getDomain()); String domainName = "test domain"; - api.setProviderAndWait(new AlwaysBrokenWithExceptionProvider()); + api.setProviderAndWait(TestProvider.builder().withExceptionOnFlagEvaluation()); Client c2 = api.getClient(domainName); assertEquals(domainName, c2.getMetadata().getName()); @@ -448,7 +476,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() { - api.setProviderAndWait(new AlwaysBrokenWithExceptionProvider()); + api.setProviderAndWait(TestProvider.builder().withExceptionOnFlagEvaluation()); Client c = api.getClient(); FlagEvaluationDetails result = c.getBooleanDetails("test", false); assertEquals(Reason.ERROR.toString(), result.getReason()); @@ -460,7 +488,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() { - api.setProviderAndWait(new DoSomethingProvider(null)); + api.setProviderAndWait(TestProvider.builder().allowUnknownFlags().initsToReady()); Client c = api.getClient(); FlagEvaluationDetails result = c.getBooleanDetails("test", false); assertNotNull(result.getFlagMetadata()); @@ -471,7 +499,7 @@ void flag_metadata_passed() { void api_context() { String contextKey = "some-key"; String contextValue = "some-value"; - DoSomethingProvider provider = spy(new DoSomethingProvider()); + var provider = spy(TestProvider.builder().allowUnknownFlags().initsToReady()); api.setProviderAndWait(provider); Map attributes = new HashMap<>(); @@ -498,7 +526,7 @@ void api_context() { "Evaluation context MUST be merged in the order: API (global; lowest precedence) -> transaction -> client -> invocation -> before hooks (highest precedence), with duplicate values being overwritten.") @Test void multi_layer_context_merges_correctly() { - DoSomethingProvider provider = spy(new DoSomethingProvider()); + var provider = spy(TestProvider.builder().allowUnknownFlags().initsToReady()); api.setProviderAndWait(provider); TransactionContextPropagator transactionContextPropagator = new ThreadLocalTransactionContextPropagator(); api.setTransactionContextPropagator(transactionContextPropagator); @@ -686,7 +714,7 @@ public void after( text = "The API SHOULD have a method for setting a transaction context propagator.") @Test void setting_transaction_context_propagator() { - DoSomethingProvider provider = new DoSomethingProvider(); + var provider = spy(TestProvider.builder().initsToReady()); api.setProviderAndWait(provider); TransactionContextPropagator transactionContextPropagator = new ThreadLocalTransactionContextPropagator(); @@ -700,7 +728,7 @@ void setting_transaction_context_propagator() { "The API MUST have a method for setting the evaluation context of the transaction context propagator for the current transaction.") @Test void setting_transaction_context() { - DoSomethingProvider provider = new DoSomethingProvider(); + var provider = spy(TestProvider.builder().initsToReady()); api.setProviderAndWait(provider); TransactionContextPropagator transactionContextPropagator = new ThreadLocalTransactionContextPropagator(); diff --git a/src/test/java/dev/openfeature/sdk/HookSpecTest.java b/src/test/java/dev/openfeature/sdk/HookSpecTest.java index 56d88dfba..163007120 100644 --- a/src/test/java/dev/openfeature/sdk/HookSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSpecTest.java @@ -19,7 +19,7 @@ import dev.openfeature.sdk.exceptions.FlagNotFoundError; import dev.openfeature.sdk.fixtures.HookFixtures; -import dev.openfeature.sdk.testutils.TestEventsProvider; +import dev.openfeature.sdk.testutils.testProvider.TestProvider; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -176,7 +176,7 @@ void optional_properties() { @Test void before_runs_ahead_of_evaluation() { - api.setProviderAndWait(new AlwaysBrokenWithExceptionProvider()); + api.setProviderAndWait(TestProvider.builder().withExceptionOnFlagEvaluation()); Client client = api.getClient(); Hook evalHook = mockBooleanHook(); @@ -261,39 +261,41 @@ void error_hook_must_run_if_resolution_details_returns_an_error_code() { void hook_eval_order() { List evalOrder = new ArrayList<>(); - api.setProviderAndWait("evalOrder", new TestEventsProvider() { - public List getProviderHooks() { - return Collections.singletonList(new BooleanHook() { - - @Override - public Optional before(HookContext ctx, Map hints) { - evalOrder.add("provider before"); - return null; - } - - @Override - public void after( - HookContext ctx, - FlagEvaluationDetails details, - Map hints) { - evalOrder.add("provider after"); - } - - @Override - public void error(HookContext ctx, Exception error, Map hints) { - evalOrder.add("provider error"); - } - - @Override - public void finallyAfter( - HookContext ctx, - FlagEvaluationDetails details, - Map hints) { - evalOrder.add("provider finally"); - } - }); - } - }); + api.setProviderAndWait( + "evalOrder", + TestProvider.builder() + .withHook(new BooleanHook() { + + @Override + public Optional before( + HookContext ctx, Map hints) { + evalOrder.add("provider before"); + return null; + } + + @Override + public void after( + HookContext ctx, + FlagEvaluationDetails details, + Map hints) { + evalOrder.add("provider after"); + } + + @Override + public void error(HookContext ctx, Exception error, Map hints) { + evalOrder.add("provider error"); + } + + @Override + public void finallyAfter( + HookContext ctx, + FlagEvaluationDetails details, + Map hints) { + evalOrder.add("provider finally"); + } + }) + .allowUnknownFlags() + .initsToReady()); api.addHooks(new BooleanHook() { @Override public Optional before(HookContext ctx, Map hints) { @@ -412,7 +414,7 @@ void error_stops_before() { doThrow(RuntimeException.class).when(h).before(any(), any()); Hook h2 = mockBooleanHook(); - api.setProviderAndWait(new AlwaysBrokenWithExceptionProvider()); + api.setProviderAndWait(TestProvider.builder().withExceptionOnFlagEvaluation()); Client c = api.getClient(); c.getBooleanDetails( @@ -435,7 +437,7 @@ void error_stops_after() { doThrow(RuntimeException.class).when(h).after(any(), any(), any()); Hook h2 = mockBooleanHook(); - Client c = getClient(TestEventsProvider.newInitializedTestEventsProvider()); + Client c = getClient(TestProvider.builder().allowUnknownFlags().initsToReady()); c.getBooleanDetails( "key", @@ -540,7 +542,7 @@ void flag_eval_hook_order() { void error_hooks__before() { Hook hook = mockBooleanHook(); doThrow(RuntimeException.class).when(hook).before(any(), any()); - Client client = getClient(TestEventsProvider.newInitializedTestEventsProvider()); + Client client = getClient(TestProvider.builder().initsToReady()); Boolean value = client.getBooleanValue( "key", false, @@ -558,7 +560,7 @@ void error_hooks__before() { void error_hooks__after() { Hook hook = mockBooleanHook(); doThrow(RuntimeException.class).when(hook).after(any(), any(), any()); - Client client = getClient(TestEventsProvider.newInitializedTestEventsProvider()); + Client client = getClient(TestProvider.builder().allowUnknownFlags().initsToReady()); client.getBooleanValue( "key", false, @@ -573,7 +575,7 @@ void erroneous_flagResolution_setsAppropriateFieldsInFlagEvaluationDetails() { Hook hook = mockBooleanHook(); doThrow(RuntimeException.class).when(hook).after(any(), any(), any()); String flagKey = "test-flag-key"; - Client client = getClient(TestEventsProvider.newInitializedTestEventsProvider()); + Client client = getClient(TestProvider.builder().allowUnknownFlags().initsToReady()); client.getBooleanValue( flagKey, true, @@ -598,7 +600,7 @@ void erroneous_flagResolution_setsAppropriateFieldsInFlagEvaluationDetails() { @Test void shortCircuit_flagResolution_runsHooksWithAllFields() { String domain = "shortCircuit_flagResolution_setsAppropriateFieldsInFlagEvaluationDetails"; - api.setProvider(domain, new FatalErrorProvider()); + api.setProvider(domain, TestProvider.builder().initsToFatal()); Hook hook = mockBooleanHook(); String flagKey = "test-flag-key"; @@ -618,7 +620,7 @@ void shortCircuit_flagResolution_runsHooksWithAllFields() { void successful_flagResolution_setsAppropriateFieldsInFlagEvaluationDetails() { Hook hook = mockBooleanHook(); String flagKey = "test-flag-key"; - Client client = getClient(TestEventsProvider.newInitializedTestEventsProvider()); + Client client = getClient(TestProvider.builder().allowUnknownFlags().initsToReady()); client.getBooleanValue( flagKey, true, @@ -631,7 +633,7 @@ void successful_flagResolution_setsAppropriateFieldsInFlagEvaluationDetails() { FlagEvaluationDetails evaluationDetails = captor.getValue(); assertThat(evaluationDetails).isNotNull(); assertThat(evaluationDetails.getErrorCode()).isNull(); - assertThat(evaluationDetails.getReason()).isEqualTo("DEFAULT"); + assertThat(evaluationDetails.getReason()).isEqualTo(Reason.STATIC.name()); assertThat(evaluationDetails.getVariant()).isEqualTo("Passed in default"); assertThat(evaluationDetails.getFlagKey()).isEqualTo(flagKey); assertThat(evaluationDetails.getFlagMetadata()) @@ -779,7 +781,7 @@ void first_error_broken() { private Client getClient(FeatureProvider provider) { if (provider == null) { - api.setProviderAndWait(TestEventsProvider.newInitializedTestEventsProvider()); + api.setProviderAndWait(TestProvider.builder().initsToReady()); } else { api.setProviderAndWait(provider); } diff --git a/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java b/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java index 66fd06d55..2fdb4e3f0 100644 --- a/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java +++ b/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java @@ -8,9 +8,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import dev.openfeature.sdk.providers.memory.InMemoryProvider; -import dev.openfeature.sdk.testutils.TestEventsProvider; -import java.util.Collections; +import dev.openfeature.sdk.testutils.testProvider.TestProvider; import java.util.HashMap; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -28,7 +26,7 @@ void setupTest() { @Test void namedProviderTest() { - FeatureProvider provider = new NoOpProvider(); + var provider = TestProvider.builder().initsToReady(); api.setProviderAndWait("namedProviderTest", provider); assertThat(provider.getMetadata().getName()) @@ -42,18 +40,19 @@ void namedProviderTest() { @Test void namedProviderOverwrittenTest() { String domain = "namedProviderOverwrittenTest"; - FeatureProvider provider1 = new NoOpProvider(); - FeatureProvider provider2 = new DoSomethingProvider(); + var provider1 = TestProvider.builder().withName("provider1").initsToReady(); + var provider2 = TestProvider.builder().withName("provider2").initsToReady(); api.setProviderAndWait(domain, provider1); api.setProviderAndWait(domain, provider2); - assertThat(api.getProvider(domain).getMetadata().getName()).isEqualTo(DoSomethingProvider.name); + assertThat(api.getProvider(domain).getMetadata().getName()) + .isEqualTo(provider2.getMetadata().getName()); } @Test void providerToMultipleNames() throws Exception { - FeatureProvider inMemAsEventingProvider = new InMemoryProvider(Collections.EMPTY_MAP); - FeatureProvider noOpAsNonEventingProvider = new NoOpProvider(); + var inMemAsEventingProvider = TestProvider.builder().initsToReady(); + var noOpAsNonEventingProvider = TestProvider.builder().initsToReady(); // register same provider for multiple names & as default provider api.setProviderAndWait(inMemAsEventingProvider); @@ -95,8 +94,8 @@ void setEvaluationContextShouldAllowChaining() { @Test void getStateReturnsTheStateOfTheAppropriateProvider() throws Exception { String domain = "namedProviderOverwrittenTest"; - FeatureProvider provider1 = new NoOpProvider(); - FeatureProvider provider2 = new TestEventsProvider(); + var provider1 = TestProvider.builder().initsToReady(); + var provider2 = TestProvider.builder().initsToReady(); api.setProviderAndWait(domain, provider1); api.setProviderAndWait(domain, provider2); diff --git a/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java b/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java index 88ebfaf9d..91509bd45 100644 --- a/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java +++ b/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java @@ -10,7 +10,7 @@ import dev.openfeature.sdk.exceptions.FatalError; import dev.openfeature.sdk.fixtures.HookFixtures; -import dev.openfeature.sdk.testutils.TestEventsProvider; +import dev.openfeature.sdk.testutils.testProvider.TestProvider; import java.util.HashMap; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -42,10 +42,11 @@ void reset_logs() { void shouldNotThrowExceptionIfHookHasDifferentTypeArgumentThanHookContext() { OpenFeatureAPI api = new OpenFeatureAPI(); api.setProviderAndWait( - "shouldNotThrowExceptionIfHookHasDifferentTypeArgumentThanHookContext", new DoSomethingProvider()); + "shouldNotThrowExceptionIfHookHasDifferentTypeArgumentThanHookContext", + TestProvider.builder().initsToReady()); Client client = api.getClient("shouldNotThrowExceptionIfHookHasDifferentTypeArgumentThanHookContext"); client.addHooks(mockBooleanHook(), mockStringHook()); - FlagEvaluationDetails actual = client.getBooleanDetails("feature key", Boolean.FALSE); + FlagEvaluationDetails actual = client.getBooleanDetails("feature key", Boolean.TRUE); assertThat(actual.getValue()).isTrue(); // I dislike this, but given the mocking tools available, there's no way that I know of to say "no errors were @@ -83,7 +84,7 @@ void setEvaluationContextShouldAllowChaining() { @Test @DisplayName("Should not call evaluation methods when the provider has state FATAL") void shouldNotCallEvaluationMethodsWhenProviderIsInFatalErrorState() { - FeatureProvider provider = new TestEventsProvider(100, true, "fake fatal", true); + var provider = TestProvider.builder().initWaitsFor(100).initsToFatal(); OpenFeatureAPI api = new OpenFeatureAPI(); Client client = api.getClient("shouldNotCallEvaluationMethodsWhenProviderIsInFatalErrorState"); @@ -98,13 +99,15 @@ void shouldNotCallEvaluationMethodsWhenProviderIsInFatalErrorState() { @Test @DisplayName("Should not call evaluation methods when the provider has state NOT_READY") void shouldNotCallEvaluationMethodsWhenProviderIsInNotReadyState() { - FeatureProvider provider = new TestEventsProvider(5000); + var awaitable = new Awaitable(); + var provider = TestProvider.builder().initWaitsFor(awaitable).initsToReady(); OpenFeatureAPI api = new OpenFeatureAPI(); api.setProvider("shouldNotCallEvaluationMethodsWhenProviderIsInNotReadyState", provider); Client client = api.getClient("shouldNotCallEvaluationMethodsWhenProviderIsInNotReadyState"); FlagEvaluationDetails details = client.getBooleanDetails("key", true); assertThat(details.getErrorCode()).isEqualTo(ErrorCode.PROVIDER_NOT_READY); + awaitable.wakeup(); } @ParameterizedTest @@ -112,13 +115,9 @@ void shouldNotCallEvaluationMethodsWhenProviderIsInNotReadyState() { @DisplayName("Should support usage of HookData with/without error") void shouldSupportUsageOfHookData(boolean isError) { OpenFeatureAPI api = new OpenFeatureAPI(); - FeatureProvider provider; - if (isError) { - provider = new AlwaysBrokenWithExceptionProvider(); - } else { - provider = new DoSomethingProvider(); - } - api.setProviderAndWait("shouldSupportUsageOfHookData", provider); + api.setProviderAndWait( + "shouldSupportUsageOfHookData", + TestProvider.builder().allowUnknownFlags(!isError).initsToReady()); var testHook = new TestHookWithData("test-data"); api.addHooks(testHook); diff --git a/src/test/java/dev/openfeature/sdk/e2e/Flag.java b/src/test/java/dev/openfeature/sdk/e2e/Flag.java index 2c4ffdb57..7e3a11c90 100644 --- a/src/test/java/dev/openfeature/sdk/e2e/Flag.java +++ b/src/test/java/dev/openfeature/sdk/e2e/Flag.java @@ -1,13 +1,21 @@ package dev.openfeature.sdk.e2e; +import dev.openfeature.sdk.ImmutableMetadata; + public class Flag { - public String name; - public Object defaultValue; - public String type; + public final String name; + public final Object defaultValue; + public final String type; + public final ImmutableMetadata flagMetadata; public Flag(String type, String name, Object defaultValue) { + this(type, name, defaultValue, ImmutableMetadata.EMPTY); + } + + public Flag(String type, String name, Object defaultValue, ImmutableMetadata flagMetadata) { this.name = name; this.defaultValue = defaultValue; this.type = type; + this.flagMetadata = flagMetadata; } } diff --git a/src/test/java/dev/openfeature/sdk/testutils/TestEventsProvider.java b/src/test/java/dev/openfeature/sdk/testutils/TestEventsProvider.java deleted file mode 100644 index 7cd2ea318..000000000 --- a/src/test/java/dev/openfeature/sdk/testutils/TestEventsProvider.java +++ /dev/null @@ -1,127 +0,0 @@ -package dev.openfeature.sdk.testutils; - -import dev.openfeature.sdk.EvaluationContext; -import dev.openfeature.sdk.EventProvider; -import dev.openfeature.sdk.Metadata; -import dev.openfeature.sdk.ProviderEvaluation; -import dev.openfeature.sdk.ProviderEvent; -import dev.openfeature.sdk.ProviderEventDetails; -import dev.openfeature.sdk.Reason; -import dev.openfeature.sdk.Value; -import dev.openfeature.sdk.exceptions.FatalError; -import dev.openfeature.sdk.exceptions.GeneralError; -import lombok.SneakyThrows; - -public class TestEventsProvider extends EventProvider { - public static final String PASSED_IN_DEFAULT = "Passed in default"; - - private boolean initError = false; - private String initErrorMessage; - private boolean shutDown = false; - private int initTimeoutMs = 0; - private String name = "test"; - private Metadata metadata = () -> name; - private boolean isFatalInitError = false; - - public TestEventsProvider() {} - - public TestEventsProvider(int initTimeoutMs) { - this.initTimeoutMs = initTimeoutMs; - } - - public TestEventsProvider(int initTimeoutMs, boolean initError, String initErrorMessage) { - this.initTimeoutMs = initTimeoutMs; - this.initError = initError; - this.initErrorMessage = initErrorMessage; - } - - public TestEventsProvider(int initTimeoutMs, boolean initError, String initErrorMessage, boolean fatal) { - this.initTimeoutMs = initTimeoutMs; - this.initError = initError; - this.initErrorMessage = initErrorMessage; - this.isFatalInitError = fatal; - } - - @SneakyThrows - public static TestEventsProvider newInitializedTestEventsProvider() { - TestEventsProvider provider = new TestEventsProvider(); - provider.initialize(null); - return provider; - } - - public void mockEvent(ProviderEvent event, ProviderEventDetails details) { - emit(event, details); - } - - public boolean isShutDown() { - return this.shutDown; - } - - @Override - public void shutdown() { - this.shutDown = true; - } - - @Override - public void initialize(EvaluationContext evaluationContext) throws Exception { - // wait half the TIMEOUT, otherwise some init/errors can be fired before we add handlers - Thread.sleep(initTimeoutMs); - if (this.initError) { - if (this.isFatalInitError) { - throw new FatalError(initErrorMessage); - } - throw new GeneralError(initErrorMessage); - } - } - - @Override - public Metadata getMetadata() { - return this.metadata; - } - - @Override - public ProviderEvaluation getBooleanEvaluation(String key, Boolean defaultValue, EvaluationContext ctx) { - return ProviderEvaluation.builder() - .value(defaultValue) - .variant(PASSED_IN_DEFAULT) - .reason(Reason.DEFAULT.toString()) - .build(); - } - - @Override - public ProviderEvaluation getStringEvaluation(String key, String defaultValue, EvaluationContext ctx) { - return ProviderEvaluation.builder() - .value(defaultValue) - .variant(PASSED_IN_DEFAULT) - .reason(Reason.DEFAULT.toString()) - .build(); - } - - @Override - public ProviderEvaluation getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx) { - return ProviderEvaluation.builder() - .value(defaultValue) - .variant(PASSED_IN_DEFAULT) - .reason(Reason.DEFAULT.toString()) - .build(); - } - - @Override - public ProviderEvaluation getDoubleEvaluation(String key, Double defaultValue, EvaluationContext ctx) { - return ProviderEvaluation.builder() - .value(defaultValue) - .variant(PASSED_IN_DEFAULT) - .reason(Reason.DEFAULT.toString()) - .build(); - } - - @Override - public ProviderEvaluation getObjectEvaluation( - String key, Value defaultValue, EvaluationContext invocationContext) { - return ProviderEvaluation.builder() - .value(defaultValue) - .variant(PASSED_IN_DEFAULT) - .reason(Reason.DEFAULT.toString()) - .build(); - } -} diff --git a/src/test/java/dev/openfeature/sdk/testutils/testProvider/FlagEvaluation.java b/src/test/java/dev/openfeature/sdk/testutils/testProvider/FlagEvaluation.java new file mode 100644 index 000000000..61860a050 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/testutils/testProvider/FlagEvaluation.java @@ -0,0 +1,16 @@ +package dev.openfeature.sdk.testutils.testProvider; + +import dev.openfeature.sdk.EvaluationContext; +import dev.openfeature.sdk.FlagValueType; + +public class FlagEvaluation { + public final String flagKey; + public final FlagValueType flagType; + public final EvaluationContext evaluationContext; + + public FlagEvaluation(String flagKey, FlagValueType flagType, EvaluationContext evaluationContext) { + this.flagKey = flagKey; + this.flagType = flagType; + this.evaluationContext = evaluationContext; + } +} diff --git a/src/test/java/dev/openfeature/sdk/testutils/testProvider/TestProvider.java b/src/test/java/dev/openfeature/sdk/testutils/testProvider/TestProvider.java new file mode 100644 index 000000000..383ade483 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/testutils/testProvider/TestProvider.java @@ -0,0 +1,396 @@ +package dev.openfeature.sdk.testutils.testProvider; + +import dev.openfeature.sdk.*; +import dev.openfeature.sdk.e2e.Flag; +import dev.openfeature.sdk.exceptions.FatalError; +import dev.openfeature.sdk.exceptions.FlagNotFoundError; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicBoolean; + +public class TestProvider extends EventProvider { + public static final String DEFAULT_VARIANT = "Passed in default"; + + private final String name; + private final List hooks; + private final int initDelay; + private final Awaitable initWaitsFor; + private final Map flags; + private final boolean fatalOnInit; + private final boolean errorOnInit; + private final boolean errorsOnFlagEvaluation; + private final ErrorCode errorCode; + private final String errorMessage; + private final RuntimeException throwable; + private final ConcurrentLinkedQueue flagEvaluations = new ConcurrentLinkedQueue<>(); + private final AtomicBoolean isShutdown = new AtomicBoolean(false); + private final boolean allowAnyFlag; + + private TestProvider( + String name, + List hooks, + int initDelay, + Awaitable initWaitsFor, + boolean allowAnyFlag, + Map flags, + boolean errorsOnFlagEvaluation, + boolean errorOnInit, + ErrorCode errorCode, + String errorMessage, + RuntimeException throwable, + boolean fatalOnInit) { + this.name = name == null ? "TestProvider" : name; + this.hooks = hooks; + this.initDelay = initDelay; + this.initWaitsFor = initWaitsFor; + this.allowAnyFlag = allowAnyFlag; + this.flags = flags; + this.errorsOnFlagEvaluation = errorsOnFlagEvaluation; + this.errorOnInit = errorOnInit; + this.errorCode = errorCode == null ? ErrorCode.GENERAL : errorCode; + this.errorMessage = errorMessage == null ? "Test error" : errorMessage; + this.throwable = throwable; + this.fatalOnInit = fatalOnInit; + } + + public List getFlagEvaluations() { + return new ArrayList<>(flagEvaluations); + } + + @Override + public List getProviderHooks() { + return hooks; + } + + @Override + public void initialize(EvaluationContext evaluationContext) throws Exception { + if (initWaitsFor != null) { + initWaitsFor.await(); + } else if (initDelay > 0) { + var end = System.currentTimeMillis() + initDelay; + long delta = initDelay; + while (delta > 0) { + try { + Thread.sleep(delta); + } catch (InterruptedException e) { + // ignore + } + delta = end - System.currentTimeMillis(); + } + } + + if (fatalOnInit) { + throw new FatalError("TestProvider is set to fatal state, thus will throw on init"); + } + if (errorOnInit) { + throw new RuntimeException("TestProvider is set to error state, thus will throw on init"); + } + } + + @Override + public void shutdown() { + super.shutdown(); + isShutdown.set(true); + } + + public boolean isShutdown() { + return isShutdown.get(); + } + + @Override + public Metadata getMetadata() { + return () -> name; + } + + private ProviderEvaluation getEvaluation( + String key, T defaultValue, FlagValueType flagType, Class clazz, EvaluationContext evaluationContext) { + flagEvaluations.add(new FlagEvaluation(key, flagType, evaluationContext)); + if (throwable != null) { + throw throwable; + } + var builder = ProviderEvaluation.builder(); + if (errorsOnFlagEvaluation) { + return builder.errorMessage(errorMessage).errorCode(errorCode).build(); + } + if (allowAnyFlag) { + return builder.reason(Reason.STATIC.name()) + .value(clazz.cast(defaultValue)) + .flagMetadata(ImmutableMetadata.EMPTY) + .variant(DEFAULT_VARIANT) + .build(); + } + var flag = flags.get(key); + if (flag == null) { + return builder.errorCode(ErrorCode.FLAG_NOT_FOUND) + .errorMessage("Flag not found") + .build(); + } + if (flagType.name().equals(flag.type)) { + return builder.reason(Reason.STATIC.name()) + .value(clazz.cast(flag.defaultValue)) + .flagMetadata(flag.flagMetadata) + .variant(DEFAULT_VARIANT) + .build(); + } + return builder.errorCode(ErrorCode.TYPE_MISMATCH) + .errorMessage("Flag type mismatch") + .flagMetadata(flag.flagMetadata) + .build(); + } + + @Override + public ProviderEvaluation getBooleanEvaluation(String key, Boolean defaultValue, EvaluationContext ctx) { + return getEvaluation(key, defaultValue, FlagValueType.BOOLEAN, Boolean.class, ctx); + } + + @Override + public ProviderEvaluation getStringEvaluation(String key, String defaultValue, EvaluationContext ctx) { + return getEvaluation(key, defaultValue, FlagValueType.STRING, String.class, ctx); + } + + @Override + public ProviderEvaluation getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx) { + return getEvaluation(key, defaultValue, FlagValueType.INTEGER, Integer.class, ctx); + } + + @Override + public ProviderEvaluation getDoubleEvaluation(String key, Double defaultValue, EvaluationContext ctx) { + return getEvaluation(key, defaultValue, FlagValueType.DOUBLE, Double.class, ctx); + } + + @Override + public ProviderEvaluation getObjectEvaluation(String key, Value defaultValue, EvaluationContext ctx) { + return getEvaluation(key, defaultValue, FlagValueType.OBJECT, Value.class, ctx); + } + + public interface PostInit { + TestProvider initsToReady(); + + TestProvider initsToError(boolean isError); + + default TestProvider initsToError() { + return initsToError(true); + } + + TestProvider initsToFatal(boolean isFatal); + + default TestProvider initsToFatal() { + return initsToFatal(true); + } + + TestProvider withExceptionOnFlagEvaluation(RuntimeException runtimeException); + + default TestProvider withExceptionOnFlagEvaluation() { + return withExceptionOnFlagEvaluation(new FlagNotFoundError(TestConstants.BROKEN_MESSAGE)); + } + } + + public interface InitConfig { + PostInit initWaitsFor(int millis); + + PostInit initWaitsFor(Awaitable awaitable); + } + + public interface WithFlags extends InitConfig, PostInit {} + + public interface FlagConfig { + FlagConfig withFlag(Flag flag); + + WithFlags withFlags(Flag... flags); + + WithFlags withFlags(Iterable flags); + + default WithFlags errorsOnFlagEvaluation() { + return errorsOnFlagEvaluation(true); + } + + WithFlags errorsOnFlagEvaluation(boolean error); + + WithFlags errorsOnFlagEvaluation(ErrorCode errorCode); + + WithFlags errorsOnFlagEvaluation(ErrorCode errorCode, String errorMessage); + + default WithFlags allowUnknownFlags() { + return allowUnknownFlags(true); + } + + WithFlags allowUnknownFlags(boolean allowEveryRequestedFlag); + } + + public interface WithHooks extends FlagConfig, WithFlags {} + + public interface HookConfig { + Builder withHook(Hook hook); + + WithHooks withHooks(Hook... hooks); + + WithHooks withHooks(Iterable hooks); + } + + public interface WithName extends WithHooks, HookConfig {} + + public interface NameConfig { + WithName withName(String name); + } + + public interface Builder extends WithName, NameConfig {} + + public static Builder builder() { + return new TestProviderBuilder(); + } + + public static class TestProviderBuilder implements Builder { + private final List hooks = new ArrayList<>(); + private final Map flags = new HashMap<>(); + private Awaitable initWaitsFor; + private int initDelay = 0; + private boolean errorsOnFlagEvaluation; + private ErrorCode errorCode; + private String errorMessage; + private RuntimeException runtimeException; + private boolean errorOnInit = false; + private boolean fatalOnInit = false; + private boolean allowAnyFlag = false; + private String name; + + @Override + public WithName withName(String name) { + this.name = name; + return this; + } + + @Override + public Builder withHook(Hook hook) { + this.hooks.add(hook); + return this; + } + + @Override + public WithHooks withHooks(Hook... hooks) { + for (int i = 0; i < hooks.length; i++) { + this.hooks.add(hooks[i]); + } + return this; + } + + @Override + public WithHooks withHooks(Iterable hooks) { + for (Hook hook : hooks) { + this.hooks.add(hook); + } + return this; + } + + @Override + public WithFlags errorsOnFlagEvaluation(boolean error) { + this.errorsOnFlagEvaluation = error; + return this; + } + + @Override + public WithFlags errorsOnFlagEvaluation(ErrorCode errorCode) { + this.errorsOnFlagEvaluation = true; + this.errorCode = errorCode; + return this; + } + + @Override + public WithFlags errorsOnFlagEvaluation(ErrorCode errorCode, String errorMessage) { + this.errorsOnFlagEvaluation = true; + this.errorCode = errorCode; + this.errorMessage = errorMessage; + return this; + } + + @Override + public WithFlags allowUnknownFlags(boolean allowEveryRequestedFlag) { + this.allowAnyFlag = allowEveryRequestedFlag; + return this; + } + + @Override + public FlagConfig withFlag(Flag flag) { + flags.put(flag.name, flag); + return this; + } + + @Override + public WithFlags withFlags(Flag... flags) { + for (Flag flag : flags) { + this.flags.put(flag.name, flag); + } + return this; + } + + @Override + public WithFlags withFlags(Iterable flags) { + for (Flag flag : flags) { + this.flags.put(flag.name, flag); + } + return this; + } + + @Override + public PostInit initWaitsFor(int millis) { + initDelay = millis; + initWaitsFor = null; + return this; + } + + @Override + public PostInit initWaitsFor(Awaitable awaitable) { + initDelay = 0; + initWaitsFor = awaitable; + return this; + } + + @Override + public TestProvider initsToReady() { + errorOnInit = false; + return build(); + } + + @Override + public TestProvider initsToError(boolean isError) { + this.errorOnInit = isError; + return build(); + } + + @Override + public TestProvider initsToError() { + errorOnInit = true; + return build(); + } + + @Override + public TestProvider initsToFatal(boolean isFatal) { + this.fatalOnInit = isFatal; + return build(); + } + + @Override + public TestProvider withExceptionOnFlagEvaluation(RuntimeException runtimeException) { + this.runtimeException = runtimeException; + return build(); + } + + private TestProvider build() { + return new TestProvider( + name, + hooks, + initDelay, + initWaitsFor, + allowAnyFlag, + flags, + errorsOnFlagEvaluation, + errorOnInit, + errorCode, + errorMessage, + runtimeException, + fatalOnInit); + } + } +} From ca9f1acb0c0a0a68a5cb49b5af3477c8f4abb1b7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 21 Oct 2025 01:56:21 +0000 Subject: [PATCH 463/745] chore(deps): update github/codeql-action digest to 9b0ac1c (#1681) 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 8faba4042..90b7752f2 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@d88a5540c3fd916f4e15b7744d287a124278e065 + uses: github/codeql-action/init@9b0ac1cc3b2985145e276933b2b96f423f56e68b with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@d88a5540c3fd916f4e15b7744d287a124278e065 + uses: github/codeql-action/analyze@9b0ac1cc3b2985145e276933b2b96f423f56e68b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index c65ca82a7..95c14288e 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@d88a5540c3fd916f4e15b7744d287a124278e065 + uses: github/codeql-action/init@9b0ac1cc3b2985145e276933b2b96f423f56e68b with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@d88a5540c3fd916f4e15b7744d287a124278e065 + uses: github/codeql-action/autobuild@9b0ac1cc3b2985145e276933b2b96f423f56e68b - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@d88a5540c3fd916f4e15b7744d287a124278e065 + uses: github/codeql-action/analyze@9b0ac1cc3b2985145e276933b2b96f423f56e68b From d16fe3d598fdcc0197532200e723e9abed63dcd6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 22 Oct 2025 08:28:09 +0200 Subject: [PATCH 464/745] chore(deps): update github/codeql-action digest to 0c5185d (#1683) 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 90b7752f2..a6b3031a0 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@9b0ac1cc3b2985145e276933b2b96f423f56e68b + uses: github/codeql-action/init@0c5185d061ea8cb82b9c5cd84d2c51a7fc2d9d6b with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9b0ac1cc3b2985145e276933b2b96f423f56e68b + uses: github/codeql-action/analyze@0c5185d061ea8cb82b9c5cd84d2c51a7fc2d9d6b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 95c14288e..1f4b0465b 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@9b0ac1cc3b2985145e276933b2b96f423f56e68b + uses: github/codeql-action/init@0c5185d061ea8cb82b9c5cd84d2c51a7fc2d9d6b with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@9b0ac1cc3b2985145e276933b2b96f423f56e68b + uses: github/codeql-action/autobuild@0c5185d061ea8cb82b9c5cd84d2c51a7fc2d9d6b - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9b0ac1cc3b2985145e276933b2b96f423f56e68b + uses: github/codeql-action/analyze@0c5185d061ea8cb82b9c5cd84d2c51a7fc2d9d6b From 9152b21599ccc07389d32c083dc9f2b99e5d130c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 22 Oct 2025 22:10:00 +0000 Subject: [PATCH 465/745] chore(deps): update github/codeql-action digest to 4264208 (#1684) 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 a6b3031a0..5b0bb70c4 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@0c5185d061ea8cb82b9c5cd84d2c51a7fc2d9d6b + uses: github/codeql-action/init@42642085de2a94da10d5b87c0c7b9f51e147aa1f with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0c5185d061ea8cb82b9c5cd84d2c51a7fc2d9d6b + uses: github/codeql-action/analyze@42642085de2a94da10d5b87c0c7b9f51e147aa1f diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 1f4b0465b..376f0bcb4 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@0c5185d061ea8cb82b9c5cd84d2c51a7fc2d9d6b + uses: github/codeql-action/init@42642085de2a94da10d5b87c0c7b9f51e147aa1f with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@0c5185d061ea8cb82b9c5cd84d2c51a7fc2d9d6b + uses: github/codeql-action/autobuild@42642085de2a94da10d5b87c0c7b9f51e147aa1f - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0c5185d061ea8cb82b9c5cd84d2c51a7fc2d9d6b + uses: github/codeql-action/analyze@42642085de2a94da10d5b87c0c7b9f51e147aa1f From c57c8a5fb7e5384fbd5e7f34fe2bf65e36b40811 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 23 Oct 2025 20:46:35 +0000 Subject: [PATCH 466/745] chore(deps): update github/codeql-action digest to 9625890 (#1686) 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 5b0bb70c4..33aa6f522 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@42642085de2a94da10d5b87c0c7b9f51e147aa1f + uses: github/codeql-action/init@9625890712c7f078b834b0cb549f00b374edb8ec with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@42642085de2a94da10d5b87c0c7b9f51e147aa1f + uses: github/codeql-action/analyze@9625890712c7f078b834b0cb549f00b374edb8ec diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 376f0bcb4..9be4d832d 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@42642085de2a94da10d5b87c0c7b9f51e147aa1f + uses: github/codeql-action/init@9625890712c7f078b834b0cb549f00b374edb8ec with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@42642085de2a94da10d5b87c0c7b9f51e147aa1f + uses: github/codeql-action/autobuild@9625890712c7f078b834b0cb549f00b374edb8ec - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@42642085de2a94da10d5b87c0c7b9f51e147aa1f + uses: github/codeql-action/analyze@9625890712c7f078b834b0cb549f00b374edb8ec From 9df27e42ce6472060467d4fdcbedb925a85457f5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 24 Oct 2025 17:18:23 +0200 Subject: [PATCH 467/745] chore(deps): update github/codeql-action digest to 956c567 (#1687) 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 33aa6f522..aae959073 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@9625890712c7f078b834b0cb549f00b374edb8ec + uses: github/codeql-action/init@956c56734d31557279f2769a3368010c321bb452 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9625890712c7f078b834b0cb549f00b374edb8ec + uses: github/codeql-action/analyze@956c56734d31557279f2769a3368010c321bb452 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 9be4d832d..e1799f1cf 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@9625890712c7f078b834b0cb549f00b374edb8ec + uses: github/codeql-action/init@956c56734d31557279f2769a3368010c321bb452 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@9625890712c7f078b834b0cb549f00b374edb8ec + uses: github/codeql-action/autobuild@956c56734d31557279f2769a3368010c321bb452 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9625890712c7f078b834b0cb549f00b374edb8ec + uses: github/codeql-action/analyze@956c56734d31557279f2769a3368010c321bb452 From c948e9bd862b9180b7b84781bdf155587c0c3840 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 25 Oct 2025 01:29:04 +0000 Subject: [PATCH 468/745] chore(deps): update github/codeql-action digest to ae78991 (#1688) 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 aae959073..f54c29fd6 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@956c56734d31557279f2769a3368010c321bb452 + uses: github/codeql-action/init@ae78991f558bb4195cb8a727cb6679c362b9cf24 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@956c56734d31557279f2769a3368010c321bb452 + uses: github/codeql-action/analyze@ae78991f558bb4195cb8a727cb6679c362b9cf24 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index e1799f1cf..d8af9e8ce 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@956c56734d31557279f2769a3368010c321bb452 + uses: github/codeql-action/init@ae78991f558bb4195cb8a727cb6679c362b9cf24 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@956c56734d31557279f2769a3368010c321bb452 + uses: github/codeql-action/autobuild@ae78991f558bb4195cb8a727cb6679c362b9cf24 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@956c56734d31557279f2769a3368010c321bb452 + uses: github/codeql-action/analyze@ae78991f558bb4195cb8a727cb6679c362b9cf24 From 3a58838b70b4c21312fcb182ac97f07a78d57dcd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Oct 2025 02:08:03 +0000 Subject: [PATCH 469/745] chore(deps): update com.vmlens.version to v1.2.21 (#1689) 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 f16854c8c..950d0d36d 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ 11 ${maven.compiler.source} 5.20.0 - 1.2.20 + 1.2.21 **/e2e/*.java ${project.groupId}.${project.artifactId} From 61a59a15692bee0529242621ef0c15e2af1f6fdf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Oct 2025 09:59:56 +0100 Subject: [PATCH 470/745] chore(deps): update dependency org.jacoco:jacoco-maven-plugin to v0.8.14 (#1669) 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 950d0d36d..40cf7f7a0 100644 --- a/pom.xml +++ b/pom.xml @@ -402,7 +402,7 @@ org.jacoco jacoco-maven-plugin - 0.8.13 + 0.8.14 From a5dacf963ebc71024e22925ccc99d724681e98aa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Oct 2025 09:06:30 +0000 Subject: [PATCH 471/745] chore(deps): update dependency dev.cel:cel to v0.11.1 (#1682) 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 40cf7f7a0..2e1d9f5b0 100644 --- a/pom.xml +++ b/pom.xml @@ -190,7 +190,7 @@ dev.cel cel - 0.11.0 + 0.11.1 test From cfcb20b06f17dd84ec532b96ab7fe647b93c7740 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Oct 2025 23:12:29 +0000 Subject: [PATCH 472/745] chore(deps): update github/codeql-action digest to 8d77149 (#1690) 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 f54c29fd6..7b6620ada 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@ae78991f558bb4195cb8a727cb6679c362b9cf24 + uses: github/codeql-action/init@8d77149e0c9e2199ac9cfc90c9e15116f5c69c48 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ae78991f558bb4195cb8a727cb6679c362b9cf24 + uses: github/codeql-action/analyze@8d77149e0c9e2199ac9cfc90c9e15116f5c69c48 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index d8af9e8ce..5d133a4d3 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@ae78991f558bb4195cb8a727cb6679c362b9cf24 + uses: github/codeql-action/init@8d77149e0c9e2199ac9cfc90c9e15116f5c69c48 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@ae78991f558bb4195cb8a727cb6679c362b9cf24 + uses: github/codeql-action/autobuild@8d77149e0c9e2199ac9cfc90c9e15116f5c69c48 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ae78991f558bb4195cb8a727cb6679c362b9cf24 + uses: github/codeql-action/analyze@8d77149e0c9e2199ac9cfc90c9e15116f5c69c48 From 46d71796611f080c29fdc3c954847c9160db718f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Oct 2025 00:59:50 +0000 Subject: [PATCH 473/745] chore(deps): update actions/setup-java digest to de5a937 (#1691) 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 d39980b71..93d176852 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -26,7 +26,7 @@ jobs: fetch-depth: 0 submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@ead9eaa3cfe0b0fc2fa749519ae09c3d4f4080b0 + uses: actions/setup-java@de5a937a1dc73fbc1a67d7d1aa4bebc1082f3190 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 7b6620ada..0acc90492 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -25,7 +25,7 @@ jobs: submodules: recursive - name: Set up JDK ${{ matrix.build.java }} - uses: actions/setup-java@ead9eaa3cfe0b0fc2fa749519ae09c3d4f4080b0 + uses: actions/setup-java@de5a937a1dc73fbc1a67d7d1aa4bebc1082f3190 with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c07ff847e..901c9a529 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,7 +43,7 @@ jobs: submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@ead9eaa3cfe0b0fc2fa749519ae09c3d4f4080b0 + uses: actions/setup-java@de5a937a1dc73fbc1a67d7d1aa4bebc1082f3190 with: java-version: '17' distribution: 'temurin' From 08cc1ab561bd93528ba67e7113b40b0ae8c28cd0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Oct 2025 06:47:42 +0000 Subject: [PATCH 474/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.31.0 (#1692) 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 2e1d9f5b0..4bc020f9a 100644 --- a/pom.xml +++ b/pom.xml @@ -235,7 +235,7 @@ io.cucumber cucumber-bom - 7.30.0 + 7.31.0 pom import From d2a2d6fc95e2fa8a3e6e9cc39545648faf6a0a08 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Oct 2025 01:53:44 +0000 Subject: [PATCH 475/745] chore(deps): update github/codeql-action digest to ac9aeee (#1693) 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 0acc90492..2d6d6e333 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@8d77149e0c9e2199ac9cfc90c9e15116f5c69c48 + uses: github/codeql-action/init@ac9aeee2261a2f9c74439210107de7657bd5ed42 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@8d77149e0c9e2199ac9cfc90c9e15116f5c69c48 + uses: github/codeql-action/analyze@ac9aeee2261a2f9c74439210107de7657bd5ed42 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 5d133a4d3..cbf642441 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@8d77149e0c9e2199ac9cfc90c9e15116f5c69c48 + uses: github/codeql-action/init@ac9aeee2261a2f9c74439210107de7657bd5ed42 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@8d77149e0c9e2199ac9cfc90c9e15116f5c69c48 + uses: github/codeql-action/autobuild@ac9aeee2261a2f9c74439210107de7657bd5ed42 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@8d77149e0c9e2199ac9cfc90c9e15116f5c69c48 + uses: github/codeql-action/analyze@ac9aeee2261a2f9c74439210107de7657bd5ed42 From 3df3d369f294925ee0b06823199279a2eacd64c3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Oct 2025 01:27:09 +0000 Subject: [PATCH 476/745] chore(deps): update github/codeql-action digest to 777daa0 (#1694) 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 2d6d6e333..1c9b2d625 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@ac9aeee2261a2f9c74439210107de7657bd5ed42 + uses: github/codeql-action/init@777daa0c71818e7f377c8adc5415f74544c87142 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ac9aeee2261a2f9c74439210107de7657bd5ed42 + uses: github/codeql-action/analyze@777daa0c71818e7f377c8adc5415f74544c87142 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index cbf642441..043ea3d1c 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@ac9aeee2261a2f9c74439210107de7657bd5ed42 + uses: github/codeql-action/init@777daa0c71818e7f377c8adc5415f74544c87142 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@ac9aeee2261a2f9c74439210107de7657bd5ed42 + uses: github/codeql-action/autobuild@777daa0c71818e7f377c8adc5415f74544c87142 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ac9aeee2261a2f9c74439210107de7657bd5ed42 + uses: github/codeql-action/analyze@777daa0c71818e7f377c8adc5415f74544c87142 From f8eed4e9198692fa531cbe844cba3cb15eca7a9a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Oct 2025 12:20:53 +0100 Subject: [PATCH 477/745] chore(deps): update dependency com.puppycrawl.tools:checkstyle to v12 (#1665) 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 4bc020f9a..2c8773284 100644 --- a/pom.xml +++ b/pom.xml @@ -505,7 +505,7 @@ com.puppycrawl.tools checkstyle - 11.1.0 + 12.1.1 From 982bd99430f92182dfd8063df6e2587b80bebca4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Oct 2025 12:31:40 +0100 Subject: [PATCH 478/745] chore(deps): update github/codeql-action digest to 514ff4d (#1695) 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 1c9b2d625..6090b0c9e 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@777daa0c71818e7f377c8adc5415f74544c87142 + uses: github/codeql-action/init@514ff4d116ef04d9ffc8adb3da5abb07961cb990 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@777daa0c71818e7f377c8adc5415f74544c87142 + uses: github/codeql-action/analyze@514ff4d116ef04d9ffc8adb3da5abb07961cb990 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 043ea3d1c..9861715fc 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@777daa0c71818e7f377c8adc5415f74544c87142 + uses: github/codeql-action/init@514ff4d116ef04d9ffc8adb3da5abb07961cb990 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@777daa0c71818e7f377c8adc5415f74544c87142 + uses: github/codeql-action/autobuild@514ff4d116ef04d9ffc8adb3da5abb07961cb990 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@777daa0c71818e7f377c8adc5415f74544c87142 + uses: github/codeql-action/analyze@514ff4d116ef04d9ffc8adb3da5abb07961cb990 From a6943108ab26cb718bc8590d29fcbc34c2435350 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 31 Oct 2025 00:04:29 +0000 Subject: [PATCH 479/745] chore(deps): update github/codeql-action digest to 9bd8638 (#1696) 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 6090b0c9e..47ed3e4ac 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@514ff4d116ef04d9ffc8adb3da5abb07961cb990 + uses: github/codeql-action/init@9bd86385763ccc9345d5b7648ea1b54401b24819 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@514ff4d116ef04d9ffc8adb3da5abb07961cb990 + uses: github/codeql-action/analyze@9bd86385763ccc9345d5b7648ea1b54401b24819 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 9861715fc..449b5bbd8 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@514ff4d116ef04d9ffc8adb3da5abb07961cb990 + uses: github/codeql-action/init@9bd86385763ccc9345d5b7648ea1b54401b24819 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@514ff4d116ef04d9ffc8adb3da5abb07961cb990 + uses: github/codeql-action/autobuild@9bd86385763ccc9345d5b7648ea1b54401b24819 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@514ff4d116ef04d9ffc8adb3da5abb07961cb990 + uses: github/codeql-action/analyze@9bd86385763ccc9345d5b7648ea1b54401b24819 From e473e9ebf0a8c341179d47ddc7c9dfbb01295e71 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 31 Oct 2025 02:58:16 +0000 Subject: [PATCH 480/745] fix(deps): update dependency com.fasterxml.jackson:jackson-bom to v2.20.1 (#1697) 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 2c8773284..5689d8307 100644 --- a/pom.xml +++ b/pom.xml @@ -227,7 +227,7 @@ com.fasterxml.jackson jackson-bom - 2.20.0 + 2.20.1 pom import From f6b4bb82e2b4e711175f06f52c857fa2ac72d9a4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Nov 2025 03:31:25 +0000 Subject: [PATCH 481/745] chore(deps): update github/codeql-action digest to 338146c (#1698) 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 47ed3e4ac..f50947421 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@9bd86385763ccc9345d5b7648ea1b54401b24819 + uses: github/codeql-action/init@338146ca93283a2901a142d408241096146019b5 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9bd86385763ccc9345d5b7648ea1b54401b24819 + uses: github/codeql-action/analyze@338146ca93283a2901a142d408241096146019b5 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 449b5bbd8..babfcf39f 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@9bd86385763ccc9345d5b7648ea1b54401b24819 + uses: github/codeql-action/init@338146ca93283a2901a142d408241096146019b5 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@9bd86385763ccc9345d5b7648ea1b54401b24819 + uses: github/codeql-action/autobuild@338146ca93283a2901a142d408241096146019b5 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9bd86385763ccc9345d5b7648ea1b54401b24819 + uses: github/codeql-action/analyze@338146ca93283a2901a142d408241096146019b5 From dcd037eba301e01f386e8f992c6a5d1cd1cda144 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Nov 2025 05:09:41 +0000 Subject: [PATCH 482/745] fix(deps): update dependency org.junit:junit-bom to v6.0.1 (#1699) 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 5689d8307..9db61b5f3 100644 --- a/pom.xml +++ b/pom.xml @@ -243,7 +243,7 @@ org.junit junit-bom - 6.0.0 + 6.0.1 pom import From 53073a4870b10e50e545c14dd6082ee5becd4317 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Nov 2025 01:26:37 +0000 Subject: [PATCH 483/745] chore(deps): update actions/checkout digest to 71cf226 (#1700) 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 +- .github/workflows/static-code-scanning.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index 93d176852..549aadc84 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 + - uses: actions/checkout@71cf2267d89c5cb81562390fa70a37fa40b1305e with: fetch-depth: 0 submodules: recursive diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index f50947421..b05648219 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -19,7 +19,7 @@ jobs: runs-on: ${{ matrix.os}} steps: - name: Check out the code - uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 + uses: actions/checkout@71cf2267d89c5cb81562390fa70a37fa40b1305e with: fetch-depth: 0 submodules: recursive diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 901c9a529..a8ef20057 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,7 +37,7 @@ jobs: steps: - name: Checkout Repository - uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 + uses: actions/checkout@71cf2267d89c5cb81562390fa70a37fa40b1305e with: fetch-depth: 0 submodules: recursive diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index babfcf39f..dc1e49de2 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 + uses: actions/checkout@71cf2267d89c5cb81562390fa70a37fa40b1305e # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL From 30c07d6ce30e9e6505b777ee34edd6541317a134 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Nov 2025 05:48:31 +0000 Subject: [PATCH 484/745] chore(deps): update github/codeql-action digest to 97580d7 (#1701) 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 b05648219..7487f45fe 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@338146ca93283a2901a142d408241096146019b5 + uses: github/codeql-action/init@97580d7533c1591e2e67e0a0d103da09b5c9b684 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@338146ca93283a2901a142d408241096146019b5 + uses: github/codeql-action/analyze@97580d7533c1591e2e67e0a0d103da09b5c9b684 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index dc1e49de2..c0dece840 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@338146ca93283a2901a142d408241096146019b5 + uses: github/codeql-action/init@97580d7533c1591e2e67e0a0d103da09b5c9b684 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@338146ca93283a2901a142d408241096146019b5 + uses: github/codeql-action/autobuild@97580d7533c1591e2e67e0a0d103da09b5c9b684 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@338146ca93283a2901a142d408241096146019b5 + uses: github/codeql-action/analyze@97580d7533c1591e2e67e0a0d103da09b5c9b684 From bb9a4ca8524b155e6a5091e288a3195a06d90a0a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Nov 2025 17:18:33 +0100 Subject: [PATCH 485/745] chore(deps): update com.vmlens.version to v1.2.22 (#1703) 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 9db61b5f3..f92b0d255 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ 11 ${maven.compiler.source} 5.20.0 - 1.2.21 + 1.2.22 **/e2e/*.java ${project.groupId}.${project.artifactId} From 01a3669c2e050df54a3f51386d524968b3ef15d1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Nov 2025 16:32:48 +0000 Subject: [PATCH 486/745] chore(deps): update github/codeql-action digest to 95b1867 (#1702) 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 7487f45fe..44ab31930 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@97580d7533c1591e2e67e0a0d103da09b5c9b684 + uses: github/codeql-action/init@95b1867cf797beb28ce725a6f25268e2d3304672 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@97580d7533c1591e2e67e0a0d103da09b5c9b684 + uses: github/codeql-action/analyze@95b1867cf797beb28ce725a6f25268e2d3304672 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index c0dece840..23243984b 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@97580d7533c1591e2e67e0a0d103da09b5c9b684 + uses: github/codeql-action/init@95b1867cf797beb28ce725a6f25268e2d3304672 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@97580d7533c1591e2e67e0a0d103da09b5c9b684 + uses: github/codeql-action/autobuild@95b1867cf797beb28ce725a6f25268e2d3304672 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@97580d7533c1591e2e67e0a0d103da09b5c9b684 + uses: github/codeql-action/analyze@95b1867cf797beb28ce725a6f25268e2d3304672 From 3fda8b8f94c35c04433594463112df7348331f1c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 5 Nov 2025 15:54:52 +0100 Subject: [PATCH 487/745] chore(deps): update github/codeql-action digest to e2ef519 (#1705) 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 44ab31930..1c64239cb 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@95b1867cf797beb28ce725a6f25268e2d3304672 + uses: github/codeql-action/init@e2ef519c756a7fd93c8a8187d9539cab36eb5277 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@95b1867cf797beb28ce725a6f25268e2d3304672 + uses: github/codeql-action/analyze@e2ef519c756a7fd93c8a8187d9539cab36eb5277 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 23243984b..36ce0c67c 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@95b1867cf797beb28ce725a6f25268e2d3304672 + uses: github/codeql-action/init@e2ef519c756a7fd93c8a8187d9539cab36eb5277 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@95b1867cf797beb28ce725a6f25268e2d3304672 + uses: github/codeql-action/autobuild@e2ef519c756a7fd93c8a8187d9539cab36eb5277 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@95b1867cf797beb28ce725a6f25268e2d3304672 + uses: github/codeql-action/analyze@e2ef519c756a7fd93c8a8187d9539cab36eb5277 From e22eb0beef5ed87e143bac888ca66467c062ee1c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 5 Nov 2025 22:01:19 +0000 Subject: [PATCH 488/745] chore(deps): update github/codeql-action digest to 320a6b6 (#1706) 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 1c64239cb..e48fe685c 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@e2ef519c756a7fd93c8a8187d9539cab36eb5277 + uses: github/codeql-action/init@320a6b661b23adb447724a2e4805470acb076f83 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e2ef519c756a7fd93c8a8187d9539cab36eb5277 + uses: github/codeql-action/analyze@320a6b661b23adb447724a2e4805470acb076f83 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 36ce0c67c..94deb613b 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@e2ef519c756a7fd93c8a8187d9539cab36eb5277 + uses: github/codeql-action/init@320a6b661b23adb447724a2e4805470acb076f83 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@e2ef519c756a7fd93c8a8187d9539cab36eb5277 + uses: github/codeql-action/autobuild@320a6b661b23adb447724a2e4805470acb076f83 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e2ef519c756a7fd93c8a8187d9539cab36eb5277 + uses: github/codeql-action/analyze@320a6b661b23adb447724a2e4805470acb076f83 From 6a504689cd555747c5d005f4da3315b9a9ad0d50 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 6 Nov 2025 16:00:00 +0100 Subject: [PATCH 489/745] chore(deps): update github/codeql-action digest to 71d0a56 (#1707) 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 e48fe685c..2feb430d6 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@320a6b661b23adb447724a2e4805470acb076f83 + uses: github/codeql-action/init@71d0a56d4479a74c3dd8cf7a47d5661f11752db8 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@320a6b661b23adb447724a2e4805470acb076f83 + uses: github/codeql-action/analyze@71d0a56d4479a74c3dd8cf7a47d5661f11752db8 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 94deb613b..ca9539874 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@320a6b661b23adb447724a2e4805470acb076f83 + uses: github/codeql-action/init@71d0a56d4479a74c3dd8cf7a47d5661f11752db8 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@320a6b661b23adb447724a2e4805470acb076f83 + uses: github/codeql-action/autobuild@71d0a56d4479a74c3dd8cf7a47d5661f11752db8 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@320a6b661b23adb447724a2e4805470acb076f83 + uses: github/codeql-action/analyze@71d0a56d4479a74c3dd8cf7a47d5661f11752db8 From 9f43e800fd72b1b2037a9bbcb8f8c80af307bca1 Mon Sep 17 00:00:00 2001 From: jarebudev <23311805+jarebudev@users.noreply.github.com> Date: Fri, 7 Nov 2025 16:06:33 +0000 Subject: [PATCH 490/745] feat: use descriptive thread names (#1704) * added a configurable thread factory to allow naming of threads Signed-off-by: jarebudev <23311805+jarebudev@users.noreply.github.com> * tidy up Signed-off-by: jarebudev <23311805+jarebudev@users.noreply.github.com> --------- Signed-off-by: jarebudev <23311805+jarebudev@users.noreply.github.com> --- .../dev/openfeature/sdk/EventProvider.java | 4 +- .../dev/openfeature/sdk/EventSupport.java | 4 +- .../openfeature/sdk/ProviderRepository.java | 8 ++-- .../internal/ConfigurableThreadFactory.java | 43 +++++++++++++++++++ .../ConfigurableThreadFactoryTest.java | 42 ++++++++++++++++++ 5 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 src/main/java/dev/openfeature/sdk/internal/ConfigurableThreadFactory.java create mode 100644 src/test/java/dev/openfeature/sdk/internal/ConfigurableThreadFactoryTest.java diff --git a/src/main/java/dev/openfeature/sdk/EventProvider.java b/src/main/java/dev/openfeature/sdk/EventProvider.java index 0d7e897c2..4ccac184e 100644 --- a/src/main/java/dev/openfeature/sdk/EventProvider.java +++ b/src/main/java/dev/openfeature/sdk/EventProvider.java @@ -1,5 +1,6 @@ package dev.openfeature.sdk; +import dev.openfeature.sdk.internal.ConfigurableThreadFactory; import dev.openfeature.sdk.internal.TriConsumer; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -21,7 +22,8 @@ @Slf4j public abstract class EventProvider implements FeatureProvider { private EventProviderListener eventProviderListener; - private final ExecutorService emitterExecutor = Executors.newCachedThreadPool(); + private final ExecutorService emitterExecutor = + Executors.newCachedThreadPool(new ConfigurableThreadFactory("openfeature-event-emitter-thread")); void setEventProviderListener(EventProviderListener eventProviderListener) { this.eventProviderListener = eventProviderListener; diff --git a/src/main/java/dev/openfeature/sdk/EventSupport.java b/src/main/java/dev/openfeature/sdk/EventSupport.java index 8396795bd..0b446c6b2 100644 --- a/src/main/java/dev/openfeature/sdk/EventSupport.java +++ b/src/main/java/dev/openfeature/sdk/EventSupport.java @@ -1,5 +1,6 @@ package dev.openfeature.sdk; +import dev.openfeature.sdk.internal.ConfigurableThreadFactory; import java.util.Collection; import java.util.Map; import java.util.Optional; @@ -26,7 +27,8 @@ class EventSupport { private static final String DEFAULT_CLIENT_UUID = UUID.randomUUID().toString(); private final Map handlerStores = new ConcurrentHashMap<>(); private final HandlerStore globalHandlerStore = new HandlerStore(); - private final ExecutorService taskExecutor = Executors.newCachedThreadPool(); + private final ExecutorService taskExecutor = + Executors.newCachedThreadPool(new ConfigurableThreadFactory("openfeature-event-handler-thread")); /** * Run all the event handlers associated with this domain. diff --git a/src/main/java/dev/openfeature/sdk/ProviderRepository.java b/src/main/java/dev/openfeature/sdk/ProviderRepository.java index ab024a750..147074a58 100644 --- a/src/main/java/dev/openfeature/sdk/ProviderRepository.java +++ b/src/main/java/dev/openfeature/sdk/ProviderRepository.java @@ -2,6 +2,7 @@ import dev.openfeature.sdk.exceptions.GeneralError; import dev.openfeature.sdk.exceptions.OpenFeatureError; +import dev.openfeature.sdk.internal.ConfigurableThreadFactory; import java.util.List; import java.util.Map; import java.util.Optional; @@ -22,11 +23,8 @@ class ProviderRepository { private final Map stateManagers = new ConcurrentHashMap<>(); private final AtomicReference defaultStateManger = new AtomicReference<>(new FeatureProviderStateManager(new NoOpProvider())); - private final ExecutorService taskExecutor = Executors.newCachedThreadPool(runnable -> { - final Thread thread = new Thread(runnable); - thread.setDaemon(true); - return thread; - }); + private final ExecutorService taskExecutor = + Executors.newCachedThreadPool(new ConfigurableThreadFactory("openfeature-provider-thread", true)); private final Object registerStateManagerLock = new Object(); private final OpenFeatureAPI openFeatureAPI; diff --git a/src/main/java/dev/openfeature/sdk/internal/ConfigurableThreadFactory.java b/src/main/java/dev/openfeature/sdk/internal/ConfigurableThreadFactory.java new file mode 100644 index 000000000..8d5e77db8 --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/internal/ConfigurableThreadFactory.java @@ -0,0 +1,43 @@ +package dev.openfeature.sdk.internal; + +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * A configurable thread factory for internal use in the SDK. + * Allows daemon or non-daemon threads to be created with a custom name prefix. + */ +public final class ConfigurableThreadFactory implements ThreadFactory { + + private final AtomicInteger counter = new AtomicInteger(); + private final String namePrefix; + private final boolean daemon; + + /** + * {@link ConfigurableThreadFactory}'s constructor. + * + * @param namePrefix Prefix used for setting the new thread's name. + */ + public ConfigurableThreadFactory(String namePrefix) { + this(namePrefix, false); + } + + /** + * {@link ConfigurableThreadFactory}'s constructor. + * + * @param namePrefix Prefix used for setting the new thread's name. + * @param daemon Whether daemon or non-daemon threads will be created. + */ + public ConfigurableThreadFactory(String namePrefix, boolean daemon) { + this.namePrefix = namePrefix; + this.daemon = daemon; + } + + @Override + public Thread newThread(Runnable runnable) { + final Thread thread = new Thread(runnable); + thread.setDaemon(daemon); + thread.setName(namePrefix + "-" + counter.incrementAndGet()); + return thread; + } +} diff --git a/src/test/java/dev/openfeature/sdk/internal/ConfigurableThreadFactoryTest.java b/src/test/java/dev/openfeature/sdk/internal/ConfigurableThreadFactoryTest.java new file mode 100644 index 000000000..0de360ae6 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/internal/ConfigurableThreadFactoryTest.java @@ -0,0 +1,42 @@ +package dev.openfeature.sdk.internal; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +class ConfigurableThreadFactoryTest { + + private static final String THREAD_NAME = "testthread"; + private final Runnable runnable = () -> {}; + + @Test + void verifyNewThreadHasNamePrefix() { + + var configurableThreadFactory = new ConfigurableThreadFactory(THREAD_NAME); + var thread = configurableThreadFactory.newThread(runnable); + + assertThat(thread.getName()).isEqualTo(THREAD_NAME + "-1"); + assertThat(thread.isDaemon()).isFalse(); + } + + @Test + void verifyNewThreadHasNamePrefixWithIncrement() { + + var configurableThreadFactory = new ConfigurableThreadFactory(THREAD_NAME); + var threadOne = configurableThreadFactory.newThread(runnable); + var threadTwo = configurableThreadFactory.newThread(runnable); + + assertThat(threadOne.getName()).isEqualTo(THREAD_NAME + "-1"); + assertThat(threadTwo.getName()).isEqualTo(THREAD_NAME + "-2"); + } + + @Test + void verifyNewDaemonThreadHasNamePrefix() { + + var configurableThreadFactory = new ConfigurableThreadFactory(THREAD_NAME, true); + var thread = configurableThreadFactory.newThread(runnable); + + assertThat(thread.getName()).isEqualTo(THREAD_NAME + "-1"); + assertThat(thread.isDaemon()).isTrue(); + } +} From 8c0eac6e968eda047b5348eb01233cdb7894d28c Mon Sep 17 00:00:00 2001 From: jarebudev <23311805+jarebudev@users.noreply.github.com> Date: Fri, 7 Nov 2025 16:34:36 +0000 Subject: [PATCH 491/745] chore: add additional unit tests to increase test coverage (#1708) * added missing unit tests to increase test coverage Signed-off-by: jarebudev <23311805+jarebudev@users.noreply.github.com> * applied gemini code review suggestion Signed-off-by: jarebudev <23311805+jarebudev@users.noreply.github.com> * Apply suggestion from @gemini-code-assist[bot] Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Todd Baert --------- Signed-off-by: jarebudev <23311805+jarebudev@users.noreply.github.com> Signed-off-by: Todd Baert Co-authored-by: Todd Baert Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .../dev/openfeature/sdk/BooleanHookTest.java | 31 +++++++++++++++++++ .../dev/openfeature/sdk/DoubleHookTest.java | 31 +++++++++++++++++++ .../openfeature/sdk/ImmutableContextTest.java | 13 ++++++++ .../dev/openfeature/sdk/IntegerHookTest.java | 31 +++++++++++++++++++ .../dev/openfeature/sdk/ObjectHookTest.java | 31 +++++++++++++++++++ .../dev/openfeature/sdk/StringHookTest.java | 31 +++++++++++++++++++ .../sdk/fixtures/HookFixtures.java | 5 +++ 7 files changed, 173 insertions(+) create mode 100644 src/test/java/dev/openfeature/sdk/BooleanHookTest.java create mode 100644 src/test/java/dev/openfeature/sdk/DoubleHookTest.java create mode 100644 src/test/java/dev/openfeature/sdk/IntegerHookTest.java create mode 100644 src/test/java/dev/openfeature/sdk/ObjectHookTest.java create mode 100644 src/test/java/dev/openfeature/sdk/StringHookTest.java diff --git a/src/test/java/dev/openfeature/sdk/BooleanHookTest.java b/src/test/java/dev/openfeature/sdk/BooleanHookTest.java new file mode 100644 index 000000000..a38f3ff79 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/BooleanHookTest.java @@ -0,0 +1,31 @@ +package dev.openfeature.sdk; + +import static org.assertj.core.api.Assertions.assertThat; + +import dev.openfeature.sdk.fixtures.HookFixtures; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class BooleanHookTest implements HookFixtures { + + private Hook hook; + + @BeforeEach + void setupTest() { + hook = mockBooleanHook(); + } + + @Test + void verifyFlagValueTypeIsSupportedByHook() { + boolean hookSupported = hook.supportsFlagValueType(FlagValueType.BOOLEAN); + + assertThat(hookSupported).isTrue(); + } + + @Test + void verifyFlagValueTypeIsNotSupportedByHook() { + boolean hookSupported = hook.supportsFlagValueType(FlagValueType.INTEGER); + + assertThat(hookSupported).isFalse(); + } +} diff --git a/src/test/java/dev/openfeature/sdk/DoubleHookTest.java b/src/test/java/dev/openfeature/sdk/DoubleHookTest.java new file mode 100644 index 000000000..9b198ee83 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/DoubleHookTest.java @@ -0,0 +1,31 @@ +package dev.openfeature.sdk; + +import static org.assertj.core.api.Assertions.assertThat; + +import dev.openfeature.sdk.fixtures.HookFixtures; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class DoubleHookTest implements HookFixtures { + + private Hook hook; + + @BeforeEach + void setupTest() { + hook = mockDoubleHook(); + } + + @Test + void verifyFlagValueTypeIsSupportedByHook() { + boolean hookSupported = hook.supportsFlagValueType(FlagValueType.DOUBLE); + + assertThat(hookSupported).isTrue(); + } + + @Test + void verifyFlagValueTypeIsNotSupportedByHook() { + boolean hookSupported = hook.supportsFlagValueType(FlagValueType.STRING); + + assertThat(hookSupported).isFalse(); + } +} diff --git a/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java b/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java index 2b39be741..0b8a44d0d 100644 --- a/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java +++ b/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java @@ -135,6 +135,19 @@ void mergeShouldRetainItsSubkeysWhenOverridingContextHasNoTargetingKey() { assertArrayEquals(new Object[] {"key1_1"}, value.keySet().toArray()); } + @DisplayName("Merge should obtain keys from the overriding context when the existing context is empty") + @Test + void mergeShouldObtainKeysFromOverridingContextWhenExistingContextIsEmpty() { + HashMap attributes = new HashMap<>(); + attributes.put("key1", new Value("val1")); + attributes.put("key2", new Value("val2")); + + EvaluationContext ctx = new ImmutableContext(); + EvaluationContext overriding = new ImmutableContext(attributes); + EvaluationContext merge = ctx.merge(overriding); + assertEquals(new java.util.HashSet<>(java.util.Arrays.asList("key1", "key2")), merge.keySet()); + } + @DisplayName("Two different MutableContext objects with the different contents are not considered equal") @Test void unequalImmutableContextsAreNotEqual() { diff --git a/src/test/java/dev/openfeature/sdk/IntegerHookTest.java b/src/test/java/dev/openfeature/sdk/IntegerHookTest.java new file mode 100644 index 000000000..1dee4bd8f --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/IntegerHookTest.java @@ -0,0 +1,31 @@ +package dev.openfeature.sdk; + +import static org.assertj.core.api.Assertions.assertThat; + +import dev.openfeature.sdk.fixtures.HookFixtures; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class IntegerHookTest implements HookFixtures { + + private Hook hook; + + @BeforeEach + void setupTest() { + hook = mockIntegerHook(); + } + + @Test + void verifyFlagValueTypeIsSupportedByHook() { + boolean hookSupported = hook.supportsFlagValueType(FlagValueType.INTEGER); + + assertThat(hookSupported).isTrue(); + } + + @Test + void verifyFlagValueTypeIsNotSupportedByHook() { + boolean hookSupported = hook.supportsFlagValueType(FlagValueType.STRING); + + assertThat(hookSupported).isFalse(); + } +} diff --git a/src/test/java/dev/openfeature/sdk/ObjectHookTest.java b/src/test/java/dev/openfeature/sdk/ObjectHookTest.java new file mode 100644 index 000000000..7e474c0bd --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/ObjectHookTest.java @@ -0,0 +1,31 @@ +package dev.openfeature.sdk; + +import static org.assertj.core.api.Assertions.assertThat; + +import dev.openfeature.sdk.fixtures.HookFixtures; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class ObjectHookTest implements HookFixtures { + + private Hook hook; + + @BeforeEach + void setupTest() { + hook = mockObjectHook(); + } + + @Test + void verifyFlagValueTypeIsSupportedByHook() { + boolean hookSupported = hook.supportsFlagValueType(FlagValueType.OBJECT); + + assertThat(hookSupported).isTrue(); + } + + @Test + void verifyFlagValueTypeIsNotSupportedByHook() { + boolean hookSupported = hook.supportsFlagValueType(FlagValueType.INTEGER); + + assertThat(hookSupported).isFalse(); + } +} diff --git a/src/test/java/dev/openfeature/sdk/StringHookTest.java b/src/test/java/dev/openfeature/sdk/StringHookTest.java new file mode 100644 index 000000000..16c0cd41b --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/StringHookTest.java @@ -0,0 +1,31 @@ +package dev.openfeature.sdk; + +import static org.assertj.core.api.Assertions.assertThat; + +import dev.openfeature.sdk.fixtures.HookFixtures; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class StringHookTest implements HookFixtures { + + private Hook hook; + + @BeforeEach + void setupTest() { + hook = mockStringHook(); + } + + @Test + void verifyFlagValueTypeIsSupportedByHook() { + boolean hookSupported = hook.supportsFlagValueType(FlagValueType.STRING); + + assertThat(hookSupported).isTrue(); + } + + @Test + void verifyFlagValueTypeIsNotSupportedByHook() { + boolean hookSupported = hook.supportsFlagValueType(FlagValueType.INTEGER); + + assertThat(hookSupported).isFalse(); + } +} diff --git a/src/test/java/dev/openfeature/sdk/fixtures/HookFixtures.java b/src/test/java/dev/openfeature/sdk/fixtures/HookFixtures.java index b94e58a11..d2d51bac7 100644 --- a/src/test/java/dev/openfeature/sdk/fixtures/HookFixtures.java +++ b/src/test/java/dev/openfeature/sdk/fixtures/HookFixtures.java @@ -6,6 +6,7 @@ import dev.openfeature.sdk.DoubleHook; import dev.openfeature.sdk.Hook; import dev.openfeature.sdk.IntegerHook; +import dev.openfeature.sdk.ObjectHook; import dev.openfeature.sdk.StringHook; public interface HookFixtures { @@ -26,6 +27,10 @@ default Hook mockDoubleHook() { return spy(DoubleHook.class); } + default Hook mockObjectHook() { + return spy(ObjectHook.class); + } + default Hook mockGenericHook() { return spy(Hook.class); } From 480db81a98db4bb4384b1133a4d93653adc653cf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Nov 2025 02:01:07 +0000 Subject: [PATCH 492/745] chore(deps): update github/codeql-action digest to 04bd5c6 (#1709) 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 2feb430d6..41956faa3 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@71d0a56d4479a74c3dd8cf7a47d5661f11752db8 + uses: github/codeql-action/init@04bd5c6aabdcaa5cccaf378a97ef5062b2061cd0 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@71d0a56d4479a74c3dd8cf7a47d5661f11752db8 + uses: github/codeql-action/analyze@04bd5c6aabdcaa5cccaf378a97ef5062b2061cd0 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index ca9539874..381792921 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@71d0a56d4479a74c3dd8cf7a47d5661f11752db8 + uses: github/codeql-action/init@04bd5c6aabdcaa5cccaf378a97ef5062b2061cd0 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@71d0a56d4479a74c3dd8cf7a47d5661f11752db8 + uses: github/codeql-action/autobuild@04bd5c6aabdcaa5cccaf378a97ef5062b2061cd0 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@71d0a56d4479a74c3dd8cf7a47d5661f11752db8 + uses: github/codeql-action/analyze@04bd5c6aabdcaa5cccaf378a97ef5062b2061cd0 From eefa5a772656568c2c5016b40ef66a4146d26e3f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Nov 2025 08:23:52 +0100 Subject: [PATCH 493/745] chore(deps): update amannn/action-semantic-pull-request digest to 069817c (#1710) 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 707faef76..a3c228ef4 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@e49f57ce06c1747542fce2243c7a98682384bc0e + - uses: amannn/action-semantic-pull-request@069817c298f23fab00a8f29a2e556a5eac0f6390 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 4f4a75ffe75b72fd9306ee8a983bb0a22e0198b4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Nov 2025 13:56:39 +0100 Subject: [PATCH 494/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.18.0 (#1712) 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 f92b0d255..5d25dd926 100644 --- a/pom.xml +++ b/pom.xml @@ -212,7 +212,7 @@ net.bytebuddy byte-buddy - 1.17.8 + 1.18.0 test From ac22a7268fe824b47d9f7bb0d6ff0c38d4fd6a3b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Nov 2025 13:04:02 +0000 Subject: [PATCH 495/745] chore(deps): update github/codeql-action digest to 1d9f357 (#1711) 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 41956faa3..71091995c 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@04bd5c6aabdcaa5cccaf378a97ef5062b2061cd0 + uses: github/codeql-action/init@1d9f357d018e5801d9d25e32220badc298aa1c17 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@04bd5c6aabdcaa5cccaf378a97ef5062b2061cd0 + uses: github/codeql-action/analyze@1d9f357d018e5801d9d25e32220badc298aa1c17 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 381792921..bdd83828c 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@04bd5c6aabdcaa5cccaf378a97ef5062b2061cd0 + uses: github/codeql-action/init@1d9f357d018e5801d9d25e32220badc298aa1c17 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@04bd5c6aabdcaa5cccaf378a97ef5062b2061cd0 + uses: github/codeql-action/autobuild@1d9f357d018e5801d9d25e32220badc298aa1c17 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@04bd5c6aabdcaa5cccaf378a97ef5062b2061cd0 + uses: github/codeql-action/analyze@1d9f357d018e5801d9d25e32220badc298aa1c17 From 82b169e505d4340344673fc77ceadff24fc5d534 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Nov 2025 15:20:55 +0100 Subject: [PATCH 496/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.18.0 (#1713) 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 5d25dd926..cb6622ce6 100644 --- a/pom.xml +++ b/pom.xml @@ -219,7 +219,7 @@ net.bytebuddy byte-buddy-agent - 1.17.8 + 1.18.0 test From 4880de05c6d45e4f0623cc97a9ef464be3342c23 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 13 Nov 2025 06:40:36 +0000 Subject: [PATCH 497/745] chore(deps): update github/codeql-action digest to ba454b8 (#1716) 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 71091995c..4a1297c7d 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@1d9f357d018e5801d9d25e32220badc298aa1c17 + uses: github/codeql-action/init@ba454b8ab46733eb6145342877cd148270bb77ab with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1d9f357d018e5801d9d25e32220badc298aa1c17 + uses: github/codeql-action/analyze@ba454b8ab46733eb6145342877cd148270bb77ab diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index bdd83828c..5e08f906a 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@1d9f357d018e5801d9d25e32220badc298aa1c17 + uses: github/codeql-action/init@ba454b8ab46733eb6145342877cd148270bb77ab with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@1d9f357d018e5801d9d25e32220badc298aa1c17 + uses: github/codeql-action/autobuild@ba454b8ab46733eb6145342877cd148270bb77ab - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1d9f357d018e5801d9d25e32220badc298aa1c17 + uses: github/codeql-action/analyze@ba454b8ab46733eb6145342877cd148270bb77ab From 26b6132ef8d60c4f0245da94300bbdfe29748646 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 13 Nov 2025 21:39:04 +0000 Subject: [PATCH 498/745] chore(deps): update dependency com.puppycrawl.tools:checkstyle to v12.1.2 (#1714) 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 cb6622ce6..36b73204a 100644 --- a/pom.xml +++ b/pom.xml @@ -505,7 +505,7 @@ com.puppycrawl.tools checkstyle - 12.1.1 + 12.1.2 From 8850d4a87edf25c1fdb1f3ca20c8164a8a8a310f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 14 Nov 2025 05:41:45 +0000 Subject: [PATCH 499/745] chore(deps): update actions/setup-java digest to 6ba5449 (#1721) 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 549aadc84..bd32c3c03 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -26,7 +26,7 @@ jobs: fetch-depth: 0 submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@de5a937a1dc73fbc1a67d7d1aa4bebc1082f3190 + uses: actions/setup-java@6ba5449b7dcda52941806a19f0cf626b6420191e with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 4a1297c7d..2c79dc56d 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -25,7 +25,7 @@ jobs: submodules: recursive - name: Set up JDK ${{ matrix.build.java }} - uses: actions/setup-java@de5a937a1dc73fbc1a67d7d1aa4bebc1082f3190 + uses: actions/setup-java@6ba5449b7dcda52941806a19f0cf626b6420191e with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a8ef20057..88cd73374 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,7 +43,7 @@ jobs: submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@de5a937a1dc73fbc1a67d7d1aa4bebc1082f3190 + uses: actions/setup-java@6ba5449b7dcda52941806a19f0cf626b6420191e with: java-version: '17' distribution: 'temurin' From 4e99dc53b58865f070c8af6b1c83c0091c14c812 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 14 Nov 2025 09:37:28 +0000 Subject: [PATCH 500/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.18.1 (#1719) 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 36b73204a..92ee42d0d 100644 --- a/pom.xml +++ b/pom.xml @@ -212,7 +212,7 @@ net.bytebuddy byte-buddy - 1.18.0 + 1.18.1 test From 34f7f234c7911ff16548f9fd0ad38c8d3319c668 Mon Sep 17 00:00:00 2001 From: Philipp Fehre Date: Fri, 14 Nov 2025 11:42:30 +0100 Subject: [PATCH 501/745] chore: remove fork configuration (#1685) * fix: remove fork configuration - Added previously to get around test issues, reuseForks false and forkCount 1 are no longer needed. - configure mockito as a javaagent to remove warning on newer Java versions Signed-off-by: Philipp Fehre * fix: move mockito argLine to all test plugins surefire, failsafe, vmlens all need mockito argline to work with Java 21+ to avoid deprecated dynamic java agent loading. Signed-off-by: Philipp Fehre --------- Signed-off-by: Philipp Fehre Co-authored-by: Michael Beemer Co-authored-by: Simon Schrottner --- pom.xml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 92ee42d0d..fc5d7abd6 100644 --- a/pom.xml +++ b/pom.xml @@ -20,6 +20,8 @@ false 11 + ${settings.localRepository}/org/mockito/mockito-core/${org.mockito.version}/mockito-core-${org.mockito.version}.jar + -javaagent:${org.mockito.jar} OpenFeature Java SDK @@ -300,10 +302,9 @@ maven-surefire-plugin 3.5.4 - 1 - false ${surefireArgLine} + ${org.mockito.agent.argline} --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED @@ -321,6 +322,7 @@ ${surefireArgLine} + ${org.mockito.agent.argline} @@ -364,6 +366,7 @@ **/*CT.java true + ${org.mockito.agent.argline} @@ -740,6 +743,7 @@ 3.5.4 + ${org.mockito.agent.argline} ${surefireArgLine} From 3e5977a7f67349e67790db786d018bdf91eee1a2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 14 Nov 2025 19:11:54 +0000 Subject: [PATCH 502/745] chore(deps): update github/codeql-action digest to 85f1517 (#1722) 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 2c79dc56d..06a88361d 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@ba454b8ab46733eb6145342877cd148270bb77ab + uses: github/codeql-action/init@85f1517bb46a9e4d5e1ad15a6ef251b3124ba42b with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ba454b8ab46733eb6145342877cd148270bb77ab + uses: github/codeql-action/analyze@85f1517bb46a9e4d5e1ad15a6ef251b3124ba42b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 5e08f906a..873321f54 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@ba454b8ab46733eb6145342877cd148270bb77ab + uses: github/codeql-action/init@85f1517bb46a9e4d5e1ad15a6ef251b3124ba42b with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@ba454b8ab46733eb6145342877cd148270bb77ab + uses: github/codeql-action/autobuild@85f1517bb46a9e4d5e1ad15a6ef251b3124ba42b - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ba454b8ab46733eb6145342877cd148270bb77ab + uses: github/codeql-action/analyze@85f1517bb46a9e4d5e1ad15a6ef251b3124ba42b From 43d926656d042b5fddb8d386fa603fbfa61ef42d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 15 Nov 2025 00:32:42 +0000 Subject: [PATCH 503/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.18.1 (#1720) 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 fc5d7abd6..1644709ce 100644 --- a/pom.xml +++ b/pom.xml @@ -221,7 +221,7 @@ net.bytebuddy byte-buddy-agent - 1.18.0 + 1.18.1 test From 6cdd8d062cfcb58204c4037c679b1da08b520589 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 15 Nov 2025 12:31:20 +0000 Subject: [PATCH 504/745] chore(deps): update dependency org.apache.maven.plugins:maven-jar-plugin to v3.5.0 (#1724) 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 1644709ce..5d643a938 100644 --- a/pom.xml +++ b/pom.xml @@ -331,7 +331,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.4.2 + 3.5.0 From 6ba620c6728c2daa6652ac791de0cc72a38393f5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 16 Nov 2025 21:38:36 +0000 Subject: [PATCH 505/745] chore(deps): update github/codeql-action digest to c1a2b73 (#1725) 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 06a88361d..f0fbf5e62 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@85f1517bb46a9e4d5e1ad15a6ef251b3124ba42b + uses: github/codeql-action/init@c1a2b73420f0c02efb863cc6921c531bc1a54f4f with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@85f1517bb46a9e4d5e1ad15a6ef251b3124ba42b + uses: github/codeql-action/analyze@c1a2b73420f0c02efb863cc6921c531bc1a54f4f diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 873321f54..fee69ee36 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@85f1517bb46a9e4d5e1ad15a6ef251b3124ba42b + uses: github/codeql-action/init@c1a2b73420f0c02efb863cc6921c531bc1a54f4f with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@85f1517bb46a9e4d5e1ad15a6ef251b3124ba42b + uses: github/codeql-action/autobuild@c1a2b73420f0c02efb863cc6921c531bc1a54f4f - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@85f1517bb46a9e4d5e1ad15a6ef251b3124ba42b + uses: github/codeql-action/analyze@c1a2b73420f0c02efb863cc6921c531bc1a54f4f From 8621f39baf267c1092ab3ec9e8ad781898e59cdb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Nov 2025 09:08:40 +0100 Subject: [PATCH 506/745] chore(deps): update github/codeql-action digest to ffa63f0 (#1727) 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 f0fbf5e62..69618f9eb 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@c1a2b73420f0c02efb863cc6921c531bc1a54f4f + uses: github/codeql-action/init@ffa63f0dac7bf42e00061d972fa89c8c81288540 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c1a2b73420f0c02efb863cc6921c531bc1a54f4f + uses: github/codeql-action/analyze@ffa63f0dac7bf42e00061d972fa89c8c81288540 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index fee69ee36..ff793f6d6 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@c1a2b73420f0c02efb863cc6921c531bc1a54f4f + uses: github/codeql-action/init@ffa63f0dac7bf42e00061d972fa89c8c81288540 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@c1a2b73420f0c02efb863cc6921c531bc1a54f4f + uses: github/codeql-action/autobuild@ffa63f0dac7bf42e00061d972fa89c8c81288540 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c1a2b73420f0c02efb863cc6921c531bc1a54f4f + uses: github/codeql-action/analyze@ffa63f0dac7bf42e00061d972fa89c8c81288540 From bd70a3a147b25d17a7326a945475101f2c586a16 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Nov 2025 08:13:36 +0000 Subject: [PATCH 507/745] chore(deps): update actions/setup-java digest to 66b9457 (#1726) 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 bd32c3c03..0526844ee 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -26,7 +26,7 @@ jobs: fetch-depth: 0 submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@6ba5449b7dcda52941806a19f0cf626b6420191e + uses: actions/setup-java@66b945764b75604b3cfd644c3ada5232cf6c90c6 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 69618f9eb..a025ed10c 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -25,7 +25,7 @@ jobs: submodules: recursive - name: Set up JDK ${{ matrix.build.java }} - uses: actions/setup-java@6ba5449b7dcda52941806a19f0cf626b6420191e + uses: actions/setup-java@66b945764b75604b3cfd644c3ada5232cf6c90c6 with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 88cd73374..6f8894a99 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,7 +43,7 @@ jobs: submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@6ba5449b7dcda52941806a19f0cf626b6420191e + uses: actions/setup-java@66b945764b75604b3cfd644c3ada5232cf6c90c6 with: java-version: '17' distribution: 'temurin' From c8c4426f50ea77d77630e2e3bff707a1332126f4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 19 Nov 2025 05:30:11 +0000 Subject: [PATCH 508/745] chore(deps): update actions/setup-java digest to 46c56d6 (#1729) 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 0526844ee..2df4c2838 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -26,7 +26,7 @@ jobs: fetch-depth: 0 submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@66b945764b75604b3cfd644c3ada5232cf6c90c6 + uses: actions/setup-java@46c56d6f92c88cf540acf95a12a4a41197499222 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index a025ed10c..8e7d1975f 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -25,7 +25,7 @@ jobs: submodules: recursive - name: Set up JDK ${{ matrix.build.java }} - uses: actions/setup-java@66b945764b75604b3cfd644c3ada5232cf6c90c6 + uses: actions/setup-java@46c56d6f92c88cf540acf95a12a4a41197499222 with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6f8894a99..e6ffa117f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,7 +43,7 @@ jobs: submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@66b945764b75604b3cfd644c3ada5232cf6c90c6 + uses: actions/setup-java@46c56d6f92c88cf540acf95a12a4a41197499222 with: java-version: '17' distribution: 'temurin' From 71e4b2fd04f13fd5f6a1aaee9899177d963b2346 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 19 Nov 2025 08:31:45 +0100 Subject: [PATCH 509/745] chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3.1.0 (#1730) 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 5d643a938..07e78eb42 100644 --- a/pom.xml +++ b/pom.xml @@ -524,7 +524,7 @@ com.diffplug.spotless spotless-maven-plugin - 3.0.0 + 3.1.0 From 63cd1ef568137e75a4ada7d7da097ad3d5e79a03 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 19 Nov 2025 07:36:20 +0000 Subject: [PATCH 510/745] chore(deps): update github/codeql-action digest to 378219c (#1728) 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 8e7d1975f..c13efce38 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@ffa63f0dac7bf42e00061d972fa89c8c81288540 + uses: github/codeql-action/init@378219ced27d0034fb5243e6fb8495a1f0afefe7 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ffa63f0dac7bf42e00061d972fa89c8c81288540 + uses: github/codeql-action/analyze@378219ced27d0034fb5243e6fb8495a1f0afefe7 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index ff793f6d6..c589d7fdc 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@ffa63f0dac7bf42e00061d972fa89c8c81288540 + uses: github/codeql-action/init@378219ced27d0034fb5243e6fb8495a1f0afefe7 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@ffa63f0dac7bf42e00061d972fa89c8c81288540 + uses: github/codeql-action/autobuild@378219ced27d0034fb5243e6fb8495a1f0afefe7 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ffa63f0dac7bf42e00061d972fa89c8c81288540 + uses: github/codeql-action/analyze@378219ced27d0034fb5243e6fb8495a1f0afefe7 From 1c7728d4d6d220c2285fe633d73ce1442d430999 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 19 Nov 2025 14:52:34 +0100 Subject: [PATCH 511/745] chore(deps): update github/codeql-action digest to ce07e7d (#1731) 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 c13efce38..72f5eaa79 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@378219ced27d0034fb5243e6fb8495a1f0afefe7 + uses: github/codeql-action/init@ce07e7d196a4955bc4cd530d1d854faa5818e5e4 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@378219ced27d0034fb5243e6fb8495a1f0afefe7 + uses: github/codeql-action/analyze@ce07e7d196a4955bc4cd530d1d854faa5818e5e4 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index c589d7fdc..977fc8099 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@378219ced27d0034fb5243e6fb8495a1f0afefe7 + uses: github/codeql-action/init@ce07e7d196a4955bc4cd530d1d854faa5818e5e4 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@378219ced27d0034fb5243e6fb8495a1f0afefe7 + uses: github/codeql-action/autobuild@ce07e7d196a4955bc4cd530d1d854faa5818e5e4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@378219ced27d0034fb5243e6fb8495a1f0afefe7 + uses: github/codeql-action/analyze@ce07e7d196a4955bc4cd530d1d854faa5818e5e4 From 1897a5bba3c3021ab17be3749e9fd3db0dc341a3 Mon Sep 17 00:00:00 2001 From: Jonathan Norris Date: Wed, 19 Nov 2025 10:11:14 -0500 Subject: [PATCH 512/745] chore: update LICENSE copyright notice (#1723) * chore: update LICENSE copyright notice Signed-off-by: Jonathan Norris * chore: add .cursor to .gitignore Signed-off-by: Jonathan Norris * chore: remove year from copyright Signed-off-by: Jonathan Norris --------- Signed-off-by: Jonathan Norris --- .gitignore | 1 + LICENSE | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a7575d545..dfc5642e5 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ target # vscode stuff - we may want to use a more specific pattern later if we'd like to suggest editor configurations .vscode/ +.cursor # used for spec compliance tooling java-report.json diff --git a/LICENSE b/LICENSE index 261eeb9e9..96b3dc8fc 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright OpenFeature Maintainers Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From ea5899776a924106de99ed7d993216b1c3140281 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 19 Nov 2025 16:46:21 +0100 Subject: [PATCH 513/745] chore(deps): update github/codeql-action digest to 0b43179 (#1732) 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 72f5eaa79..d650f9e70 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@ce07e7d196a4955bc4cd530d1d854faa5818e5e4 + uses: github/codeql-action/init@0b4317954f4f86bf5df18ed38d9987fb1d2ec4ad with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ce07e7d196a4955bc4cd530d1d854faa5818e5e4 + uses: github/codeql-action/analyze@0b4317954f4f86bf5df18ed38d9987fb1d2ec4ad diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 977fc8099..b8dd599a4 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@ce07e7d196a4955bc4cd530d1d854faa5818e5e4 + uses: github/codeql-action/init@0b4317954f4f86bf5df18ed38d9987fb1d2ec4ad with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@ce07e7d196a4955bc4cd530d1d854faa5818e5e4 + uses: github/codeql-action/autobuild@0b4317954f4f86bf5df18ed38d9987fb1d2ec4ad - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ce07e7d196a4955bc4cd530d1d854faa5818e5e4 + uses: github/codeql-action/analyze@0b4317954f4f86bf5df18ed38d9987fb1d2ec4ad From 2bc3d4f7c1284105cdf9cdc1c736ab23d26380b6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 19 Nov 2025 16:50:51 +0000 Subject: [PATCH 514/745] chore(deps): update github/codeql-action digest to ce729e4 (#1733) 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 d650f9e70..ff3c98f8c 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@0b4317954f4f86bf5df18ed38d9987fb1d2ec4ad + uses: github/codeql-action/init@ce729e4d353d580e6cacd6a8cf2921b72e5e310a with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0b4317954f4f86bf5df18ed38d9987fb1d2ec4ad + uses: github/codeql-action/analyze@ce729e4d353d580e6cacd6a8cf2921b72e5e310a diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index b8dd599a4..04068c3ae 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@0b4317954f4f86bf5df18ed38d9987fb1d2ec4ad + uses: github/codeql-action/init@ce729e4d353d580e6cacd6a8cf2921b72e5e310a with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@0b4317954f4f86bf5df18ed38d9987fb1d2ec4ad + uses: github/codeql-action/autobuild@ce729e4d353d580e6cacd6a8cf2921b72e5e310a - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0b4317954f4f86bf5df18ed38d9987fb1d2ec4ad + uses: github/codeql-action/analyze@ce729e4d353d580e6cacd6a8cf2921b72e5e310a From d4c7907e3f3f056b8800387241e4be5e8bbdaea4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 20 Nov 2025 21:44:38 +0000 Subject: [PATCH 515/745] chore(deps): update actions/checkout digest to 1af3b93 (#1735) 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 +- .github/workflows/static-code-scanning.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index 2df4c2838..8c978f625 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@71cf2267d89c5cb81562390fa70a37fa40b1305e + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 with: fetch-depth: 0 submodules: recursive diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index ff3c98f8c..7e815801d 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -19,7 +19,7 @@ jobs: runs-on: ${{ matrix.os}} steps: - name: Check out the code - uses: actions/checkout@71cf2267d89c5cb81562390fa70a37fa40b1305e + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 with: fetch-depth: 0 submodules: recursive diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e6ffa117f..841441307 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,7 +37,7 @@ jobs: steps: - name: Checkout Repository - uses: actions/checkout@71cf2267d89c5cb81562390fa70a37fa40b1305e + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 with: fetch-depth: 0 submodules: recursive diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 04068c3ae..c2de02806 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@71cf2267d89c5cb81562390fa70a37fa40b1305e + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL From 0de4bb6a2460f9a94adeb56605acc0948a5819c7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 21 Nov 2025 10:59:49 +0000 Subject: [PATCH 516/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.32.0 (#1736) 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 07e78eb42..b5811d458 100644 --- a/pom.xml +++ b/pom.xml @@ -237,7 +237,7 @@ io.cucumber cucumber-bom - 7.31.0 + 7.32.0 pom import From ef29b498c38ee1ffea60825001b088ccee3d7c29 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 00:50:54 +0000 Subject: [PATCH 517/745] chore(deps): update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.8.2 (#1737) 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 b5811d458..6af087035 100644 --- a/pom.xml +++ b/pom.xml @@ -464,7 +464,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.9.8.1 + 4.9.8.2 spotbugs-exclusions.xml From 6f02e840bca6106d1e7e3c6c1a55a5955746da0b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 08:55:25 +0100 Subject: [PATCH 518/745] chore(deps): update actions/checkout digest to c2d88d3 (#1738) 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 +- .github/workflows/static-code-scanning.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index 8c978f625..92db3df4e 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 + - uses: actions/checkout@c2d88d3ecc89a9ef08eebf45d9637801dcee7eb5 with: fetch-depth: 0 submodules: recursive diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 7e815801d..241c8e1b6 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -19,7 +19,7 @@ jobs: runs-on: ${{ matrix.os}} steps: - name: Check out the code - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 + uses: actions/checkout@c2d88d3ecc89a9ef08eebf45d9637801dcee7eb5 with: fetch-depth: 0 submodules: recursive diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 841441307..21bb12b81 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,7 +37,7 @@ jobs: steps: - name: Checkout Repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 + uses: actions/checkout@c2d88d3ecc89a9ef08eebf45d9637801dcee7eb5 with: fetch-depth: 0 submodules: recursive diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index c2de02806..ae541e236 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 + uses: actions/checkout@c2d88d3ecc89a9ef08eebf45d9637801dcee7eb5 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL From 537a81bdad1a2ab6126277f2622dbb605bfc1699 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 13:43:03 +0100 Subject: [PATCH 519/745] chore(deps): update github/codeql-action digest to ec2ee57 (#1739) 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 241c8e1b6..215aeb6f3 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@ce729e4d353d580e6cacd6a8cf2921b72e5e310a + uses: github/codeql-action/init@ec2ee575c053869d197f516146096427e08da443 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ce729e4d353d580e6cacd6a8cf2921b72e5e310a + uses: github/codeql-action/analyze@ec2ee575c053869d197f516146096427e08da443 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index ae541e236..ac57282ee 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@ce729e4d353d580e6cacd6a8cf2921b72e5e310a + uses: github/codeql-action/init@ec2ee575c053869d197f516146096427e08da443 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@ce729e4d353d580e6cacd6a8cf2921b72e5e310a + uses: github/codeql-action/autobuild@ec2ee575c053869d197f516146096427e08da443 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ce729e4d353d580e6cacd6a8cf2921b72e5e310a + uses: github/codeql-action/analyze@ec2ee575c053869d197f516146096427e08da443 From 169415e30aef814841ea0251770d693658635434 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 15:04:42 +0100 Subject: [PATCH 520/745] chore(deps): update github/codeql-action digest to 52f930e (#1740) 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 215aeb6f3..1c8d8a7bc 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@ec2ee575c053869d197f516146096427e08da443 + uses: github/codeql-action/init@52f930e50a5971cb8a0163b8ae04f2344c26154c with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ec2ee575c053869d197f516146096427e08da443 + uses: github/codeql-action/analyze@52f930e50a5971cb8a0163b8ae04f2344c26154c diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index ac57282ee..10c0bad33 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@ec2ee575c053869d197f516146096427e08da443 + uses: github/codeql-action/init@52f930e50a5971cb8a0163b8ae04f2344c26154c with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@ec2ee575c053869d197f516146096427e08da443 + uses: github/codeql-action/autobuild@52f930e50a5971cb8a0163b8ae04f2344c26154c - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ec2ee575c053869d197f516146096427e08da443 + uses: github/codeql-action/analyze@52f930e50a5971cb8a0163b8ae04f2344c26154c From 21df7b3b012f189139f9bd39103b9a683b654bd7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Nov 2025 16:03:44 +0100 Subject: [PATCH 521/745] chore(deps): update github/codeql-action digest to 0e52774 (#1742) 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 1c8d8a7bc..ff0104e79 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@52f930e50a5971cb8a0163b8ae04f2344c26154c + uses: github/codeql-action/init@0e52774aee3a99ebade1d021ab7e132c6f8058bf with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@52f930e50a5971cb8a0163b8ae04f2344c26154c + uses: github/codeql-action/analyze@0e52774aee3a99ebade1d021ab7e132c6f8058bf diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 10c0bad33..b37ab6b26 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@52f930e50a5971cb8a0163b8ae04f2344c26154c + uses: github/codeql-action/init@0e52774aee3a99ebade1d021ab7e132c6f8058bf with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@52f930e50a5971cb8a0163b8ae04f2344c26154c + uses: github/codeql-action/autobuild@0e52774aee3a99ebade1d021ab7e132c6f8058bf - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@52f930e50a5971cb8a0163b8ae04f2344c26154c + uses: github/codeql-action/analyze@0e52774aee3a99ebade1d021ab7e132c6f8058bf From 6de54e31a783663da04e6d94ca19a69a85c64bc8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Nov 2025 04:43:20 +0000 Subject: [PATCH 522/745] chore(deps): update actions/setup-java digest to 4e7e684 (#1743) 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 92db3df4e..9ad63fc03 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -26,7 +26,7 @@ jobs: fetch-depth: 0 submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@46c56d6f92c88cf540acf95a12a4a41197499222 + uses: actions/setup-java@4e7e684fbb6e33f88ecb2cf1e6b3797739cf499b with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index ff0104e79..4ab0f576e 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -25,7 +25,7 @@ jobs: submodules: recursive - name: Set up JDK ${{ matrix.build.java }} - uses: actions/setup-java@46c56d6f92c88cf540acf95a12a4a41197499222 + uses: actions/setup-java@4e7e684fbb6e33f88ecb2cf1e6b3797739cf499b with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 21bb12b81..1c6148efc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,7 +43,7 @@ jobs: submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@46c56d6f92c88cf540acf95a12a4a41197499222 + uses: actions/setup-java@4e7e684fbb6e33f88ecb2cf1e6b3797739cf499b with: java-version: '17' distribution: 'temurin' From 0f8125e1f2f2e3c2cb145db5b9b07659b397fcb3 Mon Sep 17 00:00:00 2001 From: chrfwow Date: Wed, 26 Nov 2025 18:08:14 +0100 Subject: [PATCH 523/745] feat: Layered context to reduce memory churn (#1717) * add bench Signed-off-by: christian.lutnik * fix bench Signed-off-by: christian.lutnik * merge master Signed-off-by: christian.lutnik * improve benchmark Signed-off-by: christian.lutnik * improve benchmark Signed-off-by: christian.lutnik * layered context Signed-off-by: christian.lutnik * add tests Signed-off-by: christian.lutnik * add merge Signed-off-by: christian.lutnik * add tests Signed-off-by: christian.lutnik * lazy init hook ctx Signed-off-by: christian.lutnik * use list for hook ctx Signed-off-by: christian.lutnik * add str hook for ctx Signed-off-by: christian.lutnik * spotless Signed-off-by: christian.lutnik * spotless Signed-off-by: christian.lutnik * improve as map Signed-off-by: christian.lutnik * improve tests Signed-off-by: christian.lutnik * spotless Signed-off-by: christian.lutnik * remove deprectaed notice Signed-off-by: christian.lutnik * check if hook context is empty Signed-off-by: christian.lutnik * revert comments Signed-off-by: christian.lutnik --------- Signed-off-by: christian.lutnik Co-authored-by: Todd Baert --- .../java/dev/openfeature/sdk/HookSupport.java | 41 +- .../dev/openfeature/sdk/HookSupportData.java | 2 +- .../sdk/LayeredEvaluationContext.java | 269 ++++++++++++ .../openfeature/sdk/OpenFeatureClient.java | 11 +- .../dev/openfeature/sdk/HookSpecTest.java | 2 +- .../dev/openfeature/sdk/HookSupportTest.java | 15 +- .../sdk/LayeredEvaluationContextTest.java | 401 ++++++++++++++++++ .../sdk/OpenFeatureClientTest.java | 51 +++ .../sdk/benchmark/AllocationBenchmark.java | 60 +++ .../benchmark/AllocationBenchmarkState.java | 63 +++ 10 files changed, 878 insertions(+), 37 deletions(-) create mode 100644 src/main/java/dev/openfeature/sdk/LayeredEvaluationContext.java create mode 100644 src/test/java/dev/openfeature/sdk/LayeredEvaluationContextTest.java create mode 100644 src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmarkState.java diff --git a/src/main/java/dev/openfeature/sdk/HookSupport.java b/src/main/java/dev/openfeature/sdk/HookSupport.java index c7a7630da..41d36be6a 100644 --- a/src/main/java/dev/openfeature/sdk/HookSupport.java +++ b/src/main/java/dev/openfeature/sdk/HookSupport.java @@ -17,9 +17,9 @@ class HookSupport { * Sets the {@link Hook}-{@link HookContext}-{@link Pair} list in the given data object with {@link HookContext} * set to null. Filters hooks by supported {@link FlagValueType}. * - * @param hookSupportData the data object to modify - * @param hooks the hooks to set - * @param type the flag value type to filter unsupported hooks + * @param hookSupportData the data object to modify + * @param hooks the hooks to set + * @param type the flag value type to filter unsupported hooks */ public void setHooks(HookSupportData hookSupportData, List hooks, FlagValueType type) { List> hookContextPairs = new ArrayList<>(); @@ -35,35 +35,20 @@ public void setHooks(HookSupportData hookSupportData, List hooks, FlagValu * Creates & sets a {@link HookContext} for every {@link Hook}-{@link HookContext}-{@link Pair} * in the given data object with a new {@link HookData} instance. * - * @param hookSupportData the data object to modify - * @param sharedContext the shared context from which the new {@link HookContext} is created + * @param hookSupportData the data object to modify + * @param sharedContext the shared context from which the new {@link HookContext} is created */ - public void setHookContexts(HookSupportData hookSupportData, SharedHookContext sharedContext) { + public void setHookContexts( + HookSupportData hookSupportData, + SharedHookContext sharedContext, + LayeredEvaluationContext evaluationContext) { for (int i = 0; i < hookSupportData.hooks.size(); i++) { Pair hookContextPair = hookSupportData.hooks.get(i); - HookContext curHookContext = sharedContext.hookContextFor(null, new DefaultHookData()); + HookContext curHookContext = sharedContext.hookContextFor(evaluationContext, new DefaultHookData()); hookContextPair.setValue(curHookContext); } } - /** - * Updates the evaluation context in the given data object's eval context and each hooks eval context. - * - * @param hookSupportData the data object to modify - * @param evaluationContext the new context to set - */ - public void updateEvaluationContext(HookSupportData hookSupportData, EvaluationContext evaluationContext) { - hookSupportData.evaluationContext = evaluationContext; - if (hookSupportData.hooks != null) { - for (Pair hookContextPair : hookSupportData.hooks) { - var curHookContext = hookContextPair.getValue(); - if (curHookContext != null) { - curHookContext.setCtx(evaluationContext); - } - } - } - } - public void executeBeforeHooks(HookSupportData data) { // These traverse backwards from normal. List> reversedHooks = new ArrayList<>(data.getHooks()); @@ -77,8 +62,10 @@ public void executeBeforeHooks(HookSupportData data) { hook.before(hookContext, data.getHints())) .orElse(Optional.empty()); if (returnedEvalContext.isPresent()) { - // update shared evaluation context for all hooks - updateEvaluationContext(data, data.getEvaluationContext().merge(returnedEvalContext.get())); + var returnedContext = returnedEvalContext.get(); + if (!returnedContext.isEmpty()) { + data.evaluationContext.putHookContext(returnedContext); + } } } } diff --git a/src/main/java/dev/openfeature/sdk/HookSupportData.java b/src/main/java/dev/openfeature/sdk/HookSupportData.java index 2d3346ba1..174702ea2 100644 --- a/src/main/java/dev/openfeature/sdk/HookSupportData.java +++ b/src/main/java/dev/openfeature/sdk/HookSupportData.java @@ -11,7 +11,7 @@ class HookSupportData { List> hooks; - EvaluationContext evaluationContext; + LayeredEvaluationContext evaluationContext; Map hints; HookSupportData() {} diff --git a/src/main/java/dev/openfeature/sdk/LayeredEvaluationContext.java b/src/main/java/dev/openfeature/sdk/LayeredEvaluationContext.java new file mode 100644 index 000000000..bdd81f8c3 --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/LayeredEvaluationContext.java @@ -0,0 +1,269 @@ +package dev.openfeature.sdk; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * LayeredEvaluationContext implements EvaluationContext by layering multiple contexts: + * API-level, Transaction-level, Client-level, Invocation-level, and Hook-level. + * The contexts are checked in that order for values, with Hook-level having the highest precedence. + */ +public class LayeredEvaluationContext implements EvaluationContext { + private final EvaluationContext apiContext; + private final EvaluationContext transactionContext; + private final EvaluationContext clientContext; + private final EvaluationContext invocationContext; + + private ArrayList hookContexts; + private String targetingKey; + private Set keySet = null; + + /** + * Constructor for LayeredEvaluationContext. + */ + public LayeredEvaluationContext( + EvaluationContext apiContext, + EvaluationContext transactionContext, + EvaluationContext clientContext, + EvaluationContext invocationContext) { + this.apiContext = apiContext; + this.transactionContext = transactionContext; + this.clientContext = clientContext; + this.invocationContext = invocationContext; + + if (invocationContext != null && invocationContext.getTargetingKey() != null) { + this.targetingKey = invocationContext.getTargetingKey(); + } else if (clientContext != null && clientContext.getTargetingKey() != null) { + this.targetingKey = clientContext.getTargetingKey(); + } else if (transactionContext != null && transactionContext.getTargetingKey() != null) { + this.targetingKey = transactionContext.getTargetingKey(); + } else if (apiContext != null && apiContext.getTargetingKey() != null) { + this.targetingKey = apiContext.getTargetingKey(); + } else { + this.targetingKey = null; + } + } + + @Override + public String getTargetingKey() { + return targetingKey; + } + + @Override + public EvaluationContext merge(EvaluationContext overridingContext) { + var merged = new LayeredEvaluationContext(apiContext, transactionContext, clientContext, invocationContext); + + if (this.hookContexts == null) { + merged.hookContexts = new ArrayList<>(1); + } else { + merged.hookContexts = new ArrayList<>(this.hookContexts.size() + 1); + merged.hookContexts.addAll(this.hookContexts); + } + merged.hookContexts.add(overridingContext); + + var otherTargetingKey = overridingContext.getTargetingKey(); + if (otherTargetingKey != null) { + merged.targetingKey = otherTargetingKey; + } + return merged; + } + + @Override + public boolean isEmpty() { + return (invocationContext == null || invocationContext.isEmpty()) + && (clientContext == null || clientContext.isEmpty()) + && (transactionContext == null || transactionContext.isEmpty()) + && (apiContext == null || apiContext.isEmpty()) + && areHookContextsEmpty(); + } + + private boolean areHookContextsEmpty() { + if (hookContexts == null || hookContexts.isEmpty()) { + return true; + } + + for (int i = 0; i < hookContexts.size(); i++) { + var current = hookContexts.get(i); + if (!current.isEmpty()) { + return false; + } + } + + return true; + } + + @Override + public Set keySet() { + return Collections.unmodifiableSet(ensureKeySet()); + } + + private Set ensureKeySet() { + if (this.keySet != null) { + return this.keySet; + } + + var keys = new HashSet(); + + if (hookContexts != null) { + for (int i = 0; i < hookContexts.size(); i++) { + var current = hookContexts.get(i); + keys.addAll(current.keySet()); + } + } + + if (invocationContext != null) { + keys.addAll(invocationContext.keySet()); + } + if (clientContext != null) { + keys.addAll(clientContext.keySet()); + } + if (transactionContext != null) { + keys.addAll(transactionContext.keySet()); + } + if (apiContext != null) { + keys.addAll(apiContext.keySet()); + } + this.keySet = keys; + return keys; + } + + private Value getFromContext(EvaluationContext context, String key) { + if (context != null) { + return context.getValue(key); + } + return null; + } + + private Value getFromContext(ArrayList context, String key) { + if (context == null) { + return null; + } + + for (int i = context.size() - 1; i >= 0; i--) { + var current = context.get(i); + var value = getFromContext(current, key); + if (value != null) { + return value; + } + } + return null; + } + + @Override + public Value getValue(String key) { + var hookValue = getFromContext(hookContexts, key); + if (hookValue != null) { + return hookValue; + } + var invocationValue = getFromContext(invocationContext, key); + if (invocationValue != null) { + return invocationValue; + } + var clientValue = getFromContext(clientContext, key); + if (clientValue != null) { + return clientValue; + } + var transactionValue = getFromContext(transactionContext, key); + if (transactionValue != null) { + return transactionValue; + } + return getFromContext(apiContext, key); + } + + @Override + public Map asMap() { + if (keySet != null && keySet.isEmpty()) { + return new HashMap<>(0); + } + + HashMap map; + if (keySet != null) { + map = new HashMap<>(keySet.size()); + } else { + map = new HashMap<>(); + } + + if (apiContext != null) { + map.putAll(apiContext.asMap()); + } + if (transactionContext != null) { + map.putAll(transactionContext.asMap()); + } + if (clientContext != null) { + map.putAll(clientContext.asMap()); + } + if (invocationContext != null) { + map.putAll(invocationContext.asMap()); + } + if (hookContexts != null) { + for (int i = 0; i < hookContexts.size(); i++) { + EvaluationContext hookContext = hookContexts.get(i); + map.putAll(hookContext.asMap()); + } + } + return map; + } + + @Override + public Map asUnmodifiableMap() { + if (keySet != null && keySet.isEmpty()) { + return Collections.emptyMap(); + } + + return Collections.unmodifiableMap(asMap()); + } + + @Override + public Map asObjectMap() { + if (keySet != null && keySet.isEmpty()) { + return new HashMap<>(0); + } + + HashMap map; + if (keySet != null) { + map = new HashMap<>(keySet.size()); + } else { + map = new HashMap<>(); + } + + if (apiContext != null) { + map.putAll(apiContext.asObjectMap()); + } + if (transactionContext != null) { + map.putAll(transactionContext.asObjectMap()); + } + if (clientContext != null) { + map.putAll(clientContext.asObjectMap()); + } + if (invocationContext != null) { + map.putAll(invocationContext.asObjectMap()); + } + if (hookContexts != null) { + for (int i = 0; i < hookContexts.size(); i++) { + EvaluationContext hookContext = hookContexts.get(i); + map.putAll(hookContext.asObjectMap()); + } + } + return map; + } + + void putHookContext(EvaluationContext context) { + if (context == null || context.isEmpty()) { + return; + } + + var targetingKey = context.getTargetingKey(); + if (targetingKey != null) { + this.targetingKey = targetingKey; + } + if (this.hookContexts == null) { + this.hookContexts = new ArrayList<>(); + } + this.hookContexts.add(context); + this.keySet = null; + } +} diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index 614bc1e34..c5548b394 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -166,6 +166,12 @@ private FlagEvaluationDetails evaluateFlag( var flagOptions = ObjectUtils.defaultIfNull( options, () -> FlagEvaluationOptions.builder().build()); hookSupportData.hints = Collections.unmodifiableMap(flagOptions.getHookHints()); + var context = new LayeredEvaluationContext( + openfeatureApi.getEvaluationContext(), + openfeatureApi.getTransactionContext(), + evaluationContext.get(), + ctx); + hookSupportData.evaluationContext = context; try { final var stateManager = openfeatureApi.getFeatureProviderStateManager(this.domain); @@ -180,10 +186,7 @@ private FlagEvaluationDetails evaluateFlag( var sharedHookContext = new SharedHookContext(key, type, this.getMetadata(), provider.getMetadata(), defaultValue); - hookSupport.setHookContexts(hookSupportData, sharedHookContext); - - var evalContext = mergeEvaluationContext(ctx); - hookSupport.updateEvaluationContext(hookSupportData, evalContext); + hookSupport.setHookContexts(hookSupportData, sharedHookContext, context); hookSupport.executeBeforeHooks(hookSupportData); diff --git a/src/test/java/dev/openfeature/sdk/HookSpecTest.java b/src/test/java/dev/openfeature/sdk/HookSpecTest.java index 163007120..69e47f353 100644 --- a/src/test/java/dev/openfeature/sdk/HookSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSpecTest.java @@ -723,7 +723,7 @@ void mergeHappensCorrectly() { invocationCtx, FlagEvaluationOptions.builder().hook(hook).build()); - ArgumentCaptor captor = ArgumentCaptor.forClass(ImmutableContext.class); + ArgumentCaptor captor = ArgumentCaptor.forClass(LayeredEvaluationContext.class); verify(provider).getBooleanEvaluation(any(), any(), captor.capture()); EvaluationContext ec = captor.getValue(); assertEquals("works", ec.getValue("test").asString()); diff --git a/src/test/java/dev/openfeature/sdk/HookSupportTest.java b/src/test/java/dev/openfeature/sdk/HookSupportTest.java index b1bb70ba1..ef8dcc396 100644 --- a/src/test/java/dev/openfeature/sdk/HookSupportTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSupportTest.java @@ -33,11 +33,12 @@ void shouldMergeEvaluationContextsOnBeforeHooksCorrectly() { when(hook1.before(any(), any())).thenReturn(Optional.of(evaluationContextWithValue("bla", "blubber"))); when(hook2.before(any(), any())).thenReturn(Optional.of(evaluationContextWithValue("foo", "bar"))); + var layered = new LayeredEvaluationContext(baseEvalContext, null, null, null); var sharedContext = getBaseHookContextForType(FlagValueType.STRING); var hookSupportData = new HookSupportData(); + hookSupportData.evaluationContext = layered; hookSupport.setHooks(hookSupportData, Arrays.asList(hook1, hook2), FlagValueType.STRING); - hookSupport.setHookContexts(hookSupportData, sharedContext); - hookSupport.updateEvaluationContext(hookSupportData, baseEvalContext); + hookSupport.setHookContexts(hookSupportData, sharedContext, layered); hookSupport.executeBeforeHooks(hookSupportData); @@ -72,7 +73,10 @@ void shouldPassDataAcrossStages(FlagValueType flagValueType) { var testHook = new TestHookWithData(); var hookSupportData = new HookSupportData(); hookSupport.setHooks(hookSupportData, List.of(testHook), flagValueType); - hookSupport.setHookContexts(hookSupportData, getBaseHookContextForType(flagValueType)); + hookSupport.setHookContexts( + hookSupportData, + getBaseHookContextForType(flagValueType), + new LayeredEvaluationContext(null, null, null, null)); hookSupport.executeBeforeHooks(hookSupportData); assertHookData(testHook, "before"); @@ -98,7 +102,10 @@ void shouldIsolateDataBetweenHooks(FlagValueType flagValueType) { var hookSupportData = new HookSupportData(); hookSupport.setHooks(hookSupportData, List.of(testHook1, testHook2), flagValueType); - hookSupport.setHookContexts(hookSupportData, getBaseHookContextForType(flagValueType)); + hookSupport.setHookContexts( + hookSupportData, + getBaseHookContextForType(flagValueType), + new LayeredEvaluationContext(null, null, null, null)); callAllHooks(hookSupportData); diff --git a/src/test/java/dev/openfeature/sdk/LayeredEvaluationContextTest.java b/src/test/java/dev/openfeature/sdk/LayeredEvaluationContextTest.java new file mode 100644 index 000000000..7eecd9abd --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/LayeredEvaluationContextTest.java @@ -0,0 +1,401 @@ +package dev.openfeature.sdk; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.Map; +import java.util.Set; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class LayeredEvaluationContextTest { + final EvaluationContext apiContext = + new MutableContext("api-level", Map.of("api", new Value("api"), "override", new Value("api"))); + final EvaluationContext transactionContext = new MutableContext( + "transaction-level", Map.of("transaction", new Value("transaction"), "override", new Value("transaction"))); + final EvaluationContext clientContext = + new MutableContext("client-level", Map.of("client", new Value("client"), "override", new Value("client"))); + final EvaluationContext invocationContext = new MutableContext( + "invocation-level", Map.of("invocation", new Value("invocation"), "override", new Value("invocation"))); + final EvaluationContext hookContext = + new MutableContext("hook-level", Map.of("hook", new Value("hook"), "override", new Value("hook"))); + + @Test + void creatingLayeredContextWithNullsWorks() { + LayeredEvaluationContext layeredContext = new LayeredEvaluationContext(null, null, null, null); + assertNotNull(layeredContext); + assertNull(layeredContext.getTargetingKey()); + assertEquals(Map.of(), layeredContext.asMap()); + assertEquals(Map.of(), layeredContext.asObjectMap()); + assertEquals(Map.of(), layeredContext.asUnmodifiableMap()); + assertEquals(Set.of(), layeredContext.keySet()); + assertTrue(layeredContext.isEmpty()); + } + + @Test + void addingNullHookWorks() { + LayeredEvaluationContext layeredContext = new LayeredEvaluationContext(null, null, null, null); + assertDoesNotThrow(() -> layeredContext.putHookContext(null)); + } + + @Nested + class TargetingKey { + @Test + void hookWins() { + LayeredEvaluationContext layeredContext = + new LayeredEvaluationContext(apiContext, transactionContext, clientContext, invocationContext); + layeredContext.putHookContext(hookContext); + assertEquals("hook-level", layeredContext.getTargetingKey()); + } + + @Test + void hookWithoutTargetingKeyDoesNotChangeIt() { + LayeredEvaluationContext layeredContext = + new LayeredEvaluationContext(apiContext, transactionContext, clientContext, invocationContext); + layeredContext.putHookContext( + new MutableContext(Map.of("hook", new Value("hook"), "override", new Value("hook")))); + assertEquals("invocation-level", layeredContext.getTargetingKey()); + } + + @Test + void invocationWinsIfHookNotSet() { + LayeredEvaluationContext layeredContext = + new LayeredEvaluationContext(apiContext, transactionContext, clientContext, invocationContext); + assertEquals("invocation-level", layeredContext.getTargetingKey()); + } + + @Test + void clientWinsIfInvocationAndHookNotSet() { + LayeredEvaluationContext layeredContext = + new LayeredEvaluationContext(apiContext, transactionContext, clientContext, null); + assertEquals("client-level", layeredContext.getTargetingKey()); + } + + @Test + void transactionWinsIfClientInvocationAndHookNotSet() { + LayeredEvaluationContext layeredContext = + new LayeredEvaluationContext(apiContext, transactionContext, null, null); + assertEquals("transaction-level", layeredContext.getTargetingKey()); + } + + @Test + void apiWinsIfTransactionClientInvocationAndHookNotSet() { + LayeredEvaluationContext layeredContext = new LayeredEvaluationContext(apiContext, null, null, null); + assertEquals("api-level", layeredContext.getTargetingKey()); + } + } + + @Nested + class GetValue { + @Test + void doesNotOverrideUniqueValues() { + LayeredEvaluationContext layeredContext = + new LayeredEvaluationContext(apiContext, transactionContext, clientContext, invocationContext); + layeredContext.putHookContext(hookContext); + + assertEquals("hook", layeredContext.getValue("hook").asString()); + assertEquals("invocation", layeredContext.getValue("invocation").asString()); + assertEquals("client", layeredContext.getValue("client").asString()); + assertEquals("transaction", layeredContext.getValue("transaction").asString()); + assertEquals("api", layeredContext.getValue("api").asString()); + } + + @Test + void hookWins() { + LayeredEvaluationContext layeredContext = + new LayeredEvaluationContext(apiContext, transactionContext, clientContext, invocationContext); + layeredContext.putHookContext(hookContext); + assertEquals("hook", layeredContext.getValue("override").asString()); + } + + @Test + void invocationWinsIfHookNotSet() { + LayeredEvaluationContext layeredContext = + new LayeredEvaluationContext(apiContext, transactionContext, clientContext, invocationContext); + assertEquals("invocation", layeredContext.getValue("override").asString()); + } + + @Test + void clientWinsIfInvocationAndHookNotSet() { + LayeredEvaluationContext layeredContext = + new LayeredEvaluationContext(apiContext, transactionContext, clientContext, null); + assertEquals("client", layeredContext.getValue("override").asString()); + } + + @Test + void transactionWinsIfClientInvocationAndHookNotSet() { + LayeredEvaluationContext layeredContext = + new LayeredEvaluationContext(apiContext, transactionContext, null, null); + assertEquals("transaction", layeredContext.getValue("override").asString()); + } + + @Test + void apiWinsIfTransactionClientInvocationAndHookNotSet() { + LayeredEvaluationContext layeredContext = new LayeredEvaluationContext(apiContext, null, null, null); + assertEquals("api", layeredContext.getValue("override").asString()); + } + } + + @Nested + class KeySet { + @Test + void keySetIsGeneratedCorrectly() { + LayeredEvaluationContext layeredContext = + new LayeredEvaluationContext(apiContext, transactionContext, clientContext, invocationContext); + layeredContext.putHookContext(hookContext); + + Set expectedKeys = Set.of( + "hook", + "invocation", + "client", + "transaction", + "api", + "override", + "targetingKey" // expected, even though not explicitly set + ); + + assertEquals(expectedKeys, layeredContext.keySet()); + // cached key set + assertEquals(expectedKeys, layeredContext.keySet()); + } + + @Test + void keySetIsUpdatedWhenHookContextChanges() { + LayeredEvaluationContext layeredContext = + new LayeredEvaluationContext(apiContext, transactionContext, clientContext, invocationContext); + layeredContext.putHookContext(hookContext); + + Set expectedKeys = + Set.of("hook", "invocation", "client", "transaction", "api", "override", "targetingKey"); + assertEquals(expectedKeys, layeredContext.keySet()); + + layeredContext.putHookContext(new ImmutableContext(Map.of("new", new Value("hook")))); + + expectedKeys = + Set.of("hook", "invocation", "client", "transaction", "api", "override", "targetingKey", "new"); + assertEquals(expectedKeys, layeredContext.keySet()); + } + } + + @Nested + class AsMap { + @Test + void mapIsGeneratedCorrectly() { + LayeredEvaluationContext layeredContext = + new LayeredEvaluationContext(apiContext, transactionContext, clientContext, invocationContext); + layeredContext.putHookContext(hookContext); + + var expectedKeys = Map.of( + "hook", new Value("hook"), + "invocation", new Value("invocation"), + "client", new Value("client"), + "transaction", new Value("transaction"), + "api", new Value("api"), + "override", new Value("hook"), + "targetingKey", new Value("hook-level") // expected, even though not explicitly set + ); + + assertEquals(expectedKeys, layeredContext.asMap()); + assertEquals(expectedKeys, layeredContext.asUnmodifiableMap()); + } + + @Test + void emptyContextGeneratesEmptyMap() { + LayeredEvaluationContext layeredContext = new LayeredEvaluationContext(null, null, null, null); + assertEquals(Map.of(), layeredContext.asMap()); + assertEquals(Map.of(), layeredContext.asUnmodifiableMap()); + assertEquals(Map.of(), layeredContext.asObjectMap()); + } + + @Test + void creatingMapWithCachedEmptyKeySetWorks() { + LayeredEvaluationContext layeredContext = new LayeredEvaluationContext(null, null, null, null); + assertNotNull(layeredContext.keySet()); + assertEquals(Map.of(), layeredContext.asMap()); + assertEquals(Map.of(), layeredContext.asUnmodifiableMap()); + } + + @Test + void creatingMapWithCachedNonEmptyKeySetWorks() { + LayeredEvaluationContext layeredContext = new LayeredEvaluationContext(apiContext, null, null, null); + assertNotNull(layeredContext.keySet()); + assertEquals(apiContext.asMap(), layeredContext.asMap()); + assertEquals(apiContext.asUnmodifiableMap(), layeredContext.asUnmodifiableMap()); + } + } + + @Nested + class AsObjectMap { + @Test + void mapIsGeneratedCorrectly() { + LayeredEvaluationContext layeredContext = + new LayeredEvaluationContext(apiContext, transactionContext, clientContext, invocationContext); + layeredContext.putHookContext(hookContext); + + var expectedKeys = Map.of( + "hook", "hook", + "invocation", "invocation", + "client", "client", + "transaction", "transaction", + "api", "api", + "override", "hook", + "targetingKey", "hook-level" // expected, even though not explicitly set in map + ); + + assertEquals(expectedKeys, layeredContext.asObjectMap()); + } + + @Test + void creatingMapWithCachedEmptyKeySetWorks() { + LayeredEvaluationContext layeredContext = new LayeredEvaluationContext(null, null, null, null); + assertNotNull(layeredContext.keySet()); + assertEquals(Map.of(), layeredContext.asObjectMap()); + } + + @Test + void creatingMapWithCachedNonEmptyKeySetWorks() { + LayeredEvaluationContext layeredContext = new LayeredEvaluationContext(apiContext, null, null, null); + assertNotNull(layeredContext.keySet()); + assertEquals(apiContext.asObjectMap(), layeredContext.asObjectMap()); + } + } + + @Nested + class IsEmpty { + @Test + void isEmptyWhenAllContextsAreNull() { + LayeredEvaluationContext layeredContext = new LayeredEvaluationContext(null, null, null, null); + assertTrue(layeredContext.isEmpty()); + } + + @Test + void isNotEmptyWhenApiContextIsSet() { + LayeredEvaluationContext layeredContext = new LayeredEvaluationContext(apiContext, null, null, null); + assertFalse(layeredContext.isEmpty()); + } + + @Test + void isNotEmptyWhenTransactionContextIsSet() { + LayeredEvaluationContext layeredContext = + new LayeredEvaluationContext(null, transactionContext, null, null); + assertFalse(layeredContext.isEmpty()); + } + + @Test + void isNotEmptyWhenClientContextIsSet() { + LayeredEvaluationContext layeredContext = new LayeredEvaluationContext(null, null, clientContext, null); + assertFalse(layeredContext.isEmpty()); + } + + @Test + void isNotEmptyWhenInvocationContextIsSet() { + LayeredEvaluationContext layeredContext = new LayeredEvaluationContext(null, null, null, invocationContext); + assertFalse(layeredContext.isEmpty()); + } + + @Test + void isNotEmptyWhenInvocationAndClientContextIsSet() { + LayeredEvaluationContext layeredContext = + new LayeredEvaluationContext(null, null, clientContext, invocationContext); + assertFalse(layeredContext.isEmpty()); + } + + @Test + void isNotEmptyWhenInvocationAndClientAndTransactionContextIsSet() { + LayeredEvaluationContext layeredContext = + new LayeredEvaluationContext(null, transactionContext, clientContext, invocationContext); + assertFalse(layeredContext.isEmpty()); + } + + @Test + void isNotEmptyWhenInvocationAndClientAndTransactionAndApiContextIsSet() { + LayeredEvaluationContext layeredContext = + new LayeredEvaluationContext(apiContext, transactionContext, clientContext, invocationContext); + assertFalse(layeredContext.isEmpty()); + } + + @Test + void isNotEmptyWhenHookContextIsSet() { + LayeredEvaluationContext layeredContext = new LayeredEvaluationContext(null, null, null, null); + layeredContext.putHookContext(hookContext); + assertFalse(layeredContext.isEmpty()); + } + + @Test + void isEmptyIfHookContextIsEmpty() { + LayeredEvaluationContext layeredContext = new LayeredEvaluationContext(null, null, null, null); + layeredContext.putHookContext(new MutableContext()); + assertTrue(layeredContext.isEmpty()); + } + } + + @Nested + class Merge { + @Test + void mergesCorrectly() { + LayeredEvaluationContext ctx1 = + new LayeredEvaluationContext(apiContext, transactionContext, clientContext, invocationContext); + EvaluationContext ctx2 = new MutableContext( + "mutable", Map.of("override", new Value("other"), "unique", new Value("unique"))); + + EvaluationContext merged = ctx1.merge(ctx2); + + assertEquals( + Map.of( + "invocation", new Value("invocation"), + "client", new Value("client"), + "transaction", new Value("transaction"), + "api", new Value("api"), + "override", new Value("other"), + "targetingKey", new Value("mutable"), + "unique", new Value("unique")), + merged.asMap()); + assertEquals("mutable", merged.getTargetingKey()); + } + + @Test + void mergesCorrectlyWithHooks() { + LayeredEvaluationContext ctx1 = + new LayeredEvaluationContext(apiContext, transactionContext, clientContext, invocationContext); + ctx1.putHookContext(hookContext); + EvaluationContext ctx2 = new MutableContext( + "mutable", Map.of("override", new Value("other"), "unique", new Value("unique"))); + + EvaluationContext merged = ctx1.merge(ctx2); + + assertEquals( + Map.of( + "invocation", new Value("invocation"), + "client", new Value("client"), + "transaction", new Value("transaction"), + "api", new Value("api"), + "override", new Value("other"), + "targetingKey", new Value("mutable"), + "unique", new Value("unique"), + "hook", new Value("hook")), + merged.asMap()); + assertEquals("mutable", merged.getTargetingKey()); + } + + @Test + void mergesCorrectlyWhenOtherHasNoTargetingKey() { + LayeredEvaluationContext ctx1 = + new LayeredEvaluationContext(apiContext, transactionContext, clientContext, invocationContext); + EvaluationContext ctx2 = + new MutableContext(Map.of("override", new Value("other"), "unique", new Value("unique"))); + + EvaluationContext merged = ctx1.merge(ctx2); + + assertEquals( + Map.of( + "invocation", new Value("invocation"), + "client", new Value("client"), + "transaction", new Value("transaction"), + "api", new Value("api"), + "override", new Value("other"), + "targetingKey", new Value(invocationContext.getTargetingKey()), + "unique", new Value("unique")), + merged.asMap()); + assertEquals(invocationContext.getTargetingKey(), merged.getTargetingKey()); + } + } +} diff --git a/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java b/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java index 91509bd45..31937ec2d 100644 --- a/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java +++ b/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java @@ -12,6 +12,8 @@ import dev.openfeature.sdk.fixtures.HookFixtures; import dev.openfeature.sdk.testutils.testProvider.TestProvider; import java.util.HashMap; +import java.util.Map; +import java.util.Optional; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -135,4 +137,53 @@ void shouldSupportUsageOfHookData(boolean isError) { assertThat(testHook.hookData.get("error")).isEqualTo(null); } } + + @Test + void flagEvaluationsUseTheCorrectContext() { + OpenFeatureAPI api = new OpenFeatureAPI(); + api.setTransactionContextPropagator(new ThreadLocalTransactionContextPropagator()); + var provider = TestProvider.builder().allowUnknownFlags(true).initsToReady(); + api.setProviderAndWait(provider); + + var apiContext = new MutableContext("api-level", Map.of("api", new Value("api"), "override", new Value("api"))); + var transactionContext = new MutableContext( + "transaction-level", + Map.of("transaction", new Value("transaction"), "override", new Value("transaction"))); + var clientContext = new MutableContext( + "client-level", Map.of("client", new Value("client"), "override", new Value("client"))); + var invocationContext = new MutableContext( + "invocation-level", Map.of("invocation", new Value("invocation"), "override", new Value("invocation"))); + + var hookContext = + new MutableContext("hook-level", Map.of("hook", new Value("hook"), "override", new Value("hook"))); + var ctxHook = new Hook<>() { + @Override + public Optional before(HookContext ctx, Map hints) { + return Optional.of(hookContext); + } + }; + + api.setEvaluationContext(apiContext); + api.setTransactionContext(transactionContext); + + var client = api.getClient(); + client.addHooks(ctxHook); + client.setEvaluationContext(clientContext); + + client.getStringValue("flag", "idc", invocationContext); + + var flagEvaluations = provider.getFlagEvaluations(); + assertThat(flagEvaluations).hasSize(1); + + var evaluation = flagEvaluations.get(0); + assertThat(evaluation.evaluationContext.getValue("api").asString()).isEqualTo("api"); + assertThat(evaluation.evaluationContext.getValue("transaction").asString()) + .isEqualTo("transaction"); + assertThat(evaluation.evaluationContext.getValue("client").asString()).isEqualTo("client"); + assertThat(evaluation.evaluationContext.getValue("invocation").asString()) + .isEqualTo("invocation"); + assertThat(evaluation.evaluationContext.getValue("hook").asString()).isEqualTo("hook"); + assertThat(evaluation.evaluationContext.getValue("override").asString()).isEqualTo("hook"); + assertThat(evaluation.evaluationContext.getTargetingKey()).isEqualTo("hook-level"); + } } diff --git a/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java b/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java index d6a03efd6..c41492577 100644 --- a/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java +++ b/src/test/java/dev/openfeature/sdk/benchmark/AllocationBenchmark.java @@ -26,6 +26,7 @@ import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Fork; import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.infra.Blackhole; /** * Runs a large volume of flag evaluations on a VM with 1G memory and GC @@ -95,4 +96,63 @@ public Optional before(HookContext ctx, Map transactionAttr; + public final Map transactionAttr2; + public final EvaluationContext invocationContext; + + public AllocationBenchmarkState() { + long start = System.currentTimeMillis(); + OpenFeatureAPI.getInstance().setProviderAndWait(new NoOpProvider()); + OpenFeatureAPI.getInstance().setTransactionContextPropagator(new ThreadLocalTransactionContextPropagator()); + long end = System.currentTimeMillis(); + System.out.println("Setup time: " + (end - start) + "ms"); + Map globalAttrs = new HashMap<>(); + globalAttrs.put("global", new Value(1)); + EvaluationContext globalContext = new ImmutableContext(globalAttrs); + OpenFeatureAPI.getInstance().setEvaluationContext(globalContext); + + client = OpenFeatureAPI.getInstance().getClient(); + + Map clientAttrs = new HashMap<>(); + clientAttrs.put("client", new Value(2)); + client.setEvaluationContext(new ImmutableContext(clientAttrs)); + + transactionAttr = new HashMap<>(); + transactionAttr.put("trans", new Value(4)); + + transactionAttr2 = new HashMap<>(); + transactionAttr2.put("trans2", new Value(5)); + + Map invocationAttrs = new HashMap<>(); + invocationAttrs.put("invoke", new Value(3)); + invocationContext = new ImmutableContext(invocationAttrs); + + Map hookAttrs = new HashMap<>(); + hookAttrs.put("hook", new Value(30)); + Optional hookCtx = Optional.of(new ImmutableContext(hookAttrs)); + + client.addHooks(new StringHook() { + @Override + public Optional before(HookContext ctx, Map hints) { + return hookCtx; + } + }); + } +} From f90293c3403e7871e376b388f4d5c3de9033c641 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Nov 2025 20:29:28 +0000 Subject: [PATCH 524/745] chore(deps): update github/codeql-action digest to 59ce4c1 (#1746) 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 4ab0f576e..8816de718 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@0e52774aee3a99ebade1d021ab7e132c6f8058bf + uses: github/codeql-action/init@59ce4c1340a74f56c129f758767ef33668e572b0 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0e52774aee3a99ebade1d021ab7e132c6f8058bf + uses: github/codeql-action/analyze@59ce4c1340a74f56c129f758767ef33668e572b0 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index b37ab6b26..a6048c983 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@0e52774aee3a99ebade1d021ab7e132c6f8058bf + uses: github/codeql-action/init@59ce4c1340a74f56c129f758767ef33668e572b0 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@0e52774aee3a99ebade1d021ab7e132c6f8058bf + uses: github/codeql-action/autobuild@59ce4c1340a74f56c129f758767ef33668e572b0 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0e52774aee3a99ebade1d021ab7e132c6f8058bf + uses: github/codeql-action/analyze@59ce4c1340a74f56c129f758767ef33668e572b0 From f61af1275e3602e724917485781b55f37b47678e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Nov 2025 04:58:49 +0000 Subject: [PATCH 525/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.18.2 (#1748) 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 6af087035..72ae503ab 100644 --- a/pom.xml +++ b/pom.xml @@ -221,7 +221,7 @@ net.bytebuddy byte-buddy-agent - 1.18.1 + 1.18.2 test From bf86db504af84d8fa4c142c16f782171e3358ceb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Nov 2025 08:32:38 +0100 Subject: [PATCH 526/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.18.2 (#1747) 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 72ae503ab..dfaf7a85a 100644 --- a/pom.xml +++ b/pom.xml @@ -214,7 +214,7 @@ net.bytebuddy byte-buddy - 1.18.1 + 1.18.2 test From ab04409e76e2485d5655b4f801e695117d6fbe76 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Nov 2025 13:12:12 +0000 Subject: [PATCH 527/745] chore(deps): update github/codeql-action digest to d29b979 (#1750) 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 8816de718..d58e83531 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@59ce4c1340a74f56c129f758767ef33668e572b0 + uses: github/codeql-action/init@d29b97960cb9ac9218c31f14ce88c6974721bc4a with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@59ce4c1340a74f56c129f758767ef33668e572b0 + uses: github/codeql-action/analyze@d29b97960cb9ac9218c31f14ce88c6974721bc4a diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index a6048c983..46081c152 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@59ce4c1340a74f56c129f758767ef33668e572b0 + uses: github/codeql-action/init@d29b97960cb9ac9218c31f14ce88c6974721bc4a with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@59ce4c1340a74f56c129f758767ef33668e572b0 + uses: github/codeql-action/autobuild@d29b97960cb9ac9218c31f14ce88c6974721bc4a - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@59ce4c1340a74f56c129f758767ef33668e572b0 + uses: github/codeql-action/analyze@d29b97960cb9ac9218c31f14ce88c6974721bc4a From 9052e9164354dc20f6ee6862fd8fc5dfc1e7a5f5 Mon Sep 17 00:00:00 2001 From: chrfwow Date: Thu, 27 Nov 2025 16:04:06 +0100 Subject: [PATCH 528/745] feat: Performance enhancements (#1741) * add bench Signed-off-by: christian.lutnik * fix bench Signed-off-by: christian.lutnik * merge master Signed-off-by: christian.lutnik * improve benchmark Signed-off-by: christian.lutnik * improve benchmark Signed-off-by: christian.lutnik * add str hook for ctx Signed-off-by: christian.lutnik * a collection of perf enhancements Signed-off-by: christian.lutnik * revert comments Signed-off-by: christian.lutnik * extract hash map generation Signed-off-by: christian.lutnik --------- Signed-off-by: christian.lutnik Co-authored-by: Todd Baert --- .../sdk/FlagEvaluationDetails.java | 26 ++++++++++--------- .../sdk/FlagEvaluationOptions.java | 4 +++ .../dev/openfeature/sdk/HashMapUtils.java | 11 ++++++++ .../dev/openfeature/sdk/ImmutableContext.java | 5 ++-- .../openfeature/sdk/ImmutableStructure.java | 19 +++++++++----- .../openfeature/sdk/OpenFeatureClient.java | 23 ++++++++-------- 6 files changed, 56 insertions(+), 32 deletions(-) create mode 100644 src/main/java/dev/openfeature/sdk/HashMapUtils.java diff --git a/src/main/java/dev/openfeature/sdk/FlagEvaluationDetails.java b/src/main/java/dev/openfeature/sdk/FlagEvaluationDetails.java index f1697e309..beeadde15 100644 --- a/src/main/java/dev/openfeature/sdk/FlagEvaluationDetails.java +++ b/src/main/java/dev/openfeature/sdk/FlagEvaluationDetails.java @@ -1,6 +1,5 @@ package dev.openfeature.sdk; -import java.util.Optional; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -26,7 +25,7 @@ public class FlagEvaluationDetails implements BaseEvaluation { private String errorMessage; @Builder.Default - private ImmutableMetadata flagMetadata = ImmutableMetadata.builder().build(); + private ImmutableMetadata flagMetadata = ImmutableMetadata.EMPTY; /** * Generate detail payload from the provider response. @@ -37,15 +36,18 @@ public class FlagEvaluationDetails implements BaseEvaluation { * @return detail payload */ public static FlagEvaluationDetails from(ProviderEvaluation providerEval, String flagKey) { - return FlagEvaluationDetails.builder() - .flagKey(flagKey) - .value(providerEval.getValue()) - .variant(providerEval.getVariant()) - .reason(providerEval.getReason()) - .errorMessage(providerEval.getErrorMessage()) - .errorCode(providerEval.getErrorCode()) - .flagMetadata(Optional.ofNullable(providerEval.getFlagMetadata()) - .orElse(ImmutableMetadata.builder().build())) - .build(); + var flagMetadata = providerEval.getFlagMetadata(); + if (flagMetadata == null) { + flagMetadata = ImmutableMetadata.EMPTY; + } + + return new FlagEvaluationDetails<>( + flagKey, + providerEval.getValue(), + providerEval.getVariant(), + providerEval.getReason(), + providerEval.getErrorCode(), + providerEval.getErrorMessage(), + flagMetadata); } } diff --git a/src/main/java/dev/openfeature/sdk/FlagEvaluationOptions.java b/src/main/java/dev/openfeature/sdk/FlagEvaluationOptions.java index 01ecb9b2e..f73bd9631 100644 --- a/src/main/java/dev/openfeature/sdk/FlagEvaluationOptions.java +++ b/src/main/java/dev/openfeature/sdk/FlagEvaluationOptions.java @@ -10,6 +10,10 @@ @lombok.Value @Builder public class FlagEvaluationOptions { + + public static final FlagEvaluationOptions EMPTY = + FlagEvaluationOptions.builder().build(); + @Singular List hooks; diff --git a/src/main/java/dev/openfeature/sdk/HashMapUtils.java b/src/main/java/dev/openfeature/sdk/HashMapUtils.java new file mode 100644 index 000000000..88d255c25 --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/HashMapUtils.java @@ -0,0 +1,11 @@ +package dev.openfeature.sdk; + +import java.util.HashMap; + +class HashMapUtils { + private HashMapUtils() {} + + static HashMap forEntries(int expectedEntries) { + return new HashMap<>((int) Math.ceil(expectedEntries / .75)); + } +} diff --git a/src/main/java/dev/openfeature/sdk/ImmutableContext.java b/src/main/java/dev/openfeature/sdk/ImmutableContext.java index e4916dfca..35f28d4f4 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableContext.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableContext.java @@ -1,6 +1,7 @@ package dev.openfeature.sdk; import dev.openfeature.sdk.internal.ExcludeFromGeneratedCoverageReport; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.function.Function; @@ -20,7 +21,7 @@ @SuppressWarnings("PMD.BeanMembersShouldSerialize") public final class ImmutableContext implements EvaluationContext { - public static final ImmutableContext EMPTY = new ImmutableContext(); + public static final ImmutableContext EMPTY = new ImmutableContext(Collections.emptyMap()); @Delegate(excludes = DelegateExclusions.class) private final ImmutableStructure structure; @@ -58,7 +59,7 @@ public ImmutableContext(Map attributes) { * @param attributes evaluation context attributes */ public ImmutableContext(String targetingKey, Map attributes) { - if (targetingKey != null && !targetingKey.trim().isEmpty()) { + if (targetingKey != null && !targetingKey.isBlank()) { this.structure = new ImmutableStructure(targetingKey, attributes); } else { this.structure = new ImmutableStructure(attributes); diff --git a/src/main/java/dev/openfeature/sdk/ImmutableStructure.java b/src/main/java/dev/openfeature/sdk/ImmutableStructure.java index 849359424..313e13057 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableStructure.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableStructure.java @@ -4,7 +4,6 @@ import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; -import java.util.Optional; import java.util.Set; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -69,15 +68,21 @@ private static Map copyAttributes(Map in) { } private static Map copyAttributes(Map in, String targetingKey) { - Map copy = new HashMap<>(); + Map copy; if (in != null) { + var numMappings = in.size(); + if (targetingKey != null) { + numMappings++; + } + copy = HashMapUtils.forEntries(numMappings); for (Entry entry : in.entrySet()) { - copy.put( - entry.getKey(), - Optional.ofNullable(entry.getValue()) - .map((Value val) -> val.clone()) - .orElse(null)); + var key = entry.getKey(); + var value = entry.getValue(); + Value cloned = value == null ? null : value.clone(); + copy.put(key, cloned); } + } else { + copy = new HashMap<>(targetingKey == null ? 0 : 1); } if (targetingKey != null) { copy.put(EvaluationContext.TARGETING_KEY, new Value(targetingKey)); diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index c5548b394..0d5d0e643 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -163,8 +163,13 @@ private FlagEvaluationDetails evaluateFlag( FlagEvaluationDetails details = null; HookSupportData hookSupportData = new HookSupportData(); - var flagOptions = ObjectUtils.defaultIfNull( - options, () -> FlagEvaluationOptions.builder().build()); + FlagEvaluationOptions flagOptions; + if (options == null) { + flagOptions = FlagEvaluationOptions.EMPTY; + } else { + flagOptions = options; + } + hookSupportData.hints = Collections.unmodifiableMap(flagOptions.getHookHints()); var context = new LayeredEvaluationContext( openfeatureApi.getEvaluationContext(), @@ -323,8 +328,7 @@ public FlagEvaluationDetails getBooleanDetails(String key, Boolean defa @Override public FlagEvaluationDetails getBooleanDetails(String key, Boolean defaultValue, EvaluationContext ctx) { - return getBooleanDetails( - key, defaultValue, ctx, FlagEvaluationOptions.builder().build()); + return getBooleanDetails(key, defaultValue, ctx, FlagEvaluationOptions.EMPTY); } @Override @@ -356,8 +360,7 @@ public FlagEvaluationDetails getStringDetails(String key, String default @Override public FlagEvaluationDetails getStringDetails(String key, String defaultValue, EvaluationContext ctx) { - return getStringDetails( - key, defaultValue, ctx, FlagEvaluationOptions.builder().build()); + return getStringDetails(key, defaultValue, ctx, FlagEvaluationOptions.EMPTY); } @Override @@ -389,8 +392,7 @@ public FlagEvaluationDetails getIntegerDetails(String key, Integer defa @Override public FlagEvaluationDetails getIntegerDetails(String key, Integer defaultValue, EvaluationContext ctx) { - return getIntegerDetails( - key, defaultValue, ctx, FlagEvaluationOptions.builder().build()); + return getIntegerDetails(key, defaultValue, ctx, FlagEvaluationOptions.EMPTY); } @Override @@ -454,8 +456,7 @@ public FlagEvaluationDetails getObjectDetails(String key, Value defaultVa @Override public FlagEvaluationDetails getObjectDetails(String key, Value defaultValue, EvaluationContext ctx) { - return getObjectDetails( - key, defaultValue, ctx, FlagEvaluationOptions.builder().build()); + return getObjectDetails(key, defaultValue, ctx, FlagEvaluationOptions.EMPTY); } @Override @@ -466,7 +467,7 @@ public FlagEvaluationDetails getObjectDetails( @Override public ClientMetadata getMetadata() { - return () -> domain; + return this::getDomain; } /** From 37d349a2dac40fff529fa413ebd1f0d1328f76c8 Mon Sep 17 00:00:00 2001 From: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> Date: Thu, 27 Nov 2025 11:13:35 -0500 Subject: [PATCH 529/745] chore(main): release 1.19.0 (#1655) Signed-off-by: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 104 ++++++++++++++++++++++++++++++++++ README.md | 8 +-- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 111 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index f386789e1..b5d8d88bb 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"1.18.2"} +{".":"1.19.0"} diff --git a/CHANGELOG.md b/CHANGELOG.md index cbb4c6135..0e676c4a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,109 @@ # Changelog +## [1.19.0](https://github.com/open-feature/java-sdk/compare/v1.18.2...v1.19.0) (2025-11-27) + + +### 🐛 Bug Fixes + +* **deps:** update dependency com.fasterxml.jackson:jackson-bom to v2.20.1 ([#1697](https://github.com/open-feature/java-sdk/issues/1697)) ([e473e9e](https://github.com/open-feature/java-sdk/commit/e473e9ebf0a8c341179d47ddc7c9dfbb01295e71)) +* **deps:** update dependency com.github.spotbugs:spotbugs to v4.9.7 ([#1670](https://github.com/open-feature/java-sdk/issues/1670)) ([4de637f](https://github.com/open-feature/java-sdk/commit/4de637f716314ae99b26bf02e8a78c4a3c5c1940)) +* **deps:** update dependency com.github.spotbugs:spotbugs to v4.9.8 ([#1677](https://github.com/open-feature/java-sdk/issues/1677)) ([b21c674](https://github.com/open-feature/java-sdk/commit/b21c6745cfca313bd48d6c975929161f934be50d)) +* **deps:** update dependency io.cucumber:cucumber-bom to v7.31.0 ([#1692](https://github.com/open-feature/java-sdk/issues/1692)) ([08cc1ab](https://github.com/open-feature/java-sdk/commit/08cc1ab561bd93528ba67e7113b40b0ae8c28cd0)) +* **deps:** update dependency io.cucumber:cucumber-bom to v7.32.0 ([#1736](https://github.com/open-feature/java-sdk/issues/1736)) ([0de4bb6](https://github.com/open-feature/java-sdk/commit/0de4bb6a2460f9a94adeb56605acc0948a5819c7)) +* **deps:** update dependency org.junit:junit-bom to v6.0.1 ([#1699](https://github.com/open-feature/java-sdk/issues/1699)) ([dcd037e](https://github.com/open-feature/java-sdk/commit/dcd037eba301e01f386e8f992c6a5d1cd1cda144)) + + +### ✨ New Features + +* Layered context to reduce memory churn ([#1717](https://github.com/open-feature/java-sdk/issues/1717)) ([0f8125e](https://github.com/open-feature/java-sdk/commit/0f8125e1f2f2e3c2cb145db5b9b07659b397fcb3)) +* Performance enhancements ([#1741](https://github.com/open-feature/java-sdk/issues/1741)) ([9052e91](https://github.com/open-feature/java-sdk/commit/9052e9164354dc20f6ee6862fd8fc5dfc1e7a5f5)) +* use descriptive thread names ([#1704](https://github.com/open-feature/java-sdk/issues/1704)) ([9f43e80](https://github.com/open-feature/java-sdk/commit/9f43e800fd72b1b2037a9bbcb8f8c80af307bca1)) + + +### 🧹 Chore + +* add additional unit tests to increase test coverage ([#1708](https://github.com/open-feature/java-sdk/issues/1708)) ([8c0eac6](https://github.com/open-feature/java-sdk/commit/8c0eac6e968eda047b5348eb01233cdb7894d28c)) +* **deps:** update actions/checkout digest to 1af3b93 ([#1735](https://github.com/open-feature/java-sdk/issues/1735)) ([d4c7907](https://github.com/open-feature/java-sdk/commit/d4c7907e3f3f056b8800387241e4be5e8bbdaea4)) +* **deps:** update actions/checkout digest to 71cf226 ([#1700](https://github.com/open-feature/java-sdk/issues/1700)) ([53073a4](https://github.com/open-feature/java-sdk/commit/53073a4870b10e50e545c14dd6082ee5becd4317)) +* **deps:** update actions/checkout digest to c2d88d3 ([#1738](https://github.com/open-feature/java-sdk/issues/1738)) ([6f02e84](https://github.com/open-feature/java-sdk/commit/6f02e840bca6106d1e7e3c6c1a55a5955746da0b)) +* **deps:** update actions/setup-java digest to 46c56d6 ([#1729](https://github.com/open-feature/java-sdk/issues/1729)) ([c8c4426](https://github.com/open-feature/java-sdk/commit/c8c4426f50ea77d77630e2e3bff707a1332126f4)) +* **deps:** update actions/setup-java digest to 4e7e684 ([#1743](https://github.com/open-feature/java-sdk/issues/1743)) ([6de54e3](https://github.com/open-feature/java-sdk/commit/6de54e31a783663da04e6d94ca19a69a85c64bc8)) +* **deps:** update actions/setup-java digest to 66b9457 ([#1726](https://github.com/open-feature/java-sdk/issues/1726)) ([bd70a3a](https://github.com/open-feature/java-sdk/commit/bd70a3a147b25d17a7326a945475101f2c586a16)) +* **deps:** update actions/setup-java digest to 6ba5449 ([#1721](https://github.com/open-feature/java-sdk/issues/1721)) ([8850d4a](https://github.com/open-feature/java-sdk/commit/8850d4a87edf25c1fdb1f3ca20c8164a8a8a310f)) +* **deps:** update actions/setup-java digest to de5a937 ([#1691](https://github.com/open-feature/java-sdk/issues/1691)) ([46d7179](https://github.com/open-feature/java-sdk/commit/46d71796611f080c29fdc3c954847c9160db718f)) +* **deps:** update amannn/action-semantic-pull-request digest to 069817c ([#1710](https://github.com/open-feature/java-sdk/issues/1710)) ([eefa5a7](https://github.com/open-feature/java-sdk/commit/eefa5a772656568c2c5016b40ef66a4146d26e3f)) +* **deps:** update com.vmlens.version to v1.2.20 ([#1675](https://github.com/open-feature/java-sdk/issues/1675)) ([e12d594](https://github.com/open-feature/java-sdk/commit/e12d594002abe54eeb56a54e3e5d429609247717)) +* **deps:** update com.vmlens.version to v1.2.21 ([#1689](https://github.com/open-feature/java-sdk/issues/1689)) ([3a58838](https://github.com/open-feature/java-sdk/commit/3a58838b70b4c21312fcb182ac97f07a78d57dcd)) +* **deps:** update com.vmlens.version to v1.2.22 ([#1703](https://github.com/open-feature/java-sdk/issues/1703)) ([bb9a4ca](https://github.com/open-feature/java-sdk/commit/bb9a4ca8524b155e6a5091e288a3195a06d90a0a)) +* **deps:** update dependency com.diffplug.spotless:spotless-maven-plugin to v3.1.0 ([#1730](https://github.com/open-feature/java-sdk/issues/1730)) ([71e4b2f](https://github.com/open-feature/java-sdk/commit/71e4b2fd04f13fd5f6a1aaee9899177d963b2346)) +* **deps:** update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.7.0 ([#1671](https://github.com/open-feature/java-sdk/issues/1671)) ([c5d5494](https://github.com/open-feature/java-sdk/commit/c5d54940bfe1e9671bd2dc2dc0f4a6f414fd6e36)) +* **deps:** update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.8.0 ([#1678](https://github.com/open-feature/java-sdk/issues/1678)) ([8c9b126](https://github.com/open-feature/java-sdk/commit/8c9b126e6b600bac9c9edbc63ad0d19e4bd9b5cf)) +* **deps:** update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.8.1 ([#1680](https://github.com/open-feature/java-sdk/issues/1680)) ([110054f](https://github.com/open-feature/java-sdk/commit/110054faa099b44b2306f16cdf4ccbd33fa61fe0)) +* **deps:** update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.8.2 ([#1737](https://github.com/open-feature/java-sdk/issues/1737)) ([ef29b49](https://github.com/open-feature/java-sdk/commit/ef29b498c38ee1ffea60825001b088ccee3d7c29)) +* **deps:** update dependency com.puppycrawl.tools:checkstyle to v12 ([#1665](https://github.com/open-feature/java-sdk/issues/1665)) ([f8eed4e](https://github.com/open-feature/java-sdk/commit/f8eed4e9198692fa531cbe844cba3cb15eca7a9a)) +* **deps:** update dependency com.puppycrawl.tools:checkstyle to v12.1.2 ([#1714](https://github.com/open-feature/java-sdk/issues/1714)) ([26b6132](https://github.com/open-feature/java-sdk/commit/26b6132ef8d60c4f0245da94300bbdfe29748646)) +* **deps:** update dependency com.vmlens:api to v1.2.17 ([#1657](https://github.com/open-feature/java-sdk/issues/1657)) ([3546320](https://github.com/open-feature/java-sdk/commit/354632084a2978db17a0d7791253c9442e843c33)) +* **deps:** update dependency com.vmlens:api to v1.2.18 ([#1666](https://github.com/open-feature/java-sdk/issues/1666)) ([7aa3445](https://github.com/open-feature/java-sdk/commit/7aa3445802ee7a64804497b7ed2d407cd0544ce7)) +* **deps:** update dependency com.vmlens:api to v1.2.19 ([#1672](https://github.com/open-feature/java-sdk/issues/1672)) ([a9a5431](https://github.com/open-feature/java-sdk/commit/a9a5431676ea37f0de0270d19cc4e98065fb09b8)) +* **deps:** update dependency com.vmlens:vmlens-maven-plugin to v1.2.17 ([#1659](https://github.com/open-feature/java-sdk/issues/1659)) ([490eeac](https://github.com/open-feature/java-sdk/commit/490eeac9b06302359f5af0c3eb79f41562e53c5b)) +* **deps:** update dependency com.vmlens:vmlens-maven-plugin to v1.2.18 ([#1667](https://github.com/open-feature/java-sdk/issues/1667)) ([1a2d324](https://github.com/open-feature/java-sdk/commit/1a2d32437976651f582b33244173347938d8c3ad)) +* **deps:** update dependency com.vmlens:vmlens-maven-plugin to v1.2.19 ([#1673](https://github.com/open-feature/java-sdk/issues/1673)) ([060dd41](https://github.com/open-feature/java-sdk/commit/060dd410fb5bf1fd2cc498e9b12ef0681667149f)) +* **deps:** update dependency dev.cel:cel to v0.11.1 ([#1682](https://github.com/open-feature/java-sdk/issues/1682)) ([a5dacf9](https://github.com/open-feature/java-sdk/commit/a5dacf963ebc71024e22925ccc99d724681e98aa)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.17.8 ([#1663](https://github.com/open-feature/java-sdk/issues/1663)) ([e3f2e42](https://github.com/open-feature/java-sdk/commit/e3f2e422df793044682328cb8f7835fec9607cb1)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.18.0 ([#1712](https://github.com/open-feature/java-sdk/issues/1712)) ([4f4a75f](https://github.com/open-feature/java-sdk/commit/4f4a75ffe75b72fd9306ee8a983bb0a22e0198b4)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.18.1 ([#1719](https://github.com/open-feature/java-sdk/issues/1719)) ([4e99dc5](https://github.com/open-feature/java-sdk/commit/4e99dc53b58865f070c8af6b1c83c0091c14c812)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.18.2 ([#1747](https://github.com/open-feature/java-sdk/issues/1747)) ([bf86db5](https://github.com/open-feature/java-sdk/commit/bf86db504af84d8fa4c142c16f782171e3358ceb)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.17.8 ([#1664](https://github.com/open-feature/java-sdk/issues/1664)) ([e264a7a](https://github.com/open-feature/java-sdk/commit/e264a7a600229b380ce1d63459990718a2f427e4)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.18.0 ([#1713](https://github.com/open-feature/java-sdk/issues/1713)) ([82b169e](https://github.com/open-feature/java-sdk/commit/82b169e505d4340344673fc77ceadff24fc5d534)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.18.1 ([#1720](https://github.com/open-feature/java-sdk/issues/1720)) ([43d9266](https://github.com/open-feature/java-sdk/commit/43d926656d042b5fddb8d386fa603fbfa61ef42d)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.18.2 ([#1748](https://github.com/open-feature/java-sdk/issues/1748)) ([f61af12](https://github.com/open-feature/java-sdk/commit/f61af1275e3602e724917485781b55f37b47678e)) +* **deps:** update dependency org.apache.maven.plugins:maven-jar-plugin to v3.5.0 ([#1724](https://github.com/open-feature/java-sdk/issues/1724)) ([6cdd8d0](https://github.com/open-feature/java-sdk/commit/6cdd8d062cfcb58204c4037c679b1da08b520589)) +* **deps:** update dependency org.codehaus.mojo:exec-maven-plugin to v3.6.2 ([#1679](https://github.com/open-feature/java-sdk/issues/1679)) ([d956362](https://github.com/open-feature/java-sdk/commit/d9563626b436961e3a4706280686d31952e42885)) +* **deps:** update dependency org.jacoco:jacoco-maven-plugin to v0.8.14 ([#1669](https://github.com/open-feature/java-sdk/issues/1669)) ([61a59a1](https://github.com/open-feature/java-sdk/commit/61a59a15692bee0529242621ef0c15e2af1f6fdf)) +* **deps:** update github/codeql-action digest to 04bd5c6 ([#1709](https://github.com/open-feature/java-sdk/issues/1709)) ([480db81](https://github.com/open-feature/java-sdk/commit/480db81a98db4bb4384b1133a4d93653adc653cf)) +* **deps:** update github/codeql-action digest to 0b43179 ([#1732](https://github.com/open-feature/java-sdk/issues/1732)) ([ea58997](https://github.com/open-feature/java-sdk/commit/ea5899776a924106de99ed7d993216b1c3140281)) +* **deps:** update github/codeql-action digest to 0c5185d ([#1683](https://github.com/open-feature/java-sdk/issues/1683)) ([d16fe3d](https://github.com/open-feature/java-sdk/commit/d16fe3d598fdcc0197532200e723e9abed63dcd6)) +* **deps:** update github/codeql-action digest to 0e52774 ([#1742](https://github.com/open-feature/java-sdk/issues/1742)) ([21df7b3](https://github.com/open-feature/java-sdk/commit/21df7b3b012f189139f9bd39103b9a683b654bd7)) +* **deps:** update github/codeql-action digest to 17783bf ([#1668](https://github.com/open-feature/java-sdk/issues/1668)) ([4cd6aeb](https://github.com/open-feature/java-sdk/commit/4cd6aeb21f2fe491320e1033674dd0db8ad72d5f)) +* **deps:** update github/codeql-action digest to 1d9f357 ([#1711](https://github.com/open-feature/java-sdk/issues/1711)) ([ac22a72](https://github.com/open-feature/java-sdk/commit/ac22a7268fe824b47d9f7bb0d6ff0c38d4fd6a3b)) +* **deps:** update github/codeql-action digest to 239d7b2 ([#1656](https://github.com/open-feature/java-sdk/issues/1656)) ([1266940](https://github.com/open-feature/java-sdk/commit/1266940ddb4347fe54b8ef26de85d7a88daa3815)) +* **deps:** update github/codeql-action digest to 2f11c17 ([#1658](https://github.com/open-feature/java-sdk/issues/1658)) ([0ab5832](https://github.com/open-feature/java-sdk/commit/0ab5832fec1df40a54c9856b3841484ace8118b4)) +* **deps:** update github/codeql-action digest to 320a6b6 ([#1706](https://github.com/open-feature/java-sdk/issues/1706)) ([e22eb0b](https://github.com/open-feature/java-sdk/commit/e22eb0beef5ed87e143bac888ca66467c062ee1c)) +* **deps:** update github/codeql-action digest to 338146c ([#1698](https://github.com/open-feature/java-sdk/issues/1698)) ([f6b4bb8](https://github.com/open-feature/java-sdk/commit/f6b4bb82e2b4e711175f06f52c857fa2ac72d9a4)) +* **deps:** update github/codeql-action digest to 378219c ([#1728](https://github.com/open-feature/java-sdk/issues/1728)) ([63cd1ef](https://github.com/open-feature/java-sdk/commit/63cd1ef568137e75a4ada7d7da097ad3d5e79a03)) +* **deps:** update github/codeql-action digest to 4264208 ([#1684](https://github.com/open-feature/java-sdk/issues/1684)) ([9152b21](https://github.com/open-feature/java-sdk/commit/9152b21599ccc07389d32c083dc9f2b99e5d130c)) +* **deps:** update github/codeql-action digest to 514ff4d ([#1695](https://github.com/open-feature/java-sdk/issues/1695)) ([982bd99](https://github.com/open-feature/java-sdk/commit/982bd99430f92182dfd8063df6e2587b80bebca4)) +* **deps:** update github/codeql-action digest to 52f930e ([#1740](https://github.com/open-feature/java-sdk/issues/1740)) ([169415e](https://github.com/open-feature/java-sdk/commit/169415e30aef814841ea0251770d693658635434)) +* **deps:** update github/codeql-action digest to 5528384 ([#1654](https://github.com/open-feature/java-sdk/issues/1654)) ([ab0553b](https://github.com/open-feature/java-sdk/commit/ab0553b31c1afe3a448a58c2df231851f4453f30)) +* **deps:** update github/codeql-action digest to 59ce4c1 ([#1746](https://github.com/open-feature/java-sdk/issues/1746)) ([f90293c](https://github.com/open-feature/java-sdk/commit/f90293c3403e7871e376b388f4d5c3de9033c641)) +* **deps:** update github/codeql-action digest to 6fd4ceb ([#1662](https://github.com/open-feature/java-sdk/issues/1662)) ([2889ca6](https://github.com/open-feature/java-sdk/commit/2889ca601ed7fe6c10d1b93a4fd2c197e9b8d516)) +* **deps:** update github/codeql-action digest to 71d0a56 ([#1707](https://github.com/open-feature/java-sdk/issues/1707)) ([6a50468](https://github.com/open-feature/java-sdk/commit/6a504689cd555747c5d005f4da3315b9a9ad0d50)) +* **deps:** update github/codeql-action digest to 777daa0 ([#1694](https://github.com/open-feature/java-sdk/issues/1694)) ([3df3d36](https://github.com/open-feature/java-sdk/commit/3df3d369f294925ee0b06823199279a2eacd64c3)) +* **deps:** update github/codeql-action digest to 85f1517 ([#1722](https://github.com/open-feature/java-sdk/issues/1722)) ([3e5977a](https://github.com/open-feature/java-sdk/commit/3e5977a7f67349e67790db786d018bdf91eee1a2)) +* **deps:** update github/codeql-action digest to 8a6b62b ([#1660](https://github.com/open-feature/java-sdk/issues/1660)) ([59fa1e2](https://github.com/open-feature/java-sdk/commit/59fa1e28602ba2a485323882cfbd7872280ec683)) +* **deps:** update github/codeql-action digest to 8d77149 ([#1690](https://github.com/open-feature/java-sdk/issues/1690)) ([cfcb20b](https://github.com/open-feature/java-sdk/commit/cfcb20b06f17dd84ec532b96ab7fe647b93c7740)) +* **deps:** update github/codeql-action digest to 956c567 ([#1687](https://github.com/open-feature/java-sdk/issues/1687)) ([9df27e4](https://github.com/open-feature/java-sdk/commit/9df27e42ce6472060467d4fdcbedb925a85457f5)) +* **deps:** update github/codeql-action digest to 95b1867 ([#1702](https://github.com/open-feature/java-sdk/issues/1702)) ([01a3669](https://github.com/open-feature/java-sdk/commit/01a3669c2e050df54a3f51386d524968b3ef15d1)) +* **deps:** update github/codeql-action digest to 9625890 ([#1686](https://github.com/open-feature/java-sdk/issues/1686)) ([c57c8a5](https://github.com/open-feature/java-sdk/commit/c57c8a5fb7e5384fbd5e7f34fe2bf65e36b40811)) +* **deps:** update github/codeql-action digest to 97580d7 ([#1701](https://github.com/open-feature/java-sdk/issues/1701)) ([30c07d6](https://github.com/open-feature/java-sdk/commit/30c07d6ce30e9e6505b777ee34edd6541317a134)) +* **deps:** update github/codeql-action digest to 9b0ac1c ([#1681](https://github.com/open-feature/java-sdk/issues/1681)) ([ca9f1ac](https://github.com/open-feature/java-sdk/commit/ca9f1acb0c0a0a68a5cb49b5af3477c8f4abb1b7)) +* **deps:** update github/codeql-action digest to 9bd8638 ([#1696](https://github.com/open-feature/java-sdk/issues/1696)) ([a694310](https://github.com/open-feature/java-sdk/commit/a6943108ab26cb718bc8590d29fcbc34c2435350)) +* **deps:** update github/codeql-action digest to ac9aeee ([#1693](https://github.com/open-feature/java-sdk/issues/1693)) ([d2a2d6f](https://github.com/open-feature/java-sdk/commit/d2a2d6fc95e2fa8a3e6e9cc39545648faf6a0a08)) +* **deps:** update github/codeql-action digest to ae78991 ([#1688](https://github.com/open-feature/java-sdk/issues/1688)) ([c948e9b](https://github.com/open-feature/java-sdk/commit/c948e9bd862b9180b7b84781bdf155587c0c3840)) +* **deps:** update github/codeql-action digest to ba454b8 ([#1716](https://github.com/open-feature/java-sdk/issues/1716)) ([4880de0](https://github.com/open-feature/java-sdk/commit/4880de05c6d45e4f0623cc97a9ef464be3342c23)) +* **deps:** update github/codeql-action digest to c1a2b73 ([#1725](https://github.com/open-feature/java-sdk/issues/1725)) ([6ba620c](https://github.com/open-feature/java-sdk/commit/6ba620c6728c2daa6652ac791de0cc72a38393f5)) +* **deps:** update github/codeql-action digest to ce07e7d ([#1731](https://github.com/open-feature/java-sdk/issues/1731)) ([1c7728d](https://github.com/open-feature/java-sdk/commit/1c7728d4d6d220c2285fe633d73ce1442d430999)) +* **deps:** update github/codeql-action digest to ce729e4 ([#1733](https://github.com/open-feature/java-sdk/issues/1733)) ([2bc3d4f](https://github.com/open-feature/java-sdk/commit/2bc3d4f7c1284105cdf9cdc1c736ab23d26380b6)) +* **deps:** update github/codeql-action digest to d29b979 ([#1750](https://github.com/open-feature/java-sdk/issues/1750)) ([ab04409](https://github.com/open-feature/java-sdk/commit/ab04409e76e2485d5655b4f801e695117d6fbe76)) +* **deps:** update github/codeql-action digest to d88a554 ([#1676](https://github.com/open-feature/java-sdk/issues/1676)) ([e0f1ab0](https://github.com/open-feature/java-sdk/commit/e0f1ab03d6694d2ae45ac10825d4fbc52a7c8b5a)) +* **deps:** update github/codeql-action digest to e2ef519 ([#1705](https://github.com/open-feature/java-sdk/issues/1705)) ([3fda8b8](https://github.com/open-feature/java-sdk/commit/3fda8b8f94c35c04433594463112df7348331f1c)) +* **deps:** update github/codeql-action digest to ec2ee57 ([#1739](https://github.com/open-feature/java-sdk/issues/1739)) ([537a81b](https://github.com/open-feature/java-sdk/commit/537a81bdad1a2ab6126277f2622dbb605bfc1699)) +* **deps:** update github/codeql-action digest to ee753b4 ([#1674](https://github.com/open-feature/java-sdk/issues/1674)) ([e2d1bb6](https://github.com/open-feature/java-sdk/commit/e2d1bb63e5f42868422d510779ebbb33c74fe377)) +* **deps:** update github/codeql-action digest to ffa63f0 ([#1727](https://github.com/open-feature/java-sdk/issues/1727)) ([8621f39](https://github.com/open-feature/java-sdk/commit/8621f39baf267c1092ab3ec9e8ad781898e59cdb)) +* Extract vmlens version ([#1610](https://github.com/open-feature/java-sdk/issues/1610)) ([fdf69f9](https://github.com/open-feature/java-sdk/commit/fdf69f9b366f5278eb3387ccd761ebb1c3f7805b)) +* remove fork configuration ([#1685](https://github.com/open-feature/java-sdk/issues/1685)) ([34f7f23](https://github.com/open-feature/java-sdk/commit/34f7f234c7911ff16548f9fd0ad38c8d3319c668)) +* update LICENSE copyright notice ([#1723](https://github.com/open-feature/java-sdk/issues/1723)) ([1897a5b](https://github.com/open-feature/java-sdk/commit/1897a5bba3c3021ab17be3749e9fd3db0dc341a3)) + ## [1.18.2](https://github.com/open-feature/java-sdk/compare/v1.18.1...v1.18.2) (2025-10-06) diff --git a/README.md b/README.md index 70b131e9a..cda5fd2b3 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.18.2 + 1.19.0 ``` @@ -84,7 +84,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:1.18.2' + implementation 'dev.openfeature:sdk:1.19.0' } ``` diff --git a/pom.xml b/pom.xml index dfaf7a85a..4b242f75f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ dev.openfeature sdk - 1.18.2 + 1.19.0 [17,) diff --git a/version.txt b/version.txt index b57fc7228..815d5ca06 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.18.2 +1.19.0 From 4e24babb7c70f23e1115100e2cc98e8b5f5837b0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Nov 2025 17:53:09 +0000 Subject: [PATCH 530/745] chore(deps): update github/codeql-action digest to c178e03 (#1751) 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 d58e83531..9360bdf72 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@d29b97960cb9ac9218c31f14ce88c6974721bc4a + uses: github/codeql-action/init@c178e03ec888882ce814ed2b300db864f3580f88 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@d29b97960cb9ac9218c31f14ce88c6974721bc4a + uses: github/codeql-action/analyze@c178e03ec888882ce814ed2b300db864f3580f88 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 46081c152..a2faa8a24 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@d29b97960cb9ac9218c31f14ce88c6974721bc4a + uses: github/codeql-action/init@c178e03ec888882ce814ed2b300db864f3580f88 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@d29b97960cb9ac9218c31f14ce88c6974721bc4a + uses: github/codeql-action/autobuild@c178e03ec888882ce814ed2b300db864f3580f88 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@d29b97960cb9ac9218c31f14ce88c6974721bc4a + uses: github/codeql-action/analyze@c178e03ec888882ce814ed2b300db864f3580f88 From 2a636325ee5f5472f1bbd3a2d05d367f424df327 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 28 Nov 2025 16:31:35 +0000 Subject: [PATCH 531/745] chore(deps): update github/codeql-action digest to ecec1f8 (#1753) 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 9360bdf72..e2cec6682 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@c178e03ec888882ce814ed2b300db864f3580f88 + uses: github/codeql-action/init@ecec1f88769052ebc45aa0affc53ea30d474cffa with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c178e03ec888882ce814ed2b300db864f3580f88 + uses: github/codeql-action/analyze@ecec1f88769052ebc45aa0affc53ea30d474cffa diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index a2faa8a24..28d9ebe77 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@c178e03ec888882ce814ed2b300db864f3580f88 + uses: github/codeql-action/init@ecec1f88769052ebc45aa0affc53ea30d474cffa with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@c178e03ec888882ce814ed2b300db864f3580f88 + uses: github/codeql-action/autobuild@ecec1f88769052ebc45aa0affc53ea30d474cffa - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c178e03ec888882ce814ed2b300db864f3580f88 + uses: github/codeql-action/analyze@ecec1f88769052ebc45aa0affc53ea30d474cffa From 595a0db8509eef87330b45f2615aca39a5bce3be Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 29 Nov 2025 04:25:34 +0000 Subject: [PATCH 532/745] chore(deps): update dependency org.apache.maven.plugins:maven-source-plugin to v3.4.0 (#1755) 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 4b242f75f..fd164ac93 100644 --- a/pom.xml +++ b/pom.xml @@ -573,7 +573,7 @@ org.apache.maven.plugins maven-source-plugin - 3.3.1 + 3.4.0 attach-sources From 01c491c667b314fb89bad6c6c845ff70a2e2a3cb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 30 Nov 2025 20:28:18 +0000 Subject: [PATCH 533/745] chore(deps): update dependency com.puppycrawl.tools:checkstyle to v12.2.0 (#1757) 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 fd164ac93..0b48a0795 100644 --- a/pom.xml +++ b/pom.xml @@ -508,7 +508,7 @@ com.puppycrawl.tools checkstyle - 12.1.2 + 12.2.0 From ec3f30ec246897bde2f80d7ff69fa75cc0fb2c9b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 17:56:32 +0000 Subject: [PATCH 534/745] chore(deps): update github/codeql-action digest to f0ac9bf (#1758) 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 e2cec6682..143458942 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@ecec1f88769052ebc45aa0affc53ea30d474cffa + uses: github/codeql-action/init@f0ac9bfbe331b3cc7be1482df79cca2865cb79b6 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ecec1f88769052ebc45aa0affc53ea30d474cffa + uses: github/codeql-action/analyze@f0ac9bfbe331b3cc7be1482df79cca2865cb79b6 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 28d9ebe77..e48e51841 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@ecec1f88769052ebc45aa0affc53ea30d474cffa + uses: github/codeql-action/init@f0ac9bfbe331b3cc7be1482df79cca2865cb79b6 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@ecec1f88769052ebc45aa0affc53ea30d474cffa + uses: github/codeql-action/autobuild@f0ac9bfbe331b3cc7be1482df79cca2865cb79b6 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ecec1f88769052ebc45aa0affc53ea30d474cffa + uses: github/codeql-action/analyze@f0ac9bfbe331b3cc7be1482df79cca2865cb79b6 From f5f595bd3af13e7b325c6a789bf60ca178636cff Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Dec 2025 08:28:53 +0000 Subject: [PATCH 535/745] chore(deps): update actions/checkout digest to 8e8c483 (#1759) 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 +- .github/workflows/static-code-scanning.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index 9ad63fc03..58aedd423 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@c2d88d3ecc89a9ef08eebf45d9637801dcee7eb5 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 with: fetch-depth: 0 submodules: recursive diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 143458942..2817d9771 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -19,7 +19,7 @@ jobs: runs-on: ${{ matrix.os}} steps: - name: Check out the code - uses: actions/checkout@c2d88d3ecc89a9ef08eebf45d9637801dcee7eb5 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 with: fetch-depth: 0 submodules: recursive diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1c6148efc..5728908c9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,7 +37,7 @@ jobs: steps: - name: Checkout Repository - uses: actions/checkout@c2d88d3ecc89a9ef08eebf45d9637801dcee7eb5 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 with: fetch-depth: 0 submodules: recursive diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index e48e51841..78d0f798c 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@c2d88d3ecc89a9ef08eebf45d9637801dcee7eb5 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL From acdbf885081c65a5ca7691a723bb0440dee3ade2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 3 Dec 2025 20:36:47 +0000 Subject: [PATCH 536/745] chore(deps): update github/codeql-action digest to 267c467 (#1761) 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 2817d9771..88a352bf7 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@f0ac9bfbe331b3cc7be1482df79cca2865cb79b6 + uses: github/codeql-action/init@267c4672a565967e4531438f2498370de5e8a98d with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f0ac9bfbe331b3cc7be1482df79cca2865cb79b6 + uses: github/codeql-action/analyze@267c4672a565967e4531438f2498370de5e8a98d diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 78d0f798c..c5c3f6cbc 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@f0ac9bfbe331b3cc7be1482df79cca2865cb79b6 + uses: github/codeql-action/init@267c4672a565967e4531438f2498370de5e8a98d with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@f0ac9bfbe331b3cc7be1482df79cca2865cb79b6 + uses: github/codeql-action/autobuild@267c4672a565967e4531438f2498370de5e8a98d - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f0ac9bfbe331b3cc7be1482df79cca2865cb79b6 + uses: github/codeql-action/analyze@267c4672a565967e4531438f2498370de5e8a98d From 79704e450fa7d1dda20f178b9502d193e47d6b95 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 08:27:10 +0100 Subject: [PATCH 537/745] chore(deps): update actions/setup-java digest to f2beeb2 (#1762) 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 58aedd423..8986abd9c 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -26,7 +26,7 @@ jobs: fetch-depth: 0 submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@4e7e684fbb6e33f88ecb2cf1e6b3797739cf499b + uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 88a352bf7..7f6ebb675 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -25,7 +25,7 @@ jobs: submodules: recursive - name: Set up JDK ${{ matrix.build.java }} - uses: actions/setup-java@4e7e684fbb6e33f88ecb2cf1e6b3797739cf499b + uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5728908c9..e146b6dfc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,7 +43,7 @@ jobs: submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@4e7e684fbb6e33f88ecb2cf1e6b3797739cf499b + uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e with: java-version: '17' distribution: 'temurin' From 412ccf81fbb6e134dfb7fac4e098678a2482b643 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 5 Dec 2025 20:23:25 +0000 Subject: [PATCH 538/745] chore(deps): update github/codeql-action digest to f5c63fa (#1763) 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 7f6ebb675..f3330d2e2 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@267c4672a565967e4531438f2498370de5e8a98d + uses: github/codeql-action/init@f5c63fadd50734aadb36128b8fd75caabc02a3dc with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@267c4672a565967e4531438f2498370de5e8a98d + uses: github/codeql-action/analyze@f5c63fadd50734aadb36128b8fd75caabc02a3dc diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index c5c3f6cbc..7640eb544 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@267c4672a565967e4531438f2498370de5e8a98d + uses: github/codeql-action/init@f5c63fadd50734aadb36128b8fd75caabc02a3dc with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@267c4672a565967e4531438f2498370de5e8a98d + uses: github/codeql-action/autobuild@f5c63fadd50734aadb36128b8fd75caabc02a3dc - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@267c4672a565967e4531438f2498370de5e8a98d + uses: github/codeql-action/analyze@f5c63fadd50734aadb36128b8fd75caabc02a3dc From 1506a108b67de890241c54ee904c7e3e0fd49370 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 04:34:56 +0000 Subject: [PATCH 539/745] chore(deps): update github/codeql-action digest to 149d184 (#1764) 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 f3330d2e2..d2e42f114 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@f5c63fadd50734aadb36128b8fd75caabc02a3dc + uses: github/codeql-action/init@149d184a5153ea45e6fbcef5588ac7b8c7af9835 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f5c63fadd50734aadb36128b8fd75caabc02a3dc + uses: github/codeql-action/analyze@149d184a5153ea45e6fbcef5588ac7b8c7af9835 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 7640eb544..4a8129da9 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@f5c63fadd50734aadb36128b8fd75caabc02a3dc + uses: github/codeql-action/init@149d184a5153ea45e6fbcef5588ac7b8c7af9835 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@f5c63fadd50734aadb36128b8fd75caabc02a3dc + uses: github/codeql-action/autobuild@149d184a5153ea45e6fbcef5588ac7b8c7af9835 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f5c63fadd50734aadb36128b8fd75caabc02a3dc + uses: github/codeql-action/analyze@149d184a5153ea45e6fbcef5588ac7b8c7af9835 From 1f211afed6bac8b04e17ab7b6603959495799abc Mon Sep 17 00:00:00 2001 From: chrfwow Date: Mon, 8 Dec 2025 19:48:49 +0100 Subject: [PATCH 540/745] fix: possible StackOverflow on recursive contexts (#1760) * Fix StackOverflow on recursive contexts Signed-off-by: christian.lutnik * Fix StackOverflow on recursive contexts Signed-off-by: christian.lutnik * Fix StackOverflow on recursive contexts Signed-off-by: christian.lutnik --------- Signed-off-by: christian.lutnik Co-authored-by: Todd Baert --- .../java/dev/openfeature/sdk/HookSupport.java | 3 +- .../dev/openfeature/sdk/HookSupportTest.java | 28 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/main/java/dev/openfeature/sdk/HookSupport.java b/src/main/java/dev/openfeature/sdk/HookSupport.java index 41d36be6a..0254c07fd 100644 --- a/src/main/java/dev/openfeature/sdk/HookSupport.java +++ b/src/main/java/dev/openfeature/sdk/HookSupport.java @@ -63,7 +63,8 @@ public void executeBeforeHooks(HookSupportData data) { .orElse(Optional.empty()); if (returnedEvalContext.isPresent()) { var returnedContext = returnedEvalContext.get(); - if (!returnedContext.isEmpty()) { + // yes, we want to check for reference equality here, this prevents recursive layered contexts + if (returnedContext != hookContext.getCtx() && !returnedContext.isEmpty()) { data.evaluationContext.putHookContext(returnedContext); } } diff --git a/src/test/java/dev/openfeature/sdk/HookSupportTest.java b/src/test/java/dev/openfeature/sdk/HookSupportTest.java index ef8dcc396..3b21aff84 100644 --- a/src/test/java/dev/openfeature/sdk/HookSupportTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSupportTest.java @@ -1,6 +1,7 @@ package dev.openfeature.sdk; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatNoException; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -113,6 +114,33 @@ void shouldIsolateDataBetweenHooks(FlagValueType flagValueType) { assertHookData(testHook2, 2, "before", "after", "finallyAfter", "error"); } + @Test + void hookThatReturnsTheGivenContext_doesNotResultInAStackOverflow() { + var hookSupportData = new HookSupportData(); + var recursiveHook = new Hook() { + @Override + public Optional before(HookContext ctx, Map hints) { + return Optional.of(ctx.getCtx()); + } + }; + var emptyHook = new Hook() { + @Override + public Optional before(HookContext ctx, Map hints) { + return Optional.of(ImmutableContext.EMPTY); + } + }; + var layeredEvaluationContext = + new LayeredEvaluationContext(evaluationContextWithValue("key", "value"), null, null, null); + hookSupportData.evaluationContext = layeredEvaluationContext; + hookSupport.setHooks(hookSupportData, List.of(recursiveHook, emptyHook), FlagValueType.STRING); + hookSupport.setHookContexts( + hookSupportData, getBaseHookContextForType(FlagValueType.STRING), layeredEvaluationContext); + + callAllHooks(hookSupportData); + + assertThatNoException().isThrownBy(layeredEvaluationContext::asObjectMap); + } + private static void callAllHooks(HookSupportData hookSupportData) { hookSupport.executeBeforeHooks(hookSupportData); hookSupport.executeAfterHooks( From 6f3a30a9aa10ce2a057ff52504e232ee52893425 Mon Sep 17 00:00:00 2001 From: Vishalup29 <67001661+Vishalup29@users.noreply.github.com> Date: Mon, 8 Dec 2025 13:33:58 -0600 Subject: [PATCH 541/745] fix: equivalent EvaluationContext .equals() not returning true (#1756) * Issue #1754 Implement equals/hashCode for EvaluationContext and add tests. Signed-off-by: vishalup29 * Apply suggestions from code review Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Todd Baert --------- Signed-off-by: vishalup29 Signed-off-by: Todd Baert Co-authored-by: vishalup29 Co-authored-by: Todd Baert Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .../dev/openfeature/sdk/ImmutableContext.java | 46 ++++++++++- .../sdk/LayeredEvaluationContext.java | 80 ++++++++++++------- .../openfeature/sdk/ImmutableContextTest.java | 44 +++++++--- .../sdk/LayeredEvaluationContextTest.java | 32 ++++++++ 4 files changed, 159 insertions(+), 43 deletions(-) diff --git a/src/main/java/dev/openfeature/sdk/ImmutableContext.java b/src/main/java/dev/openfeature/sdk/ImmutableContext.java index 35f28d4f4..e4b53e2d9 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableContext.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableContext.java @@ -5,7 +5,6 @@ import java.util.HashMap; import java.util.Map; import java.util.function.Function; -import lombok.EqualsAndHashCode; import lombok.ToString; import lombok.experimental.Delegate; @@ -17,7 +16,6 @@ * not be modified after instantiation. */ @ToString -@EqualsAndHashCode @SuppressWarnings("PMD.BeanMembersShouldSerialize") public final class ImmutableContext implements EvaluationContext { @@ -26,6 +24,9 @@ public final class ImmutableContext implements EvaluationContext { @Delegate(excludes = DelegateExclusions.class) private final ImmutableStructure structure; + // Lazily computed hash code, safe because this class is immutable. + private volatile Integer cachedHashCode; + /** * Create an immutable context with an empty targeting_key and attributes * provided. @@ -96,6 +97,47 @@ public EvaluationContext merge(EvaluationContext overridingContext) { return new ImmutableContext(attributes); } + /** + * Equality for EvaluationContext implementations is defined in terms of their resolved + * attribute maps. Two contexts are considered equal if their {@link #asMap()} representations + * contain the same key/value pairs, regardless of how the context was constructed or layered. + * + * @param o the object to compare with this context + * @return true if the other object is an EvaluationContext whose resolved attributes match + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof EvaluationContext)) { + return false; + } + EvaluationContext that = (EvaluationContext) o; + return this.asUnmodifiableMap().equals(that.asUnmodifiableMap()); + } + + /** + * Computes a hash code consistent with {@link #equals(Object)}. Since this context is immutable, + * the hash code is lazily computed once from its resolved attribute map and then cached. + * + * @return the cached hash code derived from this context's attribute map + */ + @Override + public int hashCode() { + Integer result = cachedHashCode; + if (result == null) { + synchronized (this) { + result = cachedHashCode; + if (result == null) { + result = asUnmodifiableMap().hashCode(); + cachedHashCode = result; + } + } + } + return result; + } + @SuppressWarnings("all") private static class DelegateExclusions { @ExcludeFromGeneratedCoverageReport diff --git a/src/main/java/dev/openfeature/sdk/LayeredEvaluationContext.java b/src/main/java/dev/openfeature/sdk/LayeredEvaluationContext.java index bdd81f8c3..1179ab4ad 100644 --- a/src/main/java/dev/openfeature/sdk/LayeredEvaluationContext.java +++ b/src/main/java/dev/openfeature/sdk/LayeredEvaluationContext.java @@ -21,6 +21,9 @@ public class LayeredEvaluationContext implements EvaluationContext { private ArrayList hookContexts; private String targetingKey; private Set keySet = null; + // Lazily computed resolved attribute map for this layered context. + // This must be invalidated whenever the underlying layers change. + private Map cachedMap; /** * Constructor for LayeredEvaluationContext. @@ -174,15 +177,20 @@ public Value getValue(String key) { return getFromContext(apiContext, key); } - @Override - public Map asMap() { + private Map getResolvedMap() { + if (cachedMap != null) { + return cachedMap; + } + if (keySet != null && keySet.isEmpty()) { - return new HashMap<>(0); + cachedMap = Collections.emptyMap(); + return cachedMap; } HashMap map; if (keySet != null) { - map = new HashMap<>(keySet.size()); + // use helper to size the map based on expected entries + map = HashMapUtils.forEntries(keySet.size()); } else { map = new HashMap<>(); } @@ -205,7 +213,15 @@ public Map asMap() { map.putAll(hookContext.asMap()); } } - return map; + + cachedMap = Collections.unmodifiableMap(map); + return cachedMap; + } + + @Override + public Map asMap() { + // Return a defensive copy so callers can't mutate our cached map. + return new HashMap<>(getResolvedMap()); } @Override @@ -214,41 +230,48 @@ public Map asUnmodifiableMap() { return Collections.emptyMap(); } - return Collections.unmodifiableMap(asMap()); + return getResolvedMap(); } @Override public Map asObjectMap() { - if (keySet != null && keySet.isEmpty()) { + // Build the object map directly from the resolved attribute map, + // so this stays consistent with equals/hashCode and asMap(). + Map resolved = getResolvedMap(); + if (resolved.isEmpty()) { return new HashMap<>(0); } - HashMap map; - if (keySet != null) { - map = new HashMap<>(keySet.size()); - } else { - map = new HashMap<>(); + HashMap map = HashMapUtils.forEntries(resolved.size()); + for (Map.Entry entry : resolved.entrySet()) { + Value value = entry.getValue(); + // Value is responsible for exposing the underlying Java representation. + map.put(entry.getKey(), value == null ? null : value.asObject()); } + return map; + } - if (apiContext != null) { - map.putAll(apiContext.asObjectMap()); - } - if (transactionContext != null) { - map.putAll(transactionContext.asObjectMap()); - } - if (clientContext != null) { - map.putAll(clientContext.asObjectMap()); + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - if (invocationContext != null) { - map.putAll(invocationContext.asObjectMap()); + if (!(o instanceof EvaluationContext)) { + return false; } - if (hookContexts != null) { - for (int i = 0; i < hookContexts.size(); i++) { - EvaluationContext hookContext = hookContexts.get(i); - map.putAll(hookContext.asObjectMap()); - } + + EvaluationContext that = (EvaluationContext) o; + + if (that instanceof LayeredEvaluationContext) { + return this.getResolvedMap().equals(((LayeredEvaluationContext) that).getResolvedMap()); } - return map; + + return this.getResolvedMap().equals(that.asUnmodifiableMap()); + } + + @Override + public int hashCode() { + return getResolvedMap().hashCode(); } void putHookContext(EvaluationContext context) { @@ -265,5 +288,6 @@ void putHookContext(EvaluationContext context) { } this.hookContexts.add(context); this.keySet = null; + this.cachedMap = null; } } diff --git a/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java b/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java index 0b8a44d0d..624f9b42a 100644 --- a/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java +++ b/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java @@ -4,10 +4,13 @@ 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.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -50,7 +53,7 @@ void shouldChangeTargetingKeyFromOverridingContext() { assertEquals("overriding_key", merge.getTargetingKey()); } - @DisplayName("targeting key should not changed from the overriding context if missing") + @DisplayName("targeting key should not be changed from the overriding context if missing") @Test void shouldRetainTargetingKeyWhenOverridingContextTargetingKeyValueIsEmpty() { HashMap attributes = new HashMap<>(); @@ -66,7 +69,7 @@ void shouldRetainTargetingKeyWhenOverridingContextTargetingKeyValueIsEmpty() { @Test void missingTargetingKeyShould() { EvaluationContext ctx = new ImmutableContext(); - assertEquals(null, ctx.getTargetingKey()); + assertNull(ctx.getTargetingKey()); } @DisplayName("Merge should retain all the attributes from the existing context when overriding context is null") @@ -145,10 +148,26 @@ void mergeShouldObtainKeysFromOverridingContextWhenExistingContextIsEmpty() { EvaluationContext ctx = new ImmutableContext(); EvaluationContext overriding = new ImmutableContext(attributes); EvaluationContext merge = ctx.merge(overriding); - assertEquals(new java.util.HashSet<>(java.util.Arrays.asList("key1", "key2")), merge.keySet()); + assertEquals(new HashSet<>(Arrays.asList("key1", "key2")), merge.keySet()); } - @DisplayName("Two different MutableContext objects with the different contents are not considered equal") + @DisplayName("Two ImmutableContext objects with identical attributes are considered equal") + @Test + void testImmutableContextEquality() { + Map map1 = new HashMap<>(); + map1.put("key", new Value("value")); + + Map map2 = new HashMap<>(); + map2.put("key", new Value("value")); + + ImmutableContext a = new ImmutableContext(null, map1); + ImmutableContext b = new ImmutableContext(null, map2); + + assertEquals(a, b); + assertEquals(a.hashCode(), b.hashCode()); + } + + @DisplayName("Two different ImmutableContext objects with different contents are not considered equal") @Test void unequalImmutableContextsAreNotEqual() { final Map attributes = new HashMap<>(); @@ -161,17 +180,16 @@ void unequalImmutableContextsAreNotEqual() { assertNotEquals(ctx, ctx2); } - @DisplayName("Two different MutableContext objects with the same content are considered equal") + @DisplayName("ImmutableContext hashCode is stable across multiple invocations") @Test - void equalImmutableContextsAreEqual() { - final Map attributes = new HashMap<>(); - attributes.put("key1", new Value("val1")); - final ImmutableContext ctx = new ImmutableContext(attributes); + void immutableContextHashCodeIsStable() { + Map map = new HashMap<>(); + map.put("key", new Value("value")); - final Map attributes2 = new HashMap<>(); - attributes2.put("key1", new Value("val1")); - final ImmutableContext ctx2 = new ImmutableContext(attributes2); + ImmutableContext ctx = new ImmutableContext(null, map); - assertEquals(ctx, ctx2); + int first = ctx.hashCode(); + int second = ctx.hashCode(); + assertEquals(first, second); } } diff --git a/src/test/java/dev/openfeature/sdk/LayeredEvaluationContextTest.java b/src/test/java/dev/openfeature/sdk/LayeredEvaluationContextTest.java index 7eecd9abd..511241939 100644 --- a/src/test/java/dev/openfeature/sdk/LayeredEvaluationContextTest.java +++ b/src/test/java/dev/openfeature/sdk/LayeredEvaluationContextTest.java @@ -397,5 +397,37 @@ void mergesCorrectlyWhenOtherHasNoTargetingKey() { merged.asMap()); assertEquals(invocationContext.getTargetingKey(), merged.getTargetingKey()); } + + @Test + void testLayeredContextEquality() { + Map baseMap = Map.of("k", new Value("v")); + Map layerMap = Map.of("x", new Value("y")); + + EvaluationContext base = new MutableContext(null, baseMap); + EvaluationContext layer = new MutableContext(null, layerMap); + + LayeredEvaluationContext l1 = new LayeredEvaluationContext(base, layer, null, null); + LayeredEvaluationContext l2 = new LayeredEvaluationContext(base, layer, null, null); + + assertEquals(l1, l2); + assertEquals(l1.hashCode(), l2.hashCode()); + } + + @Test + void testMixedContextEquality() { + Map map = Map.of("foo", new Value("bar")); + + EvaluationContext base = new MutableContext(null, map); + LayeredEvaluationContext layered = new LayeredEvaluationContext(null, null, null, base); + + // Equality from the layered context's perspective (map-based equality) + assertEquals(layered, base); + + // Resolved maps should be identical + assertEquals(base.asMap(), layered.asMap()); + + // Layered's hashCode must be consistent with its resolved attribute map + assertEquals(base.asMap().hashCode(), layered.hashCode()); + } } } From 7ef5f748542b2f255d1eb7b84250d9da75d982f9 Mon Sep 17 00:00:00 2001 From: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> Date: Mon, 8 Dec 2025 14:52:31 -0500 Subject: [PATCH 542/745] chore(main): release 1.19.1 (#1752) Signed-off-by: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 22 ++++++++++++++++++++++ README.md | 8 ++++---- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index b5d8d88bb..57d91355c 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"1.19.0"} +{".":"1.19.1"} diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e676c4a3..de1e8cc2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,27 @@ # Changelog +## [1.19.1](https://github.com/open-feature/java-sdk/compare/v1.19.0...v1.19.1) (2025-12-08) + + +### 🐛 Bug Fixes + +* equivalent EvaluationContext .equals() not returning true ([#1756](https://github.com/open-feature/java-sdk/issues/1756)) ([6f3a30a](https://github.com/open-feature/java-sdk/commit/6f3a30a9aa10ce2a057ff52504e232ee52893425)) +* possible StackOverflow on recursive contexts ([#1760](https://github.com/open-feature/java-sdk/issues/1760)) ([1f211af](https://github.com/open-feature/java-sdk/commit/1f211afed6bac8b04e17ab7b6603959495799abc)) + + +### 🧹 Chore + +* **deps:** update actions/checkout digest to 8e8c483 ([#1759](https://github.com/open-feature/java-sdk/issues/1759)) ([f5f595b](https://github.com/open-feature/java-sdk/commit/f5f595bd3af13e7b325c6a789bf60ca178636cff)) +* **deps:** update actions/setup-java digest to f2beeb2 ([#1762](https://github.com/open-feature/java-sdk/issues/1762)) ([79704e4](https://github.com/open-feature/java-sdk/commit/79704e450fa7d1dda20f178b9502d193e47d6b95)) +* **deps:** update dependency com.puppycrawl.tools:checkstyle to v12.2.0 ([#1757](https://github.com/open-feature/java-sdk/issues/1757)) ([01c491c](https://github.com/open-feature/java-sdk/commit/01c491c667b314fb89bad6c6c845ff70a2e2a3cb)) +* **deps:** update dependency org.apache.maven.plugins:maven-source-plugin to v3.4.0 ([#1755](https://github.com/open-feature/java-sdk/issues/1755)) ([595a0db](https://github.com/open-feature/java-sdk/commit/595a0db8509eef87330b45f2615aca39a5bce3be)) +* **deps:** update github/codeql-action digest to 149d184 ([#1764](https://github.com/open-feature/java-sdk/issues/1764)) ([1506a10](https://github.com/open-feature/java-sdk/commit/1506a108b67de890241c54ee904c7e3e0fd49370)) +* **deps:** update github/codeql-action digest to 267c467 ([#1761](https://github.com/open-feature/java-sdk/issues/1761)) ([acdbf88](https://github.com/open-feature/java-sdk/commit/acdbf885081c65a5ca7691a723bb0440dee3ade2)) +* **deps:** update github/codeql-action digest to c178e03 ([#1751](https://github.com/open-feature/java-sdk/issues/1751)) ([4e24bab](https://github.com/open-feature/java-sdk/commit/4e24babb7c70f23e1115100e2cc98e8b5f5837b0)) +* **deps:** update github/codeql-action digest to ecec1f8 ([#1753](https://github.com/open-feature/java-sdk/issues/1753)) ([2a63632](https://github.com/open-feature/java-sdk/commit/2a636325ee5f5472f1bbd3a2d05d367f424df327)) +* **deps:** update github/codeql-action digest to f0ac9bf ([#1758](https://github.com/open-feature/java-sdk/issues/1758)) ([ec3f30e](https://github.com/open-feature/java-sdk/commit/ec3f30ec246897bde2f80d7ff69fa75cc0fb2c9b)) +* **deps:** update github/codeql-action digest to f5c63fa ([#1763](https://github.com/open-feature/java-sdk/issues/1763)) ([412ccf8](https://github.com/open-feature/java-sdk/commit/412ccf81fbb6e134dfb7fac4e098678a2482b643)) + ## [1.19.0](https://github.com/open-feature/java-sdk/compare/v1.18.2...v1.19.0) (2025-11-27) diff --git a/README.md b/README.md index cda5fd2b3..3aef5bf6d 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.19.0 + 1.19.1 ``` @@ -84,7 +84,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:1.19.0' + implementation 'dev.openfeature:sdk:1.19.1' } ``` diff --git a/pom.xml b/pom.xml index 0b48a0795..29f9b0223 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ dev.openfeature sdk - 1.19.0 + 1.19.1 [17,) diff --git a/version.txt b/version.txt index 815d5ca06..66e2ae6c2 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.19.0 +1.19.1 From 04feac888fa118fa477b46ac6b36016f4b412a08 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Dec 2025 21:03:00 +0000 Subject: [PATCH 543/745] chore(deps): update com.vmlens.version to v1.2.23 (#1766) 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 29f9b0223..cec97e54d 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ 11 ${maven.compiler.source} 5.20.0 - 1.2.22 + 1.2.23 **/e2e/*.java ${project.groupId}.${project.artifactId} From 4cb39a41d975537e62af4a9ae267c687f0bf0423 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Mon, 8 Dec 2025 17:59:23 -0500 Subject: [PATCH 544/745] fix: context serialization missing props (with revert) (#1768) fix: context serialization with revert This reverts commit 6f3a30a9aa10ce2a057ff52504e232ee52893425. Signed-off-by: Todd Baert --- .../dev/openfeature/sdk/ImmutableContext.java | 46 +---------- .../sdk/LayeredEvaluationContext.java | 80 +++++++------------ .../openfeature/sdk/ImmutableContextTest.java | 44 +++------- .../sdk/LayeredEvaluationContextTest.java | 32 -------- 4 files changed, 43 insertions(+), 159 deletions(-) diff --git a/src/main/java/dev/openfeature/sdk/ImmutableContext.java b/src/main/java/dev/openfeature/sdk/ImmutableContext.java index e4b53e2d9..35f28d4f4 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableContext.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableContext.java @@ -5,6 +5,7 @@ import java.util.HashMap; import java.util.Map; import java.util.function.Function; +import lombok.EqualsAndHashCode; import lombok.ToString; import lombok.experimental.Delegate; @@ -16,6 +17,7 @@ * not be modified after instantiation. */ @ToString +@EqualsAndHashCode @SuppressWarnings("PMD.BeanMembersShouldSerialize") public final class ImmutableContext implements EvaluationContext { @@ -24,9 +26,6 @@ public final class ImmutableContext implements EvaluationContext { @Delegate(excludes = DelegateExclusions.class) private final ImmutableStructure structure; - // Lazily computed hash code, safe because this class is immutable. - private volatile Integer cachedHashCode; - /** * Create an immutable context with an empty targeting_key and attributes * provided. @@ -97,47 +96,6 @@ public EvaluationContext merge(EvaluationContext overridingContext) { return new ImmutableContext(attributes); } - /** - * Equality for EvaluationContext implementations is defined in terms of their resolved - * attribute maps. Two contexts are considered equal if their {@link #asMap()} representations - * contain the same key/value pairs, regardless of how the context was constructed or layered. - * - * @param o the object to compare with this context - * @return true if the other object is an EvaluationContext whose resolved attributes match - */ - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof EvaluationContext)) { - return false; - } - EvaluationContext that = (EvaluationContext) o; - return this.asUnmodifiableMap().equals(that.asUnmodifiableMap()); - } - - /** - * Computes a hash code consistent with {@link #equals(Object)}. Since this context is immutable, - * the hash code is lazily computed once from its resolved attribute map and then cached. - * - * @return the cached hash code derived from this context's attribute map - */ - @Override - public int hashCode() { - Integer result = cachedHashCode; - if (result == null) { - synchronized (this) { - result = cachedHashCode; - if (result == null) { - result = asUnmodifiableMap().hashCode(); - cachedHashCode = result; - } - } - } - return result; - } - @SuppressWarnings("all") private static class DelegateExclusions { @ExcludeFromGeneratedCoverageReport diff --git a/src/main/java/dev/openfeature/sdk/LayeredEvaluationContext.java b/src/main/java/dev/openfeature/sdk/LayeredEvaluationContext.java index 1179ab4ad..bdd81f8c3 100644 --- a/src/main/java/dev/openfeature/sdk/LayeredEvaluationContext.java +++ b/src/main/java/dev/openfeature/sdk/LayeredEvaluationContext.java @@ -21,9 +21,6 @@ public class LayeredEvaluationContext implements EvaluationContext { private ArrayList hookContexts; private String targetingKey; private Set keySet = null; - // Lazily computed resolved attribute map for this layered context. - // This must be invalidated whenever the underlying layers change. - private Map cachedMap; /** * Constructor for LayeredEvaluationContext. @@ -177,20 +174,15 @@ public Value getValue(String key) { return getFromContext(apiContext, key); } - private Map getResolvedMap() { - if (cachedMap != null) { - return cachedMap; - } - + @Override + public Map asMap() { if (keySet != null && keySet.isEmpty()) { - cachedMap = Collections.emptyMap(); - return cachedMap; + return new HashMap<>(0); } HashMap map; if (keySet != null) { - // use helper to size the map based on expected entries - map = HashMapUtils.forEntries(keySet.size()); + map = new HashMap<>(keySet.size()); } else { map = new HashMap<>(); } @@ -213,15 +205,7 @@ private Map getResolvedMap() { map.putAll(hookContext.asMap()); } } - - cachedMap = Collections.unmodifiableMap(map); - return cachedMap; - } - - @Override - public Map asMap() { - // Return a defensive copy so callers can't mutate our cached map. - return new HashMap<>(getResolvedMap()); + return map; } @Override @@ -230,48 +214,41 @@ public Map asUnmodifiableMap() { return Collections.emptyMap(); } - return getResolvedMap(); + return Collections.unmodifiableMap(asMap()); } @Override public Map asObjectMap() { - // Build the object map directly from the resolved attribute map, - // so this stays consistent with equals/hashCode and asMap(). - Map resolved = getResolvedMap(); - if (resolved.isEmpty()) { + if (keySet != null && keySet.isEmpty()) { return new HashMap<>(0); } - HashMap map = HashMapUtils.forEntries(resolved.size()); - for (Map.Entry entry : resolved.entrySet()) { - Value value = entry.getValue(); - // Value is responsible for exposing the underlying Java representation. - map.put(entry.getKey(), value == null ? null : value.asObject()); + HashMap map; + if (keySet != null) { + map = new HashMap<>(keySet.size()); + } else { + map = new HashMap<>(); } - return map; - } - @Override - public boolean equals(Object o) { - if (this == o) { - return true; + if (apiContext != null) { + map.putAll(apiContext.asObjectMap()); } - if (!(o instanceof EvaluationContext)) { - return false; + if (transactionContext != null) { + map.putAll(transactionContext.asObjectMap()); } - - EvaluationContext that = (EvaluationContext) o; - - if (that instanceof LayeredEvaluationContext) { - return this.getResolvedMap().equals(((LayeredEvaluationContext) that).getResolvedMap()); + if (clientContext != null) { + map.putAll(clientContext.asObjectMap()); } - - return this.getResolvedMap().equals(that.asUnmodifiableMap()); - } - - @Override - public int hashCode() { - return getResolvedMap().hashCode(); + if (invocationContext != null) { + map.putAll(invocationContext.asObjectMap()); + } + if (hookContexts != null) { + for (int i = 0; i < hookContexts.size(); i++) { + EvaluationContext hookContext = hookContexts.get(i); + map.putAll(hookContext.asObjectMap()); + } + } + return map; } void putHookContext(EvaluationContext context) { @@ -288,6 +265,5 @@ void putHookContext(EvaluationContext context) { } this.hookContexts.add(context); this.keySet = null; - this.cachedMap = null; } } diff --git a/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java b/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java index 624f9b42a..0b8a44d0d 100644 --- a/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java +++ b/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java @@ -4,13 +4,10 @@ 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.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -53,7 +50,7 @@ void shouldChangeTargetingKeyFromOverridingContext() { assertEquals("overriding_key", merge.getTargetingKey()); } - @DisplayName("targeting key should not be changed from the overriding context if missing") + @DisplayName("targeting key should not changed from the overriding context if missing") @Test void shouldRetainTargetingKeyWhenOverridingContextTargetingKeyValueIsEmpty() { HashMap attributes = new HashMap<>(); @@ -69,7 +66,7 @@ void shouldRetainTargetingKeyWhenOverridingContextTargetingKeyValueIsEmpty() { @Test void missingTargetingKeyShould() { EvaluationContext ctx = new ImmutableContext(); - assertNull(ctx.getTargetingKey()); + assertEquals(null, ctx.getTargetingKey()); } @DisplayName("Merge should retain all the attributes from the existing context when overriding context is null") @@ -148,26 +145,10 @@ void mergeShouldObtainKeysFromOverridingContextWhenExistingContextIsEmpty() { EvaluationContext ctx = new ImmutableContext(); EvaluationContext overriding = new ImmutableContext(attributes); EvaluationContext merge = ctx.merge(overriding); - assertEquals(new HashSet<>(Arrays.asList("key1", "key2")), merge.keySet()); + assertEquals(new java.util.HashSet<>(java.util.Arrays.asList("key1", "key2")), merge.keySet()); } - @DisplayName("Two ImmutableContext objects with identical attributes are considered equal") - @Test - void testImmutableContextEquality() { - Map map1 = new HashMap<>(); - map1.put("key", new Value("value")); - - Map map2 = new HashMap<>(); - map2.put("key", new Value("value")); - - ImmutableContext a = new ImmutableContext(null, map1); - ImmutableContext b = new ImmutableContext(null, map2); - - assertEquals(a, b); - assertEquals(a.hashCode(), b.hashCode()); - } - - @DisplayName("Two different ImmutableContext objects with different contents are not considered equal") + @DisplayName("Two different MutableContext objects with the different contents are not considered equal") @Test void unequalImmutableContextsAreNotEqual() { final Map attributes = new HashMap<>(); @@ -180,16 +161,17 @@ void unequalImmutableContextsAreNotEqual() { assertNotEquals(ctx, ctx2); } - @DisplayName("ImmutableContext hashCode is stable across multiple invocations") + @DisplayName("Two different MutableContext objects with the same content are considered equal") @Test - void immutableContextHashCodeIsStable() { - Map map = new HashMap<>(); - map.put("key", new Value("value")); + void equalImmutableContextsAreEqual() { + final Map attributes = new HashMap<>(); + attributes.put("key1", new Value("val1")); + final ImmutableContext ctx = new ImmutableContext(attributes); - ImmutableContext ctx = new ImmutableContext(null, map); + final Map attributes2 = new HashMap<>(); + attributes2.put("key1", new Value("val1")); + final ImmutableContext ctx2 = new ImmutableContext(attributes2); - int first = ctx.hashCode(); - int second = ctx.hashCode(); - assertEquals(first, second); + assertEquals(ctx, ctx2); } } diff --git a/src/test/java/dev/openfeature/sdk/LayeredEvaluationContextTest.java b/src/test/java/dev/openfeature/sdk/LayeredEvaluationContextTest.java index 511241939..7eecd9abd 100644 --- a/src/test/java/dev/openfeature/sdk/LayeredEvaluationContextTest.java +++ b/src/test/java/dev/openfeature/sdk/LayeredEvaluationContextTest.java @@ -397,37 +397,5 @@ void mergesCorrectlyWhenOtherHasNoTargetingKey() { merged.asMap()); assertEquals(invocationContext.getTargetingKey(), merged.getTargetingKey()); } - - @Test - void testLayeredContextEquality() { - Map baseMap = Map.of("k", new Value("v")); - Map layerMap = Map.of("x", new Value("y")); - - EvaluationContext base = new MutableContext(null, baseMap); - EvaluationContext layer = new MutableContext(null, layerMap); - - LayeredEvaluationContext l1 = new LayeredEvaluationContext(base, layer, null, null); - LayeredEvaluationContext l2 = new LayeredEvaluationContext(base, layer, null, null); - - assertEquals(l1, l2); - assertEquals(l1.hashCode(), l2.hashCode()); - } - - @Test - void testMixedContextEquality() { - Map map = Map.of("foo", new Value("bar")); - - EvaluationContext base = new MutableContext(null, map); - LayeredEvaluationContext layered = new LayeredEvaluationContext(null, null, null, base); - - // Equality from the layered context's perspective (map-based equality) - assertEquals(layered, base); - - // Resolved maps should be identical - assertEquals(base.asMap(), layered.asMap()); - - // Layered's hashCode must be consistent with its resolved attribute map - assertEquals(base.asMap().hashCode(), layered.hashCode()); - } } } From c20293598aa80d119a3986ddcd5ca42e7355e218 Mon Sep 17 00:00:00 2001 From: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> Date: Mon, 8 Dec 2025 18:04:34 -0500 Subject: [PATCH 545/745] chore(main): release 1.19.2 (#1767) Signed-off-by: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 13 +++++++++++++ README.md | 8 ++++---- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 57d91355c..0326aeb19 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"1.19.1"} +{".":"1.19.2"} diff --git a/CHANGELOG.md b/CHANGELOG.md index de1e8cc2b..ac251c3cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## [1.19.2](https://github.com/open-feature/java-sdk/compare/v1.19.1...v1.19.2) (2025-12-08) + + +### 🐛 Bug Fixes + +* context serialization missing props (with revert) ([#1768](https://github.com/open-feature/java-sdk/issues/1768)) ([4cb39a4](https://github.com/open-feature/java-sdk/commit/4cb39a41d975537e62af4a9ae267c687f0bf0423)) +* context serialization with revert ([4cb39a4](https://github.com/open-feature/java-sdk/commit/4cb39a41d975537e62af4a9ae267c687f0bf0423)) + + +### 🧹 Chore + +* **deps:** update com.vmlens.version to v1.2.23 ([#1766](https://github.com/open-feature/java-sdk/issues/1766)) ([04feac8](https://github.com/open-feature/java-sdk/commit/04feac888fa118fa477b46ac6b36016f4b412a08)) + ## [1.19.1](https://github.com/open-feature/java-sdk/compare/v1.19.0...v1.19.1) (2025-12-08) diff --git a/README.md b/README.md index 3aef5bf6d..9a8f93aa2 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.19.1 + 1.19.2 ``` @@ -84,7 +84,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:1.19.1' + implementation 'dev.openfeature:sdk:1.19.2' } ``` diff --git a/pom.xml b/pom.xml index cec97e54d..d743c9e9f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ dev.openfeature sdk - 1.19.1 + 1.19.2 [17,) diff --git a/version.txt b/version.txt index 66e2ae6c2..836ae4eda 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.19.1 +1.19.2 From a0305f965e262022701e09ae59bb20e9be5c0e4c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Dec 2025 05:10:41 +0000 Subject: [PATCH 546/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.33.0 (#1769) 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 d743c9e9f..a87aae2f0 100644 --- a/pom.xml +++ b/pom.xml @@ -237,7 +237,7 @@ io.cucumber cucumber-bom - 7.32.0 + 7.33.0 pom import From 2a37f46e9638a966e71eb30a9b5a7504faf0d817 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Dec 2025 13:39:02 +0100 Subject: [PATCH 547/745] chore(deps): update github/codeql-action digest to c43362b (#1772) 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 d2e42f114..b8a857106 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@149d184a5153ea45e6fbcef5588ac7b8c7af9835 + uses: github/codeql-action/init@c43362b91a940600cde2ebae39ec7a35ad66bdc0 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@149d184a5153ea45e6fbcef5588ac7b8c7af9835 + uses: github/codeql-action/analyze@c43362b91a940600cde2ebae39ec7a35ad66bdc0 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 4a8129da9..e576bdc6a 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@149d184a5153ea45e6fbcef5588ac7b8c7af9835 + uses: github/codeql-action/init@c43362b91a940600cde2ebae39ec7a35ad66bdc0 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@149d184a5153ea45e6fbcef5588ac7b8c7af9835 + uses: github/codeql-action/autobuild@c43362b91a940600cde2ebae39ec7a35ad66bdc0 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@149d184a5153ea45e6fbcef5588ac7b8c7af9835 + uses: github/codeql-action/analyze@c43362b91a940600cde2ebae39ec7a35ad66bdc0 From ae6941122e5dcc6bbfc816a12d0879c14c6d49ab Mon Sep 17 00:00:00 2001 From: chrfwow Date: Tue, 9 Dec 2025 21:24:45 +0100 Subject: [PATCH 548/745] feat: equivalent EvaluationContext impls are .equal (#1771) fix: .equals false for equivalent contexts (#1768)" This reverts commit 4cb39a41d975537e62af4a9ae267c687f0bf0423. Signed-off-by: Todd Baert Co-authored-by: Vishalup29 <67001661+Vishalup29@users.noreply.github.com> --- .../openfeature/sdk/AbstractStructure.java | 17 +- .../openfeature/sdk/EvaluationContext.java | 25 +++ .../dev/openfeature/sdk/ImmutableContext.java | 39 ++++- .../sdk/LayeredEvaluationContext.java | 56 +++++- .../dev/openfeature/sdk/MutableContext.java | 20 ++- .../openfeature/sdk/ImmutableContextTest.java | 86 +++++++-- .../sdk/LayeredEvaluationContextTest.java | 165 +++++++++++++++++- .../openfeature/sdk/MutableContextTest.java | 88 +++++++--- 8 files changed, 446 insertions(+), 50 deletions(-) diff --git a/src/main/java/dev/openfeature/sdk/AbstractStructure.java b/src/main/java/dev/openfeature/sdk/AbstractStructure.java index 7962705c3..4d58ded55 100644 --- a/src/main/java/dev/openfeature/sdk/AbstractStructure.java +++ b/src/main/java/dev/openfeature/sdk/AbstractStructure.java @@ -3,10 +3,9 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; -import lombok.EqualsAndHashCode; +import java.util.Objects; @SuppressWarnings({"PMD.BeanMembersShouldSerialize", "checkstyle:MissingJavadocType"}) -@EqualsAndHashCode abstract class AbstractStructure implements Structure { protected final Map attributes; @@ -48,4 +47,18 @@ public Map asObjectMap() { (accumulated, entry) -> accumulated.put(entry.getKey(), convertValue(entry.getValue())), HashMap::putAll); } + + @Override + public boolean equals(Object object) { + if (!(object instanceof AbstractStructure)) { + return false; + } + AbstractStructure that = (AbstractStructure) object; + return Objects.equals(attributes, that.attributes); + } + + @Override + public int hashCode() { + return Objects.hashCode(attributes); + } } diff --git a/src/main/java/dev/openfeature/sdk/EvaluationContext.java b/src/main/java/dev/openfeature/sdk/EvaluationContext.java index 84760c0d9..aeef33f89 100644 --- a/src/main/java/dev/openfeature/sdk/EvaluationContext.java +++ b/src/main/java/dev/openfeature/sdk/EvaluationContext.java @@ -24,6 +24,31 @@ public interface EvaluationContext extends Structure { */ EvaluationContext merge(EvaluationContext overridingContext); + /** + * If the other object is an EvaluationContext, this method compares the results of asUnmodifiableMap() for + * equality. Otherwise, it returns false. + *
+ *
+ * Implementations of EvaluationContext are encouraged to delegate their equals() method to this method, or provide + * a more optimized check with the same semantics. + * + * @param other the object to compare to + * @return true if the other object is an EvaluationContext and has the same map representation, false otherwise + */ + default boolean isEqualTo(Object other) { + if (other == null) { + return false; + } + if (other == this) { + return true; + } + if (!(other instanceof EvaluationContext)) { + return false; + } + var otherContext = (EvaluationContext) other; + return asUnmodifiableMap().equals(otherContext.asUnmodifiableMap()); + } + /** * Recursively merges the overriding map into the base Value map. * The base map is mutated, the overriding map is not. diff --git a/src/main/java/dev/openfeature/sdk/ImmutableContext.java b/src/main/java/dev/openfeature/sdk/ImmutableContext.java index 35f28d4f4..accebe6fc 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableContext.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableContext.java @@ -5,7 +5,6 @@ import java.util.HashMap; import java.util.Map; import java.util.function.Function; -import lombok.EqualsAndHashCode; import lombok.ToString; import lombok.experimental.Delegate; @@ -17,7 +16,6 @@ * not be modified after instantiation. */ @ToString -@EqualsAndHashCode @SuppressWarnings("PMD.BeanMembersShouldSerialize") public final class ImmutableContext implements EvaluationContext { @@ -26,6 +24,9 @@ public final class ImmutableContext implements EvaluationContext { @Delegate(excludes = DelegateExclusions.class) private final ImmutableStructure structure; + // Lazily computed hash code, safe because this class is immutable. + private volatile Integer cachedHashCode; + /** * Create an immutable context with an empty targeting_key and attributes * provided. @@ -96,6 +97,40 @@ public EvaluationContext merge(EvaluationContext overridingContext) { return new ImmutableContext(attributes); } + /** + * Equality for EvaluationContext implementations is defined in terms of their resolved + * attribute maps. Two contexts are considered equal if their {@link #asMap()} representations + * contain the same key/value pairs, regardless of how the context was constructed or layered. + * + * @param o the object to compare with this context + * @return true if the other object is an EvaluationContext whose resolved attributes match + */ + @Override + public boolean equals(Object o) { + return isEqualTo(o); + } + + /** + * Computes a hash code consistent with {@link #equals(Object)}. Since this context is immutable, + * the hash code is lazily computed once from its resolved attribute map and then cached. + * + * @return the cached hash code derived from this context's attribute map + */ + @Override + public int hashCode() { + Integer result = cachedHashCode; + if (result == null) { + synchronized (this) { + result = cachedHashCode; + if (result == null) { + result = structure.hashCode(); + cachedHashCode = result; + } + } + } + return result; + } + @SuppressWarnings("all") private static class DelegateExclusions { @ExcludeFromGeneratedCoverageReport diff --git a/src/main/java/dev/openfeature/sdk/LayeredEvaluationContext.java b/src/main/java/dev/openfeature/sdk/LayeredEvaluationContext.java index bdd81f8c3..a58d82685 100644 --- a/src/main/java/dev/openfeature/sdk/LayeredEvaluationContext.java +++ b/src/main/java/dev/openfeature/sdk/LayeredEvaluationContext.java @@ -21,6 +21,9 @@ public class LayeredEvaluationContext implements EvaluationContext { private ArrayList hookContexts; private String targetingKey; private Set keySet = null; + // Lazily computed resolved attribute map for this layered context. + // This must be invalidated whenever the underlying layers change. + private Map cachedMap; /** * Constructor for LayeredEvaluationContext. @@ -174,15 +177,20 @@ public Value getValue(String key) { return getFromContext(apiContext, key); } - @Override - public Map asMap() { + private Map getResolvedMap() { + if (cachedMap != null) { + return cachedMap; + } + if (keySet != null && keySet.isEmpty()) { - return new HashMap<>(0); + cachedMap = Collections.emptyMap(); + return cachedMap; } HashMap map; if (keySet != null) { - map = new HashMap<>(keySet.size()); + // use helper to size the map based on expected entries + map = HashMapUtils.forEntries(keySet.size()); } else { map = new HashMap<>(); } @@ -205,7 +213,15 @@ public Map asMap() { map.putAll(hookContext.asMap()); } } - return map; + + cachedMap = Collections.unmodifiableMap(map); + return cachedMap; + } + + @Override + public Map asMap() { + // Return a defensive copy so callers can't mutate our cached map. + return new HashMap<>(getResolvedMap()); } @Override @@ -214,7 +230,7 @@ public Map asUnmodifiableMap() { return Collections.emptyMap(); } - return Collections.unmodifiableMap(asMap()); + return getResolvedMap(); } @Override @@ -225,7 +241,8 @@ public Map asObjectMap() { HashMap map; if (keySet != null) { - map = new HashMap<>(keySet.size()); + // use helper to size the map based on expected entries + map = HashMapUtils.forEntries(keySet.size()); } else { map = new HashMap<>(); } @@ -248,9 +265,33 @@ public Map asObjectMap() { map.putAll(hookContext.asObjectMap()); } } + return map; } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof EvaluationContext)) { + return false; + } + + EvaluationContext that = (EvaluationContext) o; + + if (that instanceof LayeredEvaluationContext) { + return this.getResolvedMap().equals(((LayeredEvaluationContext) that).getResolvedMap()); + } + + return this.getResolvedMap().equals(that.asUnmodifiableMap()); + } + + @Override + public int hashCode() { + return getResolvedMap().hashCode(); + } + void putHookContext(EvaluationContext context) { if (context == null || context.isEmpty()) { return; @@ -265,5 +306,6 @@ void putHookContext(EvaluationContext context) { } this.hookContexts.add(context); this.keySet = null; + this.cachedMap = null; } } diff --git a/src/main/java/dev/openfeature/sdk/MutableContext.java b/src/main/java/dev/openfeature/sdk/MutableContext.java index 7fda58065..2ad68c98a 100644 --- a/src/main/java/dev/openfeature/sdk/MutableContext.java +++ b/src/main/java/dev/openfeature/sdk/MutableContext.java @@ -6,7 +6,6 @@ import java.util.List; import java.util.Map; import java.util.function.Function; -import lombok.EqualsAndHashCode; import lombok.ToString; import lombok.experimental.Delegate; @@ -17,7 +16,6 @@ * be modified after instantiation. */ @ToString -@EqualsAndHashCode @SuppressWarnings("PMD.BeanMembersShouldSerialize") public class MutableContext implements EvaluationContext { @@ -125,6 +123,24 @@ public EvaluationContext merge(EvaluationContext overridingContext) { return new MutableContext(attributes); } + /** + * Equality for EvaluationContext implementations is defined in terms of their resolved + * attribute maps. Two contexts are considered equal if their {@link #asMap()} representations + * contain the same key/value pairs, regardless of how the context was constructed or layered. + * + * @param o the object to compare with this context + * @return true if the other object is an EvaluationContext whose resolved attributes match + */ + @Override + public boolean equals(Object o) { + return isEqualTo(o); + } + + @Override + public int hashCode() { + return structure.hashCode(); + } + /** * Hidden class to tell Lombok not to copy these methods over via delegation. */ diff --git a/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java b/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java index 0b8a44d0d..2852be536 100644 --- a/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java +++ b/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java @@ -4,12 +4,16 @@ 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.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; class ImmutableContextTest { @@ -50,7 +54,7 @@ void shouldChangeTargetingKeyFromOverridingContext() { assertEquals("overriding_key", merge.getTargetingKey()); } - @DisplayName("targeting key should not changed from the overriding context if missing") + @DisplayName("targeting key should not be changed from the overriding context if missing") @Test void shouldRetainTargetingKeyWhenOverridingContextTargetingKeyValueIsEmpty() { HashMap attributes = new HashMap<>(); @@ -66,7 +70,7 @@ void shouldRetainTargetingKeyWhenOverridingContextTargetingKeyValueIsEmpty() { @Test void missingTargetingKeyShould() { EvaluationContext ctx = new ImmutableContext(); - assertEquals(null, ctx.getTargetingKey()); + assertNull(ctx.getTargetingKey()); } @DisplayName("Merge should retain all the attributes from the existing context when overriding context is null") @@ -145,10 +149,26 @@ void mergeShouldObtainKeysFromOverridingContextWhenExistingContextIsEmpty() { EvaluationContext ctx = new ImmutableContext(); EvaluationContext overriding = new ImmutableContext(attributes); EvaluationContext merge = ctx.merge(overriding); - assertEquals(new java.util.HashSet<>(java.util.Arrays.asList("key1", "key2")), merge.keySet()); + assertEquals(new HashSet<>(Arrays.asList("key1", "key2")), merge.keySet()); } - @DisplayName("Two different MutableContext objects with the different contents are not considered equal") + @DisplayName("Two ImmutableContext objects with identical attributes are considered equal") + @Test + void testImmutableContextEquality() { + Map map1 = new HashMap<>(); + map1.put("key", new Value("value")); + + Map map2 = new HashMap<>(); + map2.put("key", new Value("value")); + + ImmutableContext a = new ImmutableContext(null, map1); + ImmutableContext b = new ImmutableContext(null, map2); + + assertEquals(a, b); + assertEquals(a.hashCode(), b.hashCode()); + } + + @DisplayName("Two different ImmutableContext objects with different contents are not considered equal") @Test void unequalImmutableContextsAreNotEqual() { final Map attributes = new HashMap<>(); @@ -161,17 +181,57 @@ void unequalImmutableContextsAreNotEqual() { assertNotEquals(ctx, ctx2); } - @DisplayName("Two different MutableContext objects with the same content are considered equal") + @DisplayName("ImmutableContext hashCode is stable across multiple invocations") @Test - void equalImmutableContextsAreEqual() { - final Map attributes = new HashMap<>(); - attributes.put("key1", new Value("val1")); - final ImmutableContext ctx = new ImmutableContext(attributes); + void immutableContextHashCodeIsStable() { + Map map = new HashMap<>(); + map.put("key", new Value("value")); - final Map attributes2 = new HashMap<>(); - attributes2.put("key1", new Value("val1")); - final ImmutableContext ctx2 = new ImmutableContext(attributes2); + ImmutableContext ctx = new ImmutableContext(null, map); + + int first = ctx.hashCode(); + int second = ctx.hashCode(); + assertEquals(first, second); + } + + @Nested + class Equals { + ImmutableContext ctx = new ImmutableContext("c", Map.of("a", new Value("b"))); + + @Test + void equalsItself() { + assertEquals(ctx, ctx); + } + + @Test + void equalsLayeredEvalCtxIfSameValues() { + var layeredContext = new LayeredEvaluationContext(ctx, null, null, null); + assertEquals(layeredContext, ctx); + assertEquals(ctx, layeredContext); + } + + @Test + void equalsDifferentMutableEvalCtxIfSameValues() { + var mutable = new MutableContext("c", Map.of("a", new Value("b"))); + assertEquals(mutable, ctx); + assertEquals(ctx, mutable); + } + } - assertEquals(ctx, ctx2); + @Nested + class HashCode { + ImmutableContext ctx = new ImmutableContext("c", Map.of("a", new Value("b"))); + + @Test + void hashCodeEqualsLayeredEvalCtxIfSameValues() { + var layeredContext = new LayeredEvaluationContext(ctx, null, null, null); + assertEquals(layeredContext.hashCode(), ctx.hashCode()); + } + + @Test + void hashCodeEqualsDifferentMutableEvalCtxIfSameValues() { + var mutable = new MutableContext("c", Map.of("a", new Value("b"))); + assertEquals(mutable.hashCode(), ctx.hashCode()); + } } } diff --git a/src/test/java/dev/openfeature/sdk/LayeredEvaluationContextTest.java b/src/test/java/dev/openfeature/sdk/LayeredEvaluationContextTest.java index 7eecd9abd..edbea81d5 100644 --- a/src/test/java/dev/openfeature/sdk/LayeredEvaluationContextTest.java +++ b/src/test/java/dev/openfeature/sdk/LayeredEvaluationContextTest.java @@ -1,6 +1,11 @@ package dev.openfeature.sdk; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Map; import java.util.Set; @@ -257,6 +262,75 @@ void creatingMapWithCachedNonEmptyKeySetWorks() { assertNotNull(layeredContext.keySet()); assertEquals(apiContext.asObjectMap(), layeredContext.asObjectMap()); } + + @Test + void nestedContextsAreUnwrappedCorrectly() { + var innerApiContext = new ImmutableContext(Map.of("inner", new Value("api"))); + var outerApiContext = new ImmutableContext(Map.of("outer", new Value(innerApiContext))); + + var innerClientContext = new ImmutableContext(Map.of("inner", new Value("client"))); + var outerClientContext = new ImmutableContext(Map.of("outer", new Value(innerClientContext))); + var layeredContext = new LayeredEvaluationContext(outerApiContext, null, outerClientContext, null); + + var objectMap = layeredContext.asObjectMap(); + + assertEquals(Map.of("outer", Map.of("inner", "client")), objectMap); + } + + @Test + void nestedStructuresInContextsAreUnwrappedCorrectly() { + var innerApiStructure = new ImmutableStructure(Map.of("inner", new Value("api"))); + var outerApiContext = new ImmutableContext(Map.of("outer", new Value(innerApiStructure))); + + var innerClientStructure = new ImmutableStructure(Map.of("inner", new Value("client"))); + var outerClientContext = new ImmutableContext(Map.of("outer", new Value(innerClientStructure))); + var layeredContext = new LayeredEvaluationContext(outerApiContext, null, outerClientContext, null); + + var objectMap = layeredContext.asObjectMap(); + + assertEquals(Map.of("outer", Map.of("inner", "client")), objectMap); + } + + @Test + void nestedHookContextsAreUnwrappedCorrectly() { + var innerApiStructure = new ImmutableStructure(Map.of("inner", new Value("api"))); + var outerApiContext = new ImmutableContext(Map.of("outer", new Value(innerApiStructure))); + + var innerClientStructure = new ImmutableStructure(Map.of("inner", new Value("client"))); + var outerClientContext = new ImmutableContext(Map.of("outer", new Value(innerClientStructure))); + var layeredContext = new LayeredEvaluationContext(outerApiContext, null, outerClientContext, null); + + var innerHookStructure = new ImmutableStructure(Map.of("inner", new Value("hook"))); + var outerHookContext = new ImmutableContext(Map.of("outer", new Value(innerHookStructure))); + + layeredContext.putHookContext(outerHookContext); + + var objectMap = layeredContext.asObjectMap(); + + assertEquals(Map.of("outer", Map.of("inner", "hook")), objectMap); + } + + @Test + void objectMapIsMutable() { + LayeredEvaluationContext layeredContext = + new LayeredEvaluationContext(apiContext, transactionContext, clientContext, invocationContext); + + var objectMap = layeredContext.asObjectMap(); + assertDoesNotThrow(() -> objectMap.put("a", "b")); + assertEquals("b", objectMap.get("a")); + } + + @Test + void mutatingObjectMapHasNoSideEffects() { + LayeredEvaluationContext layeredContext = + new LayeredEvaluationContext(apiContext, transactionContext, clientContext, invocationContext); + + var objectMap1 = layeredContext.asObjectMap(); + objectMap1.put("a", "b"); + + var objectMap2 = layeredContext.asObjectMap(); + assertNull(objectMap2.get("a")); + } } @Nested @@ -397,5 +471,94 @@ void mergesCorrectlyWhenOtherHasNoTargetingKey() { merged.asMap()); assertEquals(invocationContext.getTargetingKey(), merged.getTargetingKey()); } + + @Test + void testLayeredContextEquality() { + Map baseMap = Map.of("k", new Value("v")); + Map layerMap = Map.of("x", new Value("y")); + + EvaluationContext base = new MutableContext(null, baseMap); + EvaluationContext layer = new MutableContext(null, layerMap); + + LayeredEvaluationContext l1 = new LayeredEvaluationContext(base, layer, null, null); + LayeredEvaluationContext l2 = new LayeredEvaluationContext(base, layer, null, null); + + assertEquals(l1, l2); + assertEquals(l1.hashCode(), l2.hashCode()); + } + + @Test + void testMixedContextEquality() { + Map map = Map.of("foo", new Value("bar")); + + EvaluationContext base = new MutableContext(null, map); + LayeredEvaluationContext layered = new LayeredEvaluationContext(null, null, null, base); + + // Equality from the layered context's perspective (map-based equality) + assertEquals(layered, base); + + // Resolved maps should be identical + assertEquals(base.asMap(), layered.asMap()); + + // Layered's hashCode must be consistent with its resolved attribute map + assertEquals(base.asMap().hashCode(), layered.hashCode()); + } + } + + @Nested + class Equals { + @Test + void equalsItself() { + var layeredContext = + new LayeredEvaluationContext(apiContext, transactionContext, clientContext, invocationContext); + layeredContext.putHookContext(hookContext); + assertEquals(layeredContext, layeredContext); + } + + @Test + void equalsDifferentLayeredEvalCtxIfSameValues() { + var layeredContext1 = new LayeredEvaluationContext(apiContext, null, null, null); + var layeredContext2 = new LayeredEvaluationContext(null, apiContext, null, null); + assertEquals(layeredContext1, layeredContext2); + } + + @Test + void equalsDifferentImmutableEvalCtxIfSameValues() { + var immutable = new ImmutableContext("key", Map.of("prop", new Value("erty"))); + var layeredContext = new LayeredEvaluationContext(immutable, null, null, null); + assertEquals(immutable, layeredContext); + assertEquals(layeredContext, immutable); + } + + @Test + void equalsDifferentMutableEvalCtxIfSameValues() { + var mutable = new MutableContext("key", Map.of("prop", new Value("erty"))); + var layeredContext = new LayeredEvaluationContext(mutable, null, null, null); + assertEquals(mutable, layeredContext); + assertEquals(layeredContext, mutable); + } + } + + @Nested + class HashCode { + ImmutableContext immutable = new ImmutableContext("c", Map.of("a", new Value("b"))); + LayeredEvaluationContext layeredContext = new LayeredEvaluationContext(immutable, null, null, null); + + @Test + void hashCodeEqualsItself() { + var layeredContext2 = new LayeredEvaluationContext(null, null, immutable, null); + assertEquals(layeredContext.hashCode(), layeredContext2.hashCode()); + } + + @Test + void hasSameHashCodeAsImmutableEvalCtxIfSameValues() { + assertEquals(immutable.hashCode(), layeredContext.hashCode()); + } + + @Test + void hashCodeEqualsDifferentMutableEvalCtxIfSameValues() { + MutableContext ctx = new MutableContext("c", Map.of("a", new Value("b"))); + assertEquals(immutable.hashCode(), ctx.hashCode()); + } } } diff --git a/src/test/java/dev/openfeature/sdk/MutableContextTest.java b/src/test/java/dev/openfeature/sdk/MutableContextTest.java index 6c471d09a..b81cbccb1 100644 --- a/src/test/java/dev/openfeature/sdk/MutableContextTest.java +++ b/src/test/java/dev/openfeature/sdk/MutableContextTest.java @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.Map; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; class MutableContextTest { @@ -139,30 +140,71 @@ void shouldAllowChainingOfMutations() { 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); + @Nested + class Equals { + MutableContext ctx = new MutableContext("c", Map.of("a", new Value("b"))); + + @Test + void equalsItself() { + assertEquals(ctx, ctx); + } + + @Test + void equalsLayeredEvalCtxIfSameValues() { + var layeredContext = new LayeredEvaluationContext(ctx, null, null, null); + assertEquals(layeredContext, ctx); + assertEquals(ctx, layeredContext); + } + + @Test + void equalsDifferentMutableEvalCtxIfSameValues() { + var immutable = new ImmutableContext("c", Map.of("a", new Value("b"))); + assertEquals(immutable, ctx); + assertEquals(ctx, immutable); + } + + @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 context = new MutableContext(attributes); + + final Map attributes2 = new HashMap<>(); + final MutableContext ctx2 = new MutableContext(attributes2); + + assertNotEquals(context, 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 context = new MutableContext(attributes); + + final Map attributes2 = new HashMap<>(); + attributes2.put("key1", new Value("val1")); + final MutableContext ctx2 = new MutableContext(attributes2); + + assertEquals(context, 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); + @Nested + class HashCode { + MutableContext ctx = new MutableContext("c", Map.of("a", new Value("b"))); + + @Test + void hashCodeEqualsLayeredEvalCtxIfSameValues() { + var layeredContext = new LayeredEvaluationContext(ctx, null, null, null); + assertEquals(layeredContext.hashCode(), ctx.hashCode()); + } + + @Test + void hashCodeEqualsDifferentMutableEvalCtxIfSameValues() { + var immutable = new ImmutableContext("c", Map.of("a", new Value("b"))); + assertEquals(immutable.hashCode(), ctx.hashCode()); + } } } From 0c308968826f2a45fed492b115ecbb84a17f0765 Mon Sep 17 00:00:00 2001 From: jarebudev <23311805+jarebudev@users.noreply.github.com> Date: Tue, 9 Dec 2025 20:49:18 +0000 Subject: [PATCH 549/745] feat: all executors now create daemon threads to reduce shutdown time (#1715) all executors now create daemon threads to reduce shutdown time Signed-off-by: jarebudev <23311805+jarebudev@users.noreply.github.com> --- src/main/java/dev/openfeature/sdk/EventProvider.java | 2 +- src/main/java/dev/openfeature/sdk/EventSupport.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/dev/openfeature/sdk/EventProvider.java b/src/main/java/dev/openfeature/sdk/EventProvider.java index 4ccac184e..c126c1451 100644 --- a/src/main/java/dev/openfeature/sdk/EventProvider.java +++ b/src/main/java/dev/openfeature/sdk/EventProvider.java @@ -23,7 +23,7 @@ public abstract class EventProvider implements FeatureProvider { private EventProviderListener eventProviderListener; private final ExecutorService emitterExecutor = - Executors.newCachedThreadPool(new ConfigurableThreadFactory("openfeature-event-emitter-thread")); + Executors.newCachedThreadPool(new ConfigurableThreadFactory("openfeature-event-emitter-thread", true)); void setEventProviderListener(EventProviderListener eventProviderListener) { this.eventProviderListener = eventProviderListener; diff --git a/src/main/java/dev/openfeature/sdk/EventSupport.java b/src/main/java/dev/openfeature/sdk/EventSupport.java index 0b446c6b2..1a7c4d870 100644 --- a/src/main/java/dev/openfeature/sdk/EventSupport.java +++ b/src/main/java/dev/openfeature/sdk/EventSupport.java @@ -28,7 +28,7 @@ class EventSupport { private final Map handlerStores = new ConcurrentHashMap<>(); private final HandlerStore globalHandlerStore = new HandlerStore(); private final ExecutorService taskExecutor = - Executors.newCachedThreadPool(new ConfigurableThreadFactory("openfeature-event-handler-thread")); + Executors.newCachedThreadPool(new ConfigurableThreadFactory("openfeature-event-handler-thread", true)); /** * Run all the event handlers associated with this domain. From 46aa311a8caab33e66eddd1cb40c11cadd0cf8ca Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Dec 2025 04:38:49 +0000 Subject: [PATCH 550/745] chore(deps): update codecov/codecov-action action to v5.5.2 (#1773) 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 8986abd9c..33b3e7ec7 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -53,7 +53,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.5.1 + uses: codecov/codecov-action@v5.5.2 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 b8a857106..8c6ec3348 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -49,7 +49,7 @@ jobs: - if: matrix.build.java == '17' name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.5.1 + uses: codecov/codecov-action@v5.5.2 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From 3e184962d6fa7bc70406abb6ed48d9d0eb9540d2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Dec 2025 08:31:59 +0100 Subject: [PATCH 551/745] chore(deps): update dependency org.mockito:mockito-core to v5.21.0 (#1774) 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 a87aae2f0..7469c8506 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ UTF-8 11 ${maven.compiler.source} - 5.20.0 + 5.21.0 1.2.23 **/e2e/*.java From 6d028f06831dbdb916981752d946c601dff81d42 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 Dec 2025 21:44:16 +0000 Subject: [PATCH 552/745] chore(deps): update github/codeql-action digest to 1b0b941 (#1775) 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 8c6ec3348..382ab817c 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@c43362b91a940600cde2ebae39ec7a35ad66bdc0 + uses: github/codeql-action/init@1b0b941e1fbd5cb8122c5ebdf087be9d02534840 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c43362b91a940600cde2ebae39ec7a35ad66bdc0 + uses: github/codeql-action/analyze@1b0b941e1fbd5cb8122c5ebdf087be9d02534840 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index e576bdc6a..60ada73d9 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@c43362b91a940600cde2ebae39ec7a35ad66bdc0 + uses: github/codeql-action/init@1b0b941e1fbd5cb8122c5ebdf087be9d02534840 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@c43362b91a940600cde2ebae39ec7a35ad66bdc0 + uses: github/codeql-action/autobuild@1b0b941e1fbd5cb8122c5ebdf087be9d02534840 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c43362b91a940600cde2ebae39ec7a35ad66bdc0 + uses: github/codeql-action/analyze@1b0b941e1fbd5cb8122c5ebdf087be9d02534840 From c36701c31f89a2a73d0a54d1135e928317b1b2de Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 12 Dec 2025 01:01:40 +0000 Subject: [PATCH 553/745] chore(deps): update actions/cache digest to a783357 (#1776) 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 33b3e7ec7..4e21fc4bb 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -36,7 +36,7 @@ jobs: server-password: ${{ secrets.CENTRAL_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 + uses: actions/cache@a7833574556fa59680c1b7cb190c1735db73ebf0 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 382ab817c..2e902efe2 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -37,7 +37,7 @@ jobs: languages: java - name: Cache local Maven repository - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 + uses: actions/cache@a7833574556fa59680c1b7cb190c1735db73ebf0 with: path: ~/.m2/repository key: ${{ runner.os }}${{ matrix.build.java }}-maven-${{ hashFiles('**/pom.xml') }} From cffa25347237640e49fc5ed0d690b3e1b4bf27d1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 12 Dec 2025 16:27:31 +0000 Subject: [PATCH 554/745] chore(deps): update github/codeql-action digest to 4b675e4 (#1777) 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 2e902efe2..82e9af467 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@1b0b941e1fbd5cb8122c5ebdf087be9d02534840 + uses: github/codeql-action/init@4b675e451b3779918647db783e324bd9fd7f3932 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1b0b941e1fbd5cb8122c5ebdf087be9d02534840 + uses: github/codeql-action/analyze@4b675e451b3779918647db783e324bd9fd7f3932 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 60ada73d9..e223eb4e3 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@1b0b941e1fbd5cb8122c5ebdf087be9d02534840 + uses: github/codeql-action/init@4b675e451b3779918647db783e324bd9fd7f3932 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@1b0b941e1fbd5cb8122c5ebdf087be9d02534840 + uses: github/codeql-action/autobuild@4b675e451b3779918647db783e324bd9fd7f3932 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1b0b941e1fbd5cb8122c5ebdf087be9d02534840 + uses: github/codeql-action/analyze@4b675e451b3779918647db783e324bd9fd7f3932 From 4a55a8a3f2dabde0eb6ee09b5fe13529a8fb5c7a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Dec 2025 00:24:58 +0000 Subject: [PATCH 555/745] chore(deps): update actions/cache digest to 9255dc7 (#1778) 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 4e21fc4bb..6d64f8e3a 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -36,7 +36,7 @@ jobs: server-password: ${{ secrets.CENTRAL_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@a7833574556fa59680c1b7cb190c1735db73ebf0 + uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb 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 82e9af467..617e1afbc 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -37,7 +37,7 @@ jobs: languages: java - name: Cache local Maven repository - uses: actions/cache@a7833574556fa59680c1b7cb190c1735db73ebf0 + uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb with: path: ~/.m2/repository key: ${{ runner.os }}${{ matrix.build.java }}-maven-${{ hashFiles('**/pom.xml') }} From 1ee5aa8d4fc2a44b565e81ff0c38c07246f12d49 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 15 Dec 2025 08:32:20 +0100 Subject: [PATCH 556/745] chore(deps): update dependency com.puppycrawl.tools:checkstyle to v12.3.0 (#1779) 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 7469c8506..0e7e78d24 100644 --- a/pom.xml +++ b/pom.xml @@ -508,7 +508,7 @@ com.puppycrawl.tools checkstyle - 12.2.0 + 12.3.0 From d0c066f0c9aecd269fa3b49908559a860a1d2b37 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 Dec 2025 08:25:31 +0100 Subject: [PATCH 557/745] chore(deps): update github/codeql-action digest to d0ad1da (#1780) 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 617e1afbc..d0a49c60f 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@4b675e451b3779918647db783e324bd9fd7f3932 + uses: github/codeql-action/init@d0ad1da72a4017827f685ffa9a4e77661a852633 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4b675e451b3779918647db783e324bd9fd7f3932 + uses: github/codeql-action/analyze@d0ad1da72a4017827f685ffa9a4e77661a852633 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index e223eb4e3..9f6bcd6e5 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@4b675e451b3779918647db783e324bd9fd7f3932 + uses: github/codeql-action/init@d0ad1da72a4017827f685ffa9a4e77661a852633 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@4b675e451b3779918647db783e324bd9fd7f3932 + uses: github/codeql-action/autobuild@d0ad1da72a4017827f685ffa9a4e77661a852633 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4b675e451b3779918647db783e324bd9fd7f3932 + uses: github/codeql-action/analyze@d0ad1da72a4017827f685ffa9a4e77661a852633 From 63227e73fac55f50684a449236fb70408a1c64d3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 Dec 2025 13:57:33 +0100 Subject: [PATCH 558/745] chore(deps): update github/codeql-action digest to b5e1a28 (#1781) 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 d0a49c60f..7084b156b 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@d0ad1da72a4017827f685ffa9a4e77661a852633 + uses: github/codeql-action/init@b5e1a28b8a0979c44ee52c52c566b0ab0bae3371 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@d0ad1da72a4017827f685ffa9a4e77661a852633 + uses: github/codeql-action/analyze@b5e1a28b8a0979c44ee52c52c566b0ab0bae3371 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 9f6bcd6e5..d1976a17e 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@d0ad1da72a4017827f685ffa9a4e77661a852633 + uses: github/codeql-action/init@b5e1a28b8a0979c44ee52c52c566b0ab0bae3371 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@d0ad1da72a4017827f685ffa9a4e77661a852633 + uses: github/codeql-action/autobuild@b5e1a28b8a0979c44ee52c52c566b0ab0bae3371 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@d0ad1da72a4017827f685ffa9a4e77661a852633 + uses: github/codeql-action/analyze@b5e1a28b8a0979c44ee52c52c566b0ab0bae3371 From 5467902994fe406f02e36f97a23750748370f9b9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 02:57:27 +0000 Subject: [PATCH 559/745] chore(deps): update github/codeql-action digest to 6dba008 (#1782) 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 7084b156b..d5e744b09 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@b5e1a28b8a0979c44ee52c52c566b0ab0bae3371 + uses: github/codeql-action/init@6dba00881c9b84392aa9a1ea5ad1bf3615699196 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b5e1a28b8a0979c44ee52c52c566b0ab0bae3371 + uses: github/codeql-action/analyze@6dba00881c9b84392aa9a1ea5ad1bf3615699196 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index d1976a17e..7a7af4acc 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@b5e1a28b8a0979c44ee52c52c566b0ab0bae3371 + uses: github/codeql-action/init@6dba00881c9b84392aa9a1ea5ad1bf3615699196 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@b5e1a28b8a0979c44ee52c52c566b0ab0bae3371 + uses: github/codeql-action/autobuild@6dba00881c9b84392aa9a1ea5ad1bf3615699196 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b5e1a28b8a0979c44ee52c52c566b0ab0bae3371 + uses: github/codeql-action/analyze@6dba00881c9b84392aa9a1ea5ad1bf3615699196 From 31b4872a52942518162153edff441491cedc0803 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 05:14:33 +0000 Subject: [PATCH 560/745] chore(deps): update dependency maven to v3.9.12 (#1783) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .mvn/wrapper/maven-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 44f3cf2c1..5f1f57004 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,2 +1,2 @@ distributionType=only-script -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.12/apache-maven-3.9.12-bin.zip From 947c1e2ef9fe63fe753fdcbce45c7774259a3fce Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 13:53:09 +0100 Subject: [PATCH 561/745] chore(deps): update github/codeql-action digest to b88acb2 (#1784) 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 d5e744b09..65a426ee7 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@6dba00881c9b84392aa9a1ea5ad1bf3615699196 + uses: github/codeql-action/init@b88acb2f6ca24bca6c428d6370a8838384be27c9 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6dba00881c9b84392aa9a1ea5ad1bf3615699196 + uses: github/codeql-action/analyze@b88acb2f6ca24bca6c428d6370a8838384be27c9 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 7a7af4acc..d3d458845 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@6dba00881c9b84392aa9a1ea5ad1bf3615699196 + uses: github/codeql-action/init@b88acb2f6ca24bca6c428d6370a8838384be27c9 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@6dba00881c9b84392aa9a1ea5ad1bf3615699196 + uses: github/codeql-action/autobuild@b88acb2f6ca24bca6c428d6370a8838384be27c9 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6dba00881c9b84392aa9a1ea5ad1bf3615699196 + uses: github/codeql-action/analyze@b88acb2f6ca24bca6c428d6370a8838384be27c9 From 9f801f49e0ad45522e967e65e663f32aaaab2fa2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Dec 2025 20:26:23 +0000 Subject: [PATCH 562/745] chore(deps): update github/codeql-action digest to f67ec12 (#1785) 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 65a426ee7..48abc1d32 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@b88acb2f6ca24bca6c428d6370a8838384be27c9 + uses: github/codeql-action/init@f67ec12472e1b361f5e1e2085f5e6f85a57e3cd6 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b88acb2f6ca24bca6c428d6370a8838384be27c9 + uses: github/codeql-action/analyze@f67ec12472e1b361f5e1e2085f5e6f85a57e3cd6 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index d3d458845..5bbb18c1f 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@b88acb2f6ca24bca6c428d6370a8838384be27c9 + uses: github/codeql-action/init@f67ec12472e1b361f5e1e2085f5e6f85a57e3cd6 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@b88acb2f6ca24bca6c428d6370a8838384be27c9 + uses: github/codeql-action/autobuild@f67ec12472e1b361f5e1e2085f5e6f85a57e3cd6 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b88acb2f6ca24bca6c428d6370a8838384be27c9 + uses: github/codeql-action/analyze@f67ec12472e1b361f5e1e2085f5e6f85a57e3cd6 From 52ebe0df7022f1f5fe58dc91d384a50fce511891 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 20:24:06 +0000 Subject: [PATCH 563/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.18.3 (#1787) 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 0e7e78d24..103d0624b 100644 --- a/pom.xml +++ b/pom.xml @@ -221,7 +221,7 @@ net.bytebuddy byte-buddy-agent - 1.18.2 + 1.18.3 test From a86588086407bdb80e3c84d37b9db49380da7bb7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 20 Dec 2025 00:25:14 +0000 Subject: [PATCH 564/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.18.3 (#1786) 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 103d0624b..4dcf71777 100644 --- a/pom.xml +++ b/pom.xml @@ -214,7 +214,7 @@ net.bytebuddy byte-buddy - 1.18.2 + 1.18.3 test From 0b4325a830997840ae3b622df93ca720e73a9088 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 22 Dec 2025 04:29:28 +0000 Subject: [PATCH 565/745] chore(deps): update dependency org.codehaus.mojo:exec-maven-plugin to v3.6.3 (#1788) 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 4dcf71777..2daa91a2f 100644 --- a/pom.xml +++ b/pom.xml @@ -672,7 +672,7 @@ org.codehaus.mojo exec-maven-plugin - 3.6.2 + 3.6.3 update-test-harness-submodule From 69521a0c96de4ca132084633f8d6e1dc3dfe27c1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 24 Dec 2025 04:26:52 +0000 Subject: [PATCH 566/745] chore(deps): update actions/setup-java digest to 5d7b214 (#1789) 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 6d64f8e3a..fc3c93e96 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -26,7 +26,7 @@ jobs: fetch-depth: 0 submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e + uses: actions/setup-java@5d7b2146334bacf88728daaa70414a99f5164e0f with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 48abc1d32..ef3955fec 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -25,7 +25,7 @@ jobs: submodules: recursive - name: Set up JDK ${{ matrix.build.java }} - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e + uses: actions/setup-java@5d7b2146334bacf88728daaa70414a99f5164e0f with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e146b6dfc..c970ca8f3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,7 +43,7 @@ jobs: submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e + uses: actions/setup-java@5d7b2146334bacf88728daaa70414a99f5164e0f with: java-version: '17' distribution: 'temurin' From a237df34cf017a4e33e790106e5e91e2befe0b9e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 31 Dec 2025 20:59:16 +0000 Subject: [PATCH 567/745] chore(deps): update dependency com.puppycrawl.tools:checkstyle to v12.3.1 (#1790) 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 2daa91a2f..d0b6dda5a 100644 --- a/pom.xml +++ b/pom.xml @@ -508,7 +508,7 @@ com.puppycrawl.tools checkstyle - 12.3.0 + 12.3.1 From af3c95073eaa8566fe3e526c3b57441ac3df1816 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 2 Jan 2026 16:40:38 +0000 Subject: [PATCH 568/745] chore(deps): update com.vmlens.version to v1.2.24 (#1791) 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 d0b6dda5a..4a27c7b02 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ 11 ${maven.compiler.source} 5.21.0 - 1.2.23 + 1.2.24 **/e2e/*.java ${project.groupId}.${project.artifactId} From e81d2f81bfe5e2cbc70debea8c3ea8ff5c05cc61 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 3 Jan 2026 12:27:47 +0000 Subject: [PATCH 569/745] chore(deps): update amannn/action-semantic-pull-request digest to 71b07ef (#1793) 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 a3c228ef4..a1d4d3136 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@069817c298f23fab00a8f29a2e556a5eac0f6390 + - uses: amannn/action-semantic-pull-request@71b07ef490c9e8ef772f64a62d41545ae5b9ef22 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 30c68867869040cb716960af90e8f63118587769 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Jan 2026 04:24:59 +0000 Subject: [PATCH 570/745] chore(deps): update github/codeql-action digest to fd448f7 (#1795) 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 ef3955fec..36a2d19e9 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@f67ec12472e1b361f5e1e2085f5e6f85a57e3cd6 + uses: github/codeql-action/init@fd448f79eb8854faeaf33eeb2afa2617df2bdf7e with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f67ec12472e1b361f5e1e2085f5e6f85a57e3cd6 + uses: github/codeql-action/analyze@fd448f79eb8854faeaf33eeb2afa2617df2bdf7e diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 5bbb18c1f..7ede265c0 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@f67ec12472e1b361f5e1e2085f5e6f85a57e3cd6 + uses: github/codeql-action/init@fd448f79eb8854faeaf33eeb2afa2617df2bdf7e with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@f67ec12472e1b361f5e1e2085f5e6f85a57e3cd6 + uses: github/codeql-action/autobuild@fd448f79eb8854faeaf33eeb2afa2617df2bdf7e - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f67ec12472e1b361f5e1e2085f5e6f85a57e3cd6 + uses: github/codeql-action/analyze@fd448f79eb8854faeaf33eeb2afa2617df2bdf7e From 0ee25d9d07e5a9b435c415fede97ab7aab1131f8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 00:22:06 +0000 Subject: [PATCH 571/745] chore(deps): update github/codeql-action digest to b2951d2 (#1796) 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 36a2d19e9..29cfe16b2 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@fd448f79eb8854faeaf33eeb2afa2617df2bdf7e + uses: github/codeql-action/init@b2951d2a1ed70de8ec57301118b487b35c13595a with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@fd448f79eb8854faeaf33eeb2afa2617df2bdf7e + uses: github/codeql-action/analyze@b2951d2a1ed70de8ec57301118b487b35c13595a diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 7ede265c0..e86b386b4 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@fd448f79eb8854faeaf33eeb2afa2617df2bdf7e + uses: github/codeql-action/init@b2951d2a1ed70de8ec57301118b487b35c13595a with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@fd448f79eb8854faeaf33eeb2afa2617df2bdf7e + uses: github/codeql-action/autobuild@b2951d2a1ed70de8ec57301118b487b35c13595a - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@fd448f79eb8854faeaf33eeb2afa2617df2bdf7e + uses: github/codeql-action/analyze@b2951d2a1ed70de8ec57301118b487b35c13595a From 796e7c3bda020c096ee9d130e12fe2940057bb60 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 08:28:08 +0000 Subject: [PATCH 572/745] fix(deps): update dependency org.junit:junit-bom to v6.0.2 (#1797) 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 4a27c7b02..f1a4bd0b4 100644 --- a/pom.xml +++ b/pom.xml @@ -245,7 +245,7 @@ org.junit junit-bom - 6.0.1 + 6.0.2 pom import From 2d03c159da0e326658ede2d847a43517b848ff88 Mon Sep 17 00:00:00 2001 From: Vishalup29 <67001661+Vishalup29@users.noreply.github.com> Date: Wed, 7 Jan 2026 14:13:20 -0600 Subject: [PATCH 573/745] feat: add multi-provider to SDK (#1765) Issue open-feature#1486 Move multi-provider into SDK, mark as experimental, and deprecate contrib implementation. Signed-off-by: vishalup29 Co-authored-by: vishalup29 Co-authored-by: suvaidkhan --- README.md | 36 ++- .../sdk/multiprovider/FirstMatchStrategy.java | 63 ++++++ .../FirstSuccessfulStrategy.java | 48 ++++ .../sdk/multiprovider/MultiProvider.java | 179 +++++++++++++++ .../multiprovider/MultiProviderMetadata.java | 20 ++ .../sdk/multiprovider/Strategy.java | 38 ++++ .../sdk/multiprovider/BaseStrategyTest.java | 214 ++++++++++++++++++ .../multiprovider/FirstMatchStrategyTest.java | 91 ++++++++ .../FirstSuccessfulStrategyTest.java | 78 +++++++ .../sdk/multiprovider/MultiProviderTest.java | 171 ++++++++++++++ 10 files changed, 937 insertions(+), 1 deletion(-) create mode 100644 src/main/java/dev/openfeature/sdk/multiprovider/FirstMatchStrategy.java create mode 100644 src/main/java/dev/openfeature/sdk/multiprovider/FirstSuccessfulStrategy.java create mode 100644 src/main/java/dev/openfeature/sdk/multiprovider/MultiProvider.java create mode 100644 src/main/java/dev/openfeature/sdk/multiprovider/MultiProviderMetadata.java create mode 100644 src/main/java/dev/openfeature/sdk/multiprovider/Strategy.java create mode 100644 src/test/java/dev/openfeature/sdk/multiprovider/BaseStrategyTest.java create mode 100644 src/test/java/dev/openfeature/sdk/multiprovider/FirstMatchStrategyTest.java create mode 100644 src/test/java/dev/openfeature/sdk/multiprovider/FirstSuccessfulStrategyTest.java create mode 100644 src/test/java/dev/openfeature/sdk/multiprovider/MultiProviderTest.java diff --git a/README.md b/README.md index 9a8f93aa2..b64aa3c46 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,7 @@ See [here](https://javadoc.io/doc/dev.openfeature/sdk/latest/) for the Javadocs. | ------ |---------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------| | ✅ | [Providers](#providers) | Integrate with a commercial, open source, or in-house feature management tool. | | ✅ | [Targeting](#targeting) | Contextually-aware flag evaluation using [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context). | +| ✅ | [Multi-provider (experimental)](#multi-provider-experimental) | Combine multiple providers and delegate evaluations according to a strategy. | | ✅ | [Hooks](#hooks) | Add functionality to various stages of the flag evaluation life-cycle. | | ✅ | [Tracking](#tracking) | Associate user actions with feature flag evaluations. | | ✅ | [Logging](#logging) | Integrate with popular logging packages. | @@ -147,7 +148,40 @@ Look [here](https://openfeature.dev/ecosystem?instant_search%5BrefinementList%5D If the provider you're looking for hasn't been created yet, see the [develop a provider](#develop-a-provider) section to learn how to build it yourself. Once you've added a provider as a dependency, it can be registered with OpenFeature like this: - + +In some situations, it may be beneficial to register multiple providers in the same application. +This is possible using [domains](#domains), which is covered in more detail below. + +#### Multi-provider (experimental) + +In addition to domains, you may want to delegate flag evaluation across multiple providers using a configurable strategy. +The multi-provider allows you to compose several `FeatureProvider` implementations and determine which provider's result to use. + +> **Experimental:** This API is experimental and may change in future releases. + +```java +import dev.openfeature.sdk.OpenFeatureAPI; +import dev.openfeature.sdk.Client; +import dev.openfeature.sdk.FeatureProvider; +import dev.openfeature.sdk.multiprovider.MultiProvider; + +import java.util.List; + +public void multiProviderExample() throws Exception { + FeatureProvider primaryProvider = new MyPrimaryProvider(); + FeatureProvider fallbackProvider = new MyFallbackProvider(); + + MultiProvider multiProvider = new MultiProvider(List.of(primaryProvider, fallbackProvider)); + + OpenFeatureAPI api = OpenFeatureAPI.getInstance(); + api.setProviderAndWait(multiProvider); + + Client client = api.getClient(); + boolean value = client.getBooleanValue("some-flag", false); +} +``` + + #### Synchronous To register a provider in a blocking manner to ensure it is ready before further actions are taken, you can use the `setProviderAndWait` method as shown below: diff --git a/src/main/java/dev/openfeature/sdk/multiprovider/FirstMatchStrategy.java b/src/main/java/dev/openfeature/sdk/multiprovider/FirstMatchStrategy.java new file mode 100644 index 000000000..8bfdec76d --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/multiprovider/FirstMatchStrategy.java @@ -0,0 +1,63 @@ +package dev.openfeature.sdk.multiprovider; + +import static dev.openfeature.sdk.ErrorCode.FLAG_NOT_FOUND; + +import dev.openfeature.sdk.ErrorCode; +import dev.openfeature.sdk.EvaluationContext; +import dev.openfeature.sdk.FeatureProvider; +import dev.openfeature.sdk.ProviderEvaluation; +import dev.openfeature.sdk.exceptions.FlagNotFoundError; +import java.util.Map; +import java.util.function.Function; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +/** + * First match strategy. + * + *

Return the first result returned by a provider. + *

    + *
  • Skip providers that indicate they had no value due to {@code FLAG_NOT_FOUND}.
  • + *
  • On any other error code, return that error result.
  • + *
  • If a provider throws {@link FlagNotFoundError}, it is treated like {@code FLAG_NOT_FOUND}.
  • + *
  • If all providers report {@code FLAG_NOT_FOUND}, return a {@code FLAG_NOT_FOUND} error.
  • + *
+ * As soon as a non-{@code FLAG_NOT_FOUND} result is returned by a provider (success or other error), + * the rest of the operation short-circuits and does not call the remaining providers. + */ +@Slf4j +@NoArgsConstructor +public class FirstMatchStrategy implements Strategy { + + @Override + public ProviderEvaluation evaluate( + Map providers, + String key, + T defaultValue, + EvaluationContext ctx, + Function> providerFunction) { + for (FeatureProvider provider : providers.values()) { + try { + ProviderEvaluation res = providerFunction.apply(provider); + ErrorCode errorCode = res.getErrorCode(); + if (errorCode == null) { + // Successful evaluation + return res; + } + if (!FLAG_NOT_FOUND.equals(errorCode)) { + // Any non-FLAG_NOT_FOUND error bubbles up + return res; + } + // else FLAG_NOT_FOUND: skip to next provider + } catch (FlagNotFoundError ignored) { + // do not log in hot path, just skip + } + } + + // All providers either threw or returned FLAG_NOT_FOUND + return ProviderEvaluation.builder() + .errorMessage("Flag not found in any provider") + .errorCode(FLAG_NOT_FOUND) + .build(); + } +} diff --git a/src/main/java/dev/openfeature/sdk/multiprovider/FirstSuccessfulStrategy.java b/src/main/java/dev/openfeature/sdk/multiprovider/FirstSuccessfulStrategy.java new file mode 100644 index 000000000..6a3fc4433 --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/multiprovider/FirstSuccessfulStrategy.java @@ -0,0 +1,48 @@ +package dev.openfeature.sdk.multiprovider; + +import dev.openfeature.sdk.ErrorCode; +import dev.openfeature.sdk.EvaluationContext; +import dev.openfeature.sdk.FeatureProvider; +import dev.openfeature.sdk.ProviderEvaluation; +import java.util.Map; +import java.util.function.Function; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +/** + * First Successful Strategy. + * + *

Similar to “First Match”, except that errors from evaluated providers do not halt execution. + * Instead, it returns the first successful result from a provider. If no provider successfully + * responds, it returns a {@code GENERAL} error result. + */ +@Slf4j +@NoArgsConstructor +public class FirstSuccessfulStrategy implements Strategy { + + @Override + public ProviderEvaluation evaluate( + Map providers, + String key, + T defaultValue, + EvaluationContext ctx, + Function> providerFunction) { + for (FeatureProvider provider : providers.values()) { + try { + ProviderEvaluation res = providerFunction.apply(provider); + if (res.getErrorCode() == null) { + // First successful result (no error code) + return res; + } + } catch (Exception ignored) { + // swallow and continue; errors from individual providers + // are not fatal for this strategy + } + } + + return ProviderEvaluation.builder() + .errorMessage("No provider successfully responded") + .errorCode(ErrorCode.GENERAL) + .build(); + } +} diff --git a/src/main/java/dev/openfeature/sdk/multiprovider/MultiProvider.java b/src/main/java/dev/openfeature/sdk/multiprovider/MultiProvider.java new file mode 100644 index 000000000..cc6fb8db2 --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/multiprovider/MultiProvider.java @@ -0,0 +1,179 @@ +package dev.openfeature.sdk.multiprovider; + +import dev.openfeature.sdk.EvaluationContext; +import dev.openfeature.sdk.EventProvider; +import dev.openfeature.sdk.FeatureProvider; +import dev.openfeature.sdk.Metadata; +import dev.openfeature.sdk.ProviderEvaluation; +import dev.openfeature.sdk.Value; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +/** + * Experimental: Provider implementation for multi-provider. + * + *

This provider delegates flag evaluations to multiple underlying providers using a configurable + * {@link Strategy}. It also exposes combined metadata containing the original metadata of each + * underlying provider. + */ +@Slf4j +public class MultiProvider extends EventProvider { + + @Getter + private static final String NAME = "multiprovider"; + + // Use CPU count as upper bound for init threads. + public static final int INIT_THREADS_COUNT = Runtime.getRuntime().availableProcessors(); + + private final Map providers; + private final Strategy strategy; + private MultiProviderMetadata metadata; + + /** + * Constructs a MultiProvider with the given list of FeatureProviders, by default uses + * {@link FirstMatchStrategy}. + * + * @param providers the list of FeatureProviders to initialize the MultiProvider with + */ + public MultiProvider(List providers) { + this(providers, new FirstMatchStrategy()); + } + + /** + * Constructs a MultiProvider with the given list of FeatureProviders and a strategy. + * + * @param providers the list of FeatureProviders to initialize the MultiProvider with + * @param strategy the strategy (if {@code null}, {@link FirstMatchStrategy} is used) + */ + public MultiProvider(List providers, Strategy strategy) { + this.providers = buildProviders(providers); + this.strategy = Objects.requireNonNull(strategy, "strategy must not be null"); + } + + protected static Map buildProviders(List providers) { + Map providersMap = new LinkedHashMap<>(providers.size()); + for (FeatureProvider provider : providers) { + FeatureProvider prevProvider = + providersMap.put(provider.getMetadata().getName(), provider); + if (prevProvider != null) { + log.info("duplicated provider name: {}", provider.getMetadata().getName()); + } + } + return Collections.unmodifiableMap(providersMap); + } + + /** + * Initialize the provider. + * + * @param evaluationContext evaluation context + * @throws Exception on error (e.g. wrapped {@link java.util.concurrent.ExecutionException} + * from a failing provider) + */ + @Override + public void initialize(EvaluationContext evaluationContext) throws Exception { + var metadataBuilder = MultiProviderMetadata.builder().name(NAME); + HashMap providersMetadata = new HashMap<>(); + + if (providers.isEmpty()) { + metadataBuilder.originalMetadata(Collections.unmodifiableMap(providersMetadata)); + metadata = metadataBuilder.build(); + return; + } + + ExecutorService executorService = Executors.newFixedThreadPool(Math.min(INIT_THREADS_COUNT, providers.size())); + try { + Collection> tasks = new ArrayList<>(providers.size()); + for (FeatureProvider provider : providers.values()) { + tasks.add(() -> { + provider.initialize(evaluationContext); + return null; + }); + Metadata providerMetadata = provider.getMetadata(); + providersMetadata.put(providerMetadata.getName(), providerMetadata); + } + + metadataBuilder.originalMetadata(Collections.unmodifiableMap(providersMetadata)); + + List> results = executorService.invokeAll(tasks); + for (Future result : results) { + // This will re-throw any exception from the provider's initialize method, + // wrapped in an ExecutionException. + result.get(); + } + } catch (Exception e) { + // If initialization fails for any provider, attempt to shut down via the + // standard shutdown path to avoid a partial/limbo state. + try { + shutdown(); + } catch (Exception shutdownEx) { + log.error("error during shutdown after failed initialize", shutdownEx); + } + throw e; + } finally { + executorService.shutdown(); + } + + metadata = metadataBuilder.build(); + } + + @SuppressFBWarnings(value = "EI_EXPOSE_REP") + @Override + public Metadata getMetadata() { + return metadata; + } + + @Override + public ProviderEvaluation getBooleanEvaluation(String key, Boolean defaultValue, EvaluationContext ctx) { + return strategy.evaluate( + providers, key, defaultValue, ctx, p -> p.getBooleanEvaluation(key, defaultValue, ctx)); + } + + @Override + public ProviderEvaluation getStringEvaluation(String key, String defaultValue, EvaluationContext ctx) { + return strategy.evaluate(providers, key, defaultValue, ctx, p -> p.getStringEvaluation(key, defaultValue, ctx)); + } + + @Override + public ProviderEvaluation getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx) { + return strategy.evaluate( + providers, key, defaultValue, ctx, p -> p.getIntegerEvaluation(key, defaultValue, ctx)); + } + + @Override + public ProviderEvaluation getDoubleEvaluation(String key, Double defaultValue, EvaluationContext ctx) { + return strategy.evaluate(providers, key, defaultValue, ctx, p -> p.getDoubleEvaluation(key, defaultValue, ctx)); + } + + @Override + public ProviderEvaluation getObjectEvaluation(String key, Value defaultValue, EvaluationContext ctx) { + return strategy.evaluate(providers, key, defaultValue, ctx, p -> p.getObjectEvaluation(key, defaultValue, ctx)); + } + + @Override + public void shutdown() { + log.debug("shutdown begin"); + for (FeatureProvider provider : providers.values()) { + try { + provider.shutdown(); + } catch (Exception e) { + log.error("error shutdown provider {}", provider.getMetadata().getName(), e); + } + } + log.debug("shutdown end"); + // Important: ensure EventProvider's executor is also shut down + super.shutdown(); + } +} diff --git a/src/main/java/dev/openfeature/sdk/multiprovider/MultiProviderMetadata.java b/src/main/java/dev/openfeature/sdk/multiprovider/MultiProviderMetadata.java new file mode 100644 index 000000000..2f1bbfd46 --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/multiprovider/MultiProviderMetadata.java @@ -0,0 +1,20 @@ +package dev.openfeature.sdk.multiprovider; + +import dev.openfeature.sdk.Metadata; +import java.util.Map; +import lombok.Builder; +import lombok.Value; + +/** + * Metadata for {@link MultiProvider}. + * + *

Contains the multiprovider's own name and a map of the original metadata from each underlying + * provider. + */ +@Value +@Builder +public class MultiProviderMetadata implements Metadata { + + String name; + Map originalMetadata; +} diff --git a/src/main/java/dev/openfeature/sdk/multiprovider/Strategy.java b/src/main/java/dev/openfeature/sdk/multiprovider/Strategy.java new file mode 100644 index 000000000..4c25fe8f0 --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/multiprovider/Strategy.java @@ -0,0 +1,38 @@ +package dev.openfeature.sdk.multiprovider; + +import dev.openfeature.sdk.EvaluationContext; +import dev.openfeature.sdk.FeatureProvider; +import dev.openfeature.sdk.ProviderEvaluation; +import java.util.Map; +import java.util.function.Function; + +/** + * Strategy for determining how to evaluate a flag across multiple providers. + * + *

Implementations decide how to: + *

    + *
  • Order or select providers
  • + *
  • Handle {@code FLAG_NOT_FOUND} results
  • + *
  • Handle errors and exceptions from providers
  • + *
+ */ +public interface Strategy { + + /** + * Evaluate a flag across multiple providers. + * + * @param providers ordered map of provider name to provider + * @param key the flag key to evaluate + * @param defaultValue the default value to fall back to + * @param ctx the evaluation context (may be {@code null}) + * @param providerFunction function that executes the provider evaluation for the given key + * @param the flag value type + * @return the resolved {@link ProviderEvaluation} + */ + ProviderEvaluation evaluate( + Map providers, + String key, + T defaultValue, + EvaluationContext ctx, + Function> providerFunction); +} diff --git a/src/test/java/dev/openfeature/sdk/multiprovider/BaseStrategyTest.java b/src/test/java/dev/openfeature/sdk/multiprovider/BaseStrategyTest.java new file mode 100644 index 000000000..405a2f094 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/multiprovider/BaseStrategyTest.java @@ -0,0 +1,214 @@ +package dev.openfeature.sdk.multiprovider; + +import static dev.openfeature.sdk.ErrorCode.FLAG_NOT_FOUND; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import dev.openfeature.sdk.ErrorCode; +import dev.openfeature.sdk.EvaluationContext; +import dev.openfeature.sdk.FeatureProvider; +import dev.openfeature.sdk.Metadata; +import dev.openfeature.sdk.MutableContext; +import dev.openfeature.sdk.ProviderEvaluation; +import dev.openfeature.sdk.Value; +import dev.openfeature.sdk.providers.memory.Flag; +import dev.openfeature.sdk.providers.memory.InMemoryProvider; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import org.junit.jupiter.api.BeforeEach; + +public abstract class BaseStrategyTest { + + protected FeatureProvider mockProvider1; + protected FeatureProvider mockProvider2; + protected FeatureProvider mockProvider3; + + protected Metadata mockMetaData1; + protected Metadata mockMetaData2; + protected Metadata mockMetaData3; + + protected InMemoryProvider inMemoryProvider1; + protected InMemoryProvider inMemoryProvider2; + + protected Map orderedProviders; + + protected EvaluationContext contextWithNewProvider; + + protected static final String FLAG_KEY = "test-flag"; + protected static final String DEFAULT_STRING = "default"; + protected static final boolean DEFAULT_BOOLEAN = false; + protected static final int DEFAULT_INTEGER = 0; + protected static final double DEFAULT_DOUBLE = 0.0; + + @BeforeEach + void setUp() { + setupMockProviders(); + setupInMemoryProviders(); + setupOrderedProviders(); + setupEvaluationContexts(); + } + + protected void setupMockProviders() { + mockProvider1 = mock(FeatureProvider.class); + mockProvider2 = mock(FeatureProvider.class); + mockProvider3 = mock(FeatureProvider.class); + mockMetaData1 = mock(Metadata.class); + mockMetaData2 = mock(Metadata.class); + mockMetaData3 = mock(Metadata.class); + when(mockMetaData1.getName()).thenReturn("provider1"); + when(mockMetaData2.getName()).thenReturn("provider2"); + when(mockMetaData3.getName()).thenReturn("provider3"); + when(mockProvider1.getMetadata()).thenReturn(mockMetaData1); + when(mockProvider2.getMetadata()).thenReturn(mockMetaData2); + when(mockProvider3.getMetadata()).thenReturn(mockMetaData3); + } + + protected void setupInMemoryProviders() { + Map> flags1 = createFlags1(); + Map> flags2 = createFlags2(); + + inMemoryProvider1 = new InMemoryProvider(flags1) { + @Override + public Metadata getMetadata() { + return () -> "old-provider"; + } + }; + + inMemoryProvider2 = new InMemoryProvider(flags2) { + @Override + public Metadata getMetadata() { + return () -> "new-provider"; + } + }; + } + + protected void setupOrderedProviders() { + orderedProviders = new LinkedHashMap<>(); + orderedProviders.put("provider1", mockProvider1); + orderedProviders.put("provider2", mockProvider2); + orderedProviders.put("provider3", mockProvider3); + } + + protected void setupEvaluationContexts() { + contextWithNewProvider = new MutableContext().add("provider", "new-provider"); + } + + protected Map> createFlags1() { + Map> flags = new HashMap<>(); + + flags.put( + "b1", + Flag.builder() + .variant("on", true) + .variant("off", false) + .defaultVariant("on") + .build()); + + flags.put( + "i1", + Flag.builder().variant("default", 1).defaultVariant("default").build()); + + flags.put( + "d1", + Flag.builder().variant("default", 1.0).defaultVariant("default").build()); + + flags.put( + "s1", + Flag.builder() + .variant("default", "str1") + .defaultVariant("default") + .build()); + + flags.put( + "o1", + Flag.builder() + .variant("default", new Value("v1")) + .defaultVariant("default") + .build()); + + return flags; + } + + protected Map> createFlags2() { + Map> flags = new HashMap<>(); + + flags.put( + "b1", + Flag.builder() + .variant("on", true) + .variant("off", false) + .defaultVariant("off") + .build()); + + flags.put( + "i1", + Flag.builder().variant("default", 2).defaultVariant("default").build()); + + flags.put( + "d1", + Flag.builder().variant("default", 2.0).defaultVariant("default").build()); + + flags.put( + "s1", + Flag.builder() + .variant("default", "str2") + .defaultVariant("default") + .build()); + + flags.put( + "o1", + Flag.builder() + .variant("default", new Value("v2")) + .defaultVariant("default") + .build()); + + flags.put( + "s2", + Flag.builder() + .variant("default", "s2str2") + .defaultVariant("default") + .build()); + + return flags; + } + + protected ProviderEvaluation createErrorResult(ErrorCode errorCode) { + ProviderEvaluation result = mock(ProviderEvaluation.class); + when(result.getErrorCode()).thenReturn(errorCode); + return result; + } + + protected void setupProviderFlagNotFound(FeatureProvider provider) { + ProviderEvaluation stringResult = createErrorResult(FLAG_NOT_FOUND); + ProviderEvaluation booleanResult = createErrorResult(FLAG_NOT_FOUND); + ProviderEvaluation integerResult = createErrorResult(FLAG_NOT_FOUND); + ProviderEvaluation doubleResult = createErrorResult(FLAG_NOT_FOUND); + ProviderEvaluation objectResult = createErrorResult(FLAG_NOT_FOUND); + + when(provider.getStringEvaluation(BaseStrategyTest.FLAG_KEY, DEFAULT_STRING, null)) + .thenReturn(stringResult); + when(provider.getBooleanEvaluation(BaseStrategyTest.FLAG_KEY, DEFAULT_BOOLEAN, null)) + .thenReturn(booleanResult); + when(provider.getIntegerEvaluation(BaseStrategyTest.FLAG_KEY, DEFAULT_INTEGER, null)) + .thenReturn(integerResult); + when(provider.getDoubleEvaluation(BaseStrategyTest.FLAG_KEY, DEFAULT_DOUBLE, null)) + .thenReturn(doubleResult); + when(provider.getObjectEvaluation(BaseStrategyTest.FLAG_KEY, null, null)) + .thenReturn(objectResult); + } + + protected void setupProviderError(FeatureProvider provider, ErrorCode errorCode) { + ProviderEvaluation result = createErrorResult(errorCode); + when(provider.getStringEvaluation(BaseStrategyTest.FLAG_KEY, DEFAULT_STRING, null)) + .thenReturn(result); + } + + protected void setupProviderSuccess(FeatureProvider provider, String value) { + ProviderEvaluation result = mock(ProviderEvaluation.class); + when(result.getErrorCode()).thenReturn(null); + when(result.getValue()).thenReturn(value); + when(provider.getStringEvaluation(BaseStrategyTest.FLAG_KEY, DEFAULT_STRING, null)) + .thenReturn(result); + } +} diff --git a/src/test/java/dev/openfeature/sdk/multiprovider/FirstMatchStrategyTest.java b/src/test/java/dev/openfeature/sdk/multiprovider/FirstMatchStrategyTest.java new file mode 100644 index 000000000..0205961cd --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/multiprovider/FirstMatchStrategyTest.java @@ -0,0 +1,91 @@ +package dev.openfeature.sdk.multiprovider; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +import dev.openfeature.sdk.ErrorCode; +import dev.openfeature.sdk.ProviderEvaluation; +import org.junit.jupiter.api.Test; + +class FirstMatchStrategyTest extends BaseStrategyTest { + + private final FirstMatchStrategy strategy = new FirstMatchStrategy(); + + @Test + void shouldSkipFlagNotFoundAndReturnFirstMatch() { + setupProviderFlagNotFound(mockProvider1); + setupProviderSuccess(mockProvider2, "success"); + + ProviderEvaluation result = strategy.evaluate( + orderedProviders, + FLAG_KEY, + DEFAULT_STRING, + null, + p -> p.getStringEvaluation(FLAG_KEY, DEFAULT_STRING, null)); + + assertNotNull(result); + assertEquals("success", result.getValue()); + assertNull(result.getErrorCode()); + } + + @Test + void shouldReturnFirstNonFlagNotFoundError() { + setupProviderError(mockProvider1, ErrorCode.PARSE_ERROR); + setupProviderSuccess(mockProvider2, "success"); + ProviderEvaluation result = strategy.evaluate( + orderedProviders, + FLAG_KEY, + DEFAULT_STRING, + null, + p -> p.getStringEvaluation(FLAG_KEY, DEFAULT_STRING, null)); + assertEquals(ErrorCode.PARSE_ERROR, result.getErrorCode()); + } + + @Test + void shouldReturnSuccessWhenFirstProviderSucceeds() { + setupProviderSuccess(mockProvider1, "first-success"); + setupProviderFlagNotFound(mockProvider2); + ProviderEvaluation result = strategy.evaluate( + orderedProviders, + FLAG_KEY, + DEFAULT_STRING, + null, + p -> p.getStringEvaluation(FLAG_KEY, DEFAULT_STRING, null)); + + assertNotNull(result); + assertEquals("first-success", result.getValue()); + assertNull(result.getErrorCode()); + } + + @Test + void shouldThrowFlagNotFoundWhenAllProvidersReturnFlagNotFound() { + setupProviderFlagNotFound(mockProvider1); + setupProviderFlagNotFound(mockProvider2); + setupProviderFlagNotFound(mockProvider3); + ProviderEvaluation providerEvaluation = strategy.evaluate( + orderedProviders, + FLAG_KEY, + DEFAULT_STRING, + null, + p -> p.getStringEvaluation(FLAG_KEY, DEFAULT_STRING, null)); + + assertEquals(ErrorCode.FLAG_NOT_FOUND, providerEvaluation.getErrorCode()); + assertEquals("Flag not found in any provider", providerEvaluation.getErrorMessage()); + } + + @Test + void shouldSkipMultipleFlagNotFoundAndReturnFirstOtherError() { + setupProviderFlagNotFound(mockProvider1); + setupProviderFlagNotFound(mockProvider2); + setupProviderError(mockProvider3, ErrorCode.PARSE_ERROR); + ProviderEvaluation result = strategy.evaluate( + orderedProviders, + FLAG_KEY, + DEFAULT_STRING, + null, + p -> p.getStringEvaluation(FLAG_KEY, DEFAULT_STRING, null)); + assertNotNull(result); + assertEquals(ErrorCode.PARSE_ERROR, result.getErrorCode()); + } +} diff --git a/src/test/java/dev/openfeature/sdk/multiprovider/FirstSuccessfulStrategyTest.java b/src/test/java/dev/openfeature/sdk/multiprovider/FirstSuccessfulStrategyTest.java new file mode 100644 index 000000000..a47af8a2f --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/multiprovider/FirstSuccessfulStrategyTest.java @@ -0,0 +1,78 @@ +package dev.openfeature.sdk.multiprovider; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +import dev.openfeature.sdk.ErrorCode; +import dev.openfeature.sdk.ProviderEvaluation; +import org.junit.jupiter.api.Test; + +class FirstSuccessfulStrategyTest extends BaseStrategyTest { + + private final FirstSuccessfulStrategy strategy = new FirstSuccessfulStrategy(); + + @Test + void shouldSkipFlagNotFoundAndReturnFirstSuccess() { + setupProviderFlagNotFound(mockProvider1); + setupProviderSuccess(mockProvider2, "success"); + ProviderEvaluation result = strategy.evaluate( + orderedProviders, + FLAG_KEY, + DEFAULT_STRING, + null, + p -> p.getStringEvaluation(FLAG_KEY, DEFAULT_STRING, null)); + assertNotNull(result); + assertEquals("success", result.getValue()); + assertNull(result.getErrorCode()); + } + + @Test + void shouldThrowGeneralErrorWhenAllProvidersFail() { + setupProviderFlagNotFound(mockProvider1); + setupProviderError(mockProvider2, ErrorCode.PARSE_ERROR); + setupProviderError(mockProvider3, ErrorCode.TYPE_MISMATCH); + ProviderEvaluation providerEvaluation = strategy.evaluate( + orderedProviders, + FLAG_KEY, + DEFAULT_STRING, + null, + p -> p.getStringEvaluation(FLAG_KEY, DEFAULT_STRING, null)); + + assertEquals(ErrorCode.GENERAL, providerEvaluation.getErrorCode()); + assertEquals("No provider successfully responded", providerEvaluation.getErrorMessage()); + } + + @Test + void shouldSkipProvidersThatOnlyReturnErrors() { + setupProviderError(mockProvider1, ErrorCode.INVALID_CONTEXT); + setupProviderError(mockProvider2, ErrorCode.PROVIDER_NOT_READY); + setupProviderError(mockProvider3, ErrorCode.GENERAL); + + ProviderEvaluation providerEvaluation = strategy.evaluate( + orderedProviders, + FLAG_KEY, + DEFAULT_STRING, + null, + p -> p.getStringEvaluation(FLAG_KEY, DEFAULT_STRING, null)); + + assertEquals(ErrorCode.GENERAL, providerEvaluation.getErrorCode()); + assertEquals("No provider successfully responded", providerEvaluation.getErrorMessage()); + } + + @Test + void shouldThrowGeneralErrorForNonExistentFlag() { + orderedProviders.clear(); + orderedProviders.put("old-provider", inMemoryProvider1); + orderedProviders.put("new-provider", inMemoryProvider2); + ProviderEvaluation providerEvaluation = strategy.evaluate( + orderedProviders, + FLAG_KEY, + DEFAULT_STRING, + null, + p -> p.getStringEvaluation(FLAG_KEY, DEFAULT_STRING, null)); + + assertEquals(ErrorCode.GENERAL, providerEvaluation.getErrorCode()); + assertEquals("No provider successfully responded", providerEvaluation.getErrorMessage()); + } +} diff --git a/src/test/java/dev/openfeature/sdk/multiprovider/MultiProviderTest.java b/src/test/java/dev/openfeature/sdk/multiprovider/MultiProviderTest.java new file mode 100644 index 000000000..887b71d0a --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/multiprovider/MultiProviderTest.java @@ -0,0 +1,171 @@ +package dev.openfeature.sdk.multiprovider; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import dev.openfeature.sdk.ErrorCode; +import dev.openfeature.sdk.EvaluationContext; +import dev.openfeature.sdk.FeatureProvider; +import dev.openfeature.sdk.Metadata; +import dev.openfeature.sdk.MutableContext; +import dev.openfeature.sdk.ProviderEvaluation; +import dev.openfeature.sdk.Value; +import dev.openfeature.sdk.exceptions.GeneralError; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.function.Function; +import lombok.SneakyThrows; +import org.junit.jupiter.api.Test; + +class MultiProviderTest extends BaseStrategyTest { + + @Test + void shouldInitializeWithEmptyProvidersList() { + MultiProvider multiProvider = new MultiProvider(new ArrayList<>()); + assertDoesNotThrow(() -> multiProvider.initialize(null)); + assertNotNull(multiProvider.getMetadata()); + assertEquals(MultiProvider.getNAME(), multiProvider.getMetadata().getName()); + } + + @SneakyThrows + @Test + void shouldInitializeSuccessfully() { + List providers = new ArrayList<>(2); + providers.add(mockProvider1); + providers.add(mockProvider2); + Strategy strategy = mock(Strategy.class); + MultiProvider multiProvider = new MultiProvider(providers, strategy); + multiProvider.initialize(null); + + MultiProviderMetadata metadata = (MultiProviderMetadata) multiProvider.getMetadata(); + Map map = metadata.getOriginalMetadata(); + assertEquals(mockMetaData1, map.get(mockProvider1.getMetadata().getName())); + assertEquals(mockMetaData2, map.get(mockProvider2.getMetadata().getName())); + assertEquals("multiprovider", multiProvider.getMetadata().getName()); + } + + @SneakyThrows + @Test + void shouldHandleInitializationFailure() { + doThrow(new GeneralError()).when(mockProvider1).initialize(any()); + doThrow(new GeneralError()).when(mockProvider1).shutdown(); + List providers = new ArrayList<>(2); + providers.add(mockProvider1); + providers.add(mockProvider2); + Strategy strategy = mock(Strategy.class); + MultiProvider multiProvider = new MultiProvider(providers, strategy); + assertThrows(ExecutionException.class, () -> multiProvider.initialize(null)); + assertDoesNotThrow(multiProvider::shutdown); + } + + @Test + void shouldHandleDuplicateProviderNames() { + when(mockProvider1.getMetadata()).thenReturn(() -> "provider"); + when(mockProvider2.getMetadata()).thenReturn(() -> "provider"); + List providers = new ArrayList<>(2); + providers.add(mockProvider1); + providers.add(mockProvider2); + assertDoesNotThrow(() -> new MultiProvider(providers).initialize(null)); + } + + @Test + void shouldRejectNullStrategyInTwoArgConstructor() { + List providers = new ArrayList<>(); + providers.add(mockProvider1); + + assertThrows(NullPointerException.class, () -> new MultiProvider(providers, null)); + } + + @SneakyThrows + @Test + void shouldRetrieveCorrectMetadataName() { + List providers = new ArrayList<>(); + providers.add(mockProvider1); + Strategy mockStrategy = mock(Strategy.class); + MultiProvider multiProvider = new MultiProvider(providers, mockStrategy); + multiProvider.initialize(null); + MultiProviderMetadata metadata = (MultiProviderMetadata) multiProvider.getMetadata(); + Map map = metadata.getOriginalMetadata(); + assertEquals(mockMetaData1, map.get(mockProvider1.getMetadata().getName())); + } + + @SneakyThrows + @Test + void shouldUseDefaultFirstMatchStrategy() { + List providers = new ArrayList<>(2); + providers.add(inMemoryProvider1); + providers.add(inMemoryProvider2); + MultiProvider multiProvider = new MultiProvider(providers); + multiProvider.initialize(null); + assertEquals(true, multiProvider.getBooleanEvaluation("b1", false, null).getValue()); + assertEquals(1, multiProvider.getIntegerEvaluation("i1", 0, null).getValue()); + assertEquals(1.0, multiProvider.getDoubleEvaluation("d1", 0.0, null).getValue()); + assertEquals("str1", multiProvider.getStringEvaluation("s1", "", null).getValue()); + assertEquals( + "v1", + multiProvider.getObjectEvaluation("o1", null, null).getValue().asString()); + + ProviderEvaluation providerEvaluation = multiProvider.getStringEvaluation("non-existing", "", null); + assertEquals(ErrorCode.FLAG_NOT_FOUND, providerEvaluation.getErrorCode()); + assertEquals("Flag not found in any provider", providerEvaluation.getErrorMessage()); + } + + @SneakyThrows + @Test + void shouldWorkWithCustomStrategy() { + Strategy customStrategy = new Strategy() { + final FirstMatchStrategy fallbackStrategy = new FirstMatchStrategy(); + + @Override + public ProviderEvaluation evaluate( + Map providers, + String key, + T defaultValue, + EvaluationContext ctx, + Function> providerFunction) { + + Value contextProvider = null; + if (ctx != null) { + contextProvider = ctx.getValue("provider"); + } + + if (contextProvider != null && "new-provider".equals(contextProvider.asString())) { + return providerFunction.apply(providers.get("new-provider")); + } + return fallbackStrategy.evaluate(providers, key, defaultValue, ctx, providerFunction); + } + }; + + List providers = new ArrayList<>(2); + providers.add(inMemoryProvider1); + providers.add(inMemoryProvider2); + MultiProvider multiProvider = new MultiProvider(providers, customStrategy); + multiProvider.initialize(null); + EvaluationContext context = new MutableContext().add("provider", "new-provider"); + assertEquals( + false, multiProvider.getBooleanEvaluation("b1", true, context).getValue()); + assertEquals(true, multiProvider.getBooleanEvaluation("b1", true, null).getValue()); + } + + @SneakyThrows + @Test + void shouldSupportAllEvaluationTypes() { + List providers = new ArrayList<>(1); + providers.add(inMemoryProvider1); + MultiProvider multiProvider = new MultiProvider(providers); + multiProvider.initialize(null); + assertNotNull(multiProvider.getBooleanEvaluation("b1", false, null)); + assertNotNull(multiProvider.getIntegerEvaluation("i1", 0, null)); + assertNotNull(multiProvider.getDoubleEvaluation("d1", 0.0, null)); + assertNotNull(multiProvider.getStringEvaluation("s1", "", null)); + assertNotNull(multiProvider.getObjectEvaluation("o1", null, null)); + } +} From c69261c051c60703ed6f791189d452579238c611 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 8 Jan 2026 21:30:27 +0000 Subject: [PATCH 574/745] chore(deps): update github/codeql-action digest to f6a16be (#1799) 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 29cfe16b2..cc503a11a 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@b2951d2a1ed70de8ec57301118b487b35c13595a + uses: github/codeql-action/init@f6a16bef8e5c39e398e4da16862d381f76824ac6 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b2951d2a1ed70de8ec57301118b487b35c13595a + uses: github/codeql-action/analyze@f6a16bef8e5c39e398e4da16862d381f76824ac6 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index e86b386b4..88a7208df 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@b2951d2a1ed70de8ec57301118b487b35c13595a + uses: github/codeql-action/init@f6a16bef8e5c39e398e4da16862d381f76824ac6 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@b2951d2a1ed70de8ec57301118b487b35c13595a + uses: github/codeql-action/autobuild@f6a16bef8e5c39e398e4da16862d381f76824ac6 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b2951d2a1ed70de8ec57301118b487b35c13595a + uses: github/codeql-action/analyze@f6a16bef8e5c39e398e4da16862d381f76824ac6 From 5ce76ff1725f6e9a3949e2747b83dce1c8ca2a97 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Jan 2026 16:25:26 +0000 Subject: [PATCH 575/745] chore(deps): update actions/checkout digest to 064fe7f (#1800) 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 +- .github/workflows/static-code-scanning.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index fc3c93e96..68acd5f4b 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + - uses: actions/checkout@064fe7f3312418007dea2b49a19844a9ee378f49 with: fetch-depth: 0 submodules: recursive diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index cc503a11a..392f7e9a8 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -19,7 +19,7 @@ jobs: runs-on: ${{ matrix.os}} steps: - name: Check out the code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + uses: actions/checkout@064fe7f3312418007dea2b49a19844a9ee378f49 with: fetch-depth: 0 submodules: recursive diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c970ca8f3..41f2c1ce1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,7 +37,7 @@ jobs: steps: - name: Checkout Repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + uses: actions/checkout@064fe7f3312418007dea2b49a19844a9ee378f49 with: fetch-depth: 0 submodules: recursive diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 88a7208df..5dc67a2e5 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + uses: actions/checkout@064fe7f3312418007dea2b49a19844a9ee378f49 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL From acfa9eff28989212fddbeba3e0553a60524064e3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 10 Jan 2026 00:21:25 +0000 Subject: [PATCH 576/745] chore(deps): update actions/checkout digest to 0c366fd (#1801) 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 +- .github/workflows/static-code-scanning.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index 68acd5f4b..7505616d8 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@064fe7f3312418007dea2b49a19844a9ee378f49 + - uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 with: fetch-depth: 0 submodules: recursive diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 392f7e9a8..1c3aa4cd1 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -19,7 +19,7 @@ jobs: runs-on: ${{ matrix.os}} steps: - name: Check out the code - uses: actions/checkout@064fe7f3312418007dea2b49a19844a9ee378f49 + uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 with: fetch-depth: 0 submodules: recursive diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 41f2c1ce1..715a85701 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,7 +37,7 @@ jobs: steps: - name: Checkout Repository - uses: actions/checkout@064fe7f3312418007dea2b49a19844a9ee378f49 + uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 with: fetch-depth: 0 submodules: recursive diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 5dc67a2e5..558e7e012 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@064fe7f3312418007dea2b49a19844a9ee378f49 + uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL From f477eb1976d02bb2453cdf1b281074f00c44f06c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 10 Jan 2026 12:21:18 +0000 Subject: [PATCH 577/745] chore(deps): update github/codeql-action digest to 0fa411e (#1802) 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 1c3aa4cd1..528071aa7 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@f6a16bef8e5c39e398e4da16862d381f76824ac6 + uses: github/codeql-action/init@0fa411efd0628aefdf9d03a0faa20a1e0edafc4a with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f6a16bef8e5c39e398e4da16862d381f76824ac6 + uses: github/codeql-action/analyze@0fa411efd0628aefdf9d03a0faa20a1e0edafc4a diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 558e7e012..fa5c39c3f 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@f6a16bef8e5c39e398e4da16862d381f76824ac6 + uses: github/codeql-action/init@0fa411efd0628aefdf9d03a0faa20a1e0edafc4a with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@f6a16bef8e5c39e398e4da16862d381f76824ac6 + uses: github/codeql-action/autobuild@0fa411efd0628aefdf9d03a0faa20a1e0edafc4a - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f6a16bef8e5c39e398e4da16862d381f76824ac6 + uses: github/codeql-action/analyze@0fa411efd0628aefdf9d03a0faa20a1e0edafc4a From 4afdfab201fe49081afc4dfe7e1c0add43694dbf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:21:56 +0000 Subject: [PATCH 578/745] chore(deps): update github/codeql-action digest to a2d9de6 (#1803) 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 528071aa7..1ccf5cc56 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@0fa411efd0628aefdf9d03a0faa20a1e0edafc4a + uses: github/codeql-action/init@a2d9de63c2916881d0621fdb7e65abe32141606d with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0fa411efd0628aefdf9d03a0faa20a1e0edafc4a + uses: github/codeql-action/analyze@a2d9de63c2916881d0621fdb7e65abe32141606d diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index fa5c39c3f..663731404 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@0fa411efd0628aefdf9d03a0faa20a1e0edafc4a + uses: github/codeql-action/init@a2d9de63c2916881d0621fdb7e65abe32141606d with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@0fa411efd0628aefdf9d03a0faa20a1e0edafc4a + uses: github/codeql-action/autobuild@a2d9de63c2916881d0621fdb7e65abe32141606d - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0fa411efd0628aefdf9d03a0faa20a1e0edafc4a + uses: github/codeql-action/analyze@a2d9de63c2916881d0621fdb7e65abe32141606d From 55accf51cae233e9edfe4f5dc6e5682a0006a2fb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 16 Jan 2026 04:25:46 +0000 Subject: [PATCH 579/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.18.4 (#1804) 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 f1a4bd0b4..d5d692373 100644 --- a/pom.xml +++ b/pom.xml @@ -214,7 +214,7 @@ net.bytebuddy byte-buddy - 1.18.3 + 1.18.4 test From 742e0e3bc693e7ad19298ed670034747c3c34d09 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 16 Jan 2026 07:17:31 +0100 Subject: [PATCH 580/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.18.4 (#1805) 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 d5d692373..307809b8a 100644 --- a/pom.xml +++ b/pom.xml @@ -221,7 +221,7 @@ net.bytebuddy byte-buddy-agent - 1.18.3 + 1.18.4 test From 8426a9ce8ae65fb15ae571dab609da269d691a8f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 16 Jan 2026 10:21:20 +0100 Subject: [PATCH 581/745] chore(deps): update amannn/action-semantic-pull-request digest to b439535 (#1806) 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 a1d4d3136..f9e52e210 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@71b07ef490c9e8ef772f64a62d41545ae5b9ef22 + - uses: amannn/action-semantic-pull-request@b439535a8eb2122b748ed2b45d1693aaabe5b0aa env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 5ffacae2a4ef6022a7d277ffc992650e7a5b589c Mon Sep 17 00:00:00 2001 From: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> Date: Fri, 16 Jan 2026 14:48:37 -0500 Subject: [PATCH 582/745] chore(main): release 1.20.0 (#1770) Signed-off-by: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 51 +++++++++++++++++++++++++++++++++++ README.md | 8 +++--- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 58 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 0326aeb19..2d2b6b2ef 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"1.19.2"} +{".":"1.20.0"} diff --git a/CHANGELOG.md b/CHANGELOG.md index ac251c3cf..7e12c7268 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,56 @@ # Changelog +## [1.20.0](https://github.com/open-feature/java-sdk/compare/v1.19.2...v1.20.0) (2026-01-16) + + +### 🐛 Bug Fixes + +* .equals false for equivalent contexts ([#1768](https://github.com/open-feature/java-sdk/issues/1768))" ([ae69411](https://github.com/open-feature/java-sdk/commit/ae6941122e5dcc6bbfc816a12d0879c14c6d49ab)) +* **deps:** update dependency io.cucumber:cucumber-bom to v7.33.0 ([#1769](https://github.com/open-feature/java-sdk/issues/1769)) ([a0305f9](https://github.com/open-feature/java-sdk/commit/a0305f965e262022701e09ae59bb20e9be5c0e4c)) +* **deps:** update dependency org.junit:junit-bom to v6.0.2 ([#1797](https://github.com/open-feature/java-sdk/issues/1797)) ([796e7c3](https://github.com/open-feature/java-sdk/commit/796e7c3bda020c096ee9d130e12fe2940057bb60)) + + +### ✨ New Features + +* add multi-provider to SDK ([#1765](https://github.com/open-feature/java-sdk/issues/1765)) ([2d03c15](https://github.com/open-feature/java-sdk/commit/2d03c159da0e326658ede2d847a43517b848ff88)) +* all executors now create daemon threads to reduce shutdown time ([#1715](https://github.com/open-feature/java-sdk/issues/1715)) ([0c30896](https://github.com/open-feature/java-sdk/commit/0c308968826f2a45fed492b115ecbb84a17f0765)) +* equivalent EvaluationContext impls are .equal ([#1771](https://github.com/open-feature/java-sdk/issues/1771)) ([ae69411](https://github.com/open-feature/java-sdk/commit/ae6941122e5dcc6bbfc816a12d0879c14c6d49ab)) + + +### 🧹 Chore + +* **deps:** update actions/cache digest to 9255dc7 ([#1778](https://github.com/open-feature/java-sdk/issues/1778)) ([4a55a8a](https://github.com/open-feature/java-sdk/commit/4a55a8a3f2dabde0eb6ee09b5fe13529a8fb5c7a)) +* **deps:** update actions/cache digest to a783357 ([#1776](https://github.com/open-feature/java-sdk/issues/1776)) ([c36701c](https://github.com/open-feature/java-sdk/commit/c36701c31f89a2a73d0a54d1135e928317b1b2de)) +* **deps:** update actions/checkout digest to 064fe7f ([#1800](https://github.com/open-feature/java-sdk/issues/1800)) ([5ce76ff](https://github.com/open-feature/java-sdk/commit/5ce76ff1725f6e9a3949e2747b83dce1c8ca2a97)) +* **deps:** update actions/checkout digest to 0c366fd ([#1801](https://github.com/open-feature/java-sdk/issues/1801)) ([acfa9ef](https://github.com/open-feature/java-sdk/commit/acfa9eff28989212fddbeba3e0553a60524064e3)) +* **deps:** update actions/setup-java digest to 5d7b214 ([#1789](https://github.com/open-feature/java-sdk/issues/1789)) ([69521a0](https://github.com/open-feature/java-sdk/commit/69521a0c96de4ca132084633f8d6e1dc3dfe27c1)) +* **deps:** update amannn/action-semantic-pull-request digest to 71b07ef ([#1793](https://github.com/open-feature/java-sdk/issues/1793)) ([e81d2f8](https://github.com/open-feature/java-sdk/commit/e81d2f81bfe5e2cbc70debea8c3ea8ff5c05cc61)) +* **deps:** update amannn/action-semantic-pull-request digest to b439535 ([#1806](https://github.com/open-feature/java-sdk/issues/1806)) ([8426a9c](https://github.com/open-feature/java-sdk/commit/8426a9ce8ae65fb15ae571dab609da269d691a8f)) +* **deps:** update codecov/codecov-action action to v5.5.2 ([#1773](https://github.com/open-feature/java-sdk/issues/1773)) ([46aa311](https://github.com/open-feature/java-sdk/commit/46aa311a8caab33e66eddd1cb40c11cadd0cf8ca)) +* **deps:** update com.vmlens.version to v1.2.24 ([#1791](https://github.com/open-feature/java-sdk/issues/1791)) ([af3c950](https://github.com/open-feature/java-sdk/commit/af3c95073eaa8566fe3e526c3b57441ac3df1816)) +* **deps:** update dependency com.puppycrawl.tools:checkstyle to v12.3.0 ([#1779](https://github.com/open-feature/java-sdk/issues/1779)) ([1ee5aa8](https://github.com/open-feature/java-sdk/commit/1ee5aa8d4fc2a44b565e81ff0c38c07246f12d49)) +* **deps:** update dependency com.puppycrawl.tools:checkstyle to v12.3.1 ([#1790](https://github.com/open-feature/java-sdk/issues/1790)) ([a237df3](https://github.com/open-feature/java-sdk/commit/a237df34cf017a4e33e790106e5e91e2befe0b9e)) +* **deps:** update dependency maven to v3.9.12 ([#1783](https://github.com/open-feature/java-sdk/issues/1783)) ([31b4872](https://github.com/open-feature/java-sdk/commit/31b4872a52942518162153edff441491cedc0803)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.18.3 ([#1786](https://github.com/open-feature/java-sdk/issues/1786)) ([a865880](https://github.com/open-feature/java-sdk/commit/a86588086407bdb80e3c84d37b9db49380da7bb7)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.18.4 ([#1804](https://github.com/open-feature/java-sdk/issues/1804)) ([55accf5](https://github.com/open-feature/java-sdk/commit/55accf51cae233e9edfe4f5dc6e5682a0006a2fb)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.18.3 ([#1787](https://github.com/open-feature/java-sdk/issues/1787)) ([52ebe0d](https://github.com/open-feature/java-sdk/commit/52ebe0df7022f1f5fe58dc91d384a50fce511891)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.18.4 ([#1805](https://github.com/open-feature/java-sdk/issues/1805)) ([742e0e3](https://github.com/open-feature/java-sdk/commit/742e0e3bc693e7ad19298ed670034747c3c34d09)) +* **deps:** update dependency org.codehaus.mojo:exec-maven-plugin to v3.6.3 ([#1788](https://github.com/open-feature/java-sdk/issues/1788)) ([0b4325a](https://github.com/open-feature/java-sdk/commit/0b4325a830997840ae3b622df93ca720e73a9088)) +* **deps:** update dependency org.mockito:mockito-core to v5.21.0 ([#1774](https://github.com/open-feature/java-sdk/issues/1774)) ([3e18496](https://github.com/open-feature/java-sdk/commit/3e184962d6fa7bc70406abb6ed48d9d0eb9540d2)) +* **deps:** update github/codeql-action digest to 0fa411e ([#1802](https://github.com/open-feature/java-sdk/issues/1802)) ([f477eb1](https://github.com/open-feature/java-sdk/commit/f477eb1976d02bb2453cdf1b281074f00c44f06c)) +* **deps:** update github/codeql-action digest to 1b0b941 ([#1775](https://github.com/open-feature/java-sdk/issues/1775)) ([6d028f0](https://github.com/open-feature/java-sdk/commit/6d028f06831dbdb916981752d946c601dff81d42)) +* **deps:** update github/codeql-action digest to 4b675e4 ([#1777](https://github.com/open-feature/java-sdk/issues/1777)) ([cffa253](https://github.com/open-feature/java-sdk/commit/cffa25347237640e49fc5ed0d690b3e1b4bf27d1)) +* **deps:** update github/codeql-action digest to 6dba008 ([#1782](https://github.com/open-feature/java-sdk/issues/1782)) ([5467902](https://github.com/open-feature/java-sdk/commit/5467902994fe406f02e36f97a23750748370f9b9)) +* **deps:** update github/codeql-action digest to a2d9de6 ([#1803](https://github.com/open-feature/java-sdk/issues/1803)) ([4afdfab](https://github.com/open-feature/java-sdk/commit/4afdfab201fe49081afc4dfe7e1c0add43694dbf)) +* **deps:** update github/codeql-action digest to b2951d2 ([#1796](https://github.com/open-feature/java-sdk/issues/1796)) ([0ee25d9](https://github.com/open-feature/java-sdk/commit/0ee25d9d07e5a9b435c415fede97ab7aab1131f8)) +* **deps:** update github/codeql-action digest to b5e1a28 ([#1781](https://github.com/open-feature/java-sdk/issues/1781)) ([63227e7](https://github.com/open-feature/java-sdk/commit/63227e73fac55f50684a449236fb70408a1c64d3)) +* **deps:** update github/codeql-action digest to b88acb2 ([#1784](https://github.com/open-feature/java-sdk/issues/1784)) ([947c1e2](https://github.com/open-feature/java-sdk/commit/947c1e2ef9fe63fe753fdcbce45c7774259a3fce)) +* **deps:** update github/codeql-action digest to c43362b ([#1772](https://github.com/open-feature/java-sdk/issues/1772)) ([2a37f46](https://github.com/open-feature/java-sdk/commit/2a37f46e9638a966e71eb30a9b5a7504faf0d817)) +* **deps:** update github/codeql-action digest to d0ad1da ([#1780](https://github.com/open-feature/java-sdk/issues/1780)) ([d0c066f](https://github.com/open-feature/java-sdk/commit/d0c066f0c9aecd269fa3b49908559a860a1d2b37)) +* **deps:** update github/codeql-action digest to f67ec12 ([#1785](https://github.com/open-feature/java-sdk/issues/1785)) ([9f801f4](https://github.com/open-feature/java-sdk/commit/9f801f49e0ad45522e967e65e663f32aaaab2fa2)) +* **deps:** update github/codeql-action digest to f6a16be ([#1799](https://github.com/open-feature/java-sdk/issues/1799)) ([c69261c](https://github.com/open-feature/java-sdk/commit/c69261c051c60703ed6f791189d452579238c611)) +* **deps:** update github/codeql-action digest to fd448f7 ([#1795](https://github.com/open-feature/java-sdk/issues/1795)) ([30c6886](https://github.com/open-feature/java-sdk/commit/30c68867869040cb716960af90e8f63118587769)) + ## [1.19.2](https://github.com/open-feature/java-sdk/compare/v1.19.1...v1.19.2) (2025-12-08) diff --git a/README.md b/README.md index b64aa3c46..8ebdb4418 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.19.2 + 1.20.0 ``` @@ -84,7 +84,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:1.19.2' + implementation 'dev.openfeature:sdk:1.20.0' } ``` diff --git a/pom.xml b/pom.xml index 307809b8a..2048564ec 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ dev.openfeature sdk - 1.19.2 + 1.20.0 [17,) diff --git a/version.txt b/version.txt index 836ae4eda..398935591 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.19.2 +1.20.0 From bf226d7cde44395be7c8222be05aaa7e199a7a9c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 16 Jan 2026 15:03:35 -0500 Subject: [PATCH 583/745] chore(deps): update actions/cache digest to 8b402f5 (#1808) 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 7505616d8..ba6ee51c1 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -36,7 +36,7 @@ jobs: server-password: ${{ secrets.CENTRAL_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb + uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 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 1ccf5cc56..dc5acb6b0 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -37,7 +37,7 @@ jobs: languages: java - name: Cache local Maven repository - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb + uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 with: path: ~/.m2/repository key: ${{ runner.os }}${{ matrix.build.java }}-maven-${{ hashFiles('**/pom.xml') }} From 852e256019a6e82ebd2b4a23a4e83e5bf1462a73 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Jan 2026 04:23:24 +0000 Subject: [PATCH 584/745] chore(deps): update github/codeql-action digest to fb650c2 (#1809) 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 dc5acb6b0..b9fc5a39f 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@a2d9de63c2916881d0621fdb7e65abe32141606d + uses: github/codeql-action/init@fb650c22f965a3eff7e20c5535e51a256dd16bf1 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@a2d9de63c2916881d0621fdb7e65abe32141606d + uses: github/codeql-action/analyze@fb650c22f965a3eff7e20c5535e51a256dd16bf1 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 663731404..47303a9d2 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@a2d9de63c2916881d0621fdb7e65abe32141606d + uses: github/codeql-action/init@fb650c22f965a3eff7e20c5535e51a256dd16bf1 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@a2d9de63c2916881d0621fdb7e65abe32141606d + uses: github/codeql-action/autobuild@fb650c22f965a3eff7e20c5535e51a256dd16bf1 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@a2d9de63c2916881d0621fdb7e65abe32141606d + uses: github/codeql-action/analyze@fb650c22f965a3eff7e20c5535e51a256dd16bf1 From 925477d4e8f6c795bc6000112ebc3830069a430f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 19 Jan 2026 04:26:45 +0000 Subject: [PATCH 585/745] fix(deps): update dependency com.fasterxml.jackson:jackson-bom to v2.21.0 (#1811) 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 2048564ec..3a29705d2 100644 --- a/pom.xml +++ b/pom.xml @@ -229,7 +229,7 @@ com.fasterxml.jackson jackson-bom - 2.20.1 + 2.21.0 pom import From 1b9eb9be8b25440b45afe5f541e09b963643cefe Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 19 Jan 2026 13:50:34 +0100 Subject: [PATCH 586/745] chore(deps): update github/codeql-action digest to f687ebf (#1812) 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 b9fc5a39f..d1c442231 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@fb650c22f965a3eff7e20c5535e51a256dd16bf1 + uses: github/codeql-action/init@f687ebf1c9abf6527d0e770ea83ee5dcff11f60e with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@fb650c22f965a3eff7e20c5535e51a256dd16bf1 + uses: github/codeql-action/analyze@f687ebf1c9abf6527d0e770ea83ee5dcff11f60e diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 47303a9d2..e02c7ae39 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@fb650c22f965a3eff7e20c5535e51a256dd16bf1 + uses: github/codeql-action/init@f687ebf1c9abf6527d0e770ea83ee5dcff11f60e with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@fb650c22f965a3eff7e20c5535e51a256dd16bf1 + uses: github/codeql-action/autobuild@f687ebf1c9abf6527d0e770ea83ee5dcff11f60e - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@fb650c22f965a3eff7e20c5535e51a256dd16bf1 + uses: github/codeql-action/analyze@f687ebf1c9abf6527d0e770ea83ee5dcff11f60e From cc81a918a39a8b3d363903a91a3c369aec84067d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 19 Jan 2026 20:35:36 +0000 Subject: [PATCH 587/745] chore(deps): update github/codeql-action digest to 1ec7dd2 (#1813) 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 d1c442231..92b94c5b1 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@f687ebf1c9abf6527d0e770ea83ee5dcff11f60e + uses: github/codeql-action/init@1ec7dd2bc4c2d5776ab565aa07221b7432e62cc7 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f687ebf1c9abf6527d0e770ea83ee5dcff11f60e + uses: github/codeql-action/analyze@1ec7dd2bc4c2d5776ab565aa07221b7432e62cc7 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index e02c7ae39..fa727e0cf 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@f687ebf1c9abf6527d0e770ea83ee5dcff11f60e + uses: github/codeql-action/init@1ec7dd2bc4c2d5776ab565aa07221b7432e62cc7 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@f687ebf1c9abf6527d0e770ea83ee5dcff11f60e + uses: github/codeql-action/autobuild@1ec7dd2bc4c2d5776ab565aa07221b7432e62cc7 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f687ebf1c9abf6527d0e770ea83ee5dcff11f60e + uses: github/codeql-action/analyze@1ec7dd2bc4c2d5776ab565aa07221b7432e62cc7 From 968b5ede67928f4906070508b29578fd4af90bfc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 20 Jan 2026 08:07:45 +0100 Subject: [PATCH 588/745] chore(deps): update actions/setup-java digest to 1b1bbe1 (#1814) 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 ba6ee51c1..d161868f7 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -26,7 +26,7 @@ jobs: fetch-depth: 0 submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@5d7b2146334bacf88728daaa70414a99f5164e0f + uses: actions/setup-java@1b1bbe1085cb6ab21b5b19b7bebc091a9430026a with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 92b94c5b1..7c6d8c3cb 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -25,7 +25,7 @@ jobs: submodules: recursive - name: Set up JDK ${{ matrix.build.java }} - uses: actions/setup-java@5d7b2146334bacf88728daaa70414a99f5164e0f + uses: actions/setup-java@1b1bbe1085cb6ab21b5b19b7bebc091a9430026a with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 715a85701..1d2f331cb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,7 +43,7 @@ jobs: submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@5d7b2146334bacf88728daaa70414a99f5164e0f + uses: actions/setup-java@1b1bbe1085cb6ab21b5b19b7bebc091a9430026a with: java-version: '17' distribution: 'temurin' From 3dd51c3f719ea6181c6cf58a22c4836cd44348c1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 20 Jan 2026 10:23:56 +0100 Subject: [PATCH 589/745] chore(deps): update dependency org.sonatype.central:central-publishing-maven-plugin to v0.10.0 (#1798) 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 3a29705d2..d47f4bfbf 100644 --- a/pom.xml +++ b/pom.xml @@ -618,7 +618,7 @@ org.sonatype.central central-publishing-maven-plugin - 0.9.0 + 0.10.0 true central From c49967717b0025e4716441e1e0a2c5e548a33ba7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 20 Jan 2026 13:54:23 +0100 Subject: [PATCH 590/745] chore(deps): update github/codeql-action digest to 044ff10 (#1815) 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 7c6d8c3cb..beb0ee63d 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@1ec7dd2bc4c2d5776ab565aa07221b7432e62cc7 + uses: github/codeql-action/init@044ff10e294c786eb4ed345ca4b2c37300df28e2 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1ec7dd2bc4c2d5776ab565aa07221b7432e62cc7 + uses: github/codeql-action/analyze@044ff10e294c786eb4ed345ca4b2c37300df28e2 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index fa727e0cf..e4e0df357 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@1ec7dd2bc4c2d5776ab565aa07221b7432e62cc7 + uses: github/codeql-action/init@044ff10e294c786eb4ed345ca4b2c37300df28e2 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@1ec7dd2bc4c2d5776ab565aa07221b7432e62cc7 + uses: github/codeql-action/autobuild@044ff10e294c786eb4ed345ca4b2c37300df28e2 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1ec7dd2bc4c2d5776ab565aa07221b7432e62cc7 + uses: github/codeql-action/analyze@044ff10e294c786eb4ed345ca4b2c37300df28e2 From ca7de4823b50d8eea4696d554c4d76bf16f7c235 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 20 Jan 2026 20:33:23 +0000 Subject: [PATCH 591/745] chore(deps): update github/codeql-action digest to 32d41f3 (#1817) 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 beb0ee63d..2e754c3fc 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@044ff10e294c786eb4ed345ca4b2c37300df28e2 + uses: github/codeql-action/init@32d41f36fe7c3d2125b2ef434749e8f445ec42cf with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@044ff10e294c786eb4ed345ca4b2c37300df28e2 + uses: github/codeql-action/analyze@32d41f36fe7c3d2125b2ef434749e8f445ec42cf diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index e4e0df357..e34d926ad 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@044ff10e294c786eb4ed345ca4b2c37300df28e2 + uses: github/codeql-action/init@32d41f36fe7c3d2125b2ef434749e8f445ec42cf with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@044ff10e294c786eb4ed345ca4b2c37300df28e2 + uses: github/codeql-action/autobuild@32d41f36fe7c3d2125b2ef434749e8f445ec42cf - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@044ff10e294c786eb4ed345ca4b2c37300df28e2 + uses: github/codeql-action/analyze@32d41f36fe7c3d2125b2ef434749e8f445ec42cf From 084539f8cbc080c08d6044e835351594bd19b73c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 21 Jan 2026 00:22:53 +0000 Subject: [PATCH 592/745] chore(deps): update actions/setup-java digest to d81c4e4 (#1816) 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 d161868f7..428500b6f 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -26,7 +26,7 @@ jobs: fetch-depth: 0 submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@1b1bbe1085cb6ab21b5b19b7bebc091a9430026a + uses: actions/setup-java@d81c4e45f3ac973cc936d79104023e20054ba578 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 2e754c3fc..a85818ef3 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -25,7 +25,7 @@ jobs: submodules: recursive - name: Set up JDK ${{ matrix.build.java }} - uses: actions/setup-java@1b1bbe1085cb6ab21b5b19b7bebc091a9430026a + uses: actions/setup-java@d81c4e45f3ac973cc936d79104023e20054ba578 with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1d2f331cb..2ac377e8d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,7 +43,7 @@ jobs: submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@1b1bbe1085cb6ab21b5b19b7bebc091a9430026a + uses: actions/setup-java@d81c4e45f3ac973cc936d79104023e20054ba578 with: java-version: '17' distribution: 'temurin' From d3df29476df0144b808c44ac7dc636f83ee55467 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 21 Jan 2026 20:24:35 +0000 Subject: [PATCH 593/745] chore(deps): update github/codeql-action digest to 1c4c0b3 (#1818) 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 a85818ef3..135287b24 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@32d41f36fe7c3d2125b2ef434749e8f445ec42cf + uses: github/codeql-action/init@1c4c0b36be82b11c8adb51fb38f7122d0debe048 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@32d41f36fe7c3d2125b2ef434749e8f445ec42cf + uses: github/codeql-action/analyze@1c4c0b36be82b11c8adb51fb38f7122d0debe048 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index e34d926ad..104a753e6 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@32d41f36fe7c3d2125b2ef434749e8f445ec42cf + uses: github/codeql-action/init@1c4c0b36be82b11c8adb51fb38f7122d0debe048 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@32d41f36fe7c3d2125b2ef434749e8f445ec42cf + uses: github/codeql-action/autobuild@1c4c0b36be82b11c8adb51fb38f7122d0debe048 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@32d41f36fe7c3d2125b2ef434749e8f445ec42cf + uses: github/codeql-action/analyze@1c4c0b36be82b11c8adb51fb38f7122d0debe048 From e8fb3a18ca514c686b4a0655f95562ff1f4d1529 Mon Sep 17 00:00:00 2001 From: Leo Romanovsky Date: Thu, 22 Jan 2026 01:32:35 -0500 Subject: [PATCH 594/745] fix: Allow empty string as a valid targeting key (#1807) * Allow empty string as a valid targeting key The OpenFeature spec defines targeting key as "a string" with no restriction on empty strings. The TARGETING_KEY_MISSING error code is for when a key is "not provided" (null), not when it's an empty string. Previously, MutableContext rejected empty strings by checking `!targetingKey.trim().isEmpty()`, treating them the same as null. This made it impossible to distinguish between "not provided" and "explicitly set to empty string". Changes: - Remove isEmpty check from constructor and setTargetingKey() - Empty string is now stored and returned by getTargetingKey() - Null still results in no targeting key being set - Updated tests to reflect new behavior - Added explicit tests for empty string targeting key Signed-off-by: Leo Romanovsky * Also update ImmutableContext and add whitespace tests - Update ImmutableContext to allow empty string targeting keys, matching the MutableContext behavior for consistency - Add tests for whitespace-only targeting keys to explicitly document this is now permitted - Update merge behavior tests to reflect that empty string targeting keys now override existing values Signed-off-by: Leo Romanovsky * Combine empty and whitespace setter tests per review feedback Signed-off-by: Leo Romanovsky * Fix EvalContextTest merge tests for whitespace targeting keys Signed-off-by: Leo Romanovsky * Add test for setTargetingKey(null) to improve coverage Signed-off-by: Leo Romanovsky * Add nullability test for ImmutableContext constructor Per review feedback, add test to verify that passing null to the ImmutableContext constructor results in no targeting key being set. Signed-off-by: Leo Romanovsky * Fix ambiguous constructor call in ImmutableContext test Cast null to String to disambiguate between ImmutableContext(String) and ImmutableContext(Map) constructors. Signed-off-by: Leo Romanovsky --------- Signed-off-by: Leo Romanovsky Co-authored-by: Justin Abrahms --- .../dev/openfeature/sdk/ImmutableContext.java | 3 +- .../dev/openfeature/sdk/MutableContext.java | 9 ++-- .../dev/openfeature/sdk/EvalContextTest.java | 6 ++- .../openfeature/sdk/ImmutableContextTest.java | 28 +++++++++++-- .../openfeature/sdk/MutableContextTest.java | 42 +++++++++++++++++-- 5 files changed, 75 insertions(+), 13 deletions(-) diff --git a/src/main/java/dev/openfeature/sdk/ImmutableContext.java b/src/main/java/dev/openfeature/sdk/ImmutableContext.java index accebe6fc..150f9c171 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableContext.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableContext.java @@ -55,12 +55,13 @@ public ImmutableContext(Map attributes) { /** * Create an immutable context with given targetingKey and attributes provided. + * Empty string is a valid targeting key value. * * @param targetingKey targeting key * @param attributes evaluation context attributes */ public ImmutableContext(String targetingKey, Map attributes) { - if (targetingKey != null && !targetingKey.isBlank()) { + if (targetingKey != null) { this.structure = new ImmutableStructure(targetingKey, attributes); } else { this.structure = new ImmutableStructure(attributes); diff --git a/src/main/java/dev/openfeature/sdk/MutableContext.java b/src/main/java/dev/openfeature/sdk/MutableContext.java index 2ad68c98a..5e684a8b3 100644 --- a/src/main/java/dev/openfeature/sdk/MutableContext.java +++ b/src/main/java/dev/openfeature/sdk/MutableContext.java @@ -36,14 +36,14 @@ public MutableContext(Map attributes) { /** * Create a mutable context with given targetingKey and attributes provided. TargetingKey should be non-null - * and non-empty to be accepted. + * to be accepted. Empty string is a valid targeting key value. * * @param targetingKey targeting key * @param attributes evaluation context attributes */ public MutableContext(String targetingKey, Map attributes) { this.structure = new MutableStructure(new HashMap<>(attributes)); - if (targetingKey != null && !targetingKey.trim().isEmpty()) { + if (targetingKey != null) { this.structure.attributes.put(TARGETING_KEY, new Value(targetingKey)); } } @@ -85,10 +85,11 @@ public MutableContext add(String key, List value) { } /** - * Override or set targeting key for this mutable context. Value should be non-null and non-empty to be accepted. + * Override or set targeting key for this mutable context. Value should be non-null to be accepted. + * Empty string is a valid targeting key value. */ public MutableContext setTargetingKey(String targetingKey) { - if (targetingKey != null && !targetingKey.trim().isEmpty()) { + if (targetingKey != null) { this.add(TARGETING_KEY, targetingKey); } return this; diff --git a/src/test/java/dev/openfeature/sdk/EvalContextTest.java b/src/test/java/dev/openfeature/sdk/EvalContextTest.java index 0f910b00e..a4f9fcd20 100644 --- a/src/test/java/dev/openfeature/sdk/EvalContextTest.java +++ b/src/test/java/dev/openfeature/sdk/EvalContextTest.java @@ -173,9 +173,10 @@ void Immutable_context_merge_targeting_key() { ctxMerged = ctx1.merge(ctx2); assertEquals(key2, ctxMerged.getTargetingKey()); + // Whitespace is now a valid targeting key and should override ctx2 = new ImmutableContext(" ", new HashMap<>()); ctxMerged = ctx1.merge(ctx2); - assertEquals(key1, ctxMerged.getTargetingKey()); + assertEquals(" ", ctxMerged.getTargetingKey()); } @Test @@ -200,9 +201,10 @@ void merge_targeting_key() { ctxMerged = ctx1.merge(ctx2); assertEquals(key2, ctxMerged.getTargetingKey()); + // Whitespace is now a valid targeting key and should override ctx2.setTargetingKey(" "); ctxMerged = ctx1.merge(ctx2); - assertEquals(key2, ctxMerged.getTargetingKey()); + assertEquals(" ", ctxMerged.getTargetingKey()); } @Test diff --git a/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java b/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java index 2852be536..7d8210be4 100644 --- a/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java +++ b/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java @@ -54,16 +54,17 @@ void shouldChangeTargetingKeyFromOverridingContext() { assertEquals("overriding_key", merge.getTargetingKey()); } - @DisplayName("targeting key should not be changed from the overriding context if missing") + @DisplayName("targeting key should be changed from the overriding context even if empty string") @Test - void shouldRetainTargetingKeyWhenOverridingContextTargetingKeyValueIsEmpty() { + void shouldOverrideTargetingKeyWhenOverridingContextTargetingKeyIsEmptyString() { HashMap attributes = new HashMap<>(); attributes.put("key1", new Value("val1")); attributes.put("key2", new Value("val2")); EvaluationContext ctx = new ImmutableContext("targeting_key", attributes); EvaluationContext overriding = new ImmutableContext(""); EvaluationContext merge = ctx.merge(overriding); - assertEquals("targeting_key", merge.getTargetingKey()); + // Empty string is a valid targeting key and should override + assertEquals("", merge.getTargetingKey()); } @DisplayName("missing targeting key should return null") @@ -73,6 +74,27 @@ void missingTargetingKeyShould() { assertNull(ctx.getTargetingKey()); } + @DisplayName("null targeting key in constructor should result in no targeting key") + @Test + void nullTargetingKeyInConstructorShouldResultInNoTargetingKey() { + EvaluationContext ctx = new ImmutableContext((String) null); + assertNull(ctx.getTargetingKey()); + } + + @DisplayName("empty string is a valid targeting key") + @Test + void emptyStringIsValidTargetingKey() { + EvaluationContext ctx = new ImmutableContext(""); + assertEquals("", ctx.getTargetingKey()); + } + + @DisplayName("whitespace-only string is a valid targeting key") + @Test + void whitespaceOnlyStringIsValidTargetingKey() { + EvaluationContext ctx = new ImmutableContext(" "); + assertEquals(" ", ctx.getTargetingKey()); + } + @DisplayName("Merge should retain all the attributes from the existing context when overriding context is null") @Test void mergeShouldReturnAllTheValuesFromTheContextWhenOverridingContextIsNull() { diff --git a/src/test/java/dev/openfeature/sdk/MutableContextTest.java b/src/test/java/dev/openfeature/sdk/MutableContextTest.java index b81cbccb1..0cd0e3267 100644 --- a/src/test/java/dev/openfeature/sdk/MutableContextTest.java +++ b/src/test/java/dev/openfeature/sdk/MutableContextTest.java @@ -40,16 +40,17 @@ void shouldChangeTargetingKeyFromOverridingContext() { assertEquals("overriding_key", merge.getTargetingKey()); } - @DisplayName("targeting key should not changed from the overriding context if missing") + @DisplayName("targeting key should be changed from the overriding context even if empty string") @Test - void shouldRetainTargetingKeyWhenOverridingContextTargetingKeyValueIsEmpty() { + void shouldOverrideTargetingKeyWhenOverridingContextTargetingKeyIsEmptyString() { HashMap attributes = new HashMap<>(); attributes.put("key1", new Value("val1")); attributes.put("key2", new Value("val2")); EvaluationContext ctx = new MutableContext("targeting_key", attributes); EvaluationContext overriding = new MutableContext(""); EvaluationContext merge = ctx.merge(overriding); - assertEquals("targeting_key", merge.getTargetingKey()); + // Empty string is a valid targeting key and should override + assertEquals("", merge.getTargetingKey()); } @DisplayName("missing targeting key should return null") @@ -59,6 +60,41 @@ void missingTargetingKeyShould() { assertEquals(null, ctx.getTargetingKey()); } + @DisplayName("setTargetingKey with null should not set targeting key") + @Test + void setTargetingKeyWithNullShouldNotSet() { + MutableContext ctx = new MutableContext("original"); + ctx.setTargetingKey(null); + // null should not override the existing targeting key + assertEquals("original", ctx.getTargetingKey()); + } + + @DisplayName("empty string is a valid targeting key via constructor") + @Test + void emptyStringIsValidTargetingKeyViaConstructor() { + EvaluationContext ctx = new MutableContext(""); + assertEquals("", ctx.getTargetingKey()); + } + + @DisplayName("empty and whitespace-only strings are valid targeting keys via setter") + @Test + void emptyAndWhitespaceAreValidTargetingKeysViaSetter() { + MutableContext ctx = new MutableContext(); + + ctx.setTargetingKey(""); + assertEquals("", ctx.getTargetingKey()); + + ctx.setTargetingKey(" "); + assertEquals(" ", ctx.getTargetingKey()); + } + + @DisplayName("whitespace-only string is a valid targeting key via constructor") + @Test + void whitespaceOnlyStringIsValidTargetingKeyViaConstructor() { + EvaluationContext ctx = new MutableContext(" "); + assertEquals(" ", ctx.getTargetingKey()); + } + @DisplayName("Merge should retain all the attributes from the existing context when overriding context is null") @Test void mergeShouldReturnAllTheValuesFromTheContextWhenOverridingContextIsNull() { From 1b41846c8f928478c93589c85ca48b7fdfd8e945 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 22 Jan 2026 08:07:25 +0100 Subject: [PATCH 595/745] chore(deps): update actions/setup-java digest to be666c2 (#1819) 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 428500b6f..cd35e3541 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -26,7 +26,7 @@ jobs: fetch-depth: 0 submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@d81c4e45f3ac973cc936d79104023e20054ba578 + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 135287b24..cfb3de129 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -25,7 +25,7 @@ jobs: submodules: recursive - name: Set up JDK ${{ matrix.build.java }} - uses: actions/setup-java@d81c4e45f3ac973cc936d79104023e20054ba578 + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2ac377e8d..d4db32f73 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,7 +43,7 @@ jobs: submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@d81c4e45f3ac973cc936d79104023e20054ba578 + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 with: java-version: '17' distribution: 'temurin' From f20a6931a3bbed95a1358d1ca371ba9d59570425 Mon Sep 17 00:00:00 2001 From: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> Date: Thu, 22 Jan 2026 11:12:44 -0500 Subject: [PATCH 596/745] chore(main): release 1.20.1 (#1810) Signed-off-by: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 23 +++++++++++++++++++++++ README.md | 8 ++++---- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 30 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 2d2b6b2ef..149a4cfd2 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"1.20.0"} +{".":"1.20.1"} diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e12c7268..ec2955e16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,28 @@ # Changelog +## [1.20.1](https://github.com/open-feature/java-sdk/compare/v1.20.0...v1.20.1) (2026-01-22) + + +### 🐛 Bug Fixes + +* Allow empty string as a valid targeting key ([#1807](https://github.com/open-feature/java-sdk/issues/1807)) ([e8fb3a1](https://github.com/open-feature/java-sdk/commit/e8fb3a18ca514c686b4a0655f95562ff1f4d1529)) +* **deps:** update dependency com.fasterxml.jackson:jackson-bom to v2.21.0 ([#1811](https://github.com/open-feature/java-sdk/issues/1811)) ([925477d](https://github.com/open-feature/java-sdk/commit/925477d4e8f6c795bc6000112ebc3830069a430f)) + + +### 🧹 Chore + +* **deps:** update actions/cache digest to 8b402f5 ([#1808](https://github.com/open-feature/java-sdk/issues/1808)) ([bf226d7](https://github.com/open-feature/java-sdk/commit/bf226d7cde44395be7c8222be05aaa7e199a7a9c)) +* **deps:** update actions/setup-java digest to 1b1bbe1 ([#1814](https://github.com/open-feature/java-sdk/issues/1814)) ([968b5ed](https://github.com/open-feature/java-sdk/commit/968b5ede67928f4906070508b29578fd4af90bfc)) +* **deps:** update actions/setup-java digest to be666c2 ([#1819](https://github.com/open-feature/java-sdk/issues/1819)) ([1b41846](https://github.com/open-feature/java-sdk/commit/1b41846c8f928478c93589c85ca48b7fdfd8e945)) +* **deps:** update actions/setup-java digest to d81c4e4 ([#1816](https://github.com/open-feature/java-sdk/issues/1816)) ([084539f](https://github.com/open-feature/java-sdk/commit/084539f8cbc080c08d6044e835351594bd19b73c)) +* **deps:** update dependency org.sonatype.central:central-publishing-maven-plugin to v0.10.0 ([#1798](https://github.com/open-feature/java-sdk/issues/1798)) ([3dd51c3](https://github.com/open-feature/java-sdk/commit/3dd51c3f719ea6181c6cf58a22c4836cd44348c1)) +* **deps:** update github/codeql-action digest to 044ff10 ([#1815](https://github.com/open-feature/java-sdk/issues/1815)) ([c499677](https://github.com/open-feature/java-sdk/commit/c49967717b0025e4716441e1e0a2c5e548a33ba7)) +* **deps:** update github/codeql-action digest to 1c4c0b3 ([#1818](https://github.com/open-feature/java-sdk/issues/1818)) ([d3df294](https://github.com/open-feature/java-sdk/commit/d3df29476df0144b808c44ac7dc636f83ee55467)) +* **deps:** update github/codeql-action digest to 1ec7dd2 ([#1813](https://github.com/open-feature/java-sdk/issues/1813)) ([cc81a91](https://github.com/open-feature/java-sdk/commit/cc81a918a39a8b3d363903a91a3c369aec84067d)) +* **deps:** update github/codeql-action digest to 32d41f3 ([#1817](https://github.com/open-feature/java-sdk/issues/1817)) ([ca7de48](https://github.com/open-feature/java-sdk/commit/ca7de4823b50d8eea4696d554c4d76bf16f7c235)) +* **deps:** update github/codeql-action digest to f687ebf ([#1812](https://github.com/open-feature/java-sdk/issues/1812)) ([1b9eb9b](https://github.com/open-feature/java-sdk/commit/1b9eb9be8b25440b45afe5f541e09b963643cefe)) +* **deps:** update github/codeql-action digest to fb650c2 ([#1809](https://github.com/open-feature/java-sdk/issues/1809)) ([852e256](https://github.com/open-feature/java-sdk/commit/852e256019a6e82ebd2b4a23a4e83e5bf1462a73)) + ## [1.20.0](https://github.com/open-feature/java-sdk/compare/v1.19.2...v1.20.0) (2026-01-16) diff --git a/README.md b/README.md index 8ebdb4418..d8e961aa0 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.20.0 + 1.20.1 ``` @@ -84,7 +84,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:1.20.0' + implementation 'dev.openfeature:sdk:1.20.1' } ``` diff --git a/pom.xml b/pom.xml index d47f4bfbf..4f1b1cf80 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ dev.openfeature sdk - 1.20.0 + 1.20.1 [17,) diff --git a/version.txt b/version.txt index 398935591..0044d6cb9 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.20.0 +1.20.1 From dde333f61e24a57c702d851c604b7ce3353f5277 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 22 Jan 2026 20:24:03 +0000 Subject: [PATCH 597/745] chore(deps): update github/codeql-action digest to 5e98e18 (#1820) 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 cfb3de129..04e38dfad 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@1c4c0b36be82b11c8adb51fb38f7122d0debe048 + uses: github/codeql-action/init@5e98e18a178e77b679ddf9a251beb8e3e9b232bf with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1c4c0b36be82b11c8adb51fb38f7122d0debe048 + uses: github/codeql-action/analyze@5e98e18a178e77b679ddf9a251beb8e3e9b232bf diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 104a753e6..ef520a070 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@1c4c0b36be82b11c8adb51fb38f7122d0debe048 + uses: github/codeql-action/init@5e98e18a178e77b679ddf9a251beb8e3e9b232bf with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@1c4c0b36be82b11c8adb51fb38f7122d0debe048 + uses: github/codeql-action/autobuild@5e98e18a178e77b679ddf9a251beb8e3e9b232bf - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1c4c0b36be82b11c8adb51fb38f7122d0debe048 + uses: github/codeql-action/analyze@5e98e18a178e77b679ddf9a251beb8e3e9b232bf From 2942daf9005816696d96d8d7e58c7bf261c5c086 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 23 Jan 2026 04:25:34 +0000 Subject: [PATCH 598/745] chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3.2.0 (#1822) 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 4f1b1cf80..5984ba7dd 100644 --- a/pom.xml +++ b/pom.xml @@ -524,7 +524,7 @@ com.diffplug.spotless spotless-maven-plugin - 3.1.0 + 3.2.0 From 55becc045d8e9d833d7d2293b9496b484f4e4e5e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 23 Jan 2026 21:12:39 +0000 Subject: [PATCH 599/745] chore(deps): update github/codeql-action digest to 55252c7 (#1823) 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 04e38dfad..7973e4bc4 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@5e98e18a178e77b679ddf9a251beb8e3e9b232bf + uses: github/codeql-action/init@55252c7a3a47fea1e0fdd923b269f4be8a5ad9a0 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5e98e18a178e77b679ddf9a251beb8e3e9b232bf + uses: github/codeql-action/analyze@55252c7a3a47fea1e0fdd923b269f4be8a5ad9a0 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index ef520a070..aa74dc129 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@5e98e18a178e77b679ddf9a251beb8e3e9b232bf + uses: github/codeql-action/init@55252c7a3a47fea1e0fdd923b269f4be8a5ad9a0 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@5e98e18a178e77b679ddf9a251beb8e3e9b232bf + uses: github/codeql-action/autobuild@55252c7a3a47fea1e0fdd923b269f4be8a5ad9a0 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5e98e18a178e77b679ddf9a251beb8e3e9b232bf + uses: github/codeql-action/analyze@55252c7a3a47fea1e0fdd923b269f4be8a5ad9a0 From 40ac67aaaf30fb7ef4565ed4a76ec5a68526ee15 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 25 Jan 2026 00:22:38 +0000 Subject: [PATCH 600/745] chore(deps): update dependency org.assertj:assertj-core to v3.27.7 (#1824) 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 5984ba7dd..2d7b910a5 100644 --- a/pom.xml +++ b/pom.xml @@ -91,7 +91,7 @@ org.assertj assertj-core - 3.27.6 + 3.27.7 test From 181a28eff5bc3720204862d9c143449debcf3ab6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 26 Jan 2026 14:24:26 +0100 Subject: [PATCH 601/745] chore(deps): update github/codeql-action digest to 25a224b (#1825) 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 7973e4bc4..12b12af9f 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@55252c7a3a47fea1e0fdd923b269f4be8a5ad9a0 + uses: github/codeql-action/init@25a224b8085c21d4d61b7fc051468805fc3ac490 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@55252c7a3a47fea1e0fdd923b269f4be8a5ad9a0 + uses: github/codeql-action/analyze@25a224b8085c21d4d61b7fc051468805fc3ac490 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index aa74dc129..7cdf1d9fe 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@55252c7a3a47fea1e0fdd923b269f4be8a5ad9a0 + uses: github/codeql-action/init@25a224b8085c21d4d61b7fc051468805fc3ac490 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@55252c7a3a47fea1e0fdd923b269f4be8a5ad9a0 + uses: github/codeql-action/autobuild@25a224b8085c21d4d61b7fc051468805fc3ac490 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@55252c7a3a47fea1e0fdd923b269f4be8a5ad9a0 + uses: github/codeql-action/analyze@25a224b8085c21d4d61b7fc051468805fc3ac490 From c1428cb683accd5bcd22a22f585d305c8bea3b69 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 26 Jan 2026 14:40:25 +0100 Subject: [PATCH 602/745] chore(deps): update github/codeql-action digest to 5e767ef (#1826) 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 12b12af9f..9e683e4f7 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@25a224b8085c21d4d61b7fc051468805fc3ac490 + uses: github/codeql-action/init@5e767eff5aa6e2b719f353611ff3c363d6225d18 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@25a224b8085c21d4d61b7fc051468805fc3ac490 + uses: github/codeql-action/analyze@5e767eff5aa6e2b719f353611ff3c363d6225d18 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 7cdf1d9fe..d30dc03f3 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@25a224b8085c21d4d61b7fc051468805fc3ac490 + uses: github/codeql-action/init@5e767eff5aa6e2b719f353611ff3c363d6225d18 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@25a224b8085c21d4d61b7fc051468805fc3ac490 + uses: github/codeql-action/autobuild@5e767eff5aa6e2b719f353611ff3c363d6225d18 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@25a224b8085c21d4d61b7fc051468805fc3ac490 + uses: github/codeql-action/analyze@5e767eff5aa6e2b719f353611ff3c363d6225d18 From f57c70d24173ca50e510b9577277ab6629297605 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 27 Jan 2026 00:26:30 +0000 Subject: [PATCH 603/745] chore(deps): update github/codeql-action digest to ee1e139 (#1827) 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 9e683e4f7..fe696fdd9 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@5e767eff5aa6e2b719f353611ff3c363d6225d18 + uses: github/codeql-action/init@ee1e1399e292f3386c840526dac6a4dc7509ad72 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5e767eff5aa6e2b719f353611ff3c363d6225d18 + uses: github/codeql-action/analyze@ee1e1399e292f3386c840526dac6a4dc7509ad72 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index d30dc03f3..877ae23f2 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@5e767eff5aa6e2b719f353611ff3c363d6225d18 + uses: github/codeql-action/init@ee1e1399e292f3386c840526dac6a4dc7509ad72 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@5e767eff5aa6e2b719f353611ff3c363d6225d18 + uses: github/codeql-action/autobuild@ee1e1399e292f3386c840526dac6a4dc7509ad72 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5e767eff5aa6e2b719f353611ff3c363d6225d18 + uses: github/codeql-action/analyze@ee1e1399e292f3386c840526dac6a4dc7509ad72 From 0c20c29b1c792a08e2274d69b9958966b5ba16cf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 27 Jan 2026 14:51:47 +0100 Subject: [PATCH 604/745] chore(deps): update github/codeql-action digest to bd9f639 (#1828) 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 fe696fdd9..4f10e4c9e 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@ee1e1399e292f3386c840526dac6a4dc7509ad72 + uses: github/codeql-action/init@bd9f639752973b8438be5388158675637e1034f9 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ee1e1399e292f3386c840526dac6a4dc7509ad72 + uses: github/codeql-action/analyze@bd9f639752973b8438be5388158675637e1034f9 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 877ae23f2..979d03e22 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@ee1e1399e292f3386c840526dac6a4dc7509ad72 + uses: github/codeql-action/init@bd9f639752973b8438be5388158675637e1034f9 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@ee1e1399e292f3386c840526dac6a4dc7509ad72 + uses: github/codeql-action/autobuild@bd9f639752973b8438be5388158675637e1034f9 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ee1e1399e292f3386c840526dac6a4dc7509ad72 + uses: github/codeql-action/analyze@bd9f639752973b8438be5388158675637e1034f9 From 1ce8a5e0e1b877273f86ea03ab62fd259323d494 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 27 Jan 2026 15:28:48 +0100 Subject: [PATCH 605/745] chore(deps): update github/codeql-action digest to fa9b76a (#1829) 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 4f10e4c9e..dee70711b 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@bd9f639752973b8438be5388158675637e1034f9 + uses: github/codeql-action/init@fa9b76ac378e31deb3e754ea3c54469c2891c81e with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@bd9f639752973b8438be5388158675637e1034f9 + uses: github/codeql-action/analyze@fa9b76ac378e31deb3e754ea3c54469c2891c81e diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 979d03e22..ed0d50d70 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@bd9f639752973b8438be5388158675637e1034f9 + uses: github/codeql-action/init@fa9b76ac378e31deb3e754ea3c54469c2891c81e with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@bd9f639752973b8438be5388158675637e1034f9 + uses: github/codeql-action/autobuild@fa9b76ac378e31deb3e754ea3c54469c2891c81e - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@bd9f639752973b8438be5388158675637e1034f9 + uses: github/codeql-action/analyze@fa9b76ac378e31deb3e754ea3c54469c2891c81e From b57667a143014235cf87efaecbefc5c40ac13de3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 27 Jan 2026 20:26:20 +0000 Subject: [PATCH 606/745] chore(deps): update github/codeql-action digest to b126fac (#1830) 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 dee70711b..1214c48e2 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@fa9b76ac378e31deb3e754ea3c54469c2891c81e + uses: github/codeql-action/init@b126facd4e5d140dbdf5202489ec4a70ff75ce5c with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@fa9b76ac378e31deb3e754ea3c54469c2891c81e + uses: github/codeql-action/analyze@b126facd4e5d140dbdf5202489ec4a70ff75ce5c diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index ed0d50d70..2a00e94ac 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@fa9b76ac378e31deb3e754ea3c54469c2891c81e + uses: github/codeql-action/init@b126facd4e5d140dbdf5202489ec4a70ff75ce5c with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@fa9b76ac378e31deb3e754ea3c54469c2891c81e + uses: github/codeql-action/autobuild@b126facd4e5d140dbdf5202489ec4a70ff75ce5c - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@fa9b76ac378e31deb3e754ea3c54469c2891c81e + uses: github/codeql-action/analyze@b126facd4e5d140dbdf5202489ec4a70ff75ce5c From cfd1864c0057d98b185afe3d0cec02509d40c4b1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 28 Jan 2026 04:25:43 +0000 Subject: [PATCH 607/745] chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3.2.1 (#1831) 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 2d7b910a5..972e33d42 100644 --- a/pom.xml +++ b/pom.xml @@ -524,7 +524,7 @@ com.diffplug.spotless spotless-maven-plugin - 3.2.0 + 3.2.1 From 6a11e0ee60dadf97dff81ae34e8539614eefa6fb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 28 Jan 2026 15:35:32 +0100 Subject: [PATCH 608/745] chore(deps): update github/codeql-action digest to eb5bd2d (#1832) 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 1214c48e2..5962ee17e 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@b126facd4e5d140dbdf5202489ec4a70ff75ce5c + uses: github/codeql-action/init@eb5bd2d0b9b06a3b8ec8f2963745331e2b01831e with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b126facd4e5d140dbdf5202489ec4a70ff75ce5c + uses: github/codeql-action/analyze@eb5bd2d0b9b06a3b8ec8f2963745331e2b01831e diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 2a00e94ac..06897a1db 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@b126facd4e5d140dbdf5202489ec4a70ff75ce5c + uses: github/codeql-action/init@eb5bd2d0b9b06a3b8ec8f2963745331e2b01831e with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@b126facd4e5d140dbdf5202489ec4a70ff75ce5c + uses: github/codeql-action/autobuild@eb5bd2d0b9b06a3b8ec8f2963745331e2b01831e - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b126facd4e5d140dbdf5202489ec4a70ff75ce5c + uses: github/codeql-action/analyze@eb5bd2d0b9b06a3b8ec8f2963745331e2b01831e From f5499569e3c6e8c95b7a58185e8cf79aef7386ad Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 00:27:23 +0000 Subject: [PATCH 609/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.34.1 (#1834) 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 972e33d42..8da9088ae 100644 --- a/pom.xml +++ b/pom.xml @@ -237,7 +237,7 @@ io.cucumber cucumber-bom - 7.33.0 + 7.34.1 pom import From 0fd4dfc99066b60421cb3067049ac5a5366ccdaa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 04:22:03 +0000 Subject: [PATCH 610/745] chore(deps): update github/codeql-action digest to b2ff80d (#1833) 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 5962ee17e..c3ae785c9 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@eb5bd2d0b9b06a3b8ec8f2963745331e2b01831e + uses: github/codeql-action/init@b2ff80ddacba59b60f4e0cf3b699baaea3230cd9 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@eb5bd2d0b9b06a3b8ec8f2963745331e2b01831e + uses: github/codeql-action/analyze@b2ff80ddacba59b60f4e0cf3b699baaea3230cd9 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 06897a1db..b82f25a5c 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@eb5bd2d0b9b06a3b8ec8f2963745331e2b01831e + uses: github/codeql-action/init@b2ff80ddacba59b60f4e0cf3b699baaea3230cd9 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@eb5bd2d0b9b06a3b8ec8f2963745331e2b01831e + uses: github/codeql-action/autobuild@b2ff80ddacba59b60f4e0cf3b699baaea3230cd9 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@eb5bd2d0b9b06a3b8ec8f2963745331e2b01831e + uses: github/codeql-action/analyze@b2ff80ddacba59b60f4e0cf3b699baaea3230cd9 From d11a5d72924a3a2a279224e84a083ff9e4a7a1a1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 12:28:28 +0000 Subject: [PATCH 611/745] chore(deps): update github/codeql-action digest to f985be5 (#1836) 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 c3ae785c9..ecff868f6 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@b2ff80ddacba59b60f4e0cf3b699baaea3230cd9 + uses: github/codeql-action/init@f985be5b50bd175586d44aac9ac52926adf12893 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b2ff80ddacba59b60f4e0cf3b699baaea3230cd9 + uses: github/codeql-action/analyze@f985be5b50bd175586d44aac9ac52926adf12893 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index b82f25a5c..bc6cc1ee1 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@b2ff80ddacba59b60f4e0cf3b699baaea3230cd9 + uses: github/codeql-action/init@f985be5b50bd175586d44aac9ac52926adf12893 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@b2ff80ddacba59b60f4e0cf3b699baaea3230cd9 + uses: github/codeql-action/autobuild@f985be5b50bd175586d44aac9ac52926adf12893 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b2ff80ddacba59b60f4e0cf3b699baaea3230cd9 + uses: github/codeql-action/analyze@f985be5b50bd175586d44aac9ac52926adf12893 From ffeccdf43079e306e2ecf04b46b01dfaf3b6c624 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 12:33:19 +0000 Subject: [PATCH 612/745] chore(deps): update actions/cache digest to b456236 (#1835) 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 cd35e3541..5d2c3b375 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -36,7 +36,7 @@ jobs: server-password: ${{ secrets.CENTRAL_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 + uses: actions/cache@b45623637f5737c8022070213e69ba8fd6dfe041 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 ecff868f6..da7c20655 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -37,7 +37,7 @@ jobs: languages: java - name: Cache local Maven repository - uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 + uses: actions/cache@b45623637f5737c8022070213e69ba8fd6dfe041 with: path: ~/.m2/repository key: ${{ runner.os }}${{ matrix.build.java }}-maven-${{ hashFiles('**/pom.xml') }} From b8c4b9a1e48bbcd0265b3e47c66ab823cf18d219 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 20:23:50 +0000 Subject: [PATCH 613/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.34.2 (#1837) 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 8da9088ae..13d8ba05d 100644 --- a/pom.xml +++ b/pom.xml @@ -237,7 +237,7 @@ io.cucumber cucumber-bom - 7.34.1 + 7.34.2 pom import From 99f2e0fab11bfd4f97503d3685d554280e7fcb53 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 30 Jan 2026 20:22:18 +0000 Subject: [PATCH 614/745] chore(deps): update actions/cache digest to b7e8d49 (#1838) 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 5d2c3b375..00cef75c7 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -36,7 +36,7 @@ jobs: server-password: ${{ secrets.CENTRAL_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@b45623637f5737c8022070213e69ba8fd6dfe041 + uses: actions/cache@b7e8d49f17405cc70c1c120101943203c98d3a4b 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 da7c20655..46e995ebc 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -37,7 +37,7 @@ jobs: languages: java - name: Cache local Maven repository - uses: actions/cache@b45623637f5737c8022070213e69ba8fd6dfe041 + uses: actions/cache@b7e8d49f17405cc70c1c120101943203c98d3a4b with: path: ~/.m2/repository key: ${{ runner.os }}${{ matrix.build.java }}-maven-${{ hashFiles('**/pom.xml') }} From 857fed8d03becab81860ae9286278d3b8c5c80be Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Feb 2026 00:22:43 +0000 Subject: [PATCH 615/745] chore(deps): update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.15.0 (#1839) 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 13d8ba05d..8fbf247a9 100644 --- a/pom.xml +++ b/pom.xml @@ -294,7 +294,7 @@ maven-compiler-plugin - 3.14.1 + 3.15.0 @@ -751,7 +751,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.14.1 + 3.15.0 default-testCompile From b833e9f0bb530fdb1b9ce8a6944e2b18f6e7852c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Feb 2026 12:28:24 +0000 Subject: [PATCH 616/745] chore(deps): update github/codeql-action digest to f52cbc8 (#1840) 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 46e995ebc..8c323666e 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@f985be5b50bd175586d44aac9ac52926adf12893 + uses: github/codeql-action/init@f52cbc83091da34ce9a8ae0e3db2f977e8d4ecb2 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f985be5b50bd175586d44aac9ac52926adf12893 + uses: github/codeql-action/analyze@f52cbc83091da34ce9a8ae0e3db2f977e8d4ecb2 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index bc6cc1ee1..4650c738d 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@f985be5b50bd175586d44aac9ac52926adf12893 + uses: github/codeql-action/init@f52cbc83091da34ce9a8ae0e3db2f977e8d4ecb2 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@f985be5b50bd175586d44aac9ac52926adf12893 + uses: github/codeql-action/autobuild@f52cbc83091da34ce9a8ae0e3db2f977e8d4ecb2 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f985be5b50bd175586d44aac9ac52926adf12893 + uses: github/codeql-action/analyze@f52cbc83091da34ce9a8ae0e3db2f977e8d4ecb2 From 3ee6333149ecc2fd6b8e85265cdfa5a248d7c39f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 12:32:54 +0000 Subject: [PATCH 617/745] chore(deps): update github/codeql-action digest to f959778 (#1841) 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 8c323666e..e24cf5223 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@f52cbc83091da34ce9a8ae0e3db2f977e8d4ecb2 + uses: github/codeql-action/init@f959778b39f110f7919139e242fa5ac47393c877 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f52cbc83091da34ce9a8ae0e3db2f977e8d4ecb2 + uses: github/codeql-action/analyze@f959778b39f110f7919139e242fa5ac47393c877 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 4650c738d..3b635deba 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@f52cbc83091da34ce9a8ae0e3db2f977e8d4ecb2 + uses: github/codeql-action/init@f959778b39f110f7919139e242fa5ac47393c877 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@f52cbc83091da34ce9a8ae0e3db2f977e8d4ecb2 + uses: github/codeql-action/autobuild@f959778b39f110f7919139e242fa5ac47393c877 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f52cbc83091da34ce9a8ae0e3db2f977e8d4ecb2 + uses: github/codeql-action/analyze@f959778b39f110f7919139e242fa5ac47393c877 From e92f911d5119436e0af4022d1fe2bc891b32760f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Feb 2026 00:24:30 +0000 Subject: [PATCH 618/745] chore(deps): update github/codeql-action digest to 7deb0a1 (#1842) 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 e24cf5223..5c3d4ed3c 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@f959778b39f110f7919139e242fa5ac47393c877 + uses: github/codeql-action/init@7deb0a15d3029449bc515a36324b0b21d24f6e27 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f959778b39f110f7919139e242fa5ac47393c877 + uses: github/codeql-action/analyze@7deb0a15d3029449bc515a36324b0b21d24f6e27 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 3b635deba..39653f61f 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@f959778b39f110f7919139e242fa5ac47393c877 + uses: github/codeql-action/init@7deb0a15d3029449bc515a36324b0b21d24f6e27 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@f959778b39f110f7919139e242fa5ac47393c877 + uses: github/codeql-action/autobuild@7deb0a15d3029449bc515a36324b0b21d24f6e27 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f959778b39f110f7919139e242fa5ac47393c877 + uses: github/codeql-action/analyze@7deb0a15d3029449bc515a36324b0b21d24f6e27 From fe108bb8ccc7f8460ac97051ff3cb5835a586a05 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Feb 2026 20:29:25 +0000 Subject: [PATCH 619/745] chore(deps): update github/codeql-action digest to 7aee932 (#1843) 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 5c3d4ed3c..bac449562 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@7deb0a15d3029449bc515a36324b0b21d24f6e27 + uses: github/codeql-action/init@7aee93297421a430700f5e81fe681dbc80a0b4f5 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7deb0a15d3029449bc515a36324b0b21d24f6e27 + uses: github/codeql-action/analyze@7aee93297421a430700f5e81fe681dbc80a0b4f5 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 39653f61f..77e927ba0 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@7deb0a15d3029449bc515a36324b0b21d24f6e27 + uses: github/codeql-action/init@7aee93297421a430700f5e81fe681dbc80a0b4f5 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@7deb0a15d3029449bc515a36324b0b21d24f6e27 + uses: github/codeql-action/autobuild@7aee93297421a430700f5e81fe681dbc80a0b4f5 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7deb0a15d3029449bc515a36324b0b21d24f6e27 + uses: github/codeql-action/analyze@7aee93297421a430700f5e81fe681dbc80a0b4f5 From b0ca9433092ddd477e55451a73f783f63d17d341 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 16:25:06 +0000 Subject: [PATCH 620/745] chore(deps): update github/codeql-action digest to b13d724 (#1844) 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 bac449562..3ceaf2040 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@7aee93297421a430700f5e81fe681dbc80a0b4f5 + uses: github/codeql-action/init@b13d724d35ff0a814e21683638ed68ed34cf53d1 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7aee93297421a430700f5e81fe681dbc80a0b4f5 + uses: github/codeql-action/analyze@b13d724d35ff0a814e21683638ed68ed34cf53d1 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 77e927ba0..ab7a2665d 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@7aee93297421a430700f5e81fe681dbc80a0b4f5 + uses: github/codeql-action/init@b13d724d35ff0a814e21683638ed68ed34cf53d1 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@7aee93297421a430700f5e81fe681dbc80a0b4f5 + uses: github/codeql-action/autobuild@b13d724d35ff0a814e21683638ed68ed34cf53d1 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7aee93297421a430700f5e81fe681dbc80a0b4f5 + uses: github/codeql-action/analyze@b13d724d35ff0a814e21683638ed68ed34cf53d1 From e495576d08b283286ee847eef2f4ac4530d8fa45 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 7 Feb 2026 16:22:09 +0000 Subject: [PATCH 621/745] chore(deps): update com.vmlens.version to v1.2.25 (#1845) 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 8fbf247a9..8faf5d58f 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ 11 ${maven.compiler.source} 5.21.0 - 1.2.24 + 1.2.25 **/e2e/*.java ${project.groupId}.${project.artifactId} From 102951b00f6392d5bef7bd4bfc381eaeb374e0ea Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 8 Feb 2026 12:23:50 +0000 Subject: [PATCH 622/745] chore(deps): update com.vmlens.version to v1.2.26 (#1846) 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 8faf5d58f..7c8f80f79 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ 11 ${maven.compiler.source} 5.21.0 - 1.2.25 + 1.2.26 **/e2e/*.java ${project.groupId}.${project.artifactId} From 385785641ade0b4ff5fe16d22daf45352931f056 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 9 Feb 2026 04:26:10 +0000 Subject: [PATCH 623/745] chore(deps): update dependency org.apache.maven.plugins:maven-dependency-plugin to v3.10.0 (#1847) 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 7c8f80f79..ec7316c07 100644 --- a/pom.xml +++ b/pom.xml @@ -373,7 +373,7 @@ maven-dependency-plugin - 3.9.0 + 3.10.0 verify From 07d06f55abdf91ae19a51b780195aa88f203d7d9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 12 Feb 2026 00:31:50 +0000 Subject: [PATCH 624/745] chore(deps): update github/codeql-action digest to ff33514 (#1849) 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 3ceaf2040..15990d16b 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@b13d724d35ff0a814e21683638ed68ed34cf53d1 + uses: github/codeql-action/init@ff33514494ef2488964273e05cbfb9b29533d9f0 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b13d724d35ff0a814e21683638ed68ed34cf53d1 + uses: github/codeql-action/analyze@ff33514494ef2488964273e05cbfb9b29533d9f0 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index ab7a2665d..4bc7669a5 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@b13d724d35ff0a814e21683638ed68ed34cf53d1 + uses: github/codeql-action/init@ff33514494ef2488964273e05cbfb9b29533d9f0 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@b13d724d35ff0a814e21683638ed68ed34cf53d1 + uses: github/codeql-action/autobuild@ff33514494ef2488964273e05cbfb9b29533d9f0 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b13d724d35ff0a814e21683638ed68ed34cf53d1 + uses: github/codeql-action/analyze@ff33514494ef2488964273e05cbfb9b29533d9f0 From 44057a915af2c6e123c83759cc0fee0ed9cb670b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 12 Feb 2026 20:49:10 +0000 Subject: [PATCH 625/745] chore(deps): update github/codeql-action digest to 2d6b98c (#1850) 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 15990d16b..a491d8528 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@ff33514494ef2488964273e05cbfb9b29533d9f0 + uses: github/codeql-action/init@2d6b98c7cf7260afd6954ee7de478b21127b40f4 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ff33514494ef2488964273e05cbfb9b29533d9f0 + uses: github/codeql-action/analyze@2d6b98c7cf7260afd6954ee7de478b21127b40f4 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 4bc7669a5..b8f173482 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@ff33514494ef2488964273e05cbfb9b29533d9f0 + uses: github/codeql-action/init@2d6b98c7cf7260afd6954ee7de478b21127b40f4 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@ff33514494ef2488964273e05cbfb9b29533d9f0 + uses: github/codeql-action/autobuild@2d6b98c7cf7260afd6954ee7de478b21127b40f4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ff33514494ef2488964273e05cbfb9b29533d9f0 + uses: github/codeql-action/analyze@2d6b98c7cf7260afd6954ee7de478b21127b40f4 From 6beaa1956062673b43945a1b015acb7924cd0aa9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 13 Feb 2026 16:27:05 +0000 Subject: [PATCH 626/745] chore(deps): update github/codeql-action digest to ef618fe (#1851) 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 a491d8528..12358da44 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@2d6b98c7cf7260afd6954ee7de478b21127b40f4 + uses: github/codeql-action/init@ef618feace3c4838ae42b239ab86e8fb46437508 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@2d6b98c7cf7260afd6954ee7de478b21127b40f4 + uses: github/codeql-action/analyze@ef618feace3c4838ae42b239ab86e8fb46437508 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index b8f173482..2a425eadd 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@2d6b98c7cf7260afd6954ee7de478b21127b40f4 + uses: github/codeql-action/init@ef618feace3c4838ae42b239ab86e8fb46437508 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@2d6b98c7cf7260afd6954ee7de478b21127b40f4 + uses: github/codeql-action/autobuild@ef618feace3c4838ae42b239ab86e8fb46437508 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@2d6b98c7cf7260afd6954ee7de478b21127b40f4 + uses: github/codeql-action/analyze@ef618feace3c4838ae42b239ab86e8fb46437508 From 53d3fe33df1b4b063ae14a255735e9447df4b6b0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 13 Feb 2026 20:25:28 +0000 Subject: [PATCH 627/745] chore(deps): update amannn/action-semantic-pull-request digest to ac7e3fc (#1852) 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 f9e52e210..48a8f44b6 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@b439535a8eb2122b748ed2b45d1693aaabe5b0aa + - uses: amannn/action-semantic-pull-request@ac7e3fc035c47465748bbcb1a822c1583cf79bbc env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From de2b7376cb5e390820b51cc127b739eb26dad01a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 12:26:10 +0000 Subject: [PATCH 628/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.18.5 (#1853) 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 ec7316c07..d43c374bf 100644 --- a/pom.xml +++ b/pom.xml @@ -214,7 +214,7 @@ net.bytebuddy byte-buddy - 1.18.4 + 1.18.5 test From 2fd471a4c9d4849895d99e5d11249c4576556d29 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 16:24:50 +0000 Subject: [PATCH 629/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.18.5 (#1854) 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 d43c374bf..130b6c34c 100644 --- a/pom.xml +++ b/pom.xml @@ -221,7 +221,7 @@ net.bytebuddy byte-buddy-agent - 1.18.4 + 1.18.5 test From 5af58fd750e487e95c6c0cf8cdaf386c8967a2eb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 15 Feb 2026 20:26:31 +0000 Subject: [PATCH 630/745] fix(deps): update dependency org.junit:junit-bom to v6.0.3 (#1855) 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 130b6c34c..effb856b8 100644 --- a/pom.xml +++ b/pom.xml @@ -245,7 +245,7 @@ org.junit junit-bom - 6.0.2 + 6.0.3 pom import From 74325fb5f1b182cef1acbb79e646485101832371 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 17 Feb 2026 04:25:14 +0000 Subject: [PATCH 631/745] chore(deps): update github/codeql-action digest to 147d149 (#1856) 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 12358da44..73c0ab2e4 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@ef618feace3c4838ae42b239ab86e8fb46437508 + uses: github/codeql-action/init@147d1495e44cd79bcd652a4bd2826462378e311d with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ef618feace3c4838ae42b239ab86e8fb46437508 + uses: github/codeql-action/analyze@147d1495e44cd79bcd652a4bd2826462378e311d diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 2a425eadd..381041267 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@ef618feace3c4838ae42b239ab86e8fb46437508 + uses: github/codeql-action/init@147d1495e44cd79bcd652a4bd2826462378e311d with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@ef618feace3c4838ae42b239ab86e8fb46437508 + uses: github/codeql-action/autobuild@147d1495e44cd79bcd652a4bd2826462378e311d - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ef618feace3c4838ae42b239ab86e8fb46437508 + uses: github/codeql-action/analyze@147d1495e44cd79bcd652a4bd2826462378e311d From a48fb39f10f5c030e3cc489420cf41100c2244c1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 00:45:47 +0000 Subject: [PATCH 632/745] chore(deps): update github/codeql-action digest to 015d8c7 (#1857) 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 73c0ab2e4..1a42d039e 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@147d1495e44cd79bcd652a4bd2826462378e311d + uses: github/codeql-action/init@015d8c7cbcbb8e7252a7dccfe81a90aa176260b2 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@147d1495e44cd79bcd652a4bd2826462378e311d + uses: github/codeql-action/analyze@015d8c7cbcbb8e7252a7dccfe81a90aa176260b2 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 381041267..65d7ca16a 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@147d1495e44cd79bcd652a4bd2826462378e311d + uses: github/codeql-action/init@015d8c7cbcbb8e7252a7dccfe81a90aa176260b2 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@147d1495e44cd79bcd652a4bd2826462378e311d + uses: github/codeql-action/autobuild@015d8c7cbcbb8e7252a7dccfe81a90aa176260b2 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@147d1495e44cd79bcd652a4bd2826462378e311d + uses: github/codeql-action/analyze@015d8c7cbcbb8e7252a7dccfe81a90aa176260b2 From 8cc5d401ff23eb52cc91218353e9c79f7c8d239e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 20:26:26 +0000 Subject: [PATCH 633/745] chore(deps): update github/codeql-action digest to 5e7a52f (#1858) 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 1a42d039e..163474b8c 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@015d8c7cbcbb8e7252a7dccfe81a90aa176260b2 + uses: github/codeql-action/init@5e7a52feb2a3dfb87f88be2af33b9e2275f48de6 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@015d8c7cbcbb8e7252a7dccfe81a90aa176260b2 + uses: github/codeql-action/analyze@5e7a52feb2a3dfb87f88be2af33b9e2275f48de6 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 65d7ca16a..3b7ecaa65 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@015d8c7cbcbb8e7252a7dccfe81a90aa176260b2 + uses: github/codeql-action/init@5e7a52feb2a3dfb87f88be2af33b9e2275f48de6 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@015d8c7cbcbb8e7252a7dccfe81a90aa176260b2 + uses: github/codeql-action/autobuild@5e7a52feb2a3dfb87f88be2af33b9e2275f48de6 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@015d8c7cbcbb8e7252a7dccfe81a90aa176260b2 + uses: github/codeql-action/analyze@5e7a52feb2a3dfb87f88be2af33b9e2275f48de6 From efbf27990e9937bb7b0497e6172bc1da15cb230e Mon Sep 17 00:00:00 2001 From: Nicklas Lundin Date: Wed, 18 Feb 2026 22:01:12 +0100 Subject: [PATCH 634/745] fix: allow for providers to safely shutdown (#1744) * fix: allow for providers to safely shutdown Signed-off-by: Nicklas Lundin * fix: prevent race conditions during repository shutdown Signed-off-by: Nicklas Lundin * test: comment out ProviderRepositoryCT due to VMLens limitation VMLens crashes with NPE when ThreadPoolExecutor.shutdown() is called inside AllInterleavings block. Co-Authored-By: Claude Opus 4.5 Signed-off-by: Nicklas Lundin * refactor: use throws declaration instead of try-catch in test helper Co-Authored-By: Claude Opus 4.5 Signed-off-by: Nicklas Lundin * fix: prevent deadlock during shutdown with pending init tasks Split ProviderRepository.shutdown() into prepareShutdown() and completeShutdown() phases. OpenFeatureAPI.shutdown() now releases the write lock before waiting for executor termination, allowing pending initializeProvider tasks to acquire read lock for event emission. Co-Authored-By: Claude Opus 4.5 Signed-off-by: Nicklas Lundin * test: simplify VMLens concurrency test for multiple providers Reduce from 3 to 2 providers to work around VMLens graph building bug. Co-Authored-By: Claude Opus 4.5 Signed-off-by: Nicklas Lundin * additional test for setProvider and shutdown Signed-off-by: Nicklas Lundin * test: add coverage for shutdown edge cases Co-Authored-By: Claude Opus 4.5 Signed-off-by: Nicklas Lundin * fixup: use timeout const Signed-off-by: Todd Baert --------- Signed-off-by: Nicklas Lundin Signed-off-by: Todd Baert Co-authored-by: Claude Opus 4.5 Co-authored-by: Todd Baert --- .../dev/openfeature/sdk/OpenFeatureAPI.java | 17 +- .../openfeature/sdk/ProviderRepository.java | 83 +++++++- .../sdk/ProviderRepositoryTest.java | 195 ++++++++++++++++++ .../sdk/ShutdownBehaviorSpecTest.java | 14 ++ .../sdk/vmlens/ProviderRepositoryCT.java | 158 ++++++++++++++ 5 files changed, 453 insertions(+), 14 deletions(-) create mode 100644 src/test/java/dev/openfeature/sdk/vmlens/ProviderRepositoryCT.java diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java b/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java index 6d0d8feb4..02c1edf25 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java @@ -339,12 +339,23 @@ public void clearHooks() { * Once shut down is complete, API is reset and ready to use again. */ public void shutdown() { + List managersToShutdown; try (AutoCloseableLock ignored = lock.writeLockAutoCloseable()) { - providerRepository.shutdown(); + // Mark repository as shutting down while holding lock. + // This ensures setProvider calls will throw IllegalStateException. + managersToShutdown = providerRepository.prepareShutdown(); + } + + if (managersToShutdown != null) { + // Complete shutdown without holding lock to avoid deadlock. + // Pending tasks (e.g., initializeProvider) may need the read lock to emit events. + providerRepository.completeShutdown(managersToShutdown); eventSupport.shutdown(); - providerRepository = new ProviderRepository(this); - eventSupport = new EventSupport(); + try (AutoCloseableLock ignored = lock.writeLockAutoCloseable()) { + providerRepository = new ProviderRepository(this); + eventSupport = new EventSupport(); + } } } diff --git a/src/main/java/dev/openfeature/sdk/ProviderRepository.java b/src/main/java/dev/openfeature/sdk/ProviderRepository.java index 147074a58..3a0d325df 100644 --- a/src/main/java/dev/openfeature/sdk/ProviderRepository.java +++ b/src/main/java/dev/openfeature/sdk/ProviderRepository.java @@ -10,6 +10,8 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -23,6 +25,7 @@ class ProviderRepository { private final Map stateManagers = new ConcurrentHashMap<>(); private final AtomicReference defaultStateManger = new AtomicReference<>(new FeatureProviderStateManager(new NoOpProvider())); + private final AtomicBoolean isShuttingDown = new AtomicBoolean(false); private final ExecutorService taskExecutor = Executors.newCachedThreadPool(new ConfigurableThreadFactory("openfeature-provider-thread", true)); private final Object registerStateManagerLock = new Object(); @@ -162,6 +165,9 @@ private void prepareAndInitializeProvider( final FeatureProviderStateManager oldStateManager; synchronized (registerStateManagerLock) { + if (isShuttingDown.get()) { + throw new IllegalStateException("Provider cannot be set while repository is shutting down"); + } FeatureProviderStateManager existing = getExistingStateManagerForProvider(newProvider); if (existing == null) { newStateManager = new FeatureProviderStateManager(newProvider); @@ -228,9 +234,11 @@ private void initializeProvider( } private void shutDownOld(FeatureProviderStateManager oldManager, Consumer afterShutdown) { - if (oldManager != null && !isStateManagerRegistered(oldManager)) { - shutdownProvider(oldManager); - afterShutdown.accept(oldManager.getProvider()); + synchronized (registerStateManagerLock) { + if (oldManager != null && !isStateManagerRegistered(oldManager)) { + shutdownProvider(oldManager); + afterShutdown.accept(oldManager.getProvider()); + } } } @@ -254,16 +262,27 @@ private void shutdownProvider(FeatureProviderStateManager manager) { } private void shutdownProvider(FeatureProvider provider) { - taskExecutor.submit(() -> { + try { + taskExecutor.submit(() -> { + try { + provider.shutdown(); + } catch (Exception e) { + log.error( + "Exception when shutting down feature provider {}", + provider.getClass().getName(), + e); + } + }); + } catch (java.util.concurrent.RejectedExecutionException e) { try { provider.shutdown(); - } catch (Exception e) { + } catch (Exception ex) { log.error( "Exception when shutting down feature provider {}", provider.getClass().getName(), - e); + ex); } - }); + } } /** @@ -272,10 +291,52 @@ private void shutdownProvider(FeatureProvider provider) { * including the default feature provider. */ public void shutdown() { - Stream.concat(Stream.of(this.defaultStateManger.get()), this.stateManagers.values().stream()) - .distinct() - .forEach(this::shutdownProvider); - this.stateManagers.clear(); + List managersToShutdown = prepareShutdown(); + if (managersToShutdown != null) { + completeShutdown(managersToShutdown); + } + } + + /** + * Prepares the repository for shutdown by marking it as shutting down and + * collecting all managers that need to be shut down. + * + *

After this call, any attempt to set a provider will throw IllegalStateException. + * + * @return list of managers to shut down, or null if shutdown was already initiated + */ + List prepareShutdown() { + synchronized (registerStateManagerLock) { + if (isShuttingDown.getAndSet(true)) { + return null; + } + + List managersToShutdown = Stream.concat( + Stream.of(this.defaultStateManger.get()), this.stateManagers.values().stream()) + .distinct() + .collect(Collectors.toList()); + this.stateManagers.clear(); + return managersToShutdown; + } + } + + /** + * Completes the shutdown by shutting down all providers and waiting for + * pending tasks to complete. + * + * @param managersToShutdown the managers to shut down (from prepareShutdown) + */ + void completeShutdown(List managersToShutdown) { + managersToShutdown.forEach(this::shutdownProvider); taskExecutor.shutdown(); + try { + if (!taskExecutor.awaitTermination(EventSupport.SHUTDOWN_TIMEOUT_SECONDS, TimeUnit.SECONDS)) { + log.warn("Task executor did not terminate before the timeout period had elapsed"); + taskExecutor.shutdownNow(); + } + } catch (InterruptedException e) { + taskExecutor.shutdownNow(); + Thread.currentThread().interrupt(); + } } } diff --git a/src/test/java/dev/openfeature/sdk/ProviderRepositoryTest.java b/src/test/java/dev/openfeature/sdk/ProviderRepositoryTest.java index 7041df5c1..c9d69ad73 100644 --- a/src/test/java/dev/openfeature/sdk/ProviderRepositoryTest.java +++ b/src/test/java/dev/openfeature/sdk/ProviderRepositoryTest.java @@ -4,6 +4,7 @@ import static dev.openfeature.sdk.testutils.stubbing.ConditionStubber.doDelayResponse; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.awaitility.Awaitility.await; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -15,6 +16,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; @@ -289,6 +291,199 @@ void shouldRunLambdasOnError() throws Exception { verify(afterError, timeout(TIMEOUT)).accept(eq(errorFeatureProvider), any()); } } + + @Nested + class GracefulShutdownBehavior { + + @Test + @DisplayName("should complete shutdown successfully when executor terminates within timeout") + void shouldCompleteShutdownSuccessfullyWhenExecutorTerminatesWithinTimeout() { + FeatureProvider provider = createMockedProvider(); + setFeatureProvider(provider); + + assertThatCode(() -> providerRepository.shutdown()).doesNotThrowAnyException(); + + verify(provider, timeout(TIMEOUT)).shutdown(); + } + + @Test + @DisplayName("should force shutdown when executor does not terminate within timeout") + void shouldForceShutdownWhenExecutorDoesNotTerminateWithinTimeout() throws Exception { + FeatureProvider provider = createMockedProvider(); + AtomicBoolean wasInterrupted = new AtomicBoolean(false); + doAnswer(invocation -> { + try { + Thread.sleep(TIMEOUT); + } catch (InterruptedException e) { + wasInterrupted.set(true); + throw e; + } + return null; + }) + .when(provider) + .shutdown(); + + setFeatureProvider(provider); + + assertThatCode(() -> providerRepository.shutdown()).doesNotThrowAnyException(); + + verify(provider, timeout(TIMEOUT)).shutdown(); + // Verify that shutdownNow() interrupted the running shutdown task + await().atMost(Duration.ofSeconds(1)) + .untilAsserted(() -> assertThat(wasInterrupted.get()).isTrue()); + } + + // Note: shouldHandleInterruptionDuringShutdownGracefully was removed because the + // interrupt timing is not guaranteed. Proper concurrency testing is done in + // ProviderRepositoryCT using VMLens. + + @Test + @DisplayName("should not hang indefinitely on shutdown") + void shouldNotHangIndefinitelyOnShutdown() { + FeatureProvider provider = createMockedProvider(); + setFeatureProvider(provider); + + await().alias("shutdown should complete within reasonable time") + .atMost(Duration.ofSeconds(5)) + .until(() -> { + providerRepository.shutdown(); + return true; + }); + } + + @Test + @DisplayName("should handle shutdown during provider initialization") + void shouldHandleShutdownDuringProviderInitialization() throws Exception { + FeatureProvider slowInitProvider = createMockedProvider(); + AtomicBoolean shutdownCalled = new AtomicBoolean(false); + + doDelayResponse(Duration.ofMillis(500)).when(slowInitProvider).initialize(any()); + + doAnswer(invocation -> { + shutdownCalled.set(true); + return null; + }) + .when(slowInitProvider) + .shutdown(); + + providerRepository.setProvider( + slowInitProvider, + mockAfterSet(), + mockAfterInit(), + mockAfterShutdown(), + mockAfterError(), + false); + + // Call shutdown while initialization is in progress + assertThatCode(() -> providerRepository.shutdown()).doesNotThrowAnyException(); + + await().atMost(Duration.ofSeconds(1)).untilTrue(shutdownCalled); + verify(slowInitProvider, times(1)).shutdown(); + } + + @Test + @DisplayName("should handle provider replacement during shutdown") + void shouldHandleProviderReplacementDuringShutdown() throws Exception { + FeatureProvider oldProvider = createMockedProvider(); + FeatureProvider newProvider = createMockedProvider(); + AtomicBoolean oldProviderShutdownCalled = new AtomicBoolean(false); + + doAnswer(invocation -> { + oldProviderShutdownCalled.set(true); + return null; + }) + .when(oldProvider) + .shutdown(); + + providerRepository.setProvider( + oldProvider, mockAfterSet(), mockAfterInit(), mockAfterShutdown(), mockAfterError(), true); + + // Replace provider (this will trigger old provider shutdown in background) + providerRepository.setProvider( + newProvider, mockAfterSet(), mockAfterInit(), mockAfterShutdown(), mockAfterError(), false); + + assertThatCode(() -> providerRepository.shutdown()).doesNotThrowAnyException(); + + await().atMost(Duration.ofSeconds(1)).untilTrue(oldProviderShutdownCalled); + verify(oldProvider, times(1)).shutdown(); + verify(newProvider, times(1)).shutdown(); + } + + @Test + @DisplayName("should prevent adding providers after shutdown has started") + void shouldPreventAddingProvidersAfterShutdownHasStarted() { + FeatureProvider provider = createMockedProvider(); + setFeatureProvider(provider); + + providerRepository.shutdown(); + + FeatureProvider newProvider = createMockedProvider(); + assertThatThrownBy(() -> setFeatureProvider(newProvider)) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("shutting down"); + } + + @Test + @DisplayName("prepareShutdown should return null on second call") + void prepareShutdownShouldReturnNullOnSecondCall() { + FeatureProvider provider = createMockedProvider(); + setFeatureProvider(provider); + + // First call should return managers list + var managers = providerRepository.prepareShutdown(); + assertThat(managers).isNotNull(); + assertThat(managers).isNotEmpty(); + + // Second call should be a no-op and return null (already shutting down) + var secondResult = providerRepository.prepareShutdown(); + assertThat(secondResult).isNull(); + } + + @Test + @DisplayName("should fall back to direct shutdown when executor rejects tasks") + void shouldFallBackToDirectShutdownWhenExecutorRejectsTasks() throws Exception { + FeatureProvider oldProvider = createMockedProvider(); + FeatureProvider newProvider = createMockedProvider(); + AtomicBoolean initializationStarted = new AtomicBoolean(false); + AtomicBoolean proceedWithInit = new AtomicBoolean(false); + + // Make oldProvider's initialization block until we signal + doAnswer(invocation -> { + initializationStarted.set(true); + while (!proceedWithInit.get()) { + Thread.sleep(10); + } + return null; + }) + .when(oldProvider) + .initialize(any()); + + // Start async initialization (will block) + providerRepository.setProvider( + oldProvider, mockAfterSet(), mockAfterInit(), mockAfterShutdown(), mockAfterError(), false); + + // Wait for initialization to start + await().atMost(Duration.ofSeconds(1)).untilTrue(initializationStarted); + + // Now set a new provider - this will trigger shutDownOld for oldProvider + // after initialization completes, but we haven't completed init yet + providerRepository.setProvider( + newProvider, mockAfterSet(), mockAfterInit(), mockAfterShutdown(), mockAfterError(), false); + + // Call shutdown on repository - this will shutdown the executor + var managers = providerRepository.prepareShutdown(); + providerRepository.completeShutdown(managers); + + // Now let the initialization complete - shutDownOld will be called but executor is shutdown + // This triggers the RejectedExecutionException path which falls back to direct shutdown + proceedWithInit.set(true); + + // Both providers should eventually be shut down (oldProvider via direct call due to + // RejectedExecutionException) + verify(oldProvider, timeout(TIMEOUT)).shutdown(); + verify(newProvider, timeout(TIMEOUT)).shutdown(); + } + } } @Test diff --git a/src/test/java/dev/openfeature/sdk/ShutdownBehaviorSpecTest.java b/src/test/java/dev/openfeature/sdk/ShutdownBehaviorSpecTest.java index 1bb7d4b62..2c6a6304e 100644 --- a/src/test/java/dev/openfeature/sdk/ShutdownBehaviorSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/ShutdownBehaviorSpecTest.java @@ -142,5 +142,19 @@ void apiIsReadyToUseAfterShutdown() { NoOpProvider p2 = new NoOpProvider(); api.setProvider(p2); } + + @Test + @DisplayName("calling shutdown twice should be safe and idempotent") + void callingShutdownTwiceShouldBeSafe() { + FeatureProvider provider = ProviderFixture.createMockedProvider(); + setFeatureProvider(provider); + + api.shutdown(); + + // Second shutdown should be a no-op (no exception, provider not called twice) + api.shutdown(); + + verify(provider, times(1)).shutdown(); + } } } diff --git a/src/test/java/dev/openfeature/sdk/vmlens/ProviderRepositoryCT.java b/src/test/java/dev/openfeature/sdk/vmlens/ProviderRepositoryCT.java new file mode 100644 index 000000000..2d88f698f --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/vmlens/ProviderRepositoryCT.java @@ -0,0 +1,158 @@ +package dev.openfeature.sdk.vmlens; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.vmlens.api.AllInterleavings; +import com.vmlens.api.Runner; +import dev.openfeature.sdk.FeatureProvider; +import dev.openfeature.sdk.OpenFeatureAPI; +import dev.openfeature.sdk.OpenFeatureAPITestUtil; +import java.util.concurrent.atomic.AtomicInteger; +import org.junit.jupiter.api.Test; + +/** + * Concurrency tests for ProviderRepository shutdown behavior using VMLens. + * + *

These tests verify that concurrent shutdown operations are safe and produce + * consistent results regardless of thread interleaving. Tests operate through + * the public OpenFeatureAPI since ProviderRepository is package-private. + */ +class ProviderRepositoryCT { + + private FeatureProvider createMockedProvider(String name, AtomicInteger shutdownCounter) throws Exception { + FeatureProvider provider = mock(FeatureProvider.class); + when(provider.getMetadata()).thenReturn(() -> name); + doAnswer(invocation -> { + shutdownCounter.incrementAndGet(); + return null; + }) + .when(provider) + .shutdown(); + doAnswer(invocation -> null).when(provider).initialize(any()); + return provider; + } + + @Test + void concurrentShutdown_providerShutdownCalledExactlyOnce() throws Exception { + try (AllInterleavings allInterleavings = + new AllInterleavings("Concurrent API shutdown - provider called once")) { + while (allInterleavings.hasNext()) { + // Fresh state for each interleaving + AtomicInteger shutdownCount = new AtomicInteger(0); + FeatureProvider provider = createMockedProvider("test-provider", shutdownCount); + OpenFeatureAPI api = OpenFeatureAPITestUtil.createAPI(); + + // Set provider and wait for initialization to complete + api.setProviderAndWait(provider); + + // Run concurrent shutdowns through the public API + Runner.runParallel(api::shutdown, api::shutdown, api::shutdown); + + // INVARIANT: Provider shutdown must be called exactly once + assertThat(shutdownCount.get()) + .as("Provider.shutdown() should be called exactly once regardless of thread interleaving") + .isEqualTo(1); + } + } + } + + @Test + void concurrentShutdown_providerShutdownCalledExactlyOnce_duringPendingInit() throws Exception { + try (AllInterleavings allInterleavings = new AllInterleavings("Shutdown during pending initialization")) { + while (allInterleavings.hasNext()) { + AtomicInteger shutdownCount = new AtomicInteger(0); + FeatureProvider provider = createMockedProvider("test-provider", shutdownCount); + OpenFeatureAPI api = OpenFeatureAPITestUtil.createAPI(); + + // Set provider without waiting - initialization task is pending on executor + api.setProvider(provider); + + // Shutdown while init task may still be pending + api.shutdown(); + + assertThat(shutdownCount.get()) + .as("Provider.shutdown() should be called exactly once") + .isEqualTo(1); + } + } + } + + @Test + void setProviderDuringShutdown_eitherSucceedsOrThrows() throws Exception { + try (AllInterleavings allInterleavings = new AllInterleavings("setProvider racing with shutdown")) { + while (allInterleavings.hasNext()) { + // Fresh state for each interleaving + AtomicInteger provider1ShutdownCount = new AtomicInteger(0); + AtomicInteger provider2ShutdownCount = new AtomicInteger(0); + FeatureProvider provider1 = createMockedProvider("provider-1", provider1ShutdownCount); + FeatureProvider provider2 = createMockedProvider("provider-2", provider2ShutdownCount); + OpenFeatureAPI api = OpenFeatureAPITestUtil.createAPI(); + + // Set initial provider + api.setProviderAndWait(provider1); + + // Track outcomes + AtomicInteger setProviderSucceeded = new AtomicInteger(0); + AtomicInteger setProviderFailed = new AtomicInteger(0); + + Runner.runParallel(api::shutdown, () -> { + try { + api.setProvider(provider2); + setProviderSucceeded.incrementAndGet(); + } catch (IllegalStateException e) { + if (e.getMessage().contains("shutting down")) { + setProviderFailed.incrementAndGet(); + } else { + throw e; + } + } + }); + + // INVARIANT: setProvider must have exactly one outcome + int totalOutcomes = setProviderSucceeded.get() + setProviderFailed.get(); + assertThat(totalOutcomes) + .as("setProvider must have exactly one outcome (success or failure)") + .isEqualTo(1); + + // INVARIANT: Original provider should always be shut down + assertThat(provider1ShutdownCount.get()) + .as("Original provider should be shut down exactly once") + .isEqualTo(1); + } + } + } + + @Test + void concurrentShutdown_multipleProvidersShutdownExactlyOnce() throws Exception { + try (AllInterleavings allInterleavings = new AllInterleavings("Concurrent shutdown - multiple providers")) { + while (allInterleavings.hasNext()) { + AtomicInteger provider1ShutdownCount = new AtomicInteger(0); + AtomicInteger provider2ShutdownCount = new AtomicInteger(0); + + FeatureProvider provider1 = createMockedProvider("provider-1", provider1ShutdownCount); + FeatureProvider provider2 = createMockedProvider("provider-2", provider2ShutdownCount); + + OpenFeatureAPI api = OpenFeatureAPITestUtil.createAPI(); + + // Register providers to named domains + api.setProviderAndWait("domain-1", provider1); + api.setProviderAndWait("domain-2", provider2); + + // Run concurrent shutdowns + Runner.runParallel(api::shutdown, api::shutdown); + + // INVARIANT: Each provider shut down exactly once + assertThat(provider1ShutdownCount.get()) + .as("Provider 1 shutdown count") + .isEqualTo(1); + assertThat(provider2ShutdownCount.get()) + .as("Provider 2 shutdown count") + .isEqualTo(1); + } + } + } +} From 9831c2e043e4e1164fb899acd38d24fefdbe0e14 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 00:23:13 +0000 Subject: [PATCH 635/745] chore(deps): update actions/setup-java digest to fe779bf (#1859) 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 00cef75c7..726ca9dd0 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -26,7 +26,7 @@ jobs: fetch-depth: 0 submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 + uses: actions/setup-java@fe779bf55ef683c9413269276a7588bb9cedf07a with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 163474b8c..0f59b5410 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -25,7 +25,7 @@ jobs: submodules: recursive - name: Set up JDK ${{ matrix.build.java }} - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 + uses: actions/setup-java@fe779bf55ef683c9413269276a7588bb9cedf07a with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d4db32f73..93d916e68 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,7 +43,7 @@ jobs: submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 + uses: actions/setup-java@fe779bf55ef683c9413269276a7588bb9cedf07a with: java-version: '17' distribution: 'temurin' From 641541e3c3b157b0faa19b1c3f9aa5f55f586eef Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 21 Feb 2026 00:23:04 +0000 Subject: [PATCH 636/745] chore(deps): update github/codeql-action digest to 710e294 (#1860) 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 0f59b5410..0b48dbf36 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@5e7a52feb2a3dfb87f88be2af33b9e2275f48de6 + uses: github/codeql-action/init@710e2945787622b429f8982cacb154faa182de18 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5e7a52feb2a3dfb87f88be2af33b9e2275f48de6 + uses: github/codeql-action/analyze@710e2945787622b429f8982cacb154faa182de18 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 3b7ecaa65..7af5d01dd 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@5e7a52feb2a3dfb87f88be2af33b9e2275f48de6 + uses: github/codeql-action/init@710e2945787622b429f8982cacb154faa182de18 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@5e7a52feb2a3dfb87f88be2af33b9e2275f48de6 + uses: github/codeql-action/autobuild@710e2945787622b429f8982cacb154faa182de18 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5e7a52feb2a3dfb87f88be2af33b9e2275f48de6 + uses: github/codeql-action/analyze@710e2945787622b429f8982cacb154faa182de18 From 83daace1f026b1baaa4919528ad286bd8dcec623 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 21 Feb 2026 13:36:03 +0100 Subject: [PATCH 637/745] chore(deps): update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.5 (#1862) 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 effb856b8..d587fe264 100644 --- a/pom.xml +++ b/pom.xml @@ -300,7 +300,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.5.4 + 3.5.5 ${surefireArgLine} @@ -724,7 +724,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.5.4 + 3.5.5 ${surefireArgLine} From f1fb67c177527a418d1c1eb3eb41ac0eb63b5478 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 21 Feb 2026 12:41:33 +0000 Subject: [PATCH 638/745] chore(deps): update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.5.5 (#1861) 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 d587fe264..02c0660dd 100644 --- a/pom.xml +++ b/pom.xml @@ -318,7 +318,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.5.4 + 3.5.5 ${surefireArgLine} @@ -740,7 +740,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.5.4 + 3.5.5 ${org.mockito.agent.argline} From 92a8bdbebc106205fcb25d0678730570150fb045 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 07:31:41 +0100 Subject: [PATCH 639/745] fix(deps): update dependency com.fasterxml.jackson:jackson-bom to v2.21.1 (#1863) 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 02c0660dd..c5dc7183d 100644 --- a/pom.xml +++ b/pom.xml @@ -229,7 +229,7 @@ com.fasterxml.jackson jackson-bom - 2.21.0 + 2.21.1 pom import From cfb908650e5f9f581030f43517dd6895e869d690 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 16:40:30 +0000 Subject: [PATCH 640/745] chore(deps): update github/codeql-action digest to cb4e075 (#1864) 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 0b48dbf36..d958dd111 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@710e2945787622b429f8982cacb154faa182de18 + uses: github/codeql-action/init@cb4e075f119f8bccbc942d49655b2cd4dc6e615a with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@710e2945787622b429f8982cacb154faa182de18 + uses: github/codeql-action/analyze@cb4e075f119f8bccbc942d49655b2cd4dc6e615a diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 7af5d01dd..ac41ebfb2 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@710e2945787622b429f8982cacb154faa182de18 + uses: github/codeql-action/init@cb4e075f119f8bccbc942d49655b2cd4dc6e615a with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@710e2945787622b429f8982cacb154faa182de18 + uses: github/codeql-action/autobuild@cb4e075f119f8bccbc942d49655b2cd4dc6e615a - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@710e2945787622b429f8982cacb154faa182de18 + uses: github/codeql-action/analyze@cb4e075f119f8bccbc942d49655b2cd4dc6e615a From 0544aeb56d421a5446d4eb604a033c9f8f34c3bd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 24 Feb 2026 14:40:36 +0100 Subject: [PATCH 641/745] chore(deps): update github/codeql-action digest to c4dca28 (#1865) 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 d958dd111..5671ed7df 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@cb4e075f119f8bccbc942d49655b2cd4dc6e615a + uses: github/codeql-action/init@c4dca28336f8ca0256dc5f40ed447a3220c07fec with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@cb4e075f119f8bccbc942d49655b2cd4dc6e615a + uses: github/codeql-action/analyze@c4dca28336f8ca0256dc5f40ed447a3220c07fec diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index ac41ebfb2..218f0ce94 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@cb4e075f119f8bccbc942d49655b2cd4dc6e615a + uses: github/codeql-action/init@c4dca28336f8ca0256dc5f40ed447a3220c07fec with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@cb4e075f119f8bccbc942d49655b2cd4dc6e615a + uses: github/codeql-action/autobuild@c4dca28336f8ca0256dc5f40ed447a3220c07fec - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@cb4e075f119f8bccbc942d49655b2cd4dc6e615a + uses: github/codeql-action/analyze@c4dca28336f8ca0256dc5f40ed447a3220c07fec From 29a29d64d4510fe681cf4d99686faf04586d8e38 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 25 Feb 2026 09:56:02 +0100 Subject: [PATCH 642/745] chore(deps): update github/codeql-action digest to 16adc4e (#1867) 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 5671ed7df..301e73540 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@c4dca28336f8ca0256dc5f40ed447a3220c07fec + uses: github/codeql-action/init@16adc4e6724ac45e5514b2814142af61054bcd2a with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c4dca28336f8ca0256dc5f40ed447a3220c07fec + uses: github/codeql-action/analyze@16adc4e6724ac45e5514b2814142af61054bcd2a diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 218f0ce94..302f564e4 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@c4dca28336f8ca0256dc5f40ed447a3220c07fec + uses: github/codeql-action/init@16adc4e6724ac45e5514b2814142af61054bcd2a with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@c4dca28336f8ca0256dc5f40ed447a3220c07fec + uses: github/codeql-action/autobuild@16adc4e6724ac45e5514b2814142af61054bcd2a - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c4dca28336f8ca0256dc5f40ed447a3220c07fec + uses: github/codeql-action/analyze@16adc4e6724ac45e5514b2814142af61054bcd2a From 722180f50674a39eaa2f257c7b84ae168f076ba1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 25 Feb 2026 09:01:47 +0000 Subject: [PATCH 643/745] chore(deps): update actions/cache digest to 5656298 (#1866) 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 726ca9dd0..28a9714e8 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -36,7 +36,7 @@ jobs: server-password: ${{ secrets.CENTRAL_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@b7e8d49f17405cc70c1c120101943203c98d3a4b + uses: actions/cache@565629816435f6c0b50676926c9b05c254113c0c 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 301e73540..52e8321bc 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -37,7 +37,7 @@ jobs: languages: java - name: Cache local Maven repository - uses: actions/cache@b7e8d49f17405cc70c1c120101943203c98d3a4b + uses: actions/cache@565629816435f6c0b50676926c9b05c254113c0c with: path: ~/.m2/repository key: ${{ runner.os }}${{ matrix.build.java }}-maven-${{ hashFiles('**/pom.xml') }} From f44643fa32805704fd3fc88ae88998099bb2713a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 28 Feb 2026 04:33:05 +0000 Subject: [PATCH 644/745] chore(deps): update github/codeql-action digest to 0ec47d0 (#1868) 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 52e8321bc..b81043069 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@16adc4e6724ac45e5514b2814142af61054bcd2a + uses: github/codeql-action/init@0ec47d036c68ae0cf94c629009b1029407111281 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@16adc4e6724ac45e5514b2814142af61054bcd2a + uses: github/codeql-action/analyze@0ec47d036c68ae0cf94c629009b1029407111281 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 302f564e4..6d20e4dc7 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@16adc4e6724ac45e5514b2814142af61054bcd2a + uses: github/codeql-action/init@0ec47d036c68ae0cf94c629009b1029407111281 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@16adc4e6724ac45e5514b2814142af61054bcd2a + uses: github/codeql-action/autobuild@0ec47d036c68ae0cf94c629009b1029407111281 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@16adc4e6724ac45e5514b2814142af61054bcd2a + uses: github/codeql-action/analyze@0ec47d036c68ae0cf94c629009b1029407111281 From 1df34b04bc34d17f624ac33378383ad95f06f72b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 28 Feb 2026 08:36:03 +0000 Subject: [PATCH 645/745] chore(deps): update dependency org.mockito:mockito-core to v5.22.0 (#1869) 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 c5dc7183d..13b47dea0 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ UTF-8 11 ${maven.compiler.source} - 5.21.0 + 5.22.0 1.2.26 **/e2e/*.java From aefc2feef6da355e885ace3a9864e1248f6d3daa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 28 Feb 2026 12:32:29 +0000 Subject: [PATCH 646/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.18.6-jdk6-jdk5 (#1870) 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 13b47dea0..be1e0b8c4 100644 --- a/pom.xml +++ b/pom.xml @@ -214,7 +214,7 @@ net.bytebuddy byte-buddy - 1.18.5 + 1.18.6-jdk6-jdk5 test From 1b82e5f2f3324f65c745b78279cee41ce109c952 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 28 Feb 2026 13:29:39 +0000 Subject: [PATCH 647/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.18.6-jdk6-jdk5 (#1871) 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 be1e0b8c4..2282e58fb 100644 --- a/pom.xml +++ b/pom.xml @@ -221,7 +221,7 @@ net.bytebuddy byte-buddy-agent - 1.18.5 + 1.18.6-jdk6-jdk5 test From 57706145642fb99835a04977029c402babdcdce9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 09:22:10 +0100 Subject: [PATCH 648/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.18.7-jdk5 (#1874) 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 2282e58fb..c40520665 100644 --- a/pom.xml +++ b/pom.xml @@ -221,7 +221,7 @@ net.bytebuddy byte-buddy-agent - 1.18.6-jdk6-jdk5 + 1.18.7-jdk5 test From a4c5c599d9e187af05feb2f5cb56f84431aa87a2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 08:27:16 +0000 Subject: [PATCH 649/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.18.7-jdk5 (#1873) 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 c40520665..ffa67999d 100644 --- a/pom.xml +++ b/pom.xml @@ -214,7 +214,7 @@ net.bytebuddy byte-buddy - 1.18.6-jdk6-jdk5 + 1.18.7-jdk5 test From 95aa4f7aafd37ef7f69eab22651e52994547f93f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 16:35:57 +0000 Subject: [PATCH 650/745] chore(deps): update github/codeql-action digest to b895512 (#1875) 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 b81043069..e41e94630 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@0ec47d036c68ae0cf94c629009b1029407111281 + uses: github/codeql-action/init@b895512248b1b5b0089ac3c33ecf123c2cd6f373 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0ec47d036c68ae0cf94c629009b1029407111281 + uses: github/codeql-action/analyze@b895512248b1b5b0089ac3c33ecf123c2cd6f373 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 6d20e4dc7..5c235dce2 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@0ec47d036c68ae0cf94c629009b1029407111281 + uses: github/codeql-action/init@b895512248b1b5b0089ac3c33ecf123c2cd6f373 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@0ec47d036c68ae0cf94c629009b1029407111281 + uses: github/codeql-action/autobuild@b895512248b1b5b0089ac3c33ecf123c2cd6f373 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0ec47d036c68ae0cf94c629009b1029407111281 + uses: github/codeql-action/analyze@b895512248b1b5b0089ac3c33ecf123c2cd6f373 From 036fb5094578e6f08da47b96d3cca375cca8dd28 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Mar 2026 04:35:17 +0000 Subject: [PATCH 651/745] chore(deps): update actions/setup-java digest to 1d018f9 (#1876) 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 28a9714e8..cb63f819b 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -26,7 +26,7 @@ jobs: fetch-depth: 0 submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@fe779bf55ef683c9413269276a7588bb9cedf07a + uses: actions/setup-java@1d018f9b8b9b505bb578a83b230fabcce01af93b with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index e41e94630..782ec2031 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -25,7 +25,7 @@ jobs: submodules: recursive - name: Set up JDK ${{ matrix.build.java }} - uses: actions/setup-java@fe779bf55ef683c9413269276a7588bb9cedf07a + uses: actions/setup-java@1d018f9b8b9b505bb578a83b230fabcce01af93b with: java-version: ${{ matrix.build.java }} distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 93d916e68..7427da07d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,7 +43,7 @@ jobs: submodules: recursive - name: Set up JDK 17 - uses: actions/setup-java@fe779bf55ef683c9413269276a7588bb9cedf07a + uses: actions/setup-java@1d018f9b8b9b505bb578a83b230fabcce01af93b with: java-version: '17' distribution: 'temurin' From 0a2878e761df4d4a5a06b0e98c97b8924a102110 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Mar 2026 08:35:29 +0000 Subject: [PATCH 652/745] chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3.3.0 (#1877) 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 ffa67999d..2d4983141 100644 --- a/pom.xml +++ b/pom.xml @@ -524,7 +524,7 @@ com.diffplug.spotless spotless-maven-plugin - 3.2.1 + 3.3.0 From d60cf3811b8d5cfc997d88096bc2e6bf3854a016 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Mar 2026 20:36:06 +0000 Subject: [PATCH 653/745] chore(deps): update github/codeql-action digest to 40f0fa9 (#1878) 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 782ec2031..dd1ac6ec9 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@b895512248b1b5b0089ac3c33ecf123c2cd6f373 + uses: github/codeql-action/init@40f0fa95c41fede7b43f035cb47aac899ee0ba0a with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b895512248b1b5b0089ac3c33ecf123c2cd6f373 + uses: github/codeql-action/analyze@40f0fa95c41fede7b43f035cb47aac899ee0ba0a diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 5c235dce2..35ec324e3 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@b895512248b1b5b0089ac3c33ecf123c2cd6f373 + uses: github/codeql-action/init@40f0fa95c41fede7b43f035cb47aac899ee0ba0a with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@b895512248b1b5b0089ac3c33ecf123c2cd6f373 + uses: github/codeql-action/autobuild@40f0fa95c41fede7b43f035cb47aac899ee0ba0a - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b895512248b1b5b0089ac3c33ecf123c2cd6f373 + uses: github/codeql-action/analyze@40f0fa95c41fede7b43f035cb47aac899ee0ba0a From d63ae69121bc27f15a124395fbb9b6007823285f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 4 Mar 2026 20:35:10 +0000 Subject: [PATCH 654/745] chore(deps): update github/codeql-action digest to b6dfacb (#1879) 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 dd1ac6ec9..7d4f40516 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@40f0fa95c41fede7b43f035cb47aac899ee0ba0a + uses: github/codeql-action/init@b6dfacb528092ed900ca0cfec2957487685c3bfd with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@40f0fa95c41fede7b43f035cb47aac899ee0ba0a + uses: github/codeql-action/analyze@b6dfacb528092ed900ca0cfec2957487685c3bfd diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 35ec324e3..9dd07ab2f 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@40f0fa95c41fede7b43f035cb47aac899ee0ba0a + uses: github/codeql-action/init@b6dfacb528092ed900ca0cfec2957487685c3bfd with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@40f0fa95c41fede7b43f035cb47aac899ee0ba0a + uses: github/codeql-action/autobuild@b6dfacb528092ed900ca0cfec2957487685c3bfd - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@40f0fa95c41fede7b43f035cb47aac899ee0ba0a + uses: github/codeql-action/analyze@b6dfacb528092ed900ca0cfec2957487685c3bfd From 8d354c6dd4db5253d87b9d6d40301a81653a8354 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Mar 2026 00:35:43 +0000 Subject: [PATCH 655/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.34.3 (#1880) 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 2d4983141..942e338d3 100644 --- a/pom.xml +++ b/pom.xml @@ -237,7 +237,7 @@ io.cucumber cucumber-bom - 7.34.2 + 7.34.3 pom import From a89da34cb27e438acf66c787c55bfc469f7bb3a8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Mar 2026 21:41:59 +0000 Subject: [PATCH 656/745] chore(deps): update github/codeql-action digest to 72d2d85 (#1881) 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 7d4f40516..27e68ae20 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@b6dfacb528092ed900ca0cfec2957487685c3bfd + uses: github/codeql-action/init@72d2d850d1f91d4e1e024f4cf4276fd16bb68462 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b6dfacb528092ed900ca0cfec2957487685c3bfd + uses: github/codeql-action/analyze@72d2d850d1f91d4e1e024f4cf4276fd16bb68462 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 9dd07ab2f..323c58f67 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@b6dfacb528092ed900ca0cfec2957487685c3bfd + uses: github/codeql-action/init@72d2d850d1f91d4e1e024f4cf4276fd16bb68462 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@b6dfacb528092ed900ca0cfec2957487685c3bfd + uses: github/codeql-action/autobuild@72d2d850d1f91d4e1e024f4cf4276fd16bb68462 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b6dfacb528092ed900ca0cfec2957487685c3bfd + uses: github/codeql-action/analyze@72d2d850d1f91d4e1e024f4cf4276fd16bb68462 From d43ff42f3aada33910acef06e37d8f5d0032d6e0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 16:34:24 +0000 Subject: [PATCH 657/745] chore(deps): update dependency maven to v3.9.13 (#1885) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .mvn/wrapper/maven-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 5f1f57004..1027a01fe 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,2 +1,2 @@ distributionType=only-script -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.12/apache-maven-3.9.12-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.13/apache-maven-3.9.13-bin.zip From 49a0db9974e1bb6efdf148c6a67ea931eb120767 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 20:34:35 +0000 Subject: [PATCH 658/745] chore(deps): update github/codeql-action digest to d1a6527 (#1884) 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 27e68ae20..c1f6f932e 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@72d2d850d1f91d4e1e024f4cf4276fd16bb68462 + uses: github/codeql-action/init@d1a65275e8dac7b2cc72bb121bf58f0ee7b0f92d with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@72d2d850d1f91d4e1e024f4cf4276fd16bb68462 + uses: github/codeql-action/analyze@d1a65275e8dac7b2cc72bb121bf58f0ee7b0f92d diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 323c58f67..a04024f75 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@72d2d850d1f91d4e1e024f4cf4276fd16bb68462 + uses: github/codeql-action/init@d1a65275e8dac7b2cc72bb121bf58f0ee7b0f92d with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@72d2d850d1f91d4e1e024f4cf4276fd16bb68462 + uses: github/codeql-action/autobuild@d1a65275e8dac7b2cc72bb121bf58f0ee7b0f92d - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@72d2d850d1f91d4e1e024f4cf4276fd16bb68462 + uses: github/codeql-action/analyze@d1a65275e8dac7b2cc72bb121bf58f0ee7b0f92d From 12acf601e0105a6e880f2b4ac63a64352761bc89 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 00:33:48 +0000 Subject: [PATCH 659/745] chore(deps): update com.vmlens.version to v1.2.27 (#1886) 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 942e338d3..ee251a324 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ 11 ${maven.compiler.source} 5.22.0 - 1.2.26 + 1.2.27 **/e2e/*.java ${project.groupId}.${project.artifactId} From 7cc39a1f6caea0584b94b0b2b3f1e3aafee9d480 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 10 Mar 2026 00:37:31 +0000 Subject: [PATCH 660/745] chore(deps): update github/codeql-action digest to babab88 (#1887) 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 c1f6f932e..fd9d569b0 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@d1a65275e8dac7b2cc72bb121bf58f0ee7b0f92d + uses: github/codeql-action/init@babab88e549fbc29e9b0058b5d63e2817a135c17 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@d1a65275e8dac7b2cc72bb121bf58f0ee7b0f92d + uses: github/codeql-action/analyze@babab88e549fbc29e9b0058b5d63e2817a135c17 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index a04024f75..a83f3f384 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@d1a65275e8dac7b2cc72bb121bf58f0ee7b0f92d + uses: github/codeql-action/init@babab88e549fbc29e9b0058b5d63e2817a135c17 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@d1a65275e8dac7b2cc72bb121bf58f0ee7b0f92d + uses: github/codeql-action/autobuild@babab88e549fbc29e9b0058b5d63e2817a135c17 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@d1a65275e8dac7b2cc72bb121bf58f0ee7b0f92d + uses: github/codeql-action/analyze@babab88e549fbc29e9b0058b5d63e2817a135c17 From 80f5313f98f723e397f858c198052b1c0457860d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 10 Mar 2026 12:37:35 +0000 Subject: [PATCH 661/745] chore(deps): update github/codeql-action digest to 87c3b7b (#1888) 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 fd9d569b0..21a1e788f 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@babab88e549fbc29e9b0058b5d63e2817a135c17 + uses: github/codeql-action/init@87c3b7b6a14ce5c8aa319c102325e8c2a85d7cd5 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@babab88e549fbc29e9b0058b5d63e2817a135c17 + uses: github/codeql-action/analyze@87c3b7b6a14ce5c8aa319c102325e8c2a85d7cd5 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index a83f3f384..a7fcdd563 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@babab88e549fbc29e9b0058b5d63e2817a135c17 + uses: github/codeql-action/init@87c3b7b6a14ce5c8aa319c102325e8c2a85d7cd5 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@babab88e549fbc29e9b0058b5d63e2817a135c17 + uses: github/codeql-action/autobuild@87c3b7b6a14ce5c8aa319c102325e8c2a85d7cd5 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@babab88e549fbc29e9b0058b5d63e2817a135c17 + uses: github/codeql-action/analyze@87c3b7b6a14ce5c8aa319c102325e8c2a85d7cd5 From bea082d2ffa5af3ce209caf8af628810bb596ebb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2026 02:03:50 +0000 Subject: [PATCH 662/745] chore(deps): update github/codeql-action digest to 5cb13d6 (#1889) 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 21a1e788f..e8365b030 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@87c3b7b6a14ce5c8aa319c102325e8c2a85d7cd5 + uses: github/codeql-action/init@5cb13d6ab8fe2074c40917e54a74e3d63b9927b4 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@87c3b7b6a14ce5c8aa319c102325e8c2a85d7cd5 + uses: github/codeql-action/analyze@5cb13d6ab8fe2074c40917e54a74e3d63b9927b4 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index a7fcdd563..0e737d44c 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@87c3b7b6a14ce5c8aa319c102325e8c2a85d7cd5 + uses: github/codeql-action/init@5cb13d6ab8fe2074c40917e54a74e3d63b9927b4 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@87c3b7b6a14ce5c8aa319c102325e8c2a85d7cd5 + uses: github/codeql-action/autobuild@5cb13d6ab8fe2074c40917e54a74e3d63b9927b4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@87c3b7b6a14ce5c8aa319c102325e8c2a85d7cd5 + uses: github/codeql-action/analyze@5cb13d6ab8fe2074c40917e54a74e3d63b9927b4 From 597501ad6f478c11336816f766eb1293fedb0677 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2026 09:07:31 +0100 Subject: [PATCH 663/745] fix(deps): update dependency org.projectlombok:lombok to v1.18.44 (#1890) 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 ee251a324..c9973d47e 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ org.projectlombok lombok - 1.18.42 + 1.18.44 provided From 3b48a87ecb1f10f595f1b239d8dc1684ccee0f68 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 12 Mar 2026 04:33:16 +0000 Subject: [PATCH 664/745] chore(deps): update github/codeql-action digest to 1dbebad (#1891) 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 e8365b030..450ccce21 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@5cb13d6ab8fe2074c40917e54a74e3d63b9927b4 + uses: github/codeql-action/init@1dbebad653b49a8cce7da97e33aa7a9e33a82651 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5cb13d6ab8fe2074c40917e54a74e3d63b9927b4 + uses: github/codeql-action/analyze@1dbebad653b49a8cce7da97e33aa7a9e33a82651 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 0e737d44c..dda77a299 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@5cb13d6ab8fe2074c40917e54a74e3d63b9927b4 + uses: github/codeql-action/init@1dbebad653b49a8cce7da97e33aa7a9e33a82651 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@5cb13d6ab8fe2074c40917e54a74e3d63b9927b4 + uses: github/codeql-action/autobuild@1dbebad653b49a8cce7da97e33aa7a9e33a82651 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5cb13d6ab8fe2074c40917e54a74e3d63b9927b4 + uses: github/codeql-action/analyze@1dbebad653b49a8cce7da97e33aa7a9e33a82651 From 4092074d6c68bd259097a4d7a32845fc5e2157ea Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 12 Mar 2026 08:32:34 +0000 Subject: [PATCH 665/745] chore(deps): update dependency org.mockito:mockito-core to v5.23.0 (#1893) 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 c9973d47e..42587fa9e 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ UTF-8 11 ${maven.compiler.source} - 5.22.0 + 5.23.0 1.2.27 **/e2e/*.java From 844dc422662bcf92867ac127abf6c4d05106ec3a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 12 Mar 2026 14:16:53 +0100 Subject: [PATCH 666/745] chore(deps): update dependency maven to v3.9.14 (#1894) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .mvn/wrapper/maven-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 1027a01fe..8dbfd9010 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,2 +1,2 @@ distributionType=only-script -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.13/apache-maven-3.9.13-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.14/apache-maven-3.9.14-bin.zip From afb6befdbd58e0f10458951f8f740713ebdefa2e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 21:17:53 +0000 Subject: [PATCH 667/745] chore(deps): update github/codeql-action digest to 7dd76e6 (#1895) 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 450ccce21..4ea3d4015 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@1dbebad653b49a8cce7da97e33aa7a9e33a82651 + uses: github/codeql-action/init@7dd76e6bf79d24133aa649887a6ee01d8b063816 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1dbebad653b49a8cce7da97e33aa7a9e33a82651 + uses: github/codeql-action/analyze@7dd76e6bf79d24133aa649887a6ee01d8b063816 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index dda77a299..30fa08d4c 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@1dbebad653b49a8cce7da97e33aa7a9e33a82651 + uses: github/codeql-action/init@7dd76e6bf79d24133aa649887a6ee01d8b063816 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@1dbebad653b49a8cce7da97e33aa7a9e33a82651 + uses: github/codeql-action/autobuild@7dd76e6bf79d24133aa649887a6ee01d8b063816 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1dbebad653b49a8cce7da97e33aa7a9e33a82651 + uses: github/codeql-action/analyze@7dd76e6bf79d24133aa649887a6ee01d8b063816 From ff5f51953bcebe60a1039265ced197f3d0badaad Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 18:27:41 +0000 Subject: [PATCH 668/745] chore(deps): update github/codeql-action digest to fd1ca02 (#1896) 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 4ea3d4015..04f829ac9 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@7dd76e6bf79d24133aa649887a6ee01d8b063816 + uses: github/codeql-action/init@fd1ca02d0ddf5bf468c79e6ffb6ffb24f0ecba37 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7dd76e6bf79d24133aa649887a6ee01d8b063816 + uses: github/codeql-action/analyze@fd1ca02d0ddf5bf468c79e6ffb6ffb24f0ecba37 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 30fa08d4c..86c0e844c 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@7dd76e6bf79d24133aa649887a6ee01d8b063816 + uses: github/codeql-action/init@fd1ca02d0ddf5bf468c79e6ffb6ffb24f0ecba37 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@7dd76e6bf79d24133aa649887a6ee01d8b063816 + uses: github/codeql-action/autobuild@fd1ca02d0ddf5bf468c79e6ffb6ffb24f0ecba37 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7dd76e6bf79d24133aa649887a6ee01d8b063816 + uses: github/codeql-action/analyze@fd1ca02d0ddf5bf468c79e6ffb6ffb24f0ecba37 From 5070bb2bfffa381d9f47d9c026e2db8b0c7553a0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Mar 2026 16:32:16 +0000 Subject: [PATCH 669/745] chore(deps): update github/codeql-action digest to 7da6361 (#1898) 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 04f829ac9..b80d13428 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@fd1ca02d0ddf5bf468c79e6ffb6ffb24f0ecba37 + uses: github/codeql-action/init@7da6361ba56d9e2aa798049c7f0a046fe133921e with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@fd1ca02d0ddf5bf468c79e6ffb6ffb24f0ecba37 + uses: github/codeql-action/analyze@7da6361ba56d9e2aa798049c7f0a046fe133921e diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 86c0e844c..40b55f766 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@fd1ca02d0ddf5bf468c79e6ffb6ffb24f0ecba37 + uses: github/codeql-action/init@7da6361ba56d9e2aa798049c7f0a046fe133921e with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@fd1ca02d0ddf5bf468c79e6ffb6ffb24f0ecba37 + uses: github/codeql-action/autobuild@7da6361ba56d9e2aa798049c7f0a046fe133921e - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@fd1ca02d0ddf5bf468c79e6ffb6ffb24f0ecba37 + uses: github/codeql-action/analyze@7da6361ba56d9e2aa798049c7f0a046fe133921e From 55ab429dd5692b8b82f48250c0fcb9c459d03b1c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Mar 2026 20:35:06 +0000 Subject: [PATCH 670/745] chore(deps): update actions/cache digest to 6682284 (#1899) 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 cb63f819b..b6764975d 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -36,7 +36,7 @@ jobs: server-password: ${{ secrets.CENTRAL_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@565629816435f6c0b50676926c9b05c254113c0c + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 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 b80d13428..0d32d3f5c 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -37,7 +37,7 @@ jobs: languages: java - name: Cache local Maven repository - uses: actions/cache@565629816435f6c0b50676926c9b05c254113c0c + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 with: path: ~/.m2/repository key: ${{ runner.os }}${{ matrix.build.java }}-maven-${{ hashFiles('**/pom.xml') }} From 76466a3d9362b6c45ddcee3c6c4eb351ea0f5086 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2026 00:34:19 +0000 Subject: [PATCH 671/745] chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3.4.0 (#1903) 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 42587fa9e..0cf3b363a 100644 --- a/pom.xml +++ b/pom.xml @@ -524,7 +524,7 @@ com.diffplug.spotless spotless-maven-plugin - 3.3.0 + 3.4.0 From b4a56451396c09fafc983d5248e036c80a8a97a9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2026 12:33:25 +0000 Subject: [PATCH 672/745] chore(deps): update codecov/codecov-action action to v5.5.3 (#1902) 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 b6764975d..fe533e3fe 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -53,7 +53,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.5.2 + uses: codecov/codecov-action@v5.5.3 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 0d32d3f5c..9d4c4dfcd 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -49,7 +49,7 @@ jobs: - if: matrix.build.java == '17' name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.5.2 + uses: codecov/codecov-action@v5.5.3 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From 544bc56b82946cbd2e600d75a87ba97096258458 Mon Sep 17 00:00:00 2001 From: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> Date: Thu, 19 Mar 2026 12:49:26 -0400 Subject: [PATCH 673/745] chore(main): release 1.20.2 (#1821) Signed-off-by: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 86 +++++++++++++++++++++++++++++++++++ README.md | 8 ++-- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 93 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 149a4cfd2..01385fe6f 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"1.20.1"} +{".":"1.20.2"} diff --git a/CHANGELOG.md b/CHANGELOG.md index ec2955e16..1b549e936 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,91 @@ # Changelog +## [1.20.2](https://github.com/open-feature/java-sdk/compare/v1.20.1...v1.20.2) (2026-03-19) + + +### 🐛 Bug Fixes + +* allow for providers to safely shutdown ([#1744](https://github.com/open-feature/java-sdk/issues/1744)) ([efbf279](https://github.com/open-feature/java-sdk/commit/efbf27990e9937bb7b0497e6172bc1da15cb230e)) +* **deps:** update dependency com.fasterxml.jackson:jackson-bom to v2.21.1 ([#1863](https://github.com/open-feature/java-sdk/issues/1863)) ([92a8bdb](https://github.com/open-feature/java-sdk/commit/92a8bdbebc106205fcb25d0678730570150fb045)) +* **deps:** update dependency io.cucumber:cucumber-bom to v7.34.1 ([#1834](https://github.com/open-feature/java-sdk/issues/1834)) ([f549956](https://github.com/open-feature/java-sdk/commit/f5499569e3c6e8c95b7a58185e8cf79aef7386ad)) +* **deps:** update dependency io.cucumber:cucumber-bom to v7.34.2 ([#1837](https://github.com/open-feature/java-sdk/issues/1837)) ([b8c4b9a](https://github.com/open-feature/java-sdk/commit/b8c4b9a1e48bbcd0265b3e47c66ab823cf18d219)) +* **deps:** update dependency io.cucumber:cucumber-bom to v7.34.3 ([#1880](https://github.com/open-feature/java-sdk/issues/1880)) ([8d354c6](https://github.com/open-feature/java-sdk/commit/8d354c6dd4db5253d87b9d6d40301a81653a8354)) +* **deps:** update dependency org.junit:junit-bom to v6.0.3 ([#1855](https://github.com/open-feature/java-sdk/issues/1855)) ([5af58fd](https://github.com/open-feature/java-sdk/commit/5af58fd750e487e95c6c0cf8cdaf386c8967a2eb)) +* **deps:** update dependency org.projectlombok:lombok to v1.18.44 ([#1890](https://github.com/open-feature/java-sdk/issues/1890)) ([597501a](https://github.com/open-feature/java-sdk/commit/597501ad6f478c11336816f766eb1293fedb0677)) + + +### 🧹 Chore + +* **deps:** update actions/cache digest to 5656298 ([#1866](https://github.com/open-feature/java-sdk/issues/1866)) ([722180f](https://github.com/open-feature/java-sdk/commit/722180f50674a39eaa2f257c7b84ae168f076ba1)) +* **deps:** update actions/cache digest to 6682284 ([#1899](https://github.com/open-feature/java-sdk/issues/1899)) ([55ab429](https://github.com/open-feature/java-sdk/commit/55ab429dd5692b8b82f48250c0fcb9c459d03b1c)) +* **deps:** update actions/cache digest to b456236 ([#1835](https://github.com/open-feature/java-sdk/issues/1835)) ([ffeccdf](https://github.com/open-feature/java-sdk/commit/ffeccdf43079e306e2ecf04b46b01dfaf3b6c624)) +* **deps:** update actions/cache digest to b7e8d49 ([#1838](https://github.com/open-feature/java-sdk/issues/1838)) ([99f2e0f](https://github.com/open-feature/java-sdk/commit/99f2e0fab11bfd4f97503d3685d554280e7fcb53)) +* **deps:** update actions/setup-java digest to 1d018f9 ([#1876](https://github.com/open-feature/java-sdk/issues/1876)) ([036fb50](https://github.com/open-feature/java-sdk/commit/036fb5094578e6f08da47b96d3cca375cca8dd28)) +* **deps:** update actions/setup-java digest to fe779bf ([#1859](https://github.com/open-feature/java-sdk/issues/1859)) ([9831c2e](https://github.com/open-feature/java-sdk/commit/9831c2e043e4e1164fb899acd38d24fefdbe0e14)) +* **deps:** update amannn/action-semantic-pull-request digest to ac7e3fc ([#1852](https://github.com/open-feature/java-sdk/issues/1852)) ([53d3fe3](https://github.com/open-feature/java-sdk/commit/53d3fe33df1b4b063ae14a255735e9447df4b6b0)) +* **deps:** update codecov/codecov-action action to v5.5.3 ([#1902](https://github.com/open-feature/java-sdk/issues/1902)) ([b4a5645](https://github.com/open-feature/java-sdk/commit/b4a56451396c09fafc983d5248e036c80a8a97a9)) +* **deps:** update com.vmlens.version to v1.2.25 ([#1845](https://github.com/open-feature/java-sdk/issues/1845)) ([e495576](https://github.com/open-feature/java-sdk/commit/e495576d08b283286ee847eef2f4ac4530d8fa45)) +* **deps:** update com.vmlens.version to v1.2.26 ([#1846](https://github.com/open-feature/java-sdk/issues/1846)) ([102951b](https://github.com/open-feature/java-sdk/commit/102951b00f6392d5bef7bd4bfc381eaeb374e0ea)) +* **deps:** update com.vmlens.version to v1.2.27 ([#1886](https://github.com/open-feature/java-sdk/issues/1886)) ([12acf60](https://github.com/open-feature/java-sdk/commit/12acf601e0105a6e880f2b4ac63a64352761bc89)) +* **deps:** update dependency com.diffplug.spotless:spotless-maven-plugin to v3.2.0 ([#1822](https://github.com/open-feature/java-sdk/issues/1822)) ([2942daf](https://github.com/open-feature/java-sdk/commit/2942daf9005816696d96d8d7e58c7bf261c5c086)) +* **deps:** update dependency com.diffplug.spotless:spotless-maven-plugin to v3.2.1 ([#1831](https://github.com/open-feature/java-sdk/issues/1831)) ([cfd1864](https://github.com/open-feature/java-sdk/commit/cfd1864c0057d98b185afe3d0cec02509d40c4b1)) +* **deps:** update dependency com.diffplug.spotless:spotless-maven-plugin to v3.3.0 ([#1877](https://github.com/open-feature/java-sdk/issues/1877)) ([0a2878e](https://github.com/open-feature/java-sdk/commit/0a2878e761df4d4a5a06b0e98c97b8924a102110)) +* **deps:** update dependency com.diffplug.spotless:spotless-maven-plugin to v3.4.0 ([#1903](https://github.com/open-feature/java-sdk/issues/1903)) ([76466a3](https://github.com/open-feature/java-sdk/commit/76466a3d9362b6c45ddcee3c6c4eb351ea0f5086)) +* **deps:** update dependency maven to v3.9.13 ([#1885](https://github.com/open-feature/java-sdk/issues/1885)) ([d43ff42](https://github.com/open-feature/java-sdk/commit/d43ff42f3aada33910acef06e37d8f5d0032d6e0)) +* **deps:** update dependency maven to v3.9.14 ([#1894](https://github.com/open-feature/java-sdk/issues/1894)) ([844dc42](https://github.com/open-feature/java-sdk/commit/844dc422662bcf92867ac127abf6c4d05106ec3a)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.18.5 ([#1853](https://github.com/open-feature/java-sdk/issues/1853)) ([de2b737](https://github.com/open-feature/java-sdk/commit/de2b7376cb5e390820b51cc127b739eb26dad01a)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.18.6-jdk6-jdk5 ([#1870](https://github.com/open-feature/java-sdk/issues/1870)) ([aefc2fe](https://github.com/open-feature/java-sdk/commit/aefc2feef6da355e885ace3a9864e1248f6d3daa)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.18.7-jdk5 ([#1873](https://github.com/open-feature/java-sdk/issues/1873)) ([a4c5c59](https://github.com/open-feature/java-sdk/commit/a4c5c599d9e187af05feb2f5cb56f84431aa87a2)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.18.5 ([#1854](https://github.com/open-feature/java-sdk/issues/1854)) ([2fd471a](https://github.com/open-feature/java-sdk/commit/2fd471a4c9d4849895d99e5d11249c4576556d29)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.18.6-jdk6-jdk5 ([#1871](https://github.com/open-feature/java-sdk/issues/1871)) ([1b82e5f](https://github.com/open-feature/java-sdk/commit/1b82e5f2f3324f65c745b78279cee41ce109c952)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.18.7-jdk5 ([#1874](https://github.com/open-feature/java-sdk/issues/1874)) ([5770614](https://github.com/open-feature/java-sdk/commit/57706145642fb99835a04977029c402babdcdce9)) +* **deps:** update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.15.0 ([#1839](https://github.com/open-feature/java-sdk/issues/1839)) ([857fed8](https://github.com/open-feature/java-sdk/commit/857fed8d03becab81860ae9286278d3b8c5c80be)) +* **deps:** update dependency org.apache.maven.plugins:maven-dependency-plugin to v3.10.0 ([#1847](https://github.com/open-feature/java-sdk/issues/1847)) ([3857856](https://github.com/open-feature/java-sdk/commit/385785641ade0b4ff5fe16d22daf45352931f056)) +* **deps:** update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.5.5 ([#1861](https://github.com/open-feature/java-sdk/issues/1861)) ([f1fb67c](https://github.com/open-feature/java-sdk/commit/f1fb67c177527a418d1c1eb3eb41ac0eb63b5478)) +* **deps:** update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.5 ([#1862](https://github.com/open-feature/java-sdk/issues/1862)) ([83daace](https://github.com/open-feature/java-sdk/commit/83daace1f026b1baaa4919528ad286bd8dcec623)) +* **deps:** update dependency org.assertj:assertj-core to v3.27.7 ([#1824](https://github.com/open-feature/java-sdk/issues/1824)) ([40ac67a](https://github.com/open-feature/java-sdk/commit/40ac67aaaf30fb7ef4565ed4a76ec5a68526ee15)) +* **deps:** update dependency org.mockito:mockito-core to v5.22.0 ([#1869](https://github.com/open-feature/java-sdk/issues/1869)) ([1df34b0](https://github.com/open-feature/java-sdk/commit/1df34b04bc34d17f624ac33378383ad95f06f72b)) +* **deps:** update dependency org.mockito:mockito-core to v5.23.0 ([#1893](https://github.com/open-feature/java-sdk/issues/1893)) ([4092074](https://github.com/open-feature/java-sdk/commit/4092074d6c68bd259097a4d7a32845fc5e2157ea)) +* **deps:** update github/codeql-action digest to 015d8c7 ([#1857](https://github.com/open-feature/java-sdk/issues/1857)) ([a48fb39](https://github.com/open-feature/java-sdk/commit/a48fb39f10f5c030e3cc489420cf41100c2244c1)) +* **deps:** update github/codeql-action digest to 0ec47d0 ([#1868](https://github.com/open-feature/java-sdk/issues/1868)) ([f44643f](https://github.com/open-feature/java-sdk/commit/f44643fa32805704fd3fc88ae88998099bb2713a)) +* **deps:** update github/codeql-action digest to 147d149 ([#1856](https://github.com/open-feature/java-sdk/issues/1856)) ([74325fb](https://github.com/open-feature/java-sdk/commit/74325fb5f1b182cef1acbb79e646485101832371)) +* **deps:** update github/codeql-action digest to 16adc4e ([#1867](https://github.com/open-feature/java-sdk/issues/1867)) ([29a29d6](https://github.com/open-feature/java-sdk/commit/29a29d64d4510fe681cf4d99686faf04586d8e38)) +* **deps:** update github/codeql-action digest to 1dbebad ([#1891](https://github.com/open-feature/java-sdk/issues/1891)) ([3b48a87](https://github.com/open-feature/java-sdk/commit/3b48a87ecb1f10f595f1b239d8dc1684ccee0f68)) +* **deps:** update github/codeql-action digest to 25a224b ([#1825](https://github.com/open-feature/java-sdk/issues/1825)) ([181a28e](https://github.com/open-feature/java-sdk/commit/181a28eff5bc3720204862d9c143449debcf3ab6)) +* **deps:** update github/codeql-action digest to 2d6b98c ([#1850](https://github.com/open-feature/java-sdk/issues/1850)) ([44057a9](https://github.com/open-feature/java-sdk/commit/44057a915af2c6e123c83759cc0fee0ed9cb670b)) +* **deps:** update github/codeql-action digest to 40f0fa9 ([#1878](https://github.com/open-feature/java-sdk/issues/1878)) ([d60cf38](https://github.com/open-feature/java-sdk/commit/d60cf3811b8d5cfc997d88096bc2e6bf3854a016)) +* **deps:** update github/codeql-action digest to 55252c7 ([#1823](https://github.com/open-feature/java-sdk/issues/1823)) ([55becc0](https://github.com/open-feature/java-sdk/commit/55becc045d8e9d833d7d2293b9496b484f4e4e5e)) +* **deps:** update github/codeql-action digest to 5cb13d6 ([#1889](https://github.com/open-feature/java-sdk/issues/1889)) ([bea082d](https://github.com/open-feature/java-sdk/commit/bea082d2ffa5af3ce209caf8af628810bb596ebb)) +* **deps:** update github/codeql-action digest to 5e767ef ([#1826](https://github.com/open-feature/java-sdk/issues/1826)) ([c1428cb](https://github.com/open-feature/java-sdk/commit/c1428cb683accd5bcd22a22f585d305c8bea3b69)) +* **deps:** update github/codeql-action digest to 5e7a52f ([#1858](https://github.com/open-feature/java-sdk/issues/1858)) ([8cc5d40](https://github.com/open-feature/java-sdk/commit/8cc5d401ff23eb52cc91218353e9c79f7c8d239e)) +* **deps:** update github/codeql-action digest to 5e98e18 ([#1820](https://github.com/open-feature/java-sdk/issues/1820)) ([dde333f](https://github.com/open-feature/java-sdk/commit/dde333f61e24a57c702d851c604b7ce3353f5277)) +* **deps:** update github/codeql-action digest to 710e294 ([#1860](https://github.com/open-feature/java-sdk/issues/1860)) ([641541e](https://github.com/open-feature/java-sdk/commit/641541e3c3b157b0faa19b1c3f9aa5f55f586eef)) +* **deps:** update github/codeql-action digest to 72d2d85 ([#1881](https://github.com/open-feature/java-sdk/issues/1881)) ([a89da34](https://github.com/open-feature/java-sdk/commit/a89da34cb27e438acf66c787c55bfc469f7bb3a8)) +* **deps:** update github/codeql-action digest to 7aee932 ([#1843](https://github.com/open-feature/java-sdk/issues/1843)) ([fe108bb](https://github.com/open-feature/java-sdk/commit/fe108bb8ccc7f8460ac97051ff3cb5835a586a05)) +* **deps:** update github/codeql-action digest to 7da6361 ([#1898](https://github.com/open-feature/java-sdk/issues/1898)) ([5070bb2](https://github.com/open-feature/java-sdk/commit/5070bb2bfffa381d9f47d9c026e2db8b0c7553a0)) +* **deps:** update github/codeql-action digest to 7dd76e6 ([#1895](https://github.com/open-feature/java-sdk/issues/1895)) ([afb6bef](https://github.com/open-feature/java-sdk/commit/afb6befdbd58e0f10458951f8f740713ebdefa2e)) +* **deps:** update github/codeql-action digest to 7deb0a1 ([#1842](https://github.com/open-feature/java-sdk/issues/1842)) ([e92f911](https://github.com/open-feature/java-sdk/commit/e92f911d5119436e0af4022d1fe2bc891b32760f)) +* **deps:** update github/codeql-action digest to 87c3b7b ([#1888](https://github.com/open-feature/java-sdk/issues/1888)) ([80f5313](https://github.com/open-feature/java-sdk/commit/80f5313f98f723e397f858c198052b1c0457860d)) +* **deps:** update github/codeql-action digest to b126fac ([#1830](https://github.com/open-feature/java-sdk/issues/1830)) ([b57667a](https://github.com/open-feature/java-sdk/commit/b57667a143014235cf87efaecbefc5c40ac13de3)) +* **deps:** update github/codeql-action digest to b13d724 ([#1844](https://github.com/open-feature/java-sdk/issues/1844)) ([b0ca943](https://github.com/open-feature/java-sdk/commit/b0ca9433092ddd477e55451a73f783f63d17d341)) +* **deps:** update github/codeql-action digest to b2ff80d ([#1833](https://github.com/open-feature/java-sdk/issues/1833)) ([0fd4dfc](https://github.com/open-feature/java-sdk/commit/0fd4dfc99066b60421cb3067049ac5a5366ccdaa)) +* **deps:** update github/codeql-action digest to b6dfacb ([#1879](https://github.com/open-feature/java-sdk/issues/1879)) ([d63ae69](https://github.com/open-feature/java-sdk/commit/d63ae69121bc27f15a124395fbb9b6007823285f)) +* **deps:** update github/codeql-action digest to b895512 ([#1875](https://github.com/open-feature/java-sdk/issues/1875)) ([95aa4f7](https://github.com/open-feature/java-sdk/commit/95aa4f7aafd37ef7f69eab22651e52994547f93f)) +* **deps:** update github/codeql-action digest to babab88 ([#1887](https://github.com/open-feature/java-sdk/issues/1887)) ([7cc39a1](https://github.com/open-feature/java-sdk/commit/7cc39a1f6caea0584b94b0b2b3f1e3aafee9d480)) +* **deps:** update github/codeql-action digest to bd9f639 ([#1828](https://github.com/open-feature/java-sdk/issues/1828)) ([0c20c29](https://github.com/open-feature/java-sdk/commit/0c20c29b1c792a08e2274d69b9958966b5ba16cf)) +* **deps:** update github/codeql-action digest to c4dca28 ([#1865](https://github.com/open-feature/java-sdk/issues/1865)) ([0544aeb](https://github.com/open-feature/java-sdk/commit/0544aeb56d421a5446d4eb604a033c9f8f34c3bd)) +* **deps:** update github/codeql-action digest to cb4e075 ([#1864](https://github.com/open-feature/java-sdk/issues/1864)) ([cfb9086](https://github.com/open-feature/java-sdk/commit/cfb908650e5f9f581030f43517dd6895e869d690)) +* **deps:** update github/codeql-action digest to d1a6527 ([#1884](https://github.com/open-feature/java-sdk/issues/1884)) ([49a0db9](https://github.com/open-feature/java-sdk/commit/49a0db9974e1bb6efdf148c6a67ea931eb120767)) +* **deps:** update github/codeql-action digest to eb5bd2d ([#1832](https://github.com/open-feature/java-sdk/issues/1832)) ([6a11e0e](https://github.com/open-feature/java-sdk/commit/6a11e0ee60dadf97dff81ae34e8539614eefa6fb)) +* **deps:** update github/codeql-action digest to ee1e139 ([#1827](https://github.com/open-feature/java-sdk/issues/1827)) ([f57c70d](https://github.com/open-feature/java-sdk/commit/f57c70d24173ca50e510b9577277ab6629297605)) +* **deps:** update github/codeql-action digest to ef618fe ([#1851](https://github.com/open-feature/java-sdk/issues/1851)) ([6beaa19](https://github.com/open-feature/java-sdk/commit/6beaa1956062673b43945a1b015acb7924cd0aa9)) +* **deps:** update github/codeql-action digest to f52cbc8 ([#1840](https://github.com/open-feature/java-sdk/issues/1840)) ([b833e9f](https://github.com/open-feature/java-sdk/commit/b833e9f0bb530fdb1b9ce8a6944e2b18f6e7852c)) +* **deps:** update github/codeql-action digest to f959778 ([#1841](https://github.com/open-feature/java-sdk/issues/1841)) ([3ee6333](https://github.com/open-feature/java-sdk/commit/3ee6333149ecc2fd6b8e85265cdfa5a248d7c39f)) +* **deps:** update github/codeql-action digest to f985be5 ([#1836](https://github.com/open-feature/java-sdk/issues/1836)) ([d11a5d7](https://github.com/open-feature/java-sdk/commit/d11a5d72924a3a2a279224e84a083ff9e4a7a1a1)) +* **deps:** update github/codeql-action digest to fa9b76a ([#1829](https://github.com/open-feature/java-sdk/issues/1829)) ([1ce8a5e](https://github.com/open-feature/java-sdk/commit/1ce8a5e0e1b877273f86ea03ab62fd259323d494)) +* **deps:** update github/codeql-action digest to fd1ca02 ([#1896](https://github.com/open-feature/java-sdk/issues/1896)) ([ff5f519](https://github.com/open-feature/java-sdk/commit/ff5f51953bcebe60a1039265ced197f3d0badaad)) +* **deps:** update github/codeql-action digest to ff33514 ([#1849](https://github.com/open-feature/java-sdk/issues/1849)) ([07d06f5](https://github.com/open-feature/java-sdk/commit/07d06f55abdf91ae19a51b780195aa88f203d7d9)) + ## [1.20.1](https://github.com/open-feature/java-sdk/compare/v1.20.0...v1.20.1) (2026-01-22) diff --git a/README.md b/README.md index d8e961aa0..0194d6100 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.20.1 + 1.20.2 ``` @@ -84,7 +84,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:1.20.1' + implementation 'dev.openfeature:sdk:1.20.2' } ``` diff --git a/pom.xml b/pom.xml index 0cf3b363a..2fdcc87e7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ dev.openfeature sdk - 1.20.1 + 1.20.2 [17,) diff --git a/version.txt b/version.txt index 0044d6cb9..769e37e15 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.20.1 +1.20.2 From 463862248405dd916e9d42a76ce9530956cccc32 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2026 20:34:33 +0000 Subject: [PATCH 674/745] chore(deps): update github/codeql-action digest to 30c555a (#1904) 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 9d4c4dfcd..575e4b50d 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@7da6361ba56d9e2aa798049c7f0a046fe133921e + uses: github/codeql-action/init@30c555a528e360aaf7570127a2440e1396c211cb with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7da6361ba56d9e2aa798049c7f0a046fe133921e + uses: github/codeql-action/analyze@30c555a528e360aaf7570127a2440e1396c211cb diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 40b55f766..0fc1ffa49 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@7da6361ba56d9e2aa798049c7f0a046fe133921e + uses: github/codeql-action/init@30c555a528e360aaf7570127a2440e1396c211cb with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@7da6361ba56d9e2aa798049c7f0a046fe133921e + uses: github/codeql-action/autobuild@30c555a528e360aaf7570127a2440e1396c211cb - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7da6361ba56d9e2aa798049c7f0a046fe133921e + uses: github/codeql-action/analyze@30c555a528e360aaf7570127a2440e1396c211cb From d2e15b467005264e3623f6662ab7d4cda35def86 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 21 Mar 2026 00:35:16 +0000 Subject: [PATCH 675/745] chore(deps): update github/codeql-action digest to 05b1a5d (#1906) 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 575e4b50d..200488e27 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@30c555a528e360aaf7570127a2440e1396c211cb + uses: github/codeql-action/init@05b1a5d28f8763fd11e77388fe57846f1ba8e766 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@30c555a528e360aaf7570127a2440e1396c211cb + uses: github/codeql-action/analyze@05b1a5d28f8763fd11e77388fe57846f1ba8e766 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 0fc1ffa49..b96796956 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@30c555a528e360aaf7570127a2440e1396c211cb + uses: github/codeql-action/init@05b1a5d28f8763fd11e77388fe57846f1ba8e766 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@30c555a528e360aaf7570127a2440e1396c211cb + uses: github/codeql-action/autobuild@05b1a5d28f8763fd11e77388fe57846f1ba8e766 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@30c555a528e360aaf7570127a2440e1396c211cb + uses: github/codeql-action/analyze@05b1a5d28f8763fd11e77388fe57846f1ba8e766 From bb19ba92722cbe14b0a435bebe90afd584e4408b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 21 Mar 2026 12:33:36 +0000 Subject: [PATCH 676/745] fix(deps): update dependency com.fasterxml.jackson:jackson-bom to v2.21.2 (#1907) 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 2fdcc87e7..297880542 100644 --- a/pom.xml +++ b/pom.xml @@ -229,7 +229,7 @@ com.fasterxml.jackson jackson-bom - 2.21.1 + 2.21.2 pom import From 39c9df3aebb86aaaebe8d6e5363722e427931202 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2026 20:29:56 +0000 Subject: [PATCH 677/745] chore(deps): update github/codeql-action digest to 72c0b0e (#1908) 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 200488e27..655ec92a6 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@05b1a5d28f8763fd11e77388fe57846f1ba8e766 + uses: github/codeql-action/init@72c0b0efb7def5141326c5e13760acdda431379d with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@05b1a5d28f8763fd11e77388fe57846f1ba8e766 + uses: github/codeql-action/analyze@72c0b0efb7def5141326c5e13760acdda431379d diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index b96796956..ff7b863ff 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@05b1a5d28f8763fd11e77388fe57846f1ba8e766 + uses: github/codeql-action/init@72c0b0efb7def5141326c5e13760acdda431379d with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@05b1a5d28f8763fd11e77388fe57846f1ba8e766 + uses: github/codeql-action/autobuild@72c0b0efb7def5141326c5e13760acdda431379d - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@05b1a5d28f8763fd11e77388fe57846f1ba8e766 + uses: github/codeql-action/analyze@72c0b0efb7def5141326c5e13760acdda431379d From 050633c6770f4fc28890cc8dcc343575c622f21b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 24 Mar 2026 13:35:07 +0100 Subject: [PATCH 678/745] chore(deps): update github/codeql-action digest to eedab83 (#1909) 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 655ec92a6..c3bf1ecf6 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@72c0b0efb7def5141326c5e13760acdda431379d + uses: github/codeql-action/init@eedab83377f873ae39009d167a89b7a5aab4638b with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@72c0b0efb7def5141326c5e13760acdda431379d + uses: github/codeql-action/analyze@eedab83377f873ae39009d167a89b7a5aab4638b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index ff7b863ff..37b62a771 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@72c0b0efb7def5141326c5e13760acdda431379d + uses: github/codeql-action/init@eedab83377f873ae39009d167a89b7a5aab4638b with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@72c0b0efb7def5141326c5e13760acdda431379d + uses: github/codeql-action/autobuild@eedab83377f873ae39009d167a89b7a5aab4638b - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@72c0b0efb7def5141326c5e13760acdda431379d + uses: github/codeql-action/analyze@eedab83377f873ae39009d167a89b7a5aab4638b From 88fb702984572c26d561ffcbc46f5df37b35f779 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 25 Mar 2026 20:24:35 +0000 Subject: [PATCH 679/745] chore(deps): update github/codeql-action digest to 3d564d9 (#1910) 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 c3bf1ecf6..dd710a0b5 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@eedab83377f873ae39009d167a89b7a5aab4638b + uses: github/codeql-action/init@3d564d93591dd5e79d5d6d2ff3c4a3ff8947fffd with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@eedab83377f873ae39009d167a89b7a5aab4638b + uses: github/codeql-action/analyze@3d564d93591dd5e79d5d6d2ff3c4a3ff8947fffd diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 37b62a771..93118a14b 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@eedab83377f873ae39009d167a89b7a5aab4638b + uses: github/codeql-action/init@3d564d93591dd5e79d5d6d2ff3c4a3ff8947fffd with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@eedab83377f873ae39009d167a89b7a5aab4638b + uses: github/codeql-action/autobuild@3d564d93591dd5e79d5d6d2ff3c4a3ff8947fffd - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@eedab83377f873ae39009d167a89b7a5aab4638b + uses: github/codeql-action/analyze@3d564d93591dd5e79d5d6d2ff3c4a3ff8947fffd From f2f14e3652cdbb031341972a94619c6dc85a4425 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2026 20:27:17 +0000 Subject: [PATCH 680/745] chore(deps): update codecov/codecov-action action to v6 (#1913) 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 fe533e3fe..27485372b 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -53,7 +53,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.5.3 + uses: codecov/codecov-action@v6.0.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 dd710a0b5..1aac26814 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -49,7 +49,7 @@ jobs: - if: matrix.build.java == '17' name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.5.3 + uses: codecov/codecov-action@v6.0.0 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From e8a99d8dc33f290c1348f113e109fb7e9ce05499 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 00:28:33 +0000 Subject: [PATCH 681/745] chore(deps): update github/codeql-action digest to f94817b (#1911) 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 1aac26814..2ac209d25 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@3d564d93591dd5e79d5d6d2ff3c4a3ff8947fffd + uses: github/codeql-action/init@f94817b9f0deeb3871261446912ae8f854d1b675 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3d564d93591dd5e79d5d6d2ff3c4a3ff8947fffd + uses: github/codeql-action/analyze@f94817b9f0deeb3871261446912ae8f854d1b675 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 93118a14b..d37bd99af 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@3d564d93591dd5e79d5d6d2ff3c4a3ff8947fffd + uses: github/codeql-action/init@f94817b9f0deeb3871261446912ae8f854d1b675 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@3d564d93591dd5e79d5d6d2ff3c4a3ff8947fffd + uses: github/codeql-action/autobuild@f94817b9f0deeb3871261446912ae8f854d1b675 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3d564d93591dd5e79d5d6d2ff3c4a3ff8947fffd + uses: github/codeql-action/analyze@f94817b9f0deeb3871261446912ae8f854d1b675 From f938b26efbabfe577e304099c26caa3b58513d3c Mon Sep 17 00:00:00 2001 From: Parth Suthar Date: Fri, 27 Mar 2026 13:56:32 -0400 Subject: [PATCH 682/745] fix: collect and propagate per-provider errors in multi-provider strategies (#1901) * fix: collect and propagate per-provider errors in multi-provider strategies Signed-off-by: Parth Suthar * update to refactor buildAggregateMessage in ProviderError Signed-off-by: Parth Suthar * update to use SuperBuilder for MultiProviderEvaluation Signed-off-by: Parth Suthar --------- Signed-off-by: Parth Suthar Co-authored-by: Todd Baert --- .../openfeature/sdk/ProviderEvaluation.java | 3 +- .../sdk/multiprovider/FirstMatchStrategy.java | 26 ++- .../FirstSuccessfulStrategy.java | 27 +++- .../MultiProviderEvaluation.java | 44 ++++++ .../sdk/multiprovider/ProviderError.java | 70 +++++++++ .../sdk/multiprovider/Strategy.java | 4 + .../sdk/multiprovider/BaseStrategyTest.java | 13 ++ .../multiprovider/FirstMatchStrategyTest.java | 72 ++++++++- .../FirstSuccessfulStrategyTest.java | 148 ++++++++++++++++-- .../sdk/multiprovider/MultiProviderTest.java | 6 +- 10 files changed, 377 insertions(+), 36 deletions(-) create mode 100644 src/main/java/dev/openfeature/sdk/multiprovider/MultiProviderEvaluation.java create mode 100644 src/main/java/dev/openfeature/sdk/multiprovider/ProviderError.java diff --git a/src/main/java/dev/openfeature/sdk/ProviderEvaluation.java b/src/main/java/dev/openfeature/sdk/ProviderEvaluation.java index 39fddf24c..0df2f3709 100644 --- a/src/main/java/dev/openfeature/sdk/ProviderEvaluation.java +++ b/src/main/java/dev/openfeature/sdk/ProviderEvaluation.java @@ -4,6 +4,7 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; /** * Contains information about how the a flag was evaluated, including the resolved value. @@ -11,7 +12,7 @@ * @param the type of the flag being evaluated. */ @Data -@Builder +@SuperBuilder @NoArgsConstructor @AllArgsConstructor public class ProviderEvaluation implements BaseEvaluation { diff --git a/src/main/java/dev/openfeature/sdk/multiprovider/FirstMatchStrategy.java b/src/main/java/dev/openfeature/sdk/multiprovider/FirstMatchStrategy.java index 8bfdec76d..b85430799 100644 --- a/src/main/java/dev/openfeature/sdk/multiprovider/FirstMatchStrategy.java +++ b/src/main/java/dev/openfeature/sdk/multiprovider/FirstMatchStrategy.java @@ -7,6 +7,8 @@ import dev.openfeature.sdk.FeatureProvider; import dev.openfeature.sdk.ProviderEvaluation; import dev.openfeature.sdk.exceptions.FlagNotFoundError; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.function.Function; import lombok.NoArgsConstructor; @@ -20,7 +22,8 @@ *

  • Skip providers that indicate they had no value due to {@code FLAG_NOT_FOUND}.
  • *
  • On any other error code, return that error result.
  • *
  • If a provider throws {@link FlagNotFoundError}, it is treated like {@code FLAG_NOT_FOUND}.
  • - *
  • If all providers report {@code FLAG_NOT_FOUND}, return a {@code FLAG_NOT_FOUND} error.
  • + *
  • If all providers report {@code FLAG_NOT_FOUND}, return a {@code FLAG_NOT_FOUND} error + * with per-provider error details.
  • * * As soon as a non-{@code FLAG_NOT_FOUND} result is returned by a provider (success or other error), * the rest of the operation short-circuits and does not call the remaining providers. @@ -36,7 +39,11 @@ public ProviderEvaluation evaluate( T defaultValue, EvaluationContext ctx, Function> providerFunction) { - for (FeatureProvider provider : providers.values()) { + List collectedErrors = new ArrayList<>(); + + for (Map.Entry entry : providers.entrySet()) { + String providerName = entry.getKey(); + FeatureProvider provider = entry.getValue(); try { ProviderEvaluation res = providerFunction.apply(provider); ErrorCode errorCode = res.getErrorCode(); @@ -45,19 +52,22 @@ public ProviderEvaluation evaluate( return res; } if (!FLAG_NOT_FOUND.equals(errorCode)) { - // Any non-FLAG_NOT_FOUND error bubbles up + // Any non-FLAG_NOT_FOUND error bubbles up immediately return res; } - // else FLAG_NOT_FOUND: skip to next provider - } catch (FlagNotFoundError ignored) { - // do not log in hot path, just skip + // FLAG_NOT_FOUND: record and skip to next provider + collectedErrors.add(ProviderError.fromResult(providerName, FLAG_NOT_FOUND, res.getErrorMessage())); + } catch (FlagNotFoundError e) { + // Treat thrown FlagNotFoundError like a FLAG_NOT_FOUND result + collectedErrors.add(ProviderError.fromException(providerName, e)); } } // All providers either threw or returned FLAG_NOT_FOUND - return ProviderEvaluation.builder() - .errorMessage("Flag not found in any provider") + return MultiProviderEvaluation.builder() + .errorMessage(ProviderError.buildAggregateMessage("Flag not found in any provider", collectedErrors)) .errorCode(FLAG_NOT_FOUND) + .providerErrors(collectedErrors) .build(); } } diff --git a/src/main/java/dev/openfeature/sdk/multiprovider/FirstSuccessfulStrategy.java b/src/main/java/dev/openfeature/sdk/multiprovider/FirstSuccessfulStrategy.java index 6a3fc4433..617c61719 100644 --- a/src/main/java/dev/openfeature/sdk/multiprovider/FirstSuccessfulStrategy.java +++ b/src/main/java/dev/openfeature/sdk/multiprovider/FirstSuccessfulStrategy.java @@ -4,6 +4,8 @@ import dev.openfeature.sdk.EvaluationContext; import dev.openfeature.sdk.FeatureProvider; import dev.openfeature.sdk.ProviderEvaluation; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.function.Function; import lombok.NoArgsConstructor; @@ -12,9 +14,10 @@ /** * First Successful Strategy. * - *

    Similar to “First Match”, except that errors from evaluated providers do not halt execution. + *

    Similar to "First Match", except that errors from evaluated providers do not halt execution. * Instead, it returns the first successful result from a provider. If no provider successfully - * responds, it returns a {@code GENERAL} error result. + * responds, it returns a {@code GENERAL} error result that includes per-provider error details + * describing why each provider failed. */ @Slf4j @NoArgsConstructor @@ -27,22 +30,30 @@ public ProviderEvaluation evaluate( T defaultValue, EvaluationContext ctx, Function> providerFunction) { - for (FeatureProvider provider : providers.values()) { + List collectedErrors = new ArrayList<>(); + + for (Map.Entry entry : providers.entrySet()) { + String providerName = entry.getKey(); + FeatureProvider provider = entry.getValue(); try { ProviderEvaluation res = providerFunction.apply(provider); if (res.getErrorCode() == null) { // First successful result (no error code) return res; } - } catch (Exception ignored) { - // swallow and continue; errors from individual providers - // are not fatal for this strategy + // Record error-coded result + collectedErrors.add(ProviderError.fromResult(providerName, res.getErrorCode(), res.getErrorMessage())); + } catch (Exception e) { + // Record thrown exception + collectedErrors.add(ProviderError.fromException(providerName, e)); } } - return ProviderEvaluation.builder() - .errorMessage("No provider successfully responded") + return MultiProviderEvaluation.builder() + .errorMessage( + ProviderError.buildAggregateMessage("No provider successfully responded", collectedErrors)) .errorCode(ErrorCode.GENERAL) + .providerErrors(collectedErrors) .build(); } } diff --git a/src/main/java/dev/openfeature/sdk/multiprovider/MultiProviderEvaluation.java b/src/main/java/dev/openfeature/sdk/multiprovider/MultiProviderEvaluation.java new file mode 100644 index 000000000..675917305 --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/multiprovider/MultiProviderEvaluation.java @@ -0,0 +1,44 @@ +package dev.openfeature.sdk.multiprovider; + +import dev.openfeature.sdk.ProviderEvaluation; +import java.util.Collections; +import java.util.List; +import lombok.Builder; +import lombok.Getter; +import lombok.experimental.SuperBuilder; + +/** + * A {@link ProviderEvaluation} subtype returned by multi-provider strategies that carries + * per-provider error details. + * + *

    This type can represent both successful and failed evaluations. When a strategy exhausts + * all providers without a successful result, the per-provider errors describe why each provider + * failed. Custom strategies may also use this type for successful results to surface information + * about providers that were skipped or failed before the successful one. + * + *

    Usage: + *

    {@code
    + * ProviderEvaluation result = strategy.evaluate(...);
    + * if (result instanceof MultiProviderEvaluation multiResult) {
    + *     for (ProviderError error : multiResult.getProviderErrors()) {
    + *         log.warn("Provider {} failed: {} - {}",
    + *             error.getProviderName(), error.getErrorCode(), error.getErrorMessage());
    + *     }
    + * }
    + * }
    + * + * @param the type of the flag being evaluated + */ +@Getter +@SuperBuilder +public class MultiProviderEvaluation extends ProviderEvaluation { + + /** + * Per-provider error details. + * + *

    Each entry describes why a specific provider failed during multi-provider evaluation. + * Defaults to an empty list when not set. + */ + @Builder.Default + private List providerErrors = Collections.emptyList(); +} diff --git a/src/main/java/dev/openfeature/sdk/multiprovider/ProviderError.java b/src/main/java/dev/openfeature/sdk/multiprovider/ProviderError.java new file mode 100644 index 000000000..921b881fa --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/multiprovider/ProviderError.java @@ -0,0 +1,70 @@ +package dev.openfeature.sdk.multiprovider; + +import dev.openfeature.sdk.ErrorCode; +import dev.openfeature.sdk.exceptions.OpenFeatureError; +import java.util.List; +import java.util.stream.Collectors; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + +/** + * Represents an error from a single provider during multi-provider evaluation. + * + *

    Captures the provider name, error code, error message, and optionally the original exception + * that occurred during flag evaluation. This allows callers to inspect per-provider error details + * when a multi-provider strategy exhausts all providers without a successful result. + */ +@Data +@Builder +@AllArgsConstructor +public class ProviderError { + private String providerName; + private ErrorCode errorCode; + private String errorMessage; + private Exception exception; + + /** + * Create a ProviderError from an error-coded {@code ProviderEvaluation} result. + * + * @param providerName the name of the provider that returned the error + * @param errorCode the error code from the evaluation result + * @param errorMessage the error message from the evaluation result (may be {@code null}) + * @return a new ProviderError + */ + public static ProviderError fromResult(String providerName, ErrorCode errorCode, String errorMessage) { + return new ProviderError(providerName, errorCode, errorMessage, null); + } + + /** + * Create a ProviderError from a thrown exception. + * + * @param providerName the name of the provider that threw the exception + * @param exception the exception that was thrown + * @return a new ProviderError + */ + public static ProviderError fromException(String providerName, Exception exception) { + ErrorCode code = ErrorCode.GENERAL; + if (exception instanceof OpenFeatureError) { + code = ((OpenFeatureError) exception).getErrorCode(); + } + return new ProviderError(providerName, code, exception.getMessage(), exception); + } + + /** + * Build an aggregate error message from a list of provider errors. + * + * @param baseMessage the base message to use (e.g. "No provider successfully responded") + * @param errors the list of per-provider errors + * @return an aggregate message including per-provider details + */ + public static String buildAggregateMessage(String baseMessage, List errors) { + String details = errors.stream().map(ProviderError::toString).collect(Collectors.joining(", ")); + return baseMessage + ". Provider errors: [" + details + "]"; + } + + @Override + public String toString() { + return providerName + ": " + errorCode + " (" + (errorMessage != null ? errorMessage : "unknown") + ")"; + } +} diff --git a/src/main/java/dev/openfeature/sdk/multiprovider/Strategy.java b/src/main/java/dev/openfeature/sdk/multiprovider/Strategy.java index 4c25fe8f0..31b769449 100644 --- a/src/main/java/dev/openfeature/sdk/multiprovider/Strategy.java +++ b/src/main/java/dev/openfeature/sdk/multiprovider/Strategy.java @@ -14,6 +14,10 @@ *

  • Order or select providers
  • *
  • Handle {@code FLAG_NOT_FOUND} results
  • *
  • Handle errors and exceptions from providers
  • + *
  • Collect per-provider error details when no provider returns a successful result. + * Implementations should return a {@link MultiProviderEvaluation} populated with + * a {@link ProviderError} for each failed provider, so that callers can inspect individual + * failure reasons.
  • * */ public interface Strategy { diff --git a/src/test/java/dev/openfeature/sdk/multiprovider/BaseStrategyTest.java b/src/test/java/dev/openfeature/sdk/multiprovider/BaseStrategyTest.java index 405a2f094..a7070fd11 100644 --- a/src/test/java/dev/openfeature/sdk/multiprovider/BaseStrategyTest.java +++ b/src/test/java/dev/openfeature/sdk/multiprovider/BaseStrategyTest.java @@ -211,4 +211,17 @@ protected void setupProviderSuccess(FeatureProvider provider, String value) { when(provider.getStringEvaluation(BaseStrategyTest.FLAG_KEY, DEFAULT_STRING, null)) .thenReturn(result); } + + protected void setupProviderErrorWithMessage(FeatureProvider provider, ErrorCode errorCode, String errorMessage) { + ProviderEvaluation result = mock(ProviderEvaluation.class); + when(result.getErrorCode()).thenReturn(errorCode); + when(result.getErrorMessage()).thenReturn(errorMessage); + when(provider.getStringEvaluation(BaseStrategyTest.FLAG_KEY, DEFAULT_STRING, null)) + .thenReturn(result); + } + + protected void setupProviderException(FeatureProvider provider, RuntimeException exception) { + when(provider.getStringEvaluation(BaseStrategyTest.FLAG_KEY, DEFAULT_STRING, null)) + .thenThrow(exception); + } } diff --git a/src/test/java/dev/openfeature/sdk/multiprovider/FirstMatchStrategyTest.java b/src/test/java/dev/openfeature/sdk/multiprovider/FirstMatchStrategyTest.java index 0205961cd..95a1d603e 100644 --- a/src/test/java/dev/openfeature/sdk/multiprovider/FirstMatchStrategyTest.java +++ b/src/test/java/dev/openfeature/sdk/multiprovider/FirstMatchStrategyTest.java @@ -1,11 +1,15 @@ package dev.openfeature.sdk.multiprovider; 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 static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import dev.openfeature.sdk.ErrorCode; import dev.openfeature.sdk.ProviderEvaluation; +import dev.openfeature.sdk.exceptions.FlagNotFoundError; +import java.util.List; import org.junit.jupiter.api.Test; class FirstMatchStrategyTest extends BaseStrategyTest { @@ -59,19 +63,30 @@ void shouldReturnSuccessWhenFirstProviderSucceeds() { } @Test - void shouldThrowFlagNotFoundWhenAllProvidersReturnFlagNotFound() { + void shouldReturnMultiProviderEvaluationWhenAllProvidersReturnFlagNotFound() { setupProviderFlagNotFound(mockProvider1); setupProviderFlagNotFound(mockProvider2); setupProviderFlagNotFound(mockProvider3); - ProviderEvaluation providerEvaluation = strategy.evaluate( + ProviderEvaluation result = strategy.evaluate( orderedProviders, FLAG_KEY, DEFAULT_STRING, null, p -> p.getStringEvaluation(FLAG_KEY, DEFAULT_STRING, null)); - assertEquals(ErrorCode.FLAG_NOT_FOUND, providerEvaluation.getErrorCode()); - assertEquals("Flag not found in any provider", providerEvaluation.getErrorMessage()); + assertEquals(ErrorCode.FLAG_NOT_FOUND, result.getErrorCode()); + assertTrue(result.getErrorMessage().contains("Flag not found in any provider")); + + MultiProviderEvaluation multiResult = assertInstanceOf(MultiProviderEvaluation.class, result); + List errors = multiResult.getProviderErrors(); + assertNotNull(errors); + assertEquals(3, errors.size()); + assertEquals("provider1", errors.get(0).getProviderName()); + assertEquals(ErrorCode.FLAG_NOT_FOUND, errors.get(0).getErrorCode()); + assertEquals("provider2", errors.get(1).getProviderName()); + assertEquals(ErrorCode.FLAG_NOT_FOUND, errors.get(1).getErrorCode()); + assertEquals("provider3", errors.get(2).getProviderName()); + assertEquals(ErrorCode.FLAG_NOT_FOUND, errors.get(2).getErrorCode()); } @Test @@ -88,4 +103,53 @@ void shouldSkipMultipleFlagNotFoundAndReturnFirstOtherError() { assertNotNull(result); assertEquals(ErrorCode.PARSE_ERROR, result.getErrorCode()); } + + @Test + void shouldCaptureThrownFlagNotFoundErrorsAsProviderErrors() { + setupProviderException(mockProvider1, new FlagNotFoundError("not in provider1")); + setupProviderException(mockProvider2, new FlagNotFoundError("not in provider2")); + setupProviderException(mockProvider3, new FlagNotFoundError("not in provider3")); + + ProviderEvaluation result = strategy.evaluate( + orderedProviders, + FLAG_KEY, + DEFAULT_STRING, + null, + p -> p.getStringEvaluation(FLAG_KEY, DEFAULT_STRING, null)); + + assertEquals(ErrorCode.FLAG_NOT_FOUND, result.getErrorCode()); + + MultiProviderEvaluation multiResult = assertInstanceOf(MultiProviderEvaluation.class, result); + List errors = multiResult.getProviderErrors(); + assertNotNull(errors); + assertEquals(3, errors.size()); + + assertEquals("provider1", errors.get(0).getProviderName()); + assertEquals(ErrorCode.FLAG_NOT_FOUND, errors.get(0).getErrorCode()); + assertEquals("not in provider1", errors.get(0).getErrorMessage()); + assertNotNull(errors.get(0).getException()); + + assertEquals("provider2", errors.get(1).getProviderName()); + assertEquals("provider3", errors.get(2).getProviderName()); + } + + @Test + void shouldIncludeProviderNamesInAggregateErrorMessage() { + setupProviderFlagNotFound(mockProvider1); + setupProviderFlagNotFound(mockProvider2); + setupProviderFlagNotFound(mockProvider3); + + ProviderEvaluation result = strategy.evaluate( + orderedProviders, + FLAG_KEY, + DEFAULT_STRING, + null, + p -> p.getStringEvaluation(FLAG_KEY, DEFAULT_STRING, null)); + + String message = result.getErrorMessage(); + assertTrue(message.contains("provider1")); + assertTrue(message.contains("provider2")); + assertTrue(message.contains("provider3")); + assertTrue(message.contains("FLAG_NOT_FOUND")); + } } diff --git a/src/test/java/dev/openfeature/sdk/multiprovider/FirstSuccessfulStrategyTest.java b/src/test/java/dev/openfeature/sdk/multiprovider/FirstSuccessfulStrategyTest.java index a47af8a2f..157d9e8ce 100644 --- a/src/test/java/dev/openfeature/sdk/multiprovider/FirstSuccessfulStrategyTest.java +++ b/src/test/java/dev/openfeature/sdk/multiprovider/FirstSuccessfulStrategyTest.java @@ -1,11 +1,15 @@ package dev.openfeature.sdk.multiprovider; 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 static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import dev.openfeature.sdk.ErrorCode; import dev.openfeature.sdk.ProviderEvaluation; +import dev.openfeature.sdk.exceptions.GeneralError; +import java.util.List; import org.junit.jupiter.api.Test; class FirstSuccessfulStrategyTest extends BaseStrategyTest { @@ -25,22 +29,42 @@ void shouldSkipFlagNotFoundAndReturnFirstSuccess() { assertNotNull(result); assertEquals("success", result.getValue()); assertNull(result.getErrorCode()); + // Successful results should NOT be MultiProviderEvaluation + assertTrue(!(result instanceof MultiProviderEvaluation)); } @Test - void shouldThrowGeneralErrorWhenAllProvidersFail() { - setupProviderFlagNotFound(mockProvider1); - setupProviderError(mockProvider2, ErrorCode.PARSE_ERROR); - setupProviderError(mockProvider3, ErrorCode.TYPE_MISMATCH); - ProviderEvaluation providerEvaluation = strategy.evaluate( + void shouldReturnMultiProviderEvaluationWithProviderDetailsWhenAllProvidersFail() { + setupProviderErrorWithMessage(mockProvider1, ErrorCode.FLAG_NOT_FOUND, "flag missing"); + setupProviderErrorWithMessage(mockProvider2, ErrorCode.PARSE_ERROR, "parse failed"); + setupProviderErrorWithMessage(mockProvider3, ErrorCode.TYPE_MISMATCH, "type mismatch"); + ProviderEvaluation result = strategy.evaluate( orderedProviders, FLAG_KEY, DEFAULT_STRING, null, p -> p.getStringEvaluation(FLAG_KEY, DEFAULT_STRING, null)); - assertEquals(ErrorCode.GENERAL, providerEvaluation.getErrorCode()); - assertEquals("No provider successfully responded", providerEvaluation.getErrorMessage()); + assertEquals(ErrorCode.GENERAL, result.getErrorCode()); + assertNotNull(result.getErrorMessage()); + assertTrue(result.getErrorMessage().contains("No provider successfully responded")); + + MultiProviderEvaluation multiResult = assertInstanceOf(MultiProviderEvaluation.class, result); + List errors = multiResult.getProviderErrors(); + assertNotNull(errors); + assertEquals(3, errors.size()); + + assertEquals("provider1", errors.get(0).getProviderName()); + assertEquals(ErrorCode.FLAG_NOT_FOUND, errors.get(0).getErrorCode()); + assertEquals("flag missing", errors.get(0).getErrorMessage()); + + assertEquals("provider2", errors.get(1).getProviderName()); + assertEquals(ErrorCode.PARSE_ERROR, errors.get(1).getErrorCode()); + assertEquals("parse failed", errors.get(1).getErrorMessage()); + + assertEquals("provider3", errors.get(2).getProviderName()); + assertEquals(ErrorCode.TYPE_MISMATCH, errors.get(2).getErrorCode()); + assertEquals("type mismatch", errors.get(2).getErrorMessage()); } @Test @@ -49,30 +73,126 @@ void shouldSkipProvidersThatOnlyReturnErrors() { setupProviderError(mockProvider2, ErrorCode.PROVIDER_NOT_READY); setupProviderError(mockProvider3, ErrorCode.GENERAL); - ProviderEvaluation providerEvaluation = strategy.evaluate( + ProviderEvaluation result = strategy.evaluate( orderedProviders, FLAG_KEY, DEFAULT_STRING, null, p -> p.getStringEvaluation(FLAG_KEY, DEFAULT_STRING, null)); - assertEquals(ErrorCode.GENERAL, providerEvaluation.getErrorCode()); - assertEquals("No provider successfully responded", providerEvaluation.getErrorMessage()); + assertEquals(ErrorCode.GENERAL, result.getErrorCode()); + assertTrue(result.getErrorMessage().contains("No provider successfully responded")); + + MultiProviderEvaluation multiResult = assertInstanceOf(MultiProviderEvaluation.class, result); + List errors = multiResult.getProviderErrors(); + assertNotNull(errors); + assertEquals(3, errors.size()); + assertEquals(ErrorCode.INVALID_CONTEXT, errors.get(0).getErrorCode()); + assertEquals(ErrorCode.PROVIDER_NOT_READY, errors.get(1).getErrorCode()); + assertEquals(ErrorCode.GENERAL, errors.get(2).getErrorCode()); } @Test - void shouldThrowGeneralErrorForNonExistentFlag() { + void shouldCaptureExceptionDetailsFromThrowingProviders() { + setupProviderException(mockProvider1, new GeneralError("connection timeout")); + setupProviderErrorWithMessage(mockProvider2, ErrorCode.PARSE_ERROR, "bad json"); + setupProviderException(mockProvider3, new RuntimeException("unexpected failure")); + + ProviderEvaluation result = strategy.evaluate( + orderedProviders, + FLAG_KEY, + DEFAULT_STRING, + null, + p -> p.getStringEvaluation(FLAG_KEY, DEFAULT_STRING, null)); + + assertEquals(ErrorCode.GENERAL, result.getErrorCode()); + + MultiProviderEvaluation multiResult = assertInstanceOf(MultiProviderEvaluation.class, result); + List errors = multiResult.getProviderErrors(); + assertNotNull(errors); + assertEquals(3, errors.size()); + + // First provider threw GeneralError + assertEquals("provider1", errors.get(0).getProviderName()); + assertEquals(ErrorCode.GENERAL, errors.get(0).getErrorCode()); + assertEquals("connection timeout", errors.get(0).getErrorMessage()); + assertNotNull(errors.get(0).getException()); + + // Second provider returned error-coded result + assertEquals("provider2", errors.get(1).getProviderName()); + assertEquals(ErrorCode.PARSE_ERROR, errors.get(1).getErrorCode()); + assertEquals("bad json", errors.get(1).getErrorMessage()); + assertNull(errors.get(1).getException()); + + // Third provider threw RuntimeException (non-OpenFeatureError) + assertEquals("provider3", errors.get(2).getProviderName()); + assertEquals(ErrorCode.GENERAL, errors.get(2).getErrorCode()); + assertEquals("unexpected failure", errors.get(2).getErrorMessage()); + assertNotNull(errors.get(2).getException()); + } + + @Test + void shouldReturnMultiProviderEvaluationForNonExistentFlag() { orderedProviders.clear(); orderedProviders.put("old-provider", inMemoryProvider1); orderedProviders.put("new-provider", inMemoryProvider2); - ProviderEvaluation providerEvaluation = strategy.evaluate( + ProviderEvaluation result = strategy.evaluate( + orderedProviders, + FLAG_KEY, + DEFAULT_STRING, + null, + p -> p.getStringEvaluation(FLAG_KEY, DEFAULT_STRING, null)); + + assertEquals(ErrorCode.GENERAL, result.getErrorCode()); + assertTrue(result.getErrorMessage().contains("No provider successfully responded")); + + // InMemoryProvider throws FlagNotFoundError, which should be captured + MultiProviderEvaluation multiResult = assertInstanceOf(MultiProviderEvaluation.class, result); + List errors = multiResult.getProviderErrors(); + assertNotNull(errors); + assertEquals(2, errors.size()); + assertEquals("old-provider", errors.get(0).getProviderName()); + assertEquals("new-provider", errors.get(1).getProviderName()); + } + + @Test + void shouldReturnFirstSuccessEvenAfterErrors() { + setupProviderError(mockProvider1, ErrorCode.PARSE_ERROR); + setupProviderException(mockProvider2, new GeneralError("timeout")); + setupProviderSuccess(mockProvider3, "finally-success"); + + ProviderEvaluation result = strategy.evaluate( + orderedProviders, + FLAG_KEY, + DEFAULT_STRING, + null, + p -> p.getStringEvaluation(FLAG_KEY, DEFAULT_STRING, null)); + + assertNotNull(result); + assertEquals("finally-success", result.getValue()); + assertNull(result.getErrorCode()); + assertTrue(!(result instanceof MultiProviderEvaluation)); + } + + @Test + void shouldIncludeProviderErrorDetailsInErrorMessage() { + setupProviderErrorWithMessage(mockProvider1, ErrorCode.PARSE_ERROR, "parse failed"); + setupProviderErrorWithMessage(mockProvider2, ErrorCode.GENERAL, "timeout"); + setupProviderErrorWithMessage(mockProvider3, ErrorCode.FLAG_NOT_FOUND, "not found"); + + ProviderEvaluation result = strategy.evaluate( orderedProviders, FLAG_KEY, DEFAULT_STRING, null, p -> p.getStringEvaluation(FLAG_KEY, DEFAULT_STRING, null)); - assertEquals(ErrorCode.GENERAL, providerEvaluation.getErrorCode()); - assertEquals("No provider successfully responded", providerEvaluation.getErrorMessage()); + String message = result.getErrorMessage(); + assertTrue(message.contains("provider1")); + assertTrue(message.contains("PARSE_ERROR")); + assertTrue(message.contains("provider2")); + assertTrue(message.contains("GENERAL")); + assertTrue(message.contains("provider3")); + assertTrue(message.contains("FLAG_NOT_FOUND")); } } diff --git a/src/test/java/dev/openfeature/sdk/multiprovider/MultiProviderTest.java b/src/test/java/dev/openfeature/sdk/multiprovider/MultiProviderTest.java index 887b71d0a..d69cd821f 100644 --- a/src/test/java/dev/openfeature/sdk/multiprovider/MultiProviderTest.java +++ b/src/test/java/dev/openfeature/sdk/multiprovider/MultiProviderTest.java @@ -115,7 +115,11 @@ void shouldUseDefaultFirstMatchStrategy() { ProviderEvaluation providerEvaluation = multiProvider.getStringEvaluation("non-existing", "", null); assertEquals(ErrorCode.FLAG_NOT_FOUND, providerEvaluation.getErrorCode()); - assertEquals("Flag not found in any provider", providerEvaluation.getErrorMessage()); + assertEquals( + "Flag not found in any provider. Provider errors: [" + + "old-provider: FLAG_NOT_FOUND (flag non-existing not found), " + + "new-provider: FLAG_NOT_FOUND (flag non-existing not found)]", + providerEvaluation.getErrorMessage()); } @SneakyThrows From eecb2d623210390c7e5127003eac1894b05dec6f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 28 Mar 2026 00:23:02 +0000 Subject: [PATCH 683/745] chore(deps): update github/codeql-action digest to a899987 (#1914) 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 2ac209d25..ef0139ea0 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@f94817b9f0deeb3871261446912ae8f854d1b675 + uses: github/codeql-action/init@a899987af240c0578ed84ce13c02319a693e168f with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f94817b9f0deeb3871261446912ae8f854d1b675 + uses: github/codeql-action/analyze@a899987af240c0578ed84ce13c02319a693e168f diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index d37bd99af..5914d32c0 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@f94817b9f0deeb3871261446912ae8f854d1b675 + uses: github/codeql-action/init@a899987af240c0578ed84ce13c02319a693e168f with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@f94817b9f0deeb3871261446912ae8f854d1b675 + uses: github/codeql-action/autobuild@a899987af240c0578ed84ce13c02319a693e168f - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f94817b9f0deeb3871261446912ae8f854d1b675 + uses: github/codeql-action/analyze@a899987af240c0578ed84ce13c02319a693e168f From c476180e3a4044e28fb9abc6664e881a11d86f6d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 29 Mar 2026 04:23:02 +0000 Subject: [PATCH 684/745] chore(deps): update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.8.3 (#1915) 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 297880542..c988fc971 100644 --- a/pom.xml +++ b/pom.xml @@ -464,7 +464,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.9.8.2 + 4.9.8.3 spotbugs-exclusions.xml From 36eb2e08e79b86bf14494edae29675b3d5b7539e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 20:26:49 +0000 Subject: [PATCH 685/745] chore(deps): update github/codeql-action digest to c618c9b (#1916) 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 ef0139ea0..1b612802f 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@a899987af240c0578ed84ce13c02319a693e168f + uses: github/codeql-action/init@c618c9bddbf8ce520050acf14e9bb6c220e22931 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@a899987af240c0578ed84ce13c02319a693e168f + uses: github/codeql-action/analyze@c618c9bddbf8ce520050acf14e9bb6c220e22931 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 5914d32c0..4deb22fef 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@a899987af240c0578ed84ce13c02319a693e168f + uses: github/codeql-action/init@c618c9bddbf8ce520050acf14e9bb6c220e22931 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@a899987af240c0578ed84ce13c02319a693e168f + uses: github/codeql-action/autobuild@c618c9bddbf8ce520050acf14e9bb6c220e22931 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@a899987af240c0578ed84ce13c02319a693e168f + uses: github/codeql-action/analyze@c618c9bddbf8ce520050acf14e9bb6c220e22931 From 04ca748688c6df9ca27efde42bf31e7d75d57459 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 Apr 2026 04:25:50 +0000 Subject: [PATCH 686/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.18.8-jdk5 (#1918) 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 c988fc971..f5910e17d 100644 --- a/pom.xml +++ b/pom.xml @@ -221,7 +221,7 @@ net.bytebuddy byte-buddy-agent - 1.18.7-jdk5 + 1.18.8-jdk5 test From 0c26c70fd2eb2988d339c0be727af9dc74bbcd2c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 Apr 2026 08:29:42 +0000 Subject: [PATCH 687/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.18.8-jdk5 (#1917) 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 f5910e17d..17dfa701f 100644 --- a/pom.xml +++ b/pom.xml @@ -214,7 +214,7 @@ net.bytebuddy byte-buddy - 1.18.7-jdk5 + 1.18.8-jdk5 test From fcd0773043d50f23b8eb0b8df66930091b921c94 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 Apr 2026 15:09:08 +0200 Subject: [PATCH 688/745] chore(deps): update github/codeql-action digest to 57ec7e1 (#1920) 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 1b612802f..4c42bef63 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@c618c9bddbf8ce520050acf14e9bb6c220e22931 + uses: github/codeql-action/init@57ec7e10003e75d16bbdf6cf95ea30604347dbb4 with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c618c9bddbf8ce520050acf14e9bb6c220e22931 + uses: github/codeql-action/analyze@57ec7e10003e75d16bbdf6cf95ea30604347dbb4 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 4deb22fef..0a6989411 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@c618c9bddbf8ce520050acf14e9bb6c220e22931 + uses: github/codeql-action/init@57ec7e10003e75d16bbdf6cf95ea30604347dbb4 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@c618c9bddbf8ce520050acf14e9bb6c220e22931 + uses: github/codeql-action/autobuild@57ec7e10003e75d16bbdf6cf95ea30604347dbb4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c618c9bddbf8ce520050acf14e9bb6c220e22931 + uses: github/codeql-action/analyze@57ec7e10003e75d16bbdf6cf95ea30604347dbb4 From ea2d573d340f17b66570aef3103e613a6422ed1e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 Apr 2026 21:59:28 +0000 Subject: [PATCH 689/745] chore(deps): update github/codeql-action digest to 34950e1 (#1921) 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 4c42bef63..c37fc716f 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@57ec7e10003e75d16bbdf6cf95ea30604347dbb4 + uses: github/codeql-action/init@34950e1b113b30df4edee1a6d3a605242df0c40b with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@57ec7e10003e75d16bbdf6cf95ea30604347dbb4 + uses: github/codeql-action/analyze@34950e1b113b30df4edee1a6d3a605242df0c40b diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 0a6989411..4947fb996 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@57ec7e10003e75d16bbdf6cf95ea30604347dbb4 + uses: github/codeql-action/init@34950e1b113b30df4edee1a6d3a605242df0c40b with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@57ec7e10003e75d16bbdf6cf95ea30604347dbb4 + uses: github/codeql-action/autobuild@34950e1b113b30df4edee1a6d3a605242df0c40b - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@57ec7e10003e75d16bbdf6cf95ea30604347dbb4 + uses: github/codeql-action/analyze@34950e1b113b30df4edee1a6d3a605242df0c40b From f2f7df7f04699a90e79fa95f7804b11924ff4e31 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 20:25:53 +0000 Subject: [PATCH 690/745] chore(deps): update com.vmlens.version to v1.2.28 (#1923) 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 17dfa701f..80909d114 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ 11 ${maven.compiler.source} 5.23.0 - 1.2.27 + 1.2.28 **/e2e/*.java ${project.groupId}.${project.artifactId} From d5f7a645688f5f45129626b5eaac1af32280245e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:30:21 +0000 Subject: [PATCH 691/745] chore(deps): update github/codeql-action digest to b623f5f (#1924) 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 c37fc716f..67a1ecb46 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -32,7 +32,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@34950e1b113b30df4edee1a6d3a605242df0c40b + uses: github/codeql-action/init@b623f5fd572a69d335c9da3487c1ce53741a09bf with: languages: java @@ -58,4 +58,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@34950e1b113b30df4edee1a6d3a605242df0c40b + uses: github/codeql-action/analyze@b623f5fd572a69d335c9da3487c1ce53741a09bf diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 4947fb996..296dcc6d7 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@34950e1b113b30df4edee1a6d3a605242df0c40b + uses: github/codeql-action/init@b623f5fd572a69d335c9da3487c1ce53741a09bf with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@34950e1b113b30df4edee1a6d3a605242df0c40b + uses: github/codeql-action/autobuild@b623f5fd572a69d335c9da3487c1ce53741a09bf - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@34950e1b113b30df4edee1a6d3a605242df0c40b + uses: github/codeql-action/analyze@b623f5fd572a69d335c9da3487c1ce53741a09bf From c69bb0ebb6a8864085f00049b3885c3b9e01bb9d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2026 00:21:22 +0000 Subject: [PATCH 692/745] chore(deps): update dependency com.google.guava:guava to v33.6.0-jre (#1927) 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 80909d114..7fffba419 100644 --- a/pom.xml +++ b/pom.xml @@ -153,7 +153,7 @@ com.google.guava guava - 33.5.0-jre + 33.6.0-jre test From e300520e22de266056af920b50d4f294a4e91043 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2026 17:20:20 +0000 Subject: [PATCH 693/745] chore(deps): update dependency maven to v3.9.15 (#1929) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .mvn/wrapper/maven-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 8dbfd9010..475e64909 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,2 +1,2 @@ distributionType=only-script -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.14/apache-maven-3.9.14-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.15/apache-maven-3.9.15-bin.zip From b683371cca495e16a56558c4bc58352c975ed71a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 Apr 2026 08:28:13 +0000 Subject: [PATCH 694/745] chore(deps): update dependency com.tngtech.archunit:archunit-junit5 to v1.4.2 (#1930) 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 7fffba419..ec94ecfc5 100644 --- a/pom.xml +++ b/pom.xml @@ -77,7 +77,7 @@ com.tngtech.archunit archunit-junit5 - 1.4.1 + 1.4.2 test From 639ee618c83b5eea679f6c45ff72fcf744420659 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 22 Apr 2026 04:45:30 +0000 Subject: [PATCH 695/745] fix(deps): update dependency org.projectlombok:lombok to v1.18.46 (#1932) 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 ec94ecfc5..52f8cd7e3 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ org.projectlombok lombok - 1.18.44 + 1.18.46 provided From 72259d144f5463a137f5038f6f4114cb4dd5ba62 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 00:33:59 +0000 Subject: [PATCH 696/745] chore(deps): update googleapis/release-please-action action to v5 (#1933) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7427da07d..186a7fc22 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: # Release-please creates a PR that tracks all changes steps: - - uses: googleapis/release-please-action@v4 + - uses: googleapis/release-please-action@v5 id: release with: token: ${{secrets.RELEASE_PLEASE_ACTION_TOKEN}} From 51754a56e491b6b6868f17cbd6a3692ce5f0c95b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Apr 2026 00:23:25 +0000 Subject: [PATCH 697/745] fix(deps): update dependency com.fasterxml.jackson:jackson-bom to v2.21.3 (#1935) 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 52f8cd7e3..9ce59eb91 100644 --- a/pom.xml +++ b/pom.xml @@ -229,7 +229,7 @@ com.fasterxml.jackson jackson-bom - 2.21.2 + 2.21.3 pom import From fb2181f974af3d121ee013ede152d4e91eb8e0b3 Mon Sep 17 00:00:00 2001 From: jarebudev <23311805+jarebudev@users.noreply.github.com> Date: Wed, 20 May 2026 16:45:12 +0100 Subject: [PATCH 698/745] fix: shutdown now clears hooks, evaluationContext and transactionContextPropagator as per spec 1.6.2 (#1936) Signed-off-by: jarebudev <23311805+jarebudev@users.noreply.github.com> --- .../dev/openfeature/sdk/OpenFeatureAPI.java | 3 ++ .../sdk/ShutdownBehaviorSpecTest.java | 31 +++++++++++++++---- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java b/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java index 02c1edf25..04ad504c3 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java @@ -355,6 +355,9 @@ public void shutdown() { try (AutoCloseableLock ignored = lock.writeLockAutoCloseable()) { providerRepository = new ProviderRepository(this); eventSupport = new EventSupport(); + clearHooks(); + setEvaluationContext(ImmutableContext.EMPTY); + setTransactionContextPropagator(new NoOpTransactionContextPropagator()); } } } diff --git a/src/test/java/dev/openfeature/sdk/ShutdownBehaviorSpecTest.java b/src/test/java/dev/openfeature/sdk/ShutdownBehaviorSpecTest.java index 2c6a6304e..d18cbac8e 100644 --- a/src/test/java/dev/openfeature/sdk/ShutdownBehaviorSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/ShutdownBehaviorSpecTest.java @@ -1,5 +1,8 @@ package dev.openfeature.sdk; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.*; import dev.openfeature.sdk.fixtures.ProviderFixture; @@ -131,16 +134,32 @@ void mustShutdownAllProvidersOnShuttingDownApi() { } @Test - @DisplayName("once shutdown is complete, api must be ready to use again") - void apiIsReadyToUseAfterShutdown() { + @Specification( + number = "1.6.2", + text = + "The API's `shutdown` function MUST reset all state of the API, removing all hooks, event handlers, evaluation context, transaction context propagators, and providers.") + @DisplayName("shutdown must reset the state of the API") + void apiStateMustBeResetOnShuttingDownApi() { - NoOpProvider p1 = new NoOpProvider(); - api.setProvider(p1); + FeatureProvider provider = ProviderFixture.createMockedProvider(); + TransactionContextPropagator transactionContextPropagator = mock(TransactionContextPropagator.class); + EvaluationContext evaluationContext = mock(EvaluationContext.class); + + api.addHooks(mock(Hook.class)); + api.setProvider(provider); + api.setEvaluationContext(evaluationContext); + api.setTransactionContextPropagator(transactionContextPropagator); api.shutdown(); - NoOpProvider p2 = new NoOpProvider(); - api.setProvider(p2); + assertNotEquals(provider, api.getProvider()); + assertTrue(api.getHooks().isEmpty()); + assertNotEquals(evaluationContext, api.getEvaluationContext()); + assertNotEquals(transactionContextPropagator, api.getTransactionContextPropagator()); + + assertInstanceOf(NoOpProvider.class, api.getProvider()); + assertInstanceOf(ImmutableContext.class, api.getEvaluationContext()); + assertInstanceOf(NoOpTransactionContextPropagator.class, api.getTransactionContextPropagator()); } @Test From fb84d68157cf7c73762578ff780ff23f8a739ad5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 May 2026 16:59:28 +0000 Subject: [PATCH 699/745] chore(deps): update codecov/codecov-action action to v6.0.1 (#1940) 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 27485372b..dcfcb23a5 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -53,7 +53,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v6.0.0 + uses: codecov/codecov-action@v6.0.1 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 67a1ecb46..5fd41ec3b 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -49,7 +49,7 @@ jobs: - if: matrix.build.java == '17' name: Upload coverage to Codecov - uses: codecov/codecov-action@v6.0.0 + uses: codecov/codecov-action@v6.0.1 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From b4b913c9118833bf75ebe4bff1baa61a7433b7c0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 May 2026 20:26:05 +0000 Subject: [PATCH 700/745] chore(deps): update dependency maven to v3.9.16 (#1939) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .mvn/wrapper/maven-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 475e64909..e788e5e69 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,2 +1,2 @@ distributionType=only-script -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.15/apache-maven-3.9.15-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.16/apache-maven-3.9.16-bin.zip From ea41f9079329a94bbecd581c64a2524840c23555 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 21 May 2026 00:23:14 +0000 Subject: [PATCH 701/745] fix(deps): update dependency org.slf4j:slf4j-api to v2.0.18 (#1937) 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 9ce59eb91..494c3ef3b 100644 --- a/pom.xml +++ b/pom.xml @@ -70,7 +70,7 @@ org.slf4j slf4j-api - 2.0.17 + 2.0.18 From 6367b8a1c69d605b86491e5bee266b8369695f93 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 21 May 2026 04:25:02 +0000 Subject: [PATCH 702/745] chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3.5.1 (#1938) 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 494c3ef3b..eabb89a96 100644 --- a/pom.xml +++ b/pom.xml @@ -524,7 +524,7 @@ com.diffplug.spotless spotless-maven-plugin - 3.4.0 + 3.5.1 From 76b71c205b132b2d5c78f2c2d082eb127df99c39 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 21 May 2026 12:28:12 +0000 Subject: [PATCH 703/745] fix(deps): update dependency org.junit:junit-bom to v6.1.0 (#1941) 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 eabb89a96..52a1e9795 100644 --- a/pom.xml +++ b/pom.xml @@ -245,7 +245,7 @@ org.junit junit-bom - 6.0.3 + 6.1.0 pom import From 5562cb93fc8e769ed1b2800f8e6ceece3baaab4e Mon Sep 17 00:00:00 2001 From: man85 <44162080+man85@users.noreply.github.com> Date: Wed, 27 May 2026 15:13:07 +0300 Subject: [PATCH 704/745] fix: Domain client event handlers no longer disappear (#1922) * ISSUE-1919 Fixed: Domain client event handlers no longer disappear Signed-off-by: man85 * ISSUE-1919 Fixed: Domain client event handlers no longer disappear Signed-off-by: man85 --------- Signed-off-by: man85 Co-authored-by: Michael Beemer --- .../dev/openfeature/sdk/EventSupport.java | 3 +- .../openfeature/sdk/OpenFeatureAPITest.java | 37 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/main/java/dev/openfeature/sdk/EventSupport.java b/src/main/java/dev/openfeature/sdk/EventSupport.java index 1a7c4d870..1458a610f 100644 --- a/src/main/java/dev/openfeature/sdk/EventSupport.java +++ b/src/main/java/dev/openfeature/sdk/EventSupport.java @@ -2,6 +2,7 @@ import dev.openfeature.sdk.internal.ConfigurableThreadFactory; import java.util.Collection; +import java.util.HashSet; import java.util.Map; import java.util.Optional; import java.util.Set; @@ -117,7 +118,7 @@ public void removeGlobalHandler(ProviderEvent event, Consumer hand * @return set of domain names */ public Set getAllDomainNames() { - return this.handlerStores.keySet(); + return new HashSet<>(this.handlerStores.keySet()); } /** diff --git a/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java b/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java index 2fdb4e3f0..b1f5b6ed8 100644 --- a/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java +++ b/src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java @@ -1,16 +1,22 @@ package dev.openfeature.sdk; +import static dev.openfeature.sdk.ProviderEvent.PROVIDER_CONFIGURATION_CHANGED; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import dev.openfeature.sdk.testutils.testProvider.TestProvider; import java.util.HashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; class OpenFeatureAPITest { @@ -115,4 +121,35 @@ void featureProviderTrackIsCalled() throws Exception { verify(featureProvider, times(2)).getMetadata(); verify(featureProvider).track(any(), any(), any()); } + + @Test + @DisplayName( + "Domainless provider initialized after domain provider - OnConfigurationChanged handlers are invoked for both providers after emitting PROVIDER_CONFIGURATION_CHANGED") + void onConfigurationChangedAreCalledForDomainlessAndDomainProviders() throws InterruptedException { + EventProvider domainlessFeatureProvider = spy(EventProvider.class); + EventProvider featureProvider = spy(EventProvider.class); + + Client domainlessClient = api.getClient(); + Client client = api.getClient("domain"); + + CountDownLatch domainlessLatch = new CountDownLatch(1); + CountDownLatch latch = new CountDownLatch(1); + + domainlessClient.onProviderConfigurationChanged(eventDetails -> domainlessLatch.countDown()); + client.onProviderConfigurationChanged(eventDetails -> latch.countDown()); + + api.setProviderAndWait("domain", featureProvider); + api.setProviderAndWait(domainlessFeatureProvider); + + featureProvider.emit(PROVIDER_CONFIGURATION_CHANGED, mock(ProviderEventDetails.class)); + domainlessFeatureProvider.emit(PROVIDER_CONFIGURATION_CHANGED, mock(ProviderEventDetails.class)); + + boolean domainlessCompleted = domainlessLatch.await(5, TimeUnit.SECONDS); + assertTrue( + domainlessCompleted, + "onProviderConfigurationChanged was not be invoked for a client with default domain"); + + boolean completed = latch.await(5, TimeUnit.SECONDS); + assertTrue(completed, "onProviderConfigurationChanged was not be invoked for a client with domain 'domain'"); + } } From cd29cd9981cba725ab292567b31807c2b1d2d187 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 May 2026 20:40:48 +0000 Subject: [PATCH 705/745] chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3.6.0 (#1942) 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 52a1e9795..a34e15c88 100644 --- a/pom.xml +++ b/pom.xml @@ -524,7 +524,7 @@ com.diffplug.spotless spotless-maven-plugin - 3.5.1 + 3.6.0 From d0278bb183c79e18cc65976fe9e3955998492865 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 28 May 2026 04:26:48 +0000 Subject: [PATCH 706/745] chore(deps): update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.5.6 (#1943) 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 a34e15c88..c8fc5fc73 100644 --- a/pom.xml +++ b/pom.xml @@ -318,7 +318,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.5.5 + 3.5.6 ${surefireArgLine} @@ -740,7 +740,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.5.5 + 3.5.6 ${org.mockito.agent.argline} From aa284eca3ca59e444e029d1a1a8327cd5c2887d5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 28 May 2026 08:33:59 +0000 Subject: [PATCH 707/745] chore(deps): update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.6 (#1944) 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 c8fc5fc73..537993e63 100644 --- a/pom.xml +++ b/pom.xml @@ -300,7 +300,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.5.5 + 3.5.6 ${surefireArgLine} @@ -724,7 +724,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.5.5 + 3.5.6 ${surefireArgLine} From 9649ff361fc2588bd4494de6ff0c0663f8e97409 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 28 May 2026 13:01:58 +0000 Subject: [PATCH 708/745] chore(deps): update dependency org.apache.maven.plugins:maven-dependency-plugin to v3.11.0 (#1945) 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 537993e63..a60fd4c89 100644 --- a/pom.xml +++ b/pom.xml @@ -373,7 +373,7 @@ maven-dependency-plugin - 3.10.0 + 3.11.0 verify From 78fb82df2a20746a00c0226dca8feac1c37af638 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Jun 2026 02:01:04 +0000 Subject: [PATCH 709/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.18.9-jdk5 (#1947) 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 a60fd4c89..fa0690739 100644 --- a/pom.xml +++ b/pom.xml @@ -214,7 +214,7 @@ net.bytebuddy byte-buddy - 1.18.8-jdk5 + 1.18.9-jdk5 test From 647bd1d933399415adac59486d481e95556a12bf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Jun 2026 02:09:41 +0000 Subject: [PATCH 710/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.18.9-jdk5 (#1948) 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 fa0690739..74319e8de 100644 --- a/pom.xml +++ b/pom.xml @@ -221,7 +221,7 @@ net.bytebuddy byte-buddy-agent - 1.18.8-jdk5 + 1.18.9-jdk5 test From 8bd83fc58e2bda990103980a2257aefdbbcaf863 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 3 Jun 2026 21:04:53 +0000 Subject: [PATCH 711/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.18.10-jdk5 (#1949) 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 74319e8de..1e202417a 100644 --- a/pom.xml +++ b/pom.xml @@ -214,7 +214,7 @@ net.bytebuddy byte-buddy - 1.18.9-jdk5 + 1.18.10-jdk5 test From 484782b2d96e0f234378aac4acd9d2535ba688ba Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 3 Jun 2026 21:16:15 +0000 Subject: [PATCH 712/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.18.10-jdk5 (#1950) 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 1e202417a..9f4affbef 100644 --- a/pom.xml +++ b/pom.xml @@ -221,7 +221,7 @@ net.bytebuddy byte-buddy-agent - 1.18.9-jdk5 + 1.18.10-jdk5 test From 58091f34a4851513e8adbbf34f88223701544ad4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 3 Jun 2026 21:27:32 +0000 Subject: [PATCH 713/745] fix(deps): update jackson monorepo to v2.22.0 (#1946) 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 9f4affbef..d03e8faef 100644 --- a/pom.xml +++ b/pom.xml @@ -229,7 +229,7 @@ com.fasterxml.jackson jackson-bom - 2.21.3 + 2.22.0 pom import From 42418c1701dfd07df46b5deaaed5ef2749e6f3dd Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Fri, 5 Jun 2026 09:18:24 -0400 Subject: [PATCH 714/745] chore: flatten pom, add licences to jar (#1951) * use flatten-maven-plugin and maven-resources-plugin * removes test/publish deps and build profiles from published pom * packages license into jar Signed-off-by: Todd Baert --- .gitignore | 1 + pom.xml | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/.gitignore b/.gitignore index dfc5642e5..bd26102a2 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ build .idea specification.json target +.flattened-pom.xml .DS_Store # vscode stuff - we may want to use a more specific pattern later if we'd like to suggest editor configurations diff --git a/pom.xml b/pom.xml index d03e8faef..de505a903 100644 --- a/pom.xml +++ b/pom.xml @@ -53,18 +53,22 @@ + org.projectlombok lombok 1.18.46 provided + true + com.github.spotbugs spotbugs 4.9.8 provided + true @@ -340,6 +344,59 @@ + + + + org.codehaus.mojo + flatten-maven-plugin + 1.7.0 + + ossrh + + + + flatten + process-resources + + flatten + + + + flatten.clean + clean + + clean + + + + + + + + org.apache.maven.plugins + maven-resources-plugin + 3.5.0 + + + copy-license + process-resources + + copy-resources + + + ${project.build.outputDirectory}/META-INF + + + ${project.basedir} + + LICENSE + + + + + + + From 08ce6d0c9b7c47601408f5c5d02502bced18a18d Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Fri, 5 Jun 2026 10:56:00 -0400 Subject: [PATCH 715/745] fix: keep distributionManagement in flattened pom (#1958) Signed-off-by: Todd Baert --- pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pom.xml b/pom.xml index de505a903..a5a2325ce 100644 --- a/pom.xml +++ b/pom.xml @@ -352,6 +352,10 @@ 1.7.0 ossrh + + + resolve + From 733af9e714f7763363425e0651043dc254afcc91 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 5 Jun 2026 15:04:20 +0000 Subject: [PATCH 716/745] chore(deps): update dependency org.codehaus.mojo:flatten-maven-plugin to v1.7.3 (#1957) 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 a5a2325ce..6490cfb00 100644 --- a/pom.xml +++ b/pom.xml @@ -349,7 +349,7 @@ org.codehaus.mojo flatten-maven-plugin - 1.7.0 + 1.7.3 ossrh From 039adc4639f0b0ba63192432cc7dc00bdebd3a4d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 7 Jun 2026 08:24:25 +0000 Subject: [PATCH 717/745] chore(deps): update codecov/codecov-action action to v6.0.2 (#1960) 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 dcfcb23a5..ee69722a6 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -53,7 +53,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v6.0.1 + uses: codecov/codecov-action@v6.0.2 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 5fd41ec3b..b6ffb455a 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -49,7 +49,7 @@ jobs: - if: matrix.build.java == '17' name: Upload coverage to Codecov - uses: codecov/codecov-action@v6.0.1 + uses: codecov/codecov-action@v6.0.2 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From d779ae43239203167e39c5a94916de0836a8d2d2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 7 Jun 2026 12:25:00 +0000 Subject: [PATCH 718/745] chore(deps): update codecov/codecov-action action to v7 (#1961) 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 ee69722a6..791439df7 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -53,7 +53,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v6.0.2 + uses: codecov/codecov-action@v7.0.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 b6ffb455a..0205c44fc 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -49,7 +49,7 @@ jobs: - if: matrix.build.java == '17' name: Upload coverage to Codecov - uses: codecov/codecov-action@v6.0.2 + uses: codecov/codecov-action@v7.0.0 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos flags: unittests # optional From 8fbf507202453ad9e308785b96b174c750d144de Mon Sep 17 00:00:00 2001 From: tobias-ibounig-dt Date: Mon, 8 Jun 2026 15:03:05 +0200 Subject: [PATCH 719/745] =?UTF-8?q?perf:=20replace=20copy+reverse=20with?= =?UTF-8?q?=20index-based=20traversal=20in=20executeBefor=E2=80=A6=20(#195?= =?UTF-8?q?4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit perf: replace copy+reverse with index-based traversal in executeBeforeHooks Signed-off-by: Tobias Ibounig --- src/main/java/dev/openfeature/sdk/HookSupport.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/dev/openfeature/sdk/HookSupport.java b/src/main/java/dev/openfeature/sdk/HookSupport.java index 0254c07fd..821e4fd06 100644 --- a/src/main/java/dev/openfeature/sdk/HookSupport.java +++ b/src/main/java/dev/openfeature/sdk/HookSupport.java @@ -1,7 +1,6 @@ package dev.openfeature.sdk; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Optional; import lombok.extern.slf4j.Slf4j; @@ -51,10 +50,9 @@ public void setHookContexts( public void executeBeforeHooks(HookSupportData data) { // These traverse backwards from normal. - List> reversedHooks = new ArrayList<>(data.getHooks()); - Collections.reverse(reversedHooks); - - for (Pair hookContextPair : reversedHooks) { + List> hooks = data.getHooks(); + for (int i = hooks.size() - 1; i >= 0; i--) { + var hookContextPair = hooks.get(i); var hook = hookContextPair.getKey(); var hookContext = hookContextPair.getValue(); From b611d55d5fe54107ea16e06bb866ad899cad73fb Mon Sep 17 00:00:00 2001 From: tobias-ibounig-dt Date: Mon, 8 Jun 2026 15:31:49 +0200 Subject: [PATCH 720/745] perf: avoid Optional.ofNullable wrapping on hook.before() return value (#1955) * perf: avoid Optional.ofNullable wrapping on hook.before() return value Signed-off-by: Tobias Ibounig * chore: suppress sonar S2789 on defensive null-check Signed-off-by: Todd Baert --------- Signed-off-by: Tobias Ibounig Signed-off-by: Todd Baert Co-authored-by: Todd Baert --- src/main/java/dev/openfeature/sdk/HookSupport.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/dev/openfeature/sdk/HookSupport.java b/src/main/java/dev/openfeature/sdk/HookSupport.java index 821e4fd06..78a4f61b2 100644 --- a/src/main/java/dev/openfeature/sdk/HookSupport.java +++ b/src/main/java/dev/openfeature/sdk/HookSupport.java @@ -48,6 +48,8 @@ public void setHookContexts( } } + // S2789: Hook is user-implemented; defensive null check against non-conforming impls returning null. + @SuppressWarnings("java:S2789") public void executeBeforeHooks(HookSupportData data) { // These traverse backwards from normal. List> hooks = data.getHooks(); @@ -56,10 +58,8 @@ public void executeBeforeHooks(HookSupportData data) { var hook = hookContextPair.getKey(); var hookContext = hookContextPair.getValue(); - Optional returnedEvalContext = Optional.ofNullable( - hook.before(hookContext, data.getHints())) - .orElse(Optional.empty()); - if (returnedEvalContext.isPresent()) { + Optional returnedEvalContext = hook.before(hookContext, data.getHints()); + if (returnedEvalContext != null && returnedEvalContext.isPresent()) { var returnedContext = returnedEvalContext.get(); // yes, we want to check for reference equality here, this prevents recursive layered contexts if (returnedContext != hookContext.getCtx() && !returnedContext.isEmpty()) { From 85c0047c04d4ade912b3b405cd8dfda154d7cb98 Mon Sep 17 00:00:00 2001 From: tobias-ibounig-dt Date: Mon, 8 Jun 2026 16:54:42 +0200 Subject: [PATCH 721/745] perf: cache clientMetadata lambda to avoid per-call allocation (#1952) Signed-off-by: Tobias Ibounig --- src/main/java/dev/openfeature/sdk/OpenFeatureClient.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index 0d5d0e643..dd64700ef 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -51,6 +51,7 @@ public class OpenFeatureClient implements Client { private final AtomicReference evaluationContext = new AtomicReference<>(); private final HookSupport hookSupport; + private final ClientMetadata clientMetadata; /** * Deprecated public constructor. Use OpenFeature.API.getClient() instead. @@ -70,6 +71,7 @@ public OpenFeatureClient(OpenFeatureAPI openFeatureAPI, String domain, String ve this.version = version; this.hookSupport = new HookSupport(); this.clientHooks = new ConcurrentLinkedQueue<>(); + this.clientMetadata = this::getDomain; } /** @@ -467,7 +469,7 @@ public FlagEvaluationDetails getObjectDetails( @Override public ClientMetadata getMetadata() { - return this::getDomain; + return clientMetadata; } /** From 93755707aad9eb7afa8e90c415e2ad1f0273e974 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 15:13:38 +0000 Subject: [PATCH 722/745] chore(deps): update dependency com.github.spotbugs:spotbugs to v4.10.1 (#1962) 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 6490cfb00..15db5d6c6 100644 --- a/pom.xml +++ b/pom.xml @@ -66,7 +66,7 @@ com.github.spotbugs spotbugs - 4.9.8 + 4.10.1 provided true @@ -541,7 +541,7 @@ com.github.spotbugs spotbugs - 4.9.8 + 4.10.1 From 864f9cf67799345cf9b70478f6556dd2b8de3a96 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 08:31:44 +0000 Subject: [PATCH 723/745] chore(deps): update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.8.4 (#1963) 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 15db5d6c6..8f4f94938 100644 --- a/pom.xml +++ b/pom.xml @@ -525,7 +525,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.9.8.3 + 4.9.8.4 spotbugs-exclusions.xml From d8eb4fc177f455b4814d423ee28c4ad1ebd99ac2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 21:55:31 +0000 Subject: [PATCH 724/745] chore(deps): update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.8.5 (#1964) 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 8f4f94938..0eb881711 100644 --- a/pom.xml +++ b/pom.xml @@ -525,7 +525,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.9.8.4 + 4.9.8.5 spotbugs-exclusions.xml From 50da9052b876c2549913ea115ca889c7e2fcacd3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 22:02:53 +0000 Subject: [PATCH 725/745] chore(deps): update dependency com.github.spotbugs:spotbugs to v4.10.2 (#1965) 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 0eb881711..b4d8f35a8 100644 --- a/pom.xml +++ b/pom.xml @@ -66,7 +66,7 @@ com.github.spotbugs spotbugs - 4.10.1 + 4.10.2 provided true @@ -541,7 +541,7 @@ com.github.spotbugs spotbugs - 4.10.1 + 4.10.2 From b592514b6a7f4592330462d763e0124f040a6ff5 Mon Sep 17 00:00:00 2001 From: tobias-ibounig-dt Date: Wed, 10 Jun 2026 21:13:46 +0200 Subject: [PATCH 726/745] perf: skip unmodifiableMap wrapper when hookHints is empty (#1953) * perf: skip unmodifiableMap wrapper when hookHints is empty Signed-off-by: Tobias Ibounig * ensure hookHints non null via builder, added test Signed-off-by: Tobias Ibounig * test null does not throw exception Signed-off-by: Tobias Ibounig * spotless Signed-off-by: Tobias Ibounig --------- Signed-off-by: Tobias Ibounig Co-authored-by: Todd Baert --- .../sdk/FlagEvaluationOptions.java | 10 +++++++++ .../openfeature/sdk/OpenFeatureClient.java | 3 ++- .../dev/openfeature/sdk/HookSpecTest.java | 21 +++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/main/java/dev/openfeature/sdk/FlagEvaluationOptions.java b/src/main/java/dev/openfeature/sdk/FlagEvaluationOptions.java index f73bd9631..d586a9371 100644 --- a/src/main/java/dev/openfeature/sdk/FlagEvaluationOptions.java +++ b/src/main/java/dev/openfeature/sdk/FlagEvaluationOptions.java @@ -1,5 +1,6 @@ package dev.openfeature.sdk; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -19,4 +20,13 @@ public class FlagEvaluationOptions { @Builder.Default Map hookHints = new HashMap<>(); + + public static class FlagEvaluationOptionsBuilder { + /** Sets hook hints, normalizing null to an empty map. */ + public FlagEvaluationOptionsBuilder hookHints(Map hookHints) { + this.hookHints$value = hookHints != null ? hookHints : Collections.emptyMap(); + this.hookHints$set = true; + return this; + } + } } diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index dd64700ef..117b15cc4 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -172,7 +172,8 @@ private FlagEvaluationDetails evaluateFlag( flagOptions = options; } - hookSupportData.hints = Collections.unmodifiableMap(flagOptions.getHookHints()); + var hookHints = flagOptions.getHookHints(); + hookSupportData.hints = hookHints.isEmpty() ? Collections.emptyMap() : Collections.unmodifiableMap(hookHints); var context = new LayeredEvaluationContext( openfeatureApi.getEvaluationContext(), openfeatureApi.getTransactionContext(), diff --git a/src/test/java/dev/openfeature/sdk/HookSpecTest.java b/src/test/java/dev/openfeature/sdk/HookSpecTest.java index 69e47f353..480e81d32 100644 --- a/src/test/java/dev/openfeature/sdk/HookSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSpecTest.java @@ -510,6 +510,27 @@ void missing_hook_hints() { assertTrue(feo.getHookHints().isEmpty()); } + @Test + void null_hook_hints_does_not_throw() { + Hook hook = mockBooleanHook(); + FeatureProvider provider = mock(FeatureProvider.class); + when(provider.getBooleanEvaluation(any(), any(), any())) + .thenReturn(ProviderEvaluation.builder().value(true).build()); + + api.setProviderAndWait(provider); + Client client = api.getClient(); + + assertThatCode(() -> client.getBooleanValue( + "key", + false, + new ImmutableContext(), + FlagEvaluationOptions.builder() + .hook(hook) + .hookHints(null) + .build())) + .doesNotThrowAnyException(); + } + @Test void flag_eval_hook_order() { Hook hook = mockBooleanHook(); From 75391aa58af58347eb76f631f4f083e725fbe32c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Jun 2026 20:42:58 +0000 Subject: [PATCH 727/745] chore(deps): update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.10.2.0 (#1966) 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 b4d8f35a8..0185c9071 100644 --- a/pom.xml +++ b/pom.xml @@ -525,7 +525,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.9.8.5 + 4.10.2.0 spotbugs-exclusions.xml From a5ba3c667d1feec503beebe2b991d6f8561e67f5 Mon Sep 17 00:00:00 2001 From: tobias-ibounig-dt Date: Thu, 11 Jun 2026 15:19:07 +0200 Subject: [PATCH 728/745] perf: eliminate merge allocation in setHooks by accepting hook sources directly (#1956) * perf: eliminate merge allocation in setHooks by accepting hook sources directly Signed-off-by: Tobias Ibounig * improve test, to ensure hook order. Signed-off-by: Tobias Ibounig * Remove unused ObjectUtils#merge Signed-off-by: Tobias Ibounig * reintroduce and deprecate ObjectUtils.merge Signed-off-by: Tobias Ibounig * fixup: added comment Signed-off-by: Todd Baert --------- Signed-off-by: Tobias Ibounig Signed-off-by: Todd Baert Co-authored-by: Todd Baert --- .../java/dev/openfeature/sdk/HookSupport.java | 32 ++++++++-- .../openfeature/sdk/OpenFeatureClient.java | 11 ++-- .../openfeature/sdk/internal/ObjectUtils.java | 2 + .../dev/openfeature/sdk/HookSupportTest.java | 63 +++++++++++++++++-- 4 files changed, 94 insertions(+), 14 deletions(-) diff --git a/src/main/java/dev/openfeature/sdk/HookSupport.java b/src/main/java/dev/openfeature/sdk/HookSupport.java index 78a4f61b2..e936fdeda 100644 --- a/src/main/java/dev/openfeature/sdk/HookSupport.java +++ b/src/main/java/dev/openfeature/sdk/HookSupport.java @@ -1,6 +1,7 @@ package dev.openfeature.sdk; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Optional; import lombok.extern.slf4j.Slf4j; @@ -15,19 +16,40 @@ class HookSupport { /** * Sets the {@link Hook}-{@link HookContext}-{@link Pair} list in the given data object with {@link HookContext} * set to null. Filters hooks by supported {@link FlagValueType}. + * Sources are iterated in order: provider, options, client, API (reversed for the {@code before} stage by + * {@link #executeBeforeHooks}). + * + *

    The four hook sources are accepted as separate collections to avoid allocation on the evaluation hot path. * * @param hookSupportData the data object to modify - * @param hooks the hooks to set + * @param providerHooks provider-level hooks + * @param optionHooks per-evaluation option hooks + * @param clientHooks client-level hooks + * @param apiHooks API-level hooks * @param type the flag value type to filter unsupported hooks */ - public void setHooks(HookSupportData hookSupportData, List hooks, FlagValueType type) { + public void setHooks( + HookSupportData hookSupportData, + Collection providerHooks, + Collection optionHooks, + Collection clientHooks, + Collection apiHooks, + FlagValueType type) { List> hookContextPairs = new ArrayList<>(); - for (Hook hook : hooks) { + addFilteredHooks(hookContextPairs, providerHooks, type); + addFilteredHooks(hookContextPairs, optionHooks, type); + addFilteredHooks(hookContextPairs, clientHooks, type); + addFilteredHooks(hookContextPairs, apiHooks, type); + hookSupportData.hooks = hookContextPairs; + } + + private static void addFilteredHooks( + List> dest, Collection source, FlagValueType type) { + for (Hook hook : source) { if (hook.supportsFlagValueType(type)) { - hookContextPairs.add(Pair.of(hook, null)); + dest.add(Pair.of(hook, null)); } } - hookSupportData.hooks = hookContextPairs; } /** diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index 117b15cc4..818583724 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -5,7 +5,6 @@ import dev.openfeature.sdk.exceptions.GeneralError; import dev.openfeature.sdk.exceptions.OpenFeatureError; import dev.openfeature.sdk.exceptions.ProviderNotReadyError; -import dev.openfeature.sdk.internal.ObjectUtils; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.ArrayList; import java.util.Arrays; @@ -188,9 +187,13 @@ private FlagEvaluationDetails evaluateFlag( final var state = stateManager.getState(); // Hooks are initialized as early as possible to enable the execution of error stages - var mergedHooks = ObjectUtils.merge( - provider.getProviderHooks(), flagOptions.getHooks(), clientHooks, openfeatureApi.getMutableHooks()); - hookSupport.setHooks(hookSupportData, mergedHooks, type); + hookSupport.setHooks( + hookSupportData, + provider.getProviderHooks(), + flagOptions.getHooks(), + clientHooks, + openfeatureApi.getMutableHooks(), + type); var sharedHookContext = new SharedHookContext(key, type, this.getMetadata(), provider.getMetadata(), defaultValue); diff --git a/src/main/java/dev/openfeature/sdk/internal/ObjectUtils.java b/src/main/java/dev/openfeature/sdk/internal/ObjectUtils.java index 86a9ddd70..298712f13 100644 --- a/src/main/java/dev/openfeature/sdk/internal/ObjectUtils.java +++ b/src/main/java/dev/openfeature/sdk/internal/ObjectUtils.java @@ -63,7 +63,9 @@ public static T defaultIfNull(T source, Supplier defaultValue) { * @param sources bunch of lists. * @param list type * @return resulting object + * @deprecated Not used in the project anymore. This method will be removed in a future release. */ + @Deprecated(forRemoval = true) @SafeVarargs public static List merge(Collection... sources) { List merged = new ArrayList<>(); diff --git a/src/test/java/dev/openfeature/sdk/HookSupportTest.java b/src/test/java/dev/openfeature/sdk/HookSupportTest.java index 3b21aff84..f7583321a 100644 --- a/src/test/java/dev/openfeature/sdk/HookSupportTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSupportTest.java @@ -9,6 +9,7 @@ import dev.openfeature.sdk.fixtures.HookFixtures; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -38,7 +39,13 @@ void shouldMergeEvaluationContextsOnBeforeHooksCorrectly() { var sharedContext = getBaseHookContextForType(FlagValueType.STRING); var hookSupportData = new HookSupportData(); hookSupportData.evaluationContext = layered; - hookSupport.setHooks(hookSupportData, Arrays.asList(hook1, hook2), FlagValueType.STRING); + hookSupport.setHooks( + hookSupportData, + Collections.emptyList(), + Collections.emptyList(), + Arrays.asList(hook1, hook2), + Collections.emptyList(), + FlagValueType.STRING); hookSupport.setHookContexts(hookSupportData, sharedContext, layered); hookSupport.executeBeforeHooks(hookSupportData); @@ -57,7 +64,13 @@ void shouldAlwaysCallGenericHook(FlagValueType flagValueType) { Hook genericHook = mockGenericHook(); var hookSupportData = new HookSupportData(); - hookSupport.setHooks(hookSupportData, List.of(genericHook), flagValueType); + hookSupport.setHooks( + hookSupportData, + List.of(genericHook), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + flagValueType); callAllHooks(hookSupportData); @@ -73,7 +86,13 @@ void shouldAlwaysCallGenericHook(FlagValueType flagValueType) { void shouldPassDataAcrossStages(FlagValueType flagValueType) { var testHook = new TestHookWithData(); var hookSupportData = new HookSupportData(); - hookSupport.setHooks(hookSupportData, List.of(testHook), flagValueType); + hookSupport.setHooks( + hookSupportData, + Collections.emptyList(), + List.of(testHook), + Collections.emptyList(), + Collections.emptyList(), + flagValueType); hookSupport.setHookContexts( hookSupportData, getBaseHookContextForType(flagValueType), @@ -102,7 +121,13 @@ void shouldIsolateDataBetweenHooks(FlagValueType flagValueType) { var testHook2 = new TestHookWithData(2); var hookSupportData = new HookSupportData(); - hookSupport.setHooks(hookSupportData, List.of(testHook1, testHook2), flagValueType); + hookSupport.setHooks( + hookSupportData, + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + List.of(testHook1, testHook2), + flagValueType); hookSupport.setHookContexts( hookSupportData, getBaseHookContextForType(flagValueType), @@ -114,6 +139,28 @@ void shouldIsolateDataBetweenHooks(FlagValueType flagValueType) { assertHookData(testHook2, 2, "before", "after", "finallyAfter", "error"); } + @Test + @DisplayName("should place hooks in provider → options → client → API order") + void shouldOrderHooksBySource() { + Hook providerHook = mockGenericHook(); + Hook optionHook = mockGenericHook(); + Hook clientHook = mockGenericHook(); + Hook apiHook = mockGenericHook(); + + var hookSupportData = new HookSupportData(); + hookSupport.setHooks( + hookSupportData, + List.of(providerHook), + List.of(optionHook), + List.of(clientHook), + List.of(apiHook), + FlagValueType.STRING); + + assertThat(hookSupportData.getHooks()) + .extracting(Pair::getKey) + .containsExactly(providerHook, optionHook, clientHook, apiHook); + } + @Test void hookThatReturnsTheGivenContext_doesNotResultInAStackOverflow() { var hookSupportData = new HookSupportData(); @@ -132,7 +179,13 @@ public Optional before(HookContext ctx, Map hints) { var layeredEvaluationContext = new LayeredEvaluationContext(evaluationContextWithValue("key", "value"), null, null, null); hookSupportData.evaluationContext = layeredEvaluationContext; - hookSupport.setHooks(hookSupportData, List.of(recursiveHook, emptyHook), FlagValueType.STRING); + hookSupport.setHooks( + hookSupportData, + Collections.emptyList(), + Collections.emptyList(), + List.of(recursiveHook, emptyHook), + Collections.emptyList(), + FlagValueType.STRING); hookSupport.setHookContexts( hookSupportData, getBaseHookContextForType(FlagValueType.STRING), layeredEvaluationContext); From 231464a0975e2a3eceb33f75e9e31021424de31a Mon Sep 17 00:00:00 2001 From: Marco Zabel Date: Mon, 15 Jun 2026 14:39:56 +0200 Subject: [PATCH 729/745] feat: support isolated API instances (#1928) * feat: support isolated API instances Signed-off-by: marcozabel * fix(tests): separate singleton tests Signed-off-by: marcozabel * fix: spotless formatting and arch test compliance Signed-off-by: marcozabel * refactor(test): inject lock via constructor instead of field mutation Signed-off-by: marcozabel * refactor: make OpenFeatureAPI lock field final Signed-off-by: marcozabel * refactor: move OpenFeatureAPIFactory to sdk package and remove createIsolated() Signed-off-by: marcozabel * refactor: bundle EventProvider onEmit and lock into atomic attachment Signed-off-by: marcozabel * feat: move factory to isolated package and warn on multi-instance provider binding Signed-off-by: marcozabel * docs: add experimental @apiNote to OpenFeatureAPIFactory Signed-off-by: marcozabel * test: add reverse-direction singleton isolation test Signed-off-by: marcozabel * test: add delay before negative assertion in event isolation test Signed-off-by: marcozabel * test: use direct constructor in isolated tests Signed-off-by: marcozabel * refactor: remove OpenFeatureAPIFactory class Signed-off-by: marcozabel * fix: replace @apiNote with prose to satisfy javadoc plugin Signed-off-by: marcozabel * fix: use AtomicReference with CAS in EventProvider.attach Signed-off-by: marcozabel * feat: restore OpenFeatureAPIFactory with package-private constructor Signed-off-by: marcozabel * fixup: configure javadoc plugin to recognize JDK doc-tags Signed-off-by: Todd Baert * fixup: remove OpenFeatureAPIFactory class per review consensus Signed-off-by: Todd Baert * fixup: simplify EventProvider.attach to single CAS per chrfwow's review suggestion. The previous CAS loop existed to support a no-op-same-onEmit branch which is unreachable in practice: attach() is package-private (not part of the public API), and the sole production caller (OpenFeatureAPI.attachEventProvider) always passes a fresh method-reference. Drops the now-orphaned doesNotThrowWhenOnEmitSame test. Signed-off-by: Todd Baert * fixup: spotless Signed-off-by: Todd Baert * fixup: weakmap and throw Signed-off-by: Todd Baert --------- Signed-off-by: marcozabel Signed-off-by: Todd Baert Co-authored-by: Todd Baert --- mvnw | 0 pom.xml | 20 ++ .../dev/openfeature/sdk/EventProvider.java | 44 +++- .../dev/openfeature/sdk/OpenFeatureAPI.java | 86 ++++++- .../openfeature/sdk/ProviderRepository.java | 9 +- .../openfeature/sdk/EventProviderTest.java | 50 +++- .../sdk/GlobalProviderRegistryTest.java | 84 +++++++ .../openfeature/sdk/LockingSingeltonTest.java | 14 +- .../isolated/IsolatedAPISingeltonTest.java | 76 ++++++ .../sdk/isolated/IsolatedAPITest.java | 227 ++++++++++++++++++ .../openfeature/sdk/isolated/NoOpHook.java | 8 + 11 files changed, 575 insertions(+), 43 deletions(-) mode change 100644 => 100755 mvnw create mode 100644 src/test/java/dev/openfeature/sdk/GlobalProviderRegistryTest.java create mode 100644 src/test/java/dev/openfeature/sdk/isolated/IsolatedAPISingeltonTest.java create mode 100644 src/test/java/dev/openfeature/sdk/isolated/IsolatedAPITest.java create mode 100644 src/test/java/dev/openfeature/sdk/isolated/NoOpHook.java diff --git a/mvnw b/mvnw old mode 100644 new mode 100755 diff --git a/pom.xml b/pom.xml index 0185c9071..ca22308a9 100644 --- a/pom.xml +++ b/pom.xml @@ -653,6 +653,26 @@ true all,-missing + + + + apiNote + a + API Note: + + + implSpec + a + Implementation Requirements: + + + implNote + a + Implementation Note: + + diff --git a/src/main/java/dev/openfeature/sdk/EventProvider.java b/src/main/java/dev/openfeature/sdk/EventProvider.java index c126c1451..beb2e1ce3 100644 --- a/src/main/java/dev/openfeature/sdk/EventProvider.java +++ b/src/main/java/dev/openfeature/sdk/EventProvider.java @@ -1,10 +1,12 @@ package dev.openfeature.sdk; +import dev.openfeature.sdk.internal.AutoCloseableReentrantReadWriteLock; import dev.openfeature.sdk.internal.ConfigurableThreadFactory; import dev.openfeature.sdk.internal.TriConsumer; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; import lombok.extern.slf4j.Slf4j; /** @@ -29,21 +31,35 @@ void setEventProviderListener(EventProviderListener eventProviderListener) { this.eventProviderListener = eventProviderListener; } - private TriConsumer onEmit = null; + // Bundles onEmit and lock into a single volatile reference so they are always read atomically: + // a non-null attachment guarantees a non-null lock. + private static final class Attachment { + final TriConsumer onEmit; + final AutoCloseableReentrantReadWriteLock lock; + + Attachment( + TriConsumer onEmit, + AutoCloseableReentrantReadWriteLock lock) { + this.onEmit = onEmit; + this.lock = lock; + } + } + + private final AtomicReference attachment = new AtomicReference<>(null); /** * "Attach" this EventProvider to an SDK, which allows events to propagate from this provider. - * No-op if the same onEmit is already attached. * * @param onEmit the function to run when a provider emits events. + * @param lock the API instance's read/write lock for thread safety. * @throws IllegalStateException if attempted to bind a new emitter for already bound provider */ - void attach(TriConsumer onEmit) { - if (this.onEmit != null && this.onEmit != onEmit) { - // if we are trying to attach this provider to a different onEmit, something has gone wrong + void attach( + TriConsumer onEmit, + AutoCloseableReentrantReadWriteLock lock) { + Attachment newAttachment = new Attachment(onEmit, lock); + if (!this.attachment.compareAndSet(null, newAttachment)) { throw new IllegalStateException("Provider " + this.getMetadata().getName() + " is already attached."); - } else { - this.onEmit = onEmit; } } @@ -51,7 +67,7 @@ void attach(TriConsumer onEm * "Detach" this EventProvider from an SDK, stopping propagation of all events. */ void detach() { - this.onEmit = null; + this.attachment.set(null); } /** @@ -80,9 +96,9 @@ public void shutdown() { */ public Awaitable emit(final ProviderEvent event, final ProviderEventDetails details) { final var localEventProviderListener = this.eventProviderListener; - final var localOnEmit = this.onEmit; + final var localAttachment = this.attachment.get(); - if (localEventProviderListener == null && localOnEmit == null) { + if (localEventProviderListener == null && localAttachment == null) { return Awaitable.FINISHED; } @@ -91,12 +107,14 @@ public Awaitable emit(final ProviderEvent event, final ProviderEventDetails deta // These calls need to be executed on a different thread to prevent deadlocks when the provider initialization // relies on a ready event to be emitted emitterExecutor.submit(() -> { - try (var ignored = OpenFeatureAPI.lock.readLockAutoCloseable()) { + // Lock is only needed when attached to an API instance. A non-null attachment always + // carries a non-null lock, so no null check on the lock itself is required. + try (var ignored = localAttachment != null ? localAttachment.lock.readLockAutoCloseable() : null) { if (localEventProviderListener != null) { localEventProviderListener.onEmit(event, details); } - if (localOnEmit != null) { - localOnEmit.accept(this, event, details); + if (localAttachment != null) { + localAttachment.onEmit.accept(this, event, details); } } finally { awaitable.wakeup(); diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java b/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java index 04ad504c3..4f8d7d6e4 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java @@ -6,31 +6,76 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.WeakHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import lombok.extern.slf4j.Slf4j; /** - * A global singleton which holds base configuration for the OpenFeature - * library. - * Configuration here will be shared across all {@link Client}s. + * Holds base configuration for the OpenFeature library. + * + *

    Most applications should use the global singleton via {@link #getInstance()}; configuration + * there is shared across all {@link Client}s. For dependency-injection frameworks, testing, or + * multi-tenant scenarios that need fully independent state (providers, hooks, evaluation context, + * event handlers, transaction context propagators), create isolated instances via + * {@link #createIsolated()}. + * + *

    Note: Isolated API instances (per spec section 1.8) are experimental and + * subject to change. + * + * @see + * Spec §1.8 — Isolated API Instances */ @Slf4j @SuppressWarnings("PMD.UnusedLocalVariable") public class OpenFeatureAPI implements EventBus { - // package-private multi-read/single-write lock - static AutoCloseableReentrantReadWriteLock lock = new AutoCloseableReentrantReadWriteLock(); + + /** + * Global registry tracking which API instance each provider is currently bound to. + * Used to detect violations of spec requirement 1.8.4 (a provider SHOULD NOT be + * registered with more than one API instance simultaneously). + * + *

    Backed by a {@link WeakHashMap} so providers that are discarded without explicit + * deregistration do not pin the API instance in memory. + */ + private static final Map GLOBAL_PROVIDER_REGISTRY = + Collections.synchronizedMap(new WeakHashMap<>()); + + // package-private multi-read/single-write lock (instance-level for isolation) + final AutoCloseableReentrantReadWriteLock lock; private final ConcurrentLinkedQueue apiHooks; private ProviderRepository providerRepository; private EventSupport eventSupport; private final AtomicReference evaluationContext = new AtomicReference<>(); private TransactionContextPropagator transactionContextPropagator; - protected OpenFeatureAPI() { + /** + * Creates and returns a new, independent {@link OpenFeatureAPI} instance with fully isolated + * state (providers, hooks, evaluation context, event handlers, transaction context + * propagators). + * + * @apiNote This API is experimental and subject to change. + * @see + * Spec §1.8 — Isolated API Instances + */ + public static OpenFeatureAPI createIsolated() { + return new OpenFeatureAPI(); + } + + // Package-private: not part of the public API; use createIsolated(). + OpenFeatureAPI() { + this(new AutoCloseableReentrantReadWriteLock()); + } + + // Package-private constructor for testing with a custom lock. + OpenFeatureAPI(AutoCloseableReentrantReadWriteLock lock) { + this.lock = lock; apiHooks = new ConcurrentLinkedQueue<>(); providerRepository = new ProviderRepository(this); eventSupport = new EventSupport(); @@ -251,7 +296,7 @@ public void setProviderAndWait(String domain, FeatureProvider provider) throws O private void attachEventProvider(FeatureProvider provider) { if (provider instanceof EventProvider) { - ((EventProvider) provider).attach(this::runHandlersForProvider); + ((EventProvider) provider).attach(this::runHandlersForProvider, this.lock); } } @@ -332,6 +377,33 @@ public void clearHooks() { this.apiHooks.clear(); } + /** + * Registers a provider with the global registry, throwing if it is already + * bound to a different API instance (spec requirement 1.8.4). + * + * @throws IllegalStateException if the provider is already bound to a different API instance + */ + void registerGlobalProvider(FeatureProvider provider) { + synchronized (GLOBAL_PROVIDER_REGISTRY) { + OpenFeatureAPI existing = GLOBAL_PROVIDER_REGISTRY.get(provider); + if (existing != null && existing != this) { + throw new IllegalStateException("Provider " + + provider.getClass().getName() + + " is already registered with another API instance. " + + "A provider SHOULD NOT be bound to more than one API instance " + + "simultaneously (spec requirement 1.8.4)."); + } + GLOBAL_PROVIDER_REGISTRY.put(provider, this); + } + } + + /** + * Removes the provider from the global registry if this instance is the current owner. + */ + void deregisterGlobalProvider(FeatureProvider provider) { + GLOBAL_PROVIDER_REGISTRY.remove(provider, this); + } + /** * Shut down and reset the current status of OpenFeature API. * This call cleans up all active providers and attempts to shut down internal diff --git a/src/main/java/dev/openfeature/sdk/ProviderRepository.java b/src/main/java/dev/openfeature/sdk/ProviderRepository.java index 3a0d325df..7fcb8f434 100644 --- a/src/main/java/dev/openfeature/sdk/ProviderRepository.java +++ b/src/main/java/dev/openfeature/sdk/ProviderRepository.java @@ -170,6 +170,7 @@ private void prepareAndInitializeProvider( } FeatureProviderStateManager existing = getExistingStateManagerForProvider(newProvider); if (existing == null) { + openFeatureAPI.registerGlobalProvider(newProvider); newStateManager = new FeatureProviderStateManager(newProvider); // only run afterSet if new provider is not already attached afterSet.accept(newProvider); @@ -236,6 +237,8 @@ private void initializeProvider( private void shutDownOld(FeatureProviderStateManager oldManager, Consumer afterShutdown) { synchronized (registerStateManagerLock) { if (oldManager != null && !isStateManagerRegistered(oldManager)) { + // spec 1.8.4: release the provider from the global registry + openFeatureAPI.deregisterGlobalProvider(oldManager.getProvider()); shutdownProvider(oldManager); afterShutdown.accept(oldManager.getProvider()); } @@ -327,7 +330,11 @@ List prepareShutdown() { * @param managersToShutdown the managers to shut down (from prepareShutdown) */ void completeShutdown(List managersToShutdown) { - managersToShutdown.forEach(this::shutdownProvider); + managersToShutdown.forEach(m -> { + // spec 1.8.4: release all providers from the global registry on shutdown + openFeatureAPI.deregisterGlobalProvider(m.getProvider()); + shutdownProvider(m); + }); taskExecutor.shutdown(); try { if (!taskExecutor.awaitTermination(EventSupport.SHUTDOWN_TIMEOUT_SECONDS, TimeUnit.SECONDS)) { diff --git a/src/test/java/dev/openfeature/sdk/EventProviderTest.java b/src/test/java/dev/openfeature/sdk/EventProviderTest.java index d04fa88d1..a90d30bbd 100644 --- a/src/test/java/dev/openfeature/sdk/EventProviderTest.java +++ b/src/test/java/dev/openfeature/sdk/EventProviderTest.java @@ -1,12 +1,16 @@ package dev.openfeature.sdk; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; +import dev.openfeature.sdk.internal.AutoCloseableReentrantReadWriteLock; import dev.openfeature.sdk.internal.TriConsumer; import dev.openfeature.sdk.testutils.TestStackedEmitCallsProvider; import io.cucumber.java.AfterAll; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import lombok.SneakyThrows; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -36,7 +40,7 @@ public static void resetDefaultProvider() { @DisplayName("should run attached onEmit with emitters") void emitsEventsWhenAttached() { TriConsumer onEmit = mockOnEmit(); - eventProvider.attach(onEmit); + eventProvider.attach(onEmit, new AutoCloseableReentrantReadWriteLock()); ProviderEventDetails details = ProviderEventDetails.builder().build(); eventProvider.emit(ProviderEvent.PROVIDER_READY, details); @@ -73,17 +77,39 @@ void doesNotEmitsEventsWhenNotAttached() { void throwsWhenOnEmitDifferent() { TriConsumer onEmit1 = mockOnEmit(); TriConsumer onEmit2 = mockOnEmit(); - eventProvider.attach(onEmit1); - assertThrows(IllegalStateException.class, () -> eventProvider.attach(onEmit2)); + AutoCloseableReentrantReadWriteLock lock = new AutoCloseableReentrantReadWriteLock(); + eventProvider.attach(onEmit1, lock); + assertThrows(IllegalStateException.class, () -> eventProvider.attach(onEmit2, lock)); } @Test - @DisplayName("should not throw if second same onEmit attached") - void doesNotThrowWhenOnEmitSame() { - TriConsumer onEmit1 = mockOnEmit(); - TriConsumer onEmit2 = onEmit1; - eventProvider.attach(onEmit1); - eventProvider.attach(onEmit2); // should not throw, same instance. noop + @Timeout(value = 2, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) + @DisplayName("emit should acquire read lock when attached") + void emitAcquiresReadLockWhenAttached() throws Exception { + AutoCloseableReentrantReadWriteLock lock = new AutoCloseableReentrantReadWriteLock(); + CountDownLatch lockAcquired = new CountDownLatch(1); + + TriConsumer onEmit = (ep, event, details) -> { + // When the onEmit callback runs, the read lock must already be held + assertThat(lock.getReadLockCount()).isGreaterThan(0); + lockAcquired.countDown(); + }; + + eventProvider.attach(onEmit, lock); + eventProvider.emit( + ProviderEvent.PROVIDER_READY, ProviderEventDetails.builder().build()); + + assertThat(lockAcquired.await(1, TimeUnit.SECONDS)).isTrue(); + } + + @Test + @Timeout(value = 2, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) + @DisplayName("emit should not acquire lock when not attached") + void emitDoesNotAcquireLockWhenNotAttached() { + // emit without attaching — should return immediately without error + Awaitable result = eventProvider.emit( + ProviderEvent.PROVIDER_READY, ProviderEventDetails.builder().build()); + assertThat(result).isSameAs(Awaitable.FINISHED); } @Test @@ -132,8 +158,10 @@ public ProviderEvaluation getObjectEvaluation(String key, Value defaultVa } @Override - public void attach(TriConsumer onEmit) { - super.attach(onEmit); + public void attach( + TriConsumer onEmit, + AutoCloseableReentrantReadWriteLock lock) { + super.attach(onEmit, lock); } } diff --git a/src/test/java/dev/openfeature/sdk/GlobalProviderRegistryTest.java b/src/test/java/dev/openfeature/sdk/GlobalProviderRegistryTest.java new file mode 100644 index 000000000..4a0dc2f85 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/GlobalProviderRegistryTest.java @@ -0,0 +1,84 @@ +package dev.openfeature.sdk; + +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class GlobalProviderRegistryTest { + + /** + * Re-registering a provider with the same API instance should not throw. + * This exercises the {@code existing == this} path in registerGlobalProvider. + */ + @Test + @DisplayName("no throw when same API instance re-registers the same provider") + void noThrowWhenSameInstanceReRegisters() { + OpenFeatureAPI api = new OpenFeatureAPI(); + NoOpProvider provider = new NoOpProvider(); + + assertThatCode(() -> { + api.registerGlobalProvider(provider); + api.registerGlobalProvider(provider); // same instance, second call + }) + .doesNotThrowAnyException(); + } + + /** + * After deregistering a provider, binding it to a different API instance + * should not throw, proving the entry was removed. + */ + @Test + @DisplayName("deregister removes provider from global registry") + void deregisterRemovesProviderFromRegistry() { + OpenFeatureAPI api1 = new OpenFeatureAPI(); + OpenFeatureAPI api2 = new OpenFeatureAPI(); + NoOpProvider provider = new NoOpProvider(); + + api1.registerGlobalProvider(provider); + api1.deregisterGlobalProvider(provider); + + // should not throw because the provider was deregistered + assertThatCode(() -> api2.registerGlobalProvider(provider)).doesNotThrowAnyException(); + } + + /** + * Deregister is a no-op if the calling instance is not the current owner. + * The original owner's registration should remain intact. + */ + @Test + @DisplayName("deregister is a no-op when called by non-owner instance") + void deregisterIsNoOpForNonOwner() { + OpenFeatureAPI api1 = new OpenFeatureAPI(); + OpenFeatureAPI api2 = new OpenFeatureAPI(); + NoOpProvider provider = new NoOpProvider(); + + api1.registerGlobalProvider(provider); + + // api2 is not the owner; this should be a no-op + api2.deregisterGlobalProvider(provider); + + // api2 re-registering should still throw, because api1 still owns it + assertThatThrownBy(() -> api2.registerGlobalProvider(provider)) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("1.8.4"); + } + + /** + * Calling shutdown() twice on an API instance should be safe (idempotent). + * The second call returns early because prepareShutdown returns null. + */ + @Test + @DisplayName("double shutdown on API instance is safe") + void doubleShutdownIsSafe() { + OpenFeatureAPI api = new OpenFeatureAPI(); + api.setProvider(new NoOpProvider()); + + assertThatCode(() -> { + api.shutdown(); + api.shutdown(); + }) + .doesNotThrowAnyException(); + } +} diff --git a/src/test/java/dev/openfeature/sdk/LockingSingeltonTest.java b/src/test/java/dev/openfeature/sdk/LockingSingeltonTest.java index ae3246cae..b1fc0a6b2 100644 --- a/src/test/java/dev/openfeature/sdk/LockingSingeltonTest.java +++ b/src/test/java/dev/openfeature/sdk/LockingSingeltonTest.java @@ -8,7 +8,6 @@ import dev.openfeature.sdk.internal.AutoCloseableReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.function.Consumer; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -17,23 +16,16 @@ @Isolated() class LockingSingeltonTest { - private static OpenFeatureAPI api; + private OpenFeatureAPI api; private OpenFeatureClient client; private AutoCloseableReentrantReadWriteLock apiLock; private AutoCloseableReentrantReadWriteLock clientHooksLock; - @BeforeAll - static void beforeAll() { - api = OpenFeatureAPI.getInstance(); - OpenFeatureAPI.getInstance().setProvider("LockingTest", new NoOpProvider()); - } - @BeforeEach void beforeEach() { - client = (OpenFeatureClient) api.getClient("LockingTest"); - apiLock = setupLock(apiLock, mockInnerReadLock(), mockInnerWriteLock()); - OpenFeatureAPI.lock = apiLock; + api = new OpenFeatureAPI(apiLock); + client = (OpenFeatureClient) api.getClient("LockingTest"); clientHooksLock = setupLock(clientHooksLock, mockInnerReadLock(), mockInnerWriteLock()); } diff --git a/src/test/java/dev/openfeature/sdk/isolated/IsolatedAPISingeltonTest.java b/src/test/java/dev/openfeature/sdk/isolated/IsolatedAPISingeltonTest.java new file mode 100644 index 000000000..84e21f9df --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/isolated/IsolatedAPISingeltonTest.java @@ -0,0 +1,76 @@ +package dev.openfeature.sdk.isolated; + +import static org.assertj.core.api.Assertions.assertThat; + +import dev.openfeature.sdk.FeatureProvider; +import dev.openfeature.sdk.ImmutableContext; +import dev.openfeature.sdk.NoOpTransactionContextPropagator; +import dev.openfeature.sdk.OpenFeatureAPI; +import dev.openfeature.sdk.ThreadLocalTransactionContextPropagator; +import dev.openfeature.sdk.providers.memory.InMemoryProvider; +import java.util.Map; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class IsolatedAPISingeltonTest { + + private final OpenFeatureAPI singleton = OpenFeatureAPI.getInstance(); + + @AfterEach + void restoreSingleton() { + singleton.shutdown(); + singleton.clearHooks(); + singleton.setEvaluationContext(null); + singleton.setTransactionContextPropagator(new NoOpTransactionContextPropagator()); + } + + /** + * Requirement 1.8.1 — isolated instances do not share state with + * the global singleton. + */ + @Test + @DisplayName("isolated instance does not interfere with singleton") + void isolatedInstanceDoesNotInterfereWithSingleton() { + // record singleton baseline + FeatureProvider singletonProvider = singleton.getProvider(); + + OpenFeatureAPI isolated = OpenFeatureAPI.createIsolated(); + assertThat(isolated).isNotSameAs(singleton); + + // mutate only the isolated instance + isolated.setProvider(new InMemoryProvider(Map.of())); + isolated.addHooks(new NoOpHook()); + isolated.setEvaluationContext(new ImmutableContext("isolated-key")); + + // singleton remains at baseline + assertThat(singleton.getProvider()).isSameAs(singletonProvider); + assertThat(singleton.getHooks()).isEmpty(); + assertThat(singleton.getEvaluationContext()).isNull(); + } + + /** + * Requirement 1.8.1 — mutating the singleton does not affect a + * previously created isolated instance. + */ + @Test + @DisplayName("singleton does not interfere with isolated instance") + void singletonDoesNotInterfereWithIsolatedInstance() { + OpenFeatureAPI isolated = OpenFeatureAPI.createIsolated(); + + // record isolated baseline + FeatureProvider isolatedProvider = isolated.getProvider(); + + // mutate only the singleton + singleton.setProvider(new InMemoryProvider(Map.of())); + singleton.addHooks(new NoOpHook()); + singleton.setEvaluationContext(new ImmutableContext("singleton-key")); + singleton.setTransactionContextPropagator(new ThreadLocalTransactionContextPropagator()); + + // isolated instance remains at baseline + assertThat(isolated.getProvider()).isSameAs(isolatedProvider); + assertThat(isolated.getHooks()).isEmpty(); + assertThat(isolated.getEvaluationContext()).isNull(); + assertThat(isolated.getTransactionContextPropagator()).isInstanceOf(NoOpTransactionContextPropagator.class); + } +} diff --git a/src/test/java/dev/openfeature/sdk/isolated/IsolatedAPITest.java b/src/test/java/dev/openfeature/sdk/isolated/IsolatedAPITest.java new file mode 100644 index 000000000..464fefdf4 --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/isolated/IsolatedAPITest.java @@ -0,0 +1,227 @@ +package dev.openfeature.sdk.isolated; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import dev.openfeature.sdk.ImmutableContext; +import dev.openfeature.sdk.NoOpProvider; +import dev.openfeature.sdk.NoOpTransactionContextPropagator; +import dev.openfeature.sdk.OpenFeatureAPI; +import dev.openfeature.sdk.ThreadLocalTransactionContextPropagator; +import dev.openfeature.sdk.providers.memory.Flag; +import dev.openfeature.sdk.providers.memory.InMemoryProvider; +import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; + +class IsolatedAPITest { + + /** + * Requirement 1.8.1 — factory creates new, distinct instances that + * conform to the API contract. + */ + @Test + @DisplayName("factory creates distinct API instances") + void factoryCreatesDistinctInstances() { + OpenFeatureAPI api1 = OpenFeatureAPI.createIsolated(); + OpenFeatureAPI api2 = OpenFeatureAPI.createIsolated(); + + assertThat(api1).isInstanceOf(OpenFeatureAPI.class).isNotSameAs(api2); + } + + /** + * Requirement 1.8.1 — providers are isolated between instances. + */ + @Test + @DisplayName("providers are isolated between instances") + void providerIsolation() { + OpenFeatureAPI api1 = OpenFeatureAPI.createIsolated(); + OpenFeatureAPI api2 = OpenFeatureAPI.createIsolated(); + + InMemoryProvider provider = new InMemoryProvider(Map.of()); + api1.setProvider(provider); + + assertThat(api1.getProvider()).isSameAs(provider); + assertThat(api2.getProvider()).isInstanceOf(NoOpProvider.class); + } + + /** + * Requirement 1.8.1 — hooks are isolated between instances. + */ + @Test + @DisplayName("hooks are isolated between instances") + void hookIsolation() { + OpenFeatureAPI api1 = OpenFeatureAPI.createIsolated(); + OpenFeatureAPI api2 = OpenFeatureAPI.createIsolated(); + + api1.addHooks(new NoOpHook()); + + assertThat(api1.getHooks()).hasSize(1); + assertThat(api2.getHooks()).isEmpty(); + } + + /** + * Requirement 1.8.1 — evaluation context is isolated between instances. + */ + @Test + @DisplayName("evaluation context is isolated between instances") + void evaluationContextIsolation() { + OpenFeatureAPI api1 = OpenFeatureAPI.createIsolated(); + OpenFeatureAPI api2 = OpenFeatureAPI.createIsolated(); + + api1.setEvaluationContext(new ImmutableContext("key-1")); + api2.setEvaluationContext(new ImmutableContext("key-2")); + + assertThat(api1.getEvaluationContext().getTargetingKey()).isEqualTo("key-1"); + assertThat(api2.getEvaluationContext().getTargetingKey()).isEqualTo("key-2"); + } + + /** + * Requirement 1.8.1 — event handlers are isolated between instances. + */ + @Test + @Timeout(value = 2, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) + @DisplayName("event handlers are isolated between instances") + void eventHandlerIsolation() throws Exception { + OpenFeatureAPI api1 = OpenFeatureAPI.createIsolated(); + OpenFeatureAPI api2 = OpenFeatureAPI.createIsolated(); + + CountDownLatch api1HandlerLatch = new CountDownLatch(1); + AtomicBoolean api2HandlerCalled = new AtomicBoolean(false); + + // Handlers are dispatched asynchronously; use a latch to await api1's handler. + api1.onProviderReady(details -> api1HandlerLatch.countDown()); + api2.onProviderReady(details -> api2HandlerCalled.set(true)); + + // setting a provider on api1 should only trigger api1's handler + api1.setProviderAndWait(new NoOpProvider()); + + assertThat(api1HandlerLatch.await(1, TimeUnit.SECONDS)).isTrue(); + + // Short delay to allow any (incorrect) async dispatch to api2 to land + // before we assert the negative. Without this, a bug in isolation could + // slip past if api2's handler fires just after the assertion. + Thread.sleep(200); + assertThat(api2HandlerCalled.get()).isFalse(); + } + + /** + * Requirement 1.8.1 — transaction context propagators are isolated + * between instances. + */ + @Test + @DisplayName("transaction context propagator is isolated between instances") + void transactionContextPropagatorIsolation() { + OpenFeatureAPI api1 = OpenFeatureAPI.createIsolated(); + OpenFeatureAPI api2 = OpenFeatureAPI.createIsolated(); + + ThreadLocalTransactionContextPropagator propagator = new ThreadLocalTransactionContextPropagator(); + api1.setTransactionContextPropagator(propagator); + + assertThat(api1.getTransactionContextPropagator()).isSameAs(propagator); + assertThat(api2.getTransactionContextPropagator()).isInstanceOf(NoOpTransactionContextPropagator.class); + } + + /** + * Requirement 1.8.2 — an isolated instance conforms to the same API + * contract (provider, hooks, context, client creation, flag evaluation). + */ + @Test + @DisplayName("isolated instance conforms to API contract") + void isolatedInstanceConformsToAPIContract() throws Exception { + OpenFeatureAPI api = OpenFeatureAPI.createIsolated(); + + // provider management + InMemoryProvider provider = new InMemoryProvider(Map.of( + "flag1", + Flag.builder() + .variant("on", true) + .variant("off", false) + .defaultVariant("on") + .build())); + api.setProviderAndWait(provider); + assertThat(api.getProvider()).isSameAs(provider); + assertThat(api.getProviderMetadata()).isNotNull(); + + // hooks + NoOpHook hook = new NoOpHook(); + api.addHooks(hook); + assertThat(api.getHooks()).containsExactly(hook); + + // context + api.setEvaluationContext(new ImmutableContext("targeting-key")); + assertThat(api.getEvaluationContext().getTargetingKey()).isEqualTo("targeting-key"); + + // client creation and flag evaluation + var client = api.getClient("test-domain", "1.0"); + assertThat(client.getMetadata().getDomain()).isEqualTo("test-domain"); + assertThat(client.getBooleanValue("flag1", false)).isTrue(); + } + + /** + * Requirement 1.8.1 — clearHooks on one instance does not affect another. + */ + @Test + @DisplayName("clearHooks does not affect other instances") + void clearHooksDoesNotAffectOtherInstances() { + OpenFeatureAPI api1 = OpenFeatureAPI.createIsolated(); + OpenFeatureAPI api2 = OpenFeatureAPI.createIsolated(); + + NoOpHook hook = new NoOpHook(); + api1.addHooks(hook); + api2.addHooks(hook); + + api1.clearHooks(); + + assertThat(api1.getHooks()).isEmpty(); + assertThat(api2.getHooks()).hasSize(1); + } + + /** + * Requirement 1.8.2 — clients from different isolated instances use + * their own instance's provider. + */ + @Test + @DisplayName("clients use their own instance's provider") + void clientUsesItsOwnInstanceProvider() throws Exception { + OpenFeatureAPI api1 = OpenFeatureAPI.createIsolated(); + OpenFeatureAPI api2 = OpenFeatureAPI.createIsolated(); + + api1.setProviderAndWait(new InMemoryProvider(Map.of( + "flag1", + Flag.builder() + .variant("on", true) + .variant("off", false) + .defaultVariant("on") + .build()))); + + var client1 = api1.getClient(); + var client2 = api2.getClient(); + + assertThat(client1.getBooleanValue("flag1", false)).isTrue(); + // api2 has NoOpProvider, so it returns the default + assertThat(client2.getBooleanValue("flag1", false)).isFalse(); + } + + /** + * Requirement 1.8.4 — an exception is thrown when the same provider instance + * is registered with more than one API instance simultaneously. + */ + @Test + @DisplayName("throw when same provider bound to multiple API instances (req 1.8.4)") + void throwWhenProviderBoundToMultipleInstances() { + OpenFeatureAPI api1 = OpenFeatureAPI.createIsolated(); + OpenFeatureAPI api2 = OpenFeatureAPI.createIsolated(); + + NoOpProvider provider = new NoOpProvider(); + api1.setProvider(provider); + + assertThatThrownBy(() -> api2.setProvider(provider)) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("1.8.4"); + } +} diff --git a/src/test/java/dev/openfeature/sdk/isolated/NoOpHook.java b/src/test/java/dev/openfeature/sdk/isolated/NoOpHook.java new file mode 100644 index 000000000..3aa0c76ed --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/isolated/NoOpHook.java @@ -0,0 +1,8 @@ +package dev.openfeature.sdk.isolated; + +import dev.openfeature.sdk.Hook; + +/** + * Minimal no-op hook for testing purposes. + */ +class NoOpHook implements Hook {} From 3a054908e3022920d3e02b9d350f914262c10268 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 Jun 2026 15:03:06 +0000 Subject: [PATCH 730/745] chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3.7.0 (#1967) 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 ca22308a9..0886ba5d8 100644 --- a/pom.xml +++ b/pom.xml @@ -585,7 +585,7 @@ com.diffplug.spotless spotless-maven-plugin - 3.6.0 + 3.7.0 From cc837b17ee2fbd29c9162b973f4db47d29acc489 Mon Sep 17 00:00:00 2001 From: Jonathan Norris Date: Thu, 18 Jun 2026 17:17:54 -0400 Subject: [PATCH 731/745] docs: fix inaccuracies in README code examples (#1931) Signed-off-by: Jonathan Norris --- README.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 0194d6100..048e333a7 100644 --- a/README.md +++ b/README.md @@ -217,15 +217,15 @@ If the flag management system you're using supports targeting, you can provide t // set a value to the global context OpenFeatureAPI api = OpenFeatureAPI.getInstance(); Map apiAttrs = new HashMap<>(); -apiAttrs.put("region", new Value(System.getEnv("us-east-1"))); +apiAttrs.put("region", new Value(System.getenv("AWS_REGION"))); EvaluationContext apiCtx = new ImmutableContext(apiAttrs); api.setEvaluationContext(apiCtx); // set a value to the client context Map clientAttrs = new HashMap<>(); -clientAttrs.put("region", new Value(System.getEnv("us-east-1"))); +clientAttrs.put("region", new Value(System.getenv("AWS_REGION"))); EvaluationContext clientCtx = new ImmutableContext(clientAttrs); -Client client = api.getInstance().getClient(); +Client client = api.getClient(); client.setEvaluationContext(clientCtx); // set a value to the invocation context @@ -292,7 +292,7 @@ If a domain has no associated provider, the global provider is used. FeatureProvider scopedProvider = new MyProvider(); // registering the default provider -OpenFeatureAPI.getInstance().setProvider(LocalProvider()); +OpenFeatureAPI.getInstance().setProvider(new LocalProvider()); // registering a provider to a domain OpenFeatureAPI.getInstance().setProvider("my-domain", new CachedProvider()); @@ -452,25 +452,26 @@ This can be a new repository or included in [the existing contrib repository](ht Implement your own hook by conforming to the `Hook interface`. ```java -class MyHook implements Hook { +class MyHook implements Hook { @Override - public Optional before(HookContext ctx, Map hints) { + public Optional before(HookContext ctx, Map hints) { // code that runs before the flag evaluation + return Optional.empty(); } @Override - public void after(HookContext ctx, FlagEvaluationDetails details, Map hints) { + public void after(HookContext ctx, FlagEvaluationDetails details, Map hints) { // code that runs after the flag evaluation succeeds } @Override - public void error(HookContext ctx, Exception error, Map hints) { + public void error(HookContext ctx, Exception error, Map hints) { // code that runs when there's an error during a flag evaluation } @Override - public void finallyAfter(HookContext ctx, FlagEvaluationDetails details, Map hints) { + public void finallyAfter(HookContext ctx, FlagEvaluationDetails details, Map hints) { // code that runs regardless of success or error } }; From 7f92622a455cab102655fa0b25a69dfa359688b4 Mon Sep 17 00:00:00 2001 From: tobias-ibounig-dt Date: Fri, 19 Jun 2026 20:37:32 +0200 Subject: [PATCH 732/745] perf: empty default for ProviderEvaluation (#1970) Signed-off-by: Tobias Ibounig --- src/main/java/dev/openfeature/sdk/ProviderEvaluation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/dev/openfeature/sdk/ProviderEvaluation.java b/src/main/java/dev/openfeature/sdk/ProviderEvaluation.java index 0df2f3709..f48befcb6 100644 --- a/src/main/java/dev/openfeature/sdk/ProviderEvaluation.java +++ b/src/main/java/dev/openfeature/sdk/ProviderEvaluation.java @@ -23,5 +23,5 @@ public class ProviderEvaluation implements BaseEvaluation { private String errorMessage; @Builder.Default - private ImmutableMetadata flagMetadata = ImmutableMetadata.builder().build(); + private ImmutableMetadata flagMetadata = ImmutableMetadata.EMPTY; } From 78afa9840b06ca6472b100a82578e4893d136eec Mon Sep 17 00:00:00 2001 From: tobias-ibounig-dt Date: Fri, 19 Jun 2026 20:37:48 +0200 Subject: [PATCH 733/745] =?UTF-8?q?perf:=20return=20ImmutableContext.EMPTY?= =?UTF-8?q?=20from=20NoOpTransactionContextPropag=E2=80=A6=20(#1975)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit perf: return ImmutableContext.EMPTY from NoOpTransactionContextPropagator Signed-off-by: Tobias Ibounig --- .../openfeature/sdk/NoOpTransactionContextPropagator.java | 2 +- .../sdk/NoOpTransactionContextPropagatorTest.java | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/dev/openfeature/sdk/NoOpTransactionContextPropagator.java b/src/main/java/dev/openfeature/sdk/NoOpTransactionContextPropagator.java index f0949b79c..599ff6951 100644 --- a/src/main/java/dev/openfeature/sdk/NoOpTransactionContextPropagator.java +++ b/src/main/java/dev/openfeature/sdk/NoOpTransactionContextPropagator.java @@ -12,7 +12,7 @@ public class NoOpTransactionContextPropagator implements TransactionContextPropa */ @Override public EvaluationContext getTransactionContext() { - return new ImmutableContext(); + return ImmutableContext.EMPTY; } /** diff --git a/src/test/java/dev/openfeature/sdk/NoOpTransactionContextPropagatorTest.java b/src/test/java/dev/openfeature/sdk/NoOpTransactionContextPropagatorTest.java index d824a5a1a..0187f4543 100644 --- a/src/test/java/dev/openfeature/sdk/NoOpTransactionContextPropagatorTest.java +++ b/src/test/java/dev/openfeature/sdk/NoOpTransactionContextPropagatorTest.java @@ -1,5 +1,6 @@ package dev.openfeature.sdk; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; import java.util.HashMap; @@ -16,6 +17,11 @@ public void emptyTransactionContext() { assertTrue(result.asMap().isEmpty()); } + @Test + public void getTransactionContextReturnsEmptySingleton() { + assertThat(contextPropagator.getTransactionContext()).isSameAs(ImmutableContext.EMPTY); + } + @Test public void setTransactionContext() { Map transactionAttrs = new HashMap<>(); From b21f4a87dfcf100a13f89454a24c1fd8f1392d86 Mon Sep 17 00:00:00 2001 From: tobias-ibounig-dt Date: Fri, 19 Jun 2026 20:38:46 +0200 Subject: [PATCH 734/745] perf: skip iterating over empty list (#1969) Signed-off-by: Tobias Ibounig --- .../java/dev/openfeature/sdk/HookSupport.java | 3 ++ .../dev/openfeature/sdk/HookSupportTest.java | 32 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/main/java/dev/openfeature/sdk/HookSupport.java b/src/main/java/dev/openfeature/sdk/HookSupport.java index e936fdeda..0891134b3 100644 --- a/src/main/java/dev/openfeature/sdk/HookSupport.java +++ b/src/main/java/dev/openfeature/sdk/HookSupport.java @@ -45,6 +45,9 @@ public void setHooks( private static void addFilteredHooks( List> dest, Collection source, FlagValueType type) { + if (source.isEmpty()) { + return; + } for (Hook hook : source) { if (hook.supportsFlagValueType(type)) { dest.add(Pair.of(hook, null)); diff --git a/src/test/java/dev/openfeature/sdk/HookSupportTest.java b/src/test/java/dev/openfeature/sdk/HookSupportTest.java index f7583321a..8d60122d3 100644 --- a/src/test/java/dev/openfeature/sdk/HookSupportTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSupportTest.java @@ -14,6 +14,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.concurrent.ConcurrentLinkedQueue; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -161,6 +162,37 @@ void shouldOrderHooksBySource() { .containsExactly(providerHook, optionHook, clientHook, apiHook); } + @Test + @DisplayName("empty ConcurrentLinkedQueue sources produce no hooks") + void emptyQueueSourcesProduceNoHooks() { + var hookSupportData = new HookSupportData(); + hookSupport.setHooks( + hookSupportData, + new ConcurrentLinkedQueue<>(), + new ConcurrentLinkedQueue<>(), + new ConcurrentLinkedQueue<>(), + new ConcurrentLinkedQueue<>(), + FlagValueType.STRING); + assertThat(hookSupportData.getHooks()).isEmpty(); + } + + @Test + @DisplayName("non-empty ConcurrentLinkedQueue source is not skipped") + void nonEmptyQueueSourceIsNotSkipped() { + Hook hook = mockGenericHook(); + var queue = new ConcurrentLinkedQueue(); + queue.add(hook); + var hookSupportData = new HookSupportData(); + hookSupport.setHooks( + hookSupportData, + new ConcurrentLinkedQueue<>(), + new ConcurrentLinkedQueue<>(), + queue, + new ConcurrentLinkedQueue<>(), + FlagValueType.STRING); + assertThat(hookSupportData.getHooks()).extracting(Pair::getKey).containsExactly(hook); + } + @Test void hookThatReturnsTheGivenContext_doesNotResultInAStackOverflow() { var hookSupportData = new HookSupportData(); From e014572ce6631f2abc59e10c416e923ceba99852 Mon Sep 17 00:00:00 2001 From: tobias-ibounig-dt Date: Fri, 19 Jun 2026 20:39:49 +0200 Subject: [PATCH 735/745] perf: skip ImmutableMetadata allocation when builder has no entries (#1971) Signed-off-by: Tobias Ibounig --- .../dev/openfeature/sdk/ImmutableMetadata.java | 5 ++++- .../openfeature/sdk/ImmutableMetadataTest.java | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java b/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java index 945e0ea17..c6c47da59 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableMetadata.java @@ -101,7 +101,7 @@ public T getValue(final String key, final Class type) { } public Map asUnmodifiableMap() { - return Collections.unmodifiableMap(metadata); + return metadata.isEmpty() ? Collections.emptyMap() : Collections.unmodifiableMap(metadata); } public boolean isEmpty() { @@ -199,6 +199,9 @@ public ImmutableMetadataBuilder addBoolean(final String key, final Boolean value * Retrieve {@link ImmutableMetadata} with provided key,value pairs. */ public ImmutableMetadata build() { + if (metadata.isEmpty()) { + return EMPTY; + } return new ImmutableMetadata(this.metadata); } } diff --git a/src/test/java/dev/openfeature/sdk/ImmutableMetadataTest.java b/src/test/java/dev/openfeature/sdk/ImmutableMetadataTest.java index 108fac0fe..54416850c 100644 --- a/src/test/java/dev/openfeature/sdk/ImmutableMetadataTest.java +++ b/src/test/java/dev/openfeature/sdk/ImmutableMetadataTest.java @@ -1,10 +1,12 @@ package dev.openfeature.sdk; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import java.util.Map; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; class ImmutableMetadataTest { @@ -38,4 +40,18 @@ void retrieveAsUnmodifiableMap() { assertEquals(unmodifiableMap.get("key1"), "value1"); Assertions.assertThrows(UnsupportedOperationException.class, () -> unmodifiableMap.put("key3", "value3")); } + + @Test + @DisplayName("empty builder returns EMPTY singleton") + void emptyBuilderReturnsEmptySingleton() { + assertThat(ImmutableMetadata.builder().build()).isSameAs(ImmutableMetadata.EMPTY); + } + + @Test + @DisplayName("asUnmodifiableMap on empty metadata returns empty unmodifiable map") + void asUnmodifiableMapOnEmptyMetadataIsUnmodifiable() { + Map map = ImmutableMetadata.EMPTY.asUnmodifiableMap(); + assertThat(map).isEmpty(); + Assertions.assertThrows(UnsupportedOperationException.class, () -> map.put("key", "value")); + } } From b54f6dc0e4502d7182df7da0f311abcda7fc376f Mon Sep 17 00:00:00 2001 From: tobias-ibounig-dt Date: Fri, 19 Jun 2026 20:56:32 +0200 Subject: [PATCH 736/745] perf: avoid ImmutableStructure allocation for empty ImmutableContext (#1972) Signed-off-by: Tobias Ibounig --- .../dev/openfeature/sdk/ImmutableContext.java | 7 ++-- .../openfeature/sdk/ImmutableStructure.java | 3 ++ .../openfeature/sdk/ImmutableContextTest.java | 37 +++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/main/java/dev/openfeature/sdk/ImmutableContext.java b/src/main/java/dev/openfeature/sdk/ImmutableContext.java index 150f9c171..c8992db18 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableContext.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableContext.java @@ -2,7 +2,6 @@ import dev.openfeature.sdk.internal.ExcludeFromGeneratedCoverageReport; import java.util.Collections; -import java.util.HashMap; import java.util.Map; import java.util.function.Function; import lombok.ToString; @@ -32,7 +31,7 @@ public final class ImmutableContext implements EvaluationContext { * provided. */ public ImmutableContext() { - this(new HashMap<>()); + this(Collections.emptyMap()); } /** @@ -41,7 +40,7 @@ public ImmutableContext() { * @param targetingKey targeting key */ public ImmutableContext(String targetingKey) { - this(targetingKey, new HashMap<>()); + this(targetingKey, Collections.emptyMap()); } /** @@ -63,6 +62,8 @@ public ImmutableContext(Map attributes) { public ImmutableContext(String targetingKey, Map attributes) { if (targetingKey != null) { this.structure = new ImmutableStructure(targetingKey, attributes); + } else if (attributes == null || attributes.isEmpty()) { + this.structure = ImmutableStructure.EMPTY; } else { this.structure = new ImmutableStructure(attributes); } diff --git a/src/main/java/dev/openfeature/sdk/ImmutableStructure.java b/src/main/java/dev/openfeature/sdk/ImmutableStructure.java index 313e13057..e6c427007 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableStructure.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableStructure.java @@ -1,5 +1,6 @@ package dev.openfeature.sdk; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -21,6 +22,8 @@ @SuppressWarnings({"PMD.BeanMembersShouldSerialize", "checkstyle:MissingJavadocType"}) public final class ImmutableStructure extends AbstractStructure { + static final ImmutableStructure EMPTY = new ImmutableStructure(Collections.emptyMap()); + /** * create an immutable structure with the empty attributes. */ diff --git a/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java b/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java index 7d8210be4..a365b6fc2 100644 --- a/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java +++ b/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java @@ -1,6 +1,7 @@ package dev.openfeature.sdk; import static dev.openfeature.sdk.EvaluationContext.TARGETING_KEY; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; @@ -216,6 +217,42 @@ void immutableContextHashCodeIsStable() { assertEquals(first, second); } + @Nested + @DisplayName("ImmutableContext(String, Map) branch logic") + class ConstructorBranches { + + @Test + @DisplayName("non-null targeting key with empty attributes is preserved") + void nonNullTargetingKeyWithEmptyAttributesIsPreserved() { + ImmutableContext ctx = new ImmutableContext("key", Collections.emptyMap()); + assertThat(ctx.getTargetingKey()).isEqualTo("key"); + assertThat(ctx.keySet()).contains(TARGETING_KEY); + } + + @Test + @DisplayName("non-null targeting key with null attributes is preserved") + void nonNullTargetingKeyWithNullAttributesIsPreserved() { + ImmutableContext ctx = new ImmutableContext("key", null); + assertThat(ctx.getTargetingKey()).isEqualTo("key"); + } + + @Test + @DisplayName("null targeting key with empty attributes yields empty context") + void nullTargetingKeyWithEmptyAttributesYieldsEmptyContext() { + ImmutableContext ctx = new ImmutableContext((String) null, Collections.emptyMap()); + assertThat(ctx.getTargetingKey()).isNull(); + assertThat(ctx.isEmpty()).isTrue(); + } + + @Test + @DisplayName("null targeting key with null attributes yields empty context") + void nullTargetingKeyWithNullAttributesYieldsEmptyContext() { + ImmutableContext ctx = new ImmutableContext((String) null, null); + assertThat(ctx.getTargetingKey()).isNull(); + assertThat(ctx.isEmpty()).isTrue(); + } + } + @Nested class Equals { ImmutableContext ctx = new ImmutableContext("c", Map.of("a", new Value("b"))); From 62fda56d5a9d79c37b16360a000e15cf49ec7187 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 22 Jun 2026 00:27:05 +0000 Subject: [PATCH 737/745] chore(deps): update dependency org.cyclonedx:cyclonedx-maven-plugin to v2.9.2 (#1976) 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 0886ba5d8..5510a20ab 100644 --- a/pom.xml +++ b/pom.xml @@ -273,7 +273,7 @@ org.cyclonedx cyclonedx-maven-plugin - 2.9.1 + 2.9.2 library 1.3 From d492685423f3a1d375f9639a5f20082a562845da Mon Sep 17 00:00:00 2001 From: tobias-ibounig-dt Date: Mon, 22 Jun 2026 19:31:37 +0200 Subject: [PATCH 738/745] perf: return ImmutableContext.EMPTY when merging two empty contexts (#1973) Signed-off-by: Tobias Ibounig --- .../dev/openfeature/sdk/ImmutableContext.java | 3 ++ .../openfeature/sdk/ImmutableContextTest.java | 35 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/main/java/dev/openfeature/sdk/ImmutableContext.java b/src/main/java/dev/openfeature/sdk/ImmutableContext.java index c8992db18..dd65538b8 100644 --- a/src/main/java/dev/openfeature/sdk/ImmutableContext.java +++ b/src/main/java/dev/openfeature/sdk/ImmutableContext.java @@ -88,6 +88,9 @@ public String getTargetingKey() { @Override public EvaluationContext merge(EvaluationContext overridingContext) { if (overridingContext == null || overridingContext.isEmpty()) { + if (this.isEmpty()) { + return ImmutableContext.EMPTY; + } return new ImmutableContext(this.asUnmodifiableMap()); } if (this.isEmpty()) { diff --git a/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java b/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java index a365b6fc2..08744fc3e 100644 --- a/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java +++ b/src/test/java/dev/openfeature/sdk/ImmutableContextTest.java @@ -253,6 +253,41 @@ void nullTargetingKeyWithNullAttributesYieldsEmptyContext() { } } + @Nested + @DisplayName("ImmutableContext.merge() empty short-circuit") + class MergeEmpty { + + @Test + @DisplayName("merging two empty contexts returns the EMPTY singleton") + void mergingTwoEmptyContextsReturnsEmptySingleton() { + EvaluationContext result = new ImmutableContext().merge(new ImmutableContext()); + assertThat(result).isSameAs(ImmutableContext.EMPTY); + } + + @Test + @DisplayName("merging empty context with null returns the EMPTY singleton") + void mergingEmptyContextWithNullReturnsEmptySingleton() { + EvaluationContext result = new ImmutableContext().merge(null); + assertThat(result).isSameAs(ImmutableContext.EMPTY); + } + + @Test + @DisplayName("merging non-empty context with null does not return EMPTY") + void mergingNonEmptyContextWithNullDoesNotReturnEmpty() { + EvaluationContext result = new ImmutableContext("key").merge(null); + assertThat(result).isNotSameAs(ImmutableContext.EMPTY); + assertThat(result.getTargetingKey()).isEqualTo("key"); + } + + @Test + @DisplayName("merging non-empty context with empty override does not return EMPTY") + void mergingNonEmptyContextWithEmptyOverrideDoesNotReturnEmpty() { + EvaluationContext result = new ImmutableContext("key").merge(new ImmutableContext()); + assertThat(result).isNotSameAs(ImmutableContext.EMPTY); + assertThat(result.getTargetingKey()).isEqualTo("key"); + } + } + @Nested class Equals { ImmutableContext ctx = new ImmutableContext("c", Map.of("a", new Value("b"))); From a8277d0024c0bbb328a8edb1b553ece5b1be28b1 Mon Sep 17 00:00:00 2001 From: tobias-ibounig-dt Date: Mon, 22 Jun 2026 19:37:51 +0200 Subject: [PATCH 739/745] perf: return Collections.emptyMap() from asUnmodifiableMap() when attributes is empty (#1974) Signed-off-by: Tobias Ibounig --- .../dev/openfeature/sdk/AbstractStructure.java | 3 +++ .../openfeature/sdk/MutableStructureTest.java | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/main/java/dev/openfeature/sdk/AbstractStructure.java b/src/main/java/dev/openfeature/sdk/AbstractStructure.java index 4d58ded55..4ab4f7f12 100644 --- a/src/main/java/dev/openfeature/sdk/AbstractStructure.java +++ b/src/main/java/dev/openfeature/sdk/AbstractStructure.java @@ -29,6 +29,9 @@ public boolean isEmpty() { * @return immutable map */ public Map asUnmodifiableMap() { + if (attributes == null || attributes.isEmpty()) { + return Collections.emptyMap(); + } return Collections.unmodifiableMap(attributes); } diff --git a/src/test/java/dev/openfeature/sdk/MutableStructureTest.java b/src/test/java/dev/openfeature/sdk/MutableStructureTest.java index ebd11af0d..fc0410a71 100644 --- a/src/test/java/dev/openfeature/sdk/MutableStructureTest.java +++ b/src/test/java/dev/openfeature/sdk/MutableStructureTest.java @@ -1,10 +1,12 @@ package dev.openfeature.sdk; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; import java.util.HashMap; import java.util.Map; import java.util.Set; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; class MutableStructureTest { @@ -21,6 +23,20 @@ void mutableStructureWithNullBackingStructureIsEmpty() { assertTrue(m1.isEmpty()); } + @Test + void asUnmodifiableMapOnEmptyStructureIsEmpty() { + Map map = new MutableStructure().asUnmodifiableMap(); + assertThat(map).isEmpty(); + Assertions.assertThrows(UnsupportedOperationException.class, () -> map.put("key", new Value("val"))); + } + + @Test + void asUnmodifiableMapOnNullAttributesIsEmpty() { + Map map = new MutableStructure(null).asUnmodifiableMap(); + assertThat(map).isEmpty(); + Assertions.assertThrows(UnsupportedOperationException.class, () -> map.put("key", new Value("val"))); + } + @Test void unequalMutableStructuresAreNotEqual() { MutableStructure m1 = new MutableStructure(); From 1dcb770de6e87e8cbd08af7dbf2dfb3b68e2b469 Mon Sep 17 00:00:00 2001 From: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> Date: Mon, 22 Jun 2026 13:48:03 -0400 Subject: [PATCH 740/745] chore(main): release 1.21.0 (#1905) Signed-off-by: OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 90 +++++++++++++++++++++++++++++++++++ README.md | 8 ++-- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 97 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 01385fe6f..77e8cb2c9 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"1.20.2"} +{".":"1.21.0"} diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b549e936..bbb8efb24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,95 @@ # Changelog +## [1.21.0](https://github.com/open-feature/java-sdk/compare/v1.20.2...v1.21.0) (2026-06-22) + + +### 🐛 Bug Fixes + +* collect and propagate per-provider errors in multi-provider strategies ([#1901](https://github.com/open-feature/java-sdk/issues/1901)) ([f938b26](https://github.com/open-feature/java-sdk/commit/f938b26efbabfe577e304099c26caa3b58513d3c)) +* **deps:** update dependency com.fasterxml.jackson:jackson-bom to v2.21.2 ([#1907](https://github.com/open-feature/java-sdk/issues/1907)) ([bb19ba9](https://github.com/open-feature/java-sdk/commit/bb19ba92722cbe14b0a435bebe90afd584e4408b)) +* **deps:** update dependency com.fasterxml.jackson:jackson-bom to v2.21.3 ([#1935](https://github.com/open-feature/java-sdk/issues/1935)) ([51754a5](https://github.com/open-feature/java-sdk/commit/51754a56e491b6b6868f17cbd6a3692ce5f0c95b)) +* **deps:** update dependency org.junit:junit-bom to v6.1.0 ([#1941](https://github.com/open-feature/java-sdk/issues/1941)) ([76b71c2](https://github.com/open-feature/java-sdk/commit/76b71c205b132b2d5c78f2c2d082eb127df99c39)) +* **deps:** update dependency org.projectlombok:lombok to v1.18.46 ([#1932](https://github.com/open-feature/java-sdk/issues/1932)) ([639ee61](https://github.com/open-feature/java-sdk/commit/639ee618c83b5eea679f6c45ff72fcf744420659)) +* **deps:** update dependency org.slf4j:slf4j-api to v2.0.18 ([#1937](https://github.com/open-feature/java-sdk/issues/1937)) ([ea41f90](https://github.com/open-feature/java-sdk/commit/ea41f9079329a94bbecd581c64a2524840c23555)) +* **deps:** update jackson monorepo to v2.22.0 ([#1946](https://github.com/open-feature/java-sdk/issues/1946)) ([58091f3](https://github.com/open-feature/java-sdk/commit/58091f34a4851513e8adbbf34f88223701544ad4)) +* Domain client event handlers no longer disappear ([#1922](https://github.com/open-feature/java-sdk/issues/1922)) ([5562cb9](https://github.com/open-feature/java-sdk/commit/5562cb93fc8e769ed1b2800f8e6ceece3baaab4e)) +* keep distributionManagement in flattened pom ([#1958](https://github.com/open-feature/java-sdk/issues/1958)) ([08ce6d0](https://github.com/open-feature/java-sdk/commit/08ce6d0c9b7c47601408f5c5d02502bced18a18d)) +* shutdown now clears hooks, evaluationContext and transactionContextPropagator as per spec 1.6.2 ([#1936](https://github.com/open-feature/java-sdk/issues/1936)) ([fb2181f](https://github.com/open-feature/java-sdk/commit/fb2181f974af3d121ee013ede152d4e91eb8e0b3)) + + +### ✨ New Features + +* support isolated API instances ([#1928](https://github.com/open-feature/java-sdk/issues/1928)) ([231464a](https://github.com/open-feature/java-sdk/commit/231464a0975e2a3eceb33f75e9e31021424de31a)) + + +### 🧹 Chore + +* **deps:** update codecov/codecov-action action to v6 ([#1913](https://github.com/open-feature/java-sdk/issues/1913)) ([f2f14e3](https://github.com/open-feature/java-sdk/commit/f2f14e3652cdbb031341972a94619c6dc85a4425)) +* **deps:** update codecov/codecov-action action to v6.0.1 ([#1940](https://github.com/open-feature/java-sdk/issues/1940)) ([fb84d68](https://github.com/open-feature/java-sdk/commit/fb84d68157cf7c73762578ff780ff23f8a739ad5)) +* **deps:** update codecov/codecov-action action to v6.0.2 ([#1960](https://github.com/open-feature/java-sdk/issues/1960)) ([039adc4](https://github.com/open-feature/java-sdk/commit/039adc4639f0b0ba63192432cc7dc00bdebd3a4d)) +* **deps:** update codecov/codecov-action action to v7 ([#1961](https://github.com/open-feature/java-sdk/issues/1961)) ([d779ae4](https://github.com/open-feature/java-sdk/commit/d779ae43239203167e39c5a94916de0836a8d2d2)) +* **deps:** update com.vmlens.version to v1.2.28 ([#1923](https://github.com/open-feature/java-sdk/issues/1923)) ([f2f7df7](https://github.com/open-feature/java-sdk/commit/f2f7df7f04699a90e79fa95f7804b11924ff4e31)) +* **deps:** update dependency com.diffplug.spotless:spotless-maven-plugin to v3.5.1 ([#1938](https://github.com/open-feature/java-sdk/issues/1938)) ([6367b8a](https://github.com/open-feature/java-sdk/commit/6367b8a1c69d605b86491e5bee266b8369695f93)) +* **deps:** update dependency com.diffplug.spotless:spotless-maven-plugin to v3.6.0 ([#1942](https://github.com/open-feature/java-sdk/issues/1942)) ([cd29cd9](https://github.com/open-feature/java-sdk/commit/cd29cd9981cba725ab292567b31807c2b1d2d187)) +* **deps:** update dependency com.diffplug.spotless:spotless-maven-plugin to v3.7.0 ([#1967](https://github.com/open-feature/java-sdk/issues/1967)) ([3a05490](https://github.com/open-feature/java-sdk/commit/3a054908e3022920d3e02b9d350f914262c10268)) +* **deps:** update dependency com.github.spotbugs:spotbugs to v4.10.1 ([#1962](https://github.com/open-feature/java-sdk/issues/1962)) ([9375570](https://github.com/open-feature/java-sdk/commit/93755707aad9eb7afa8e90c415e2ad1f0273e974)) +* **deps:** update dependency com.github.spotbugs:spotbugs to v4.10.2 ([#1965](https://github.com/open-feature/java-sdk/issues/1965)) ([50da905](https://github.com/open-feature/java-sdk/commit/50da9052b876c2549913ea115ca889c7e2fcacd3)) +* **deps:** update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.10.2.0 ([#1966](https://github.com/open-feature/java-sdk/issues/1966)) ([75391aa](https://github.com/open-feature/java-sdk/commit/75391aa58af58347eb76f631f4f083e725fbe32c)) +* **deps:** update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.8.3 ([#1915](https://github.com/open-feature/java-sdk/issues/1915)) ([c476180](https://github.com/open-feature/java-sdk/commit/c476180e3a4044e28fb9abc6664e881a11d86f6d)) +* **deps:** update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.8.4 ([#1963](https://github.com/open-feature/java-sdk/issues/1963)) ([864f9cf](https://github.com/open-feature/java-sdk/commit/864f9cf67799345cf9b70478f6556dd2b8de3a96)) +* **deps:** update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.9.8.5 ([#1964](https://github.com/open-feature/java-sdk/issues/1964)) ([d8eb4fc](https://github.com/open-feature/java-sdk/commit/d8eb4fc177f455b4814d423ee28c4ad1ebd99ac2)) +* **deps:** update dependency com.google.guava:guava to v33.6.0-jre ([#1927](https://github.com/open-feature/java-sdk/issues/1927)) ([c69bb0e](https://github.com/open-feature/java-sdk/commit/c69bb0ebb6a8864085f00049b3885c3b9e01bb9d)) +* **deps:** update dependency com.tngtech.archunit:archunit-junit5 to v1.4.2 ([#1930](https://github.com/open-feature/java-sdk/issues/1930)) ([b683371](https://github.com/open-feature/java-sdk/commit/b683371cca495e16a56558c4bc58352c975ed71a)) +* **deps:** update dependency maven to v3.9.15 ([#1929](https://github.com/open-feature/java-sdk/issues/1929)) ([e300520](https://github.com/open-feature/java-sdk/commit/e300520e22de266056af920b50d4f294a4e91043)) +* **deps:** update dependency maven to v3.9.16 ([#1939](https://github.com/open-feature/java-sdk/issues/1939)) ([b4b913c](https://github.com/open-feature/java-sdk/commit/b4b913c9118833bf75ebe4bff1baa61a7433b7c0)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.18.10-jdk5 ([#1949](https://github.com/open-feature/java-sdk/issues/1949)) ([8bd83fc](https://github.com/open-feature/java-sdk/commit/8bd83fc58e2bda990103980a2257aefdbbcaf863)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.18.8-jdk5 ([#1917](https://github.com/open-feature/java-sdk/issues/1917)) ([0c26c70](https://github.com/open-feature/java-sdk/commit/0c26c70fd2eb2988d339c0be727af9dc74bbcd2c)) +* **deps:** update dependency net.bytebuddy:byte-buddy to v1.18.9-jdk5 ([#1947](https://github.com/open-feature/java-sdk/issues/1947)) ([78fb82d](https://github.com/open-feature/java-sdk/commit/78fb82df2a20746a00c0226dca8feac1c37af638)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.18.10-jdk5 ([#1950](https://github.com/open-feature/java-sdk/issues/1950)) ([484782b](https://github.com/open-feature/java-sdk/commit/484782b2d96e0f234378aac4acd9d2535ba688ba)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.18.8-jdk5 ([#1918](https://github.com/open-feature/java-sdk/issues/1918)) ([04ca748](https://github.com/open-feature/java-sdk/commit/04ca748688c6df9ca27efde42bf31e7d75d57459)) +* **deps:** update dependency net.bytebuddy:byte-buddy-agent to v1.18.9-jdk5 ([#1948](https://github.com/open-feature/java-sdk/issues/1948)) ([647bd1d](https://github.com/open-feature/java-sdk/commit/647bd1d933399415adac59486d481e95556a12bf)) +* **deps:** update dependency org.apache.maven.plugins:maven-dependency-plugin to v3.11.0 ([#1945](https://github.com/open-feature/java-sdk/issues/1945)) ([9649ff3](https://github.com/open-feature/java-sdk/commit/9649ff361fc2588bd4494de6ff0c0663f8e97409)) +* **deps:** update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.5.6 ([#1943](https://github.com/open-feature/java-sdk/issues/1943)) ([d0278bb](https://github.com/open-feature/java-sdk/commit/d0278bb183c79e18cc65976fe9e3955998492865)) +* **deps:** update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.6 ([#1944](https://github.com/open-feature/java-sdk/issues/1944)) ([aa284ec](https://github.com/open-feature/java-sdk/commit/aa284eca3ca59e444e029d1a1a8327cd5c2887d5)) +* **deps:** update dependency org.codehaus.mojo:flatten-maven-plugin to v1.7.3 ([#1957](https://github.com/open-feature/java-sdk/issues/1957)) ([733af9e](https://github.com/open-feature/java-sdk/commit/733af9e714f7763363425e0651043dc254afcc91)) +* **deps:** update dependency org.cyclonedx:cyclonedx-maven-plugin to v2.9.2 ([#1976](https://github.com/open-feature/java-sdk/issues/1976)) ([62fda56](https://github.com/open-feature/java-sdk/commit/62fda56d5a9d79c37b16360a000e15cf49ec7187)) +* **deps:** update github/codeql-action digest to 05b1a5d ([#1906](https://github.com/open-feature/java-sdk/issues/1906)) ([d2e15b4](https://github.com/open-feature/java-sdk/commit/d2e15b467005264e3623f6662ab7d4cda35def86)) +* **deps:** update github/codeql-action digest to 30c555a ([#1904](https://github.com/open-feature/java-sdk/issues/1904)) ([4638622](https://github.com/open-feature/java-sdk/commit/463862248405dd916e9d42a76ce9530956cccc32)) +* **deps:** update github/codeql-action digest to 34950e1 ([#1921](https://github.com/open-feature/java-sdk/issues/1921)) ([ea2d573](https://github.com/open-feature/java-sdk/commit/ea2d573d340f17b66570aef3103e613a6422ed1e)) +* **deps:** update github/codeql-action digest to 3d564d9 ([#1910](https://github.com/open-feature/java-sdk/issues/1910)) ([88fb702](https://github.com/open-feature/java-sdk/commit/88fb702984572c26d561ffcbc46f5df37b35f779)) +* **deps:** update github/codeql-action digest to 57ec7e1 ([#1920](https://github.com/open-feature/java-sdk/issues/1920)) ([fcd0773](https://github.com/open-feature/java-sdk/commit/fcd0773043d50f23b8eb0b8df66930091b921c94)) +* **deps:** update github/codeql-action digest to 72c0b0e ([#1908](https://github.com/open-feature/java-sdk/issues/1908)) ([39c9df3](https://github.com/open-feature/java-sdk/commit/39c9df3aebb86aaaebe8d6e5363722e427931202)) +* **deps:** update github/codeql-action digest to a899987 ([#1914](https://github.com/open-feature/java-sdk/issues/1914)) ([eecb2d6](https://github.com/open-feature/java-sdk/commit/eecb2d623210390c7e5127003eac1894b05dec6f)) +* **deps:** update github/codeql-action digest to b623f5f ([#1924](https://github.com/open-feature/java-sdk/issues/1924)) ([d5f7a64](https://github.com/open-feature/java-sdk/commit/d5f7a645688f5f45129626b5eaac1af32280245e)) +* **deps:** update github/codeql-action digest to c618c9b ([#1916](https://github.com/open-feature/java-sdk/issues/1916)) ([36eb2e0](https://github.com/open-feature/java-sdk/commit/36eb2e08e79b86bf14494edae29675b3d5b7539e)) +* **deps:** update github/codeql-action digest to eedab83 ([#1909](https://github.com/open-feature/java-sdk/issues/1909)) ([050633c](https://github.com/open-feature/java-sdk/commit/050633c6770f4fc28890cc8dcc343575c622f21b)) +* **deps:** update github/codeql-action digest to f94817b ([#1911](https://github.com/open-feature/java-sdk/issues/1911)) ([e8a99d8](https://github.com/open-feature/java-sdk/commit/e8a99d8dc33f290c1348f113e109fb7e9ce05499)) +* **deps:** update googleapis/release-please-action action to v5 ([#1933](https://github.com/open-feature/java-sdk/issues/1933)) ([72259d1](https://github.com/open-feature/java-sdk/commit/72259d144f5463a137f5038f6f4114cb4dd5ba62)) +* flatten pom, add licences to jar ([#1951](https://github.com/open-feature/java-sdk/issues/1951)) ([42418c1](https://github.com/open-feature/java-sdk/commit/42418c1701dfd07df46b5deaaed5ef2749e6f3dd)) + + +### 📚 Documentation + +* fix inaccuracies in README code examples ([#1931](https://github.com/open-feature/java-sdk/issues/1931)) ([cc837b1](https://github.com/open-feature/java-sdk/commit/cc837b17ee2fbd29c9162b973f4db47d29acc489)) + + +### 🚀 Performance + +* avoid ImmutableStructure allocation for empty ImmutableContext ([#1972](https://github.com/open-feature/java-sdk/issues/1972)) ([b54f6dc](https://github.com/open-feature/java-sdk/commit/b54f6dc0e4502d7182df7da0f311abcda7fc376f)) +* avoid Optional.ofNullable wrapping on hook.before() return value ([#1955](https://github.com/open-feature/java-sdk/issues/1955)) ([b611d55](https://github.com/open-feature/java-sdk/commit/b611d55d5fe54107ea16e06bb866ad899cad73fb)) +* cache clientMetadata lambda to avoid per-call allocation ([#1952](https://github.com/open-feature/java-sdk/issues/1952)) ([85c0047](https://github.com/open-feature/java-sdk/commit/85c0047c04d4ade912b3b405cd8dfda154d7cb98)) +* eliminate merge allocation in setHooks by accepting hook sources directly ([#1956](https://github.com/open-feature/java-sdk/issues/1956)) ([a5ba3c6](https://github.com/open-feature/java-sdk/commit/a5ba3c667d1feec503beebe2b991d6f8561e67f5)) +* empty default for ProviderEvaluation ([#1970](https://github.com/open-feature/java-sdk/issues/1970)) ([7f92622](https://github.com/open-feature/java-sdk/commit/7f92622a455cab102655fa0b25a69dfa359688b4)) +* replace copy+reverse with index-based traversal in executeBefor… ([#1954](https://github.com/open-feature/java-sdk/issues/1954)) ([8fbf507](https://github.com/open-feature/java-sdk/commit/8fbf507202453ad9e308785b96b174c750d144de)) +* replace copy+reverse with index-based traversal in executeBeforeHooks ([8fbf507](https://github.com/open-feature/java-sdk/commit/8fbf507202453ad9e308785b96b174c750d144de)) +* return Collections.emptyMap() from asUnmodifiableMap() when attributes is empty ([#1974](https://github.com/open-feature/java-sdk/issues/1974)) ([a8277d0](https://github.com/open-feature/java-sdk/commit/a8277d0024c0bbb328a8edb1b553ece5b1be28b1)) +* return ImmutableContext.EMPTY from NoOpTransactionContextPropag… ([#1975](https://github.com/open-feature/java-sdk/issues/1975)) ([78afa98](https://github.com/open-feature/java-sdk/commit/78afa9840b06ca6472b100a82578e4893d136eec)) +* return ImmutableContext.EMPTY from NoOpTransactionContextPropagator ([78afa98](https://github.com/open-feature/java-sdk/commit/78afa9840b06ca6472b100a82578e4893d136eec)) +* return ImmutableContext.EMPTY when merging two empty contexts ([#1973](https://github.com/open-feature/java-sdk/issues/1973)) ([d492685](https://github.com/open-feature/java-sdk/commit/d492685423f3a1d375f9639a5f20082a562845da)) +* skip ImmutableMetadata allocation when builder has no entries ([#1971](https://github.com/open-feature/java-sdk/issues/1971)) ([e014572](https://github.com/open-feature/java-sdk/commit/e014572ce6631f2abc59e10c416e923ceba99852)) +* skip iterating over empty list ([#1969](https://github.com/open-feature/java-sdk/issues/1969)) ([b21f4a8](https://github.com/open-feature/java-sdk/commit/b21f4a87dfcf100a13f89454a24c1fd8f1392d86)) +* skip unmodifiableMap wrapper when hookHints is empty ([#1953](https://github.com/open-feature/java-sdk/issues/1953)) ([b592514](https://github.com/open-feature/java-sdk/commit/b592514b6a7f4592330462d763e0124f040a6ff5)) + ## [1.20.2](https://github.com/open-feature/java-sdk/compare/v1.20.1...v1.20.2) (2026-03-19) diff --git a/README.md b/README.md index 048e333a7..bbf55e75f 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.20.2 + 1.21.0 ``` @@ -84,7 +84,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:1.20.2' + implementation 'dev.openfeature:sdk:1.21.0' } ``` diff --git a/pom.xml b/pom.xml index 5510a20ab..179d8fb7b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ dev.openfeature sdk - 1.20.2 + 1.21.0 [17,) diff --git a/version.txt b/version.txt index 769e37e15..3500250a4 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.20.2 +1.21.0 From e0bac3319f6433588e652c61f0847fcd224cd2ad Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 26 Jun 2026 18:42:42 +0000 Subject: [PATCH 741/745] fix(deps): update dependency io.cucumber:cucumber-bom to v7.34.4 (#1977) 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 179d8fb7b..940f76770 100644 --- a/pom.xml +++ b/pom.xml @@ -241,7 +241,7 @@ io.cucumber cucumber-bom - 7.34.3 + 7.34.4 pom import From 473755e4a4980f3a8fff42d8a8d08859c40b2ea8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 28 Jun 2026 16:32:46 +0000 Subject: [PATCH 742/745] fix(deps): update dependency org.junit:junit-bom to v6.1.1 (#1979) 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 940f76770..738e55560 100644 --- a/pom.xml +++ b/pom.xml @@ -249,7 +249,7 @@ org.junit junit-bom - 6.1.0 + 6.1.1 pom import From 1b4490eee948f512a1cbe9c89565caac42a8dbac Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jun 2026 00:55:45 +0000 Subject: [PATCH 743/745] chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3.8.0 (#1980) 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 738e55560..210683382 100644 --- a/pom.xml +++ b/pom.xml @@ -585,7 +585,7 @@ com.diffplug.spotless spotless-maven-plugin - 3.7.0 + 3.8.0 From e37c0e0fcea3f6ba0c160d74a719ab7a6216da5b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 04:26:22 +0000 Subject: [PATCH 744/745] chore(deps): update dependency net.bytebuddy:byte-buddy to v1.18.11-jdk5 (#1983) 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 210683382..74e733296 100644 --- a/pom.xml +++ b/pom.xml @@ -218,7 +218,7 @@ net.bytebuddy byte-buddy - 1.18.10-jdk5 + 1.18.11-jdk5 test From a7d4e8a614e5b782f93fc1f070a7a81cb3445406 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 08:30:05 +0000 Subject: [PATCH 745/745] chore(deps): update dependency net.bytebuddy:byte-buddy-agent to v1.18.11-jdk5 (#1984) 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 74e733296..17a10476c 100644 --- a/pom.xml +++ b/pom.xml @@ -225,7 +225,7 @@ net.bytebuddy byte-buddy-agent - 1.18.10-jdk5 + 1.18.11-jdk5 test