From 00dcafdb963a7b62f1fd31a3464e924278ec5497 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Tue, 20 Sep 2022 09:48:34 -0400 Subject: [PATCH 01/63] chore: add integration tests (#77) * chore: add integration tests Signed-off-by: Todd Baert * improve POM spacing Signed-off-by: Todd Baert Signed-off-by: Todd Baert Signed-off-by: Bhandari, Pramesh(AWF) --- .github/workflows/pullrequest.yml | 8 +- .gitmodules | 3 + README.md | 6 + pom.xml | 124 +++++++- .../javasdk/integration/RunCucumberTest.java | 16 + .../javasdk/integration/StepDefinitions.java | 282 ++++++++++++++++++ src/test/resources/features/.gitignore | 1 + src/test/resources/features/.gitkeep | 0 test-harness | 1 + 9 files changed, 437 insertions(+), 4 deletions(-) create mode 100644 .gitmodules create mode 100644 src/test/java/dev/openfeature/javasdk/integration/RunCucumberTest.java create mode 100644 src/test/java/dev/openfeature/javasdk/integration/StepDefinitions.java create mode 100644 src/test/resources/features/.gitignore create mode 100644 src/test/resources/features/.gitkeep create mode 160000 test-harness diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index c37478aa..8230ce59 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -9,6 +9,12 @@ permissions: jobs: build: runs-on: ubuntu-latest + services: + flagd: + image: ghcr.io/open-feature/flagd-testbed:latest + ports: + - 8013:8013 + steps: - name: Check out the code uses: actions/checkout@v3 @@ -28,7 +34,7 @@ jobs: ${{ runner.os }}-maven- - name: Build with Maven - run: mvn --batch-mode --update-snapshots verify + run: mvn --batch-mode --update-snapshots verify -P integration-test - name: Upload coverage to Codecov uses: codecov/codecov-action@v2 diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..5893173a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "test-harness"] + path = test-harness + url = https://github.com/open-feature/test-harness diff --git a/README.md b/README.md index 2db69b71..6c84e96e 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,12 @@ We hold regular meetings which you can see [here](https://github.com/open-featur We are also present on the `#openfeature` channel in the [CNCF slack](https://slack.cncf.io/). +## Developing + +### Integration tests + +The continuous integration runs a set of [gherkin integration tests](https://github.com/open-feature/test-harness/blob/main/features/evaluation.feature) using [`flagd`](https://github.com/open-feature/flagd). These tests do not run with the default maven profile. If you'd like to run them locally, you can start the flagd testbed with `docker run -p 8013:8013 ghcr.io/open-feature/flagd-testbed:latest` and then run `mvn test -P integration-test`. + ## Releasing See [releasing](./docs/release.md). diff --git a/pom.xml b/pom.xml index eda0c1be..75c59410 100644 --- a/pom.xml +++ b/pom.xml @@ -11,6 +11,8 @@ 1.8 ${maven.compiler.source} 5.8.1 + + **/integration/*.java OpenFeature Java SDK @@ -46,7 +48,6 @@ provided - com.github.spotbugs @@ -96,29 +97,81 @@ ${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.8.1 + 1.9.0 + test + + + + io.cucumber + cucumber-java test + + + io.cucumber + cucumber-junit-platform-engine + test + + + + com.google.guava + guava + 31.1-jre + test + + + + dev.openfeature.contrib.providers + flagd + 0.3.2 + test + + + + + + + io.cucumber + cucumber-bom + 7.5.0 + pom + import + + + + org.junit + junit-bom + 5.9.0 + pom + import + + + + + maven-dependency-plugin 3.3.0 @@ -137,16 +190,21 @@ org.junit* + com.google.guava* + io.cucumber* + org.junit* com.google.code.findbugs* com.github.spotbugs* uk.org.lidalia:lidalia-slf4j-ext:* + maven-compiler-plugin 3.8.1 + org.apache.maven.plugins maven-surefire-plugin @@ -155,6 +213,10 @@ ${surefireArgLine} + + + ${testExclusions} + @@ -224,7 +286,7 @@ - + @@ -257,6 +319,7 @@ + org.apache.maven.plugins maven-javadoc-plugin @@ -372,6 +435,61 @@ + + + + integration-test + + + + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.1.0 + + + update-test-harness-submodule + validate + + exec + + + + git + + submodule + update + --init + --recursive + + + + + copy-gherkin-tests + validate + + exec + + + + cp + + test-harness/features/evaluation.feature + src/test/resources/features/ + + + + + + + + + + ossrh diff --git a/src/test/java/dev/openfeature/javasdk/integration/RunCucumberTest.java b/src/test/java/dev/openfeature/javasdk/integration/RunCucumberTest.java new file mode 100644 index 00000000..65c86c29 --- /dev/null +++ b/src/test/java/dev/openfeature/javasdk/integration/RunCucumberTest.java @@ -0,0 +1,16 @@ +package dev.openfeature.javasdk.integration; + +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.PLUGIN_PROPERTY_NAME; + +@Suite +@IncludeEngines("cucumber") +@SelectClasspathResource("features") +@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "pretty") +public class RunCucumberTest { + +} diff --git a/src/test/java/dev/openfeature/javasdk/integration/StepDefinitions.java b/src/test/java/dev/openfeature/javasdk/integration/StepDefinitions.java new file mode 100644 index 00000000..7cdea962 --- /dev/null +++ b/src/test/java/dev/openfeature/javasdk/integration/StepDefinitions.java @@ -0,0 +1,282 @@ +package dev.openfeature.javasdk.integration; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeFalse; + +import dev.openfeature.contrib.providers.flagd.FlagdProvider; +import dev.openfeature.javasdk.Client; +import dev.openfeature.javasdk.ErrorCode; +import dev.openfeature.javasdk.EvaluationContext; +import dev.openfeature.javasdk.FlagEvaluationDetails; +import dev.openfeature.javasdk.OpenFeatureAPI; +import dev.openfeature.javasdk.Reason; +import dev.openfeature.javasdk.Structure; +import dev.openfeature.javasdk.Value; +import io.cucumber.java.BeforeAll; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; + +public class StepDefinitions { + + private static Client client; + private boolean booleanFlagValue; + private String stringFlagValue; + private int intFlagValue; + private double doubleFlagValue; + private Value objectFlagValue; + + private FlagEvaluationDetails booleanFlagDetails; + private FlagEvaluationDetails stringFlagDetails; + private FlagEvaluationDetails intFlagDetails; + private FlagEvaluationDetails doubleFlagDetails; + private FlagEvaluationDetails objectFlagDetails; + + private String contextAwareFlagKey; + private String contextAwareDefaultValue; + private EvaluationContext context; + private String contextAwareValue; + + private String notFoundFlagKey; + private String notFoundDefaultValue; + private FlagEvaluationDetails notFoundDetails; + private String typeErrorFlagKey; + private int typeErrorDefaultValue; + private FlagEvaluationDetails typeErrorDetails; + + @BeforeAll() + public static void setup() { + OpenFeatureAPI.getInstance().setProvider(new FlagdProvider()); + client = OpenFeatureAPI.getInstance().getClient(); + } + + /* + * Basic evaluation + */ + + // 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) { + this.booleanFlagValue = client.getBooleanValue(flagKey, Boolean.valueOf(defaultValue)); + } + + @Then("the resolved boolean value should be {string}") + public void the_resolved_boolean_value_should_be_true(String expected) { + assertEquals(Boolean.valueOf(expected), this.booleanFlagValue); + } + + // string value + @When("a string flag with key {string} is evaluated with default value {string}") + public void a_string_flag_with_key_is_evaluated_with_default_value(String flagKey, String defaultValue) { + this.stringFlagValue = client.getStringValue(flagKey, defaultValue); + } + + @Then("the resolved string value should be {string}") + public void the_resolved_string_value_should_be(String expected) { + assertEquals(expected, this.stringFlagValue); + } + + // integer value + @When("an integer flag with key {string} is evaluated with default value {int}") + public void an_integer_flag_with_key_is_evaluated_with_default_value(String flagKey, Integer defaultValue) { + this.intFlagValue = client.getIntegerValue(flagKey, defaultValue); + } + + @Then("the resolved integer value should be {int}") + public void the_resolved_integer_value_should_be(int expected) { + assertEquals(expected, this.intFlagValue); + } + + // float/double value + @When("a float flag with key {string} is evaluated with default value {double}") + public void a_float_flag_with_key_is_evaluated_with_default_value(String flagKey, double defaultValue) { + this.doubleFlagValue = client.getDoubleValue(flagKey, defaultValue); + } + + @Then("the resolved float value should be {double}") + public void the_resolved_float_value_should_be(double expected) { + assertEquals(expected, this.doubleFlagValue); + } + + // object value + @When("an object flag with key {string} is evaluated with a null default value") + public void an_object_flag_with_key_is_evaluated_with_a_null_default_value(String flagKey) { + 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) { + Structure structure = this.objectFlagValue.asStructure(); + + assertEquals(Boolean.valueOf(boolValue), structure.asMap().get(boolField).asBoolean()); + assertEquals(stringValue, structure.asMap().get(stringField).asString()); + assertEquals(numberValue, structure.asMap().get(numberField).asInteger()); + } + + /* + * Detailed evaluation + */ + + // 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) { + 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}") + public void the_resolved_boolean_value_should_be_the_variant_should_be_and_the_reason_should_be( + String expectedValue, + String expectedVariant, String expectedReason) { + assertEquals(Boolean.valueOf(expectedValue), booleanFlagDetails.getValue()); + assertEquals(expectedVariant, booleanFlagDetails.getVariant()); + assertEquals(Reason.valueOf(expectedReason), booleanFlagDetails.getReason()); + } + + // 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) { + 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) { + assertEquals(expectedValue, this.stringFlagDetails.getValue()); + assertEquals(expectedVariant, this.stringFlagDetails.getVariant()); + assertEquals(Reason.valueOf(expectedReason), this.stringFlagDetails.getReason()); + } + + // integer details + @When("an integer flag with key {string} is evaluated with details and default value {int}") + public void an_integer_flag_with_key_is_evaluated_with_details_and_default_value(String flagKey, int defaultValue) { + 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) { + assertEquals(expectedValue, this.intFlagDetails.getValue()); + assertEquals(expectedVariant, this.intFlagDetails.getVariant()); + assertEquals(Reason.valueOf(expectedReason), this.intFlagDetails.getReason()); + } + + // float/double details + @When("a float flag with key {string} is evaluated with details and default value {double}") + public void a_float_flag_with_key_is_evaluated_with_details_and_default_value(String flagKey, double defaultValue) { + 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) { + assertEquals(expectedValue, this.doubleFlagDetails.getValue()); + assertEquals(expectedVariant, this.doubleFlagDetails.getVariant()); + assertEquals(Reason.valueOf(expectedReason), this.doubleFlagDetails.getReason()); + } + + // object details + @When("an object flag with key {string} is evaluated with details and a null default value") + public void an_object_flag_with_key_is_evaluated_with_details_and_a_null_default_value(String flagKey) { + 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") + 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) { + Structure structure = this.objectFlagDetails.getValue().asStructure(); + + assertEquals(Boolean.valueOf(boolValue), structure.asMap().get(boolField).asBoolean()); + assertEquals(stringValue, structure.asMap().get(stringField).asString()); + assertEquals(numberValue, structure.asMap().get(numberField).asInteger()); + } + + @Then("the variant should be {string}, and the reason should be {string}") + public void the_variant_should_be_and_the_reason_should_be(String expectedVariant, String expectedReason) { + assertEquals(expectedVariant, this.objectFlagDetails.getVariant()); + assertEquals(Reason.valueOf(expectedReason), this.objectFlagDetails.getReason()); + } + + /* + * 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) { + this.context = new EvaluationContext() + .add(field1, value1) + .add(field2, value2) + .add(field3, value3) + .add(field4, Boolean.valueOf(value4)); + } + + @When("a flag with key {string} is evaluated with default value {string}") + 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}") + public void the_resolved_string_response_should_be(String expected) { + assertEquals(expected, this.contextAwareValue); + } + + @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 EvaluationContext()); + assertEquals(expected, emptyContextValue); + } + + /* + * Errors + */ + + // 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) { + notFoundFlagKey = flagKey; + notFoundDefaultValue = defaultValue; + notFoundDetails = client.getStringDetails(notFoundFlagKey, notFoundDefaultValue); + } + + @Then("then the default string value should be returned") + public void then_the_default_string_value_should_be_returned() { + assertEquals(notFoundDefaultValue, notFoundDetails.getValue()); + } + + @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, notFoundDetails.getReason()); + assertTrue(notFoundDetails.getErrorCode().contains(errorCode)); + } + + // 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) { + typeErrorFlagKey = flagKey; + typeErrorDefaultValue = defaultValue; + typeErrorDetails = client.getIntegerDetails(typeErrorFlagKey, typeErrorDefaultValue); + } + + @Then("then the default integer value should be returned") + public void then_the_default_integer_value_should_be_returned() { + assertEquals(typeErrorDefaultValue, typeErrorDetails.getValue()); + } + + @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, typeErrorDetails.getReason()); + assertTrue(typeErrorDetails.getErrorCode().contains(errorCode)); + } + +} diff --git a/src/test/resources/features/.gitignore b/src/test/resources/features/.gitignore new file mode 100644 index 00000000..ce4de1a7 --- /dev/null +++ b/src/test/resources/features/.gitignore @@ -0,0 +1 @@ +evaluation.feature \ No newline at end of file diff --git a/src/test/resources/features/.gitkeep b/src/test/resources/features/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/test-harness b/test-harness new file mode 160000 index 00000000..e7379cd0 --- /dev/null +++ b/test-harness @@ -0,0 +1 @@ +Subproject commit e7379cd0070f8907cacdc535184f8f626bf25e01 From 37e767029187574f6a4e29aeae412f3f5cd032df Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 23 Sep 2022 09:35:31 -0400 Subject: [PATCH 02/63] chore(main): release dev.openfeature.javasdk 0.2.2 (#76) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ README.md | 4 ++-- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index e08ffd3c..9a316268 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"0.2.1"} \ No newline at end of file +{".":"0.2.2"} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 57980a7b..f025cfa8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [0.2.2](https://github.com/open-feature/java-sdk/compare/dev.openfeature.javasdk-v0.2.1...dev.openfeature.javasdk-v0.2.2) (2022-09-20) + + +### Features + +* Add asObjectMap to get the EvaluationContext as Map ([#75](https://github.com/open-feature/java-sdk/issues/75)) ([2eec1a5](https://github.com/open-feature/java-sdk/commit/2eec1a5519b9efab7d7f9dc8b1cbd84d9218368b)) + ## [0.2.1](https://github.com/open-feature/java-sdk/compare/dev.openfeature.javasdk-v0.2.0...dev.openfeature.javasdk-v0.2.1) (2022-09-13) diff --git a/README.md b/README.md index 6c84e96e..66c86044 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ class MyClass { dev.openfeature javasdk - 0.2.1 + 0.2.2 ``` @@ -90,7 +90,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:javasdk:0.2.1' + implementation 'dev.openfeature:javasdk:0.2.2' } ``` diff --git a/pom.xml b/pom.xml index 75c59410..e05e3cab 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ dev.openfeature javasdk - 0.2.1 + 0.2.2 UTF-8 diff --git a/version.txt b/version.txt index 0c62199f..ee1372d3 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.2.1 +0.2.2 From 82fe2e5f7ae14f8280955769b103f2d0e0e31e1b Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Fri, 30 Sep 2022 12:41:48 -0400 Subject: [PATCH 03/63] feat!: errorCode as enum, reason as string (#80) * feat!: errorCode as enum, reason as string - makes errorCode an enum - makes reason a string - adds errorMessage to resolution/evaluation details Signed-off-by: Bhandari, Pramesh(AWF) --- .github/workflows/pullrequest.yml | 2 +- README.md | 2 +- pom.xml | 1 + .../openfeature/javasdk/BaseEvaluation.java | 11 ++++++++-- .../dev/openfeature/javasdk/ErrorCode.java | 2 +- .../javasdk/FlagEvaluationDetails.java | 5 +++-- .../dev/openfeature/javasdk/NoOpProvider.java | 10 ++++----- .../javasdk/OpenFeatureClient.java | 10 +++++++-- .../javasdk/ProviderEvaluation.java | 5 +++-- .../javasdk/exceptions/FlagNotFoundError.java | 2 +- .../exceptions/InvalidContextError.java | 13 +++++++++++ .../exceptions/TargetingKeyMissingError.java | 13 +++++++++++ .../javasdk/AlwaysBrokenProvider.java | 14 +++++++----- .../javasdk/DeveloperExperienceTest.java | 5 +++-- .../javasdk/FlagEvaluationSpecTest.java | 12 +++++----- .../openfeature/javasdk/ProviderSpecTest.java | 11 +++++----- .../openfeature/javasdk/TestConstants.java | 5 +++++ .../javasdk/integration/StepDefinitions.java | 22 +++++++++---------- 18 files changed, 98 insertions(+), 47 deletions(-) create mode 100644 src/main/java/dev/openfeature/javasdk/exceptions/InvalidContextError.java create mode 100644 src/main/java/dev/openfeature/javasdk/exceptions/TargetingKeyMissingError.java create mode 100644 src/test/java/dev/openfeature/javasdk/TestConstants.java diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 8230ce59..84ebee9c 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -34,7 +34,7 @@ jobs: ${{ runner.os }}-maven- - name: Build with Maven - run: mvn --batch-mode --update-snapshots verify -P integration-test + run: mvn --batch-mode --update-snapshots verify # -P integration-test - add this back once we have a compatible flagd - name: Upload coverage to Codecov uses: codecov/codecov-action@v2 diff --git a/README.md b/README.md index 66c86044..b3232710 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.openfeature/javasdk/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.openfeature/javasdk) [![javadoc](https://javadoc.io/badge2/dev.openfeature/javasdk/javadoc.svg)](https://javadoc.io/doc/dev.openfeature/javasdk) [![Project Status: WIP – Initial development is in progress, but there has not yet been a stable, usable release suitable for the public.](https://www.repostatus.org/badges/latest/wip.svg)](https://www.repostatus.org/#wip) -[![Specification](https://img.shields.io/static/v1?label=Specification&message=v0.4.0&color=yellow)](https://github.com/open-feature/spec/tree/v0.4.0) +[![Specification](https://img.shields.io/static/v1?label=Specification&message=v0.5.0&color=yellow)](https://github.com/open-feature/spec/tree/v0.5.0) [![Known Vulnerabilities](https://snyk.io/test/github/open-feature/java-sdk/badge.svg)](https://snyk.io/test/github/open-feature/java-sdk) [![on-merge](https://github.com/open-feature/java-sdk/actions/workflows/merge.yml/badge.svg)](https://github.com/open-feature/java-sdk/actions/workflows/merge.yml) [![codecov](https://codecov.io/gh/open-feature/java-sdk/branch/main/graph/badge.svg?token=XMS9L7PBY1)](https://codecov.io/gh/open-feature/java-sdk) diff --git a/pom.xml b/pom.xml index e05e3cab..1be3d653 100644 --- a/pom.xml +++ b/pom.xml @@ -141,6 +141,7 @@ dev.openfeature.contrib.providers flagd + 0.3.2 test diff --git a/src/main/java/dev/openfeature/javasdk/BaseEvaluation.java b/src/main/java/dev/openfeature/javasdk/BaseEvaluation.java index d07da854..f0524e06 100644 --- a/src/main/java/dev/openfeature/javasdk/BaseEvaluation.java +++ b/src/main/java/dev/openfeature/javasdk/BaseEvaluation.java @@ -21,11 +21,18 @@ public interface BaseEvaluation { * Describes how we came to the value that we're returning. * @return {Reason} */ - Reason getReason(); + String getReason(); /** * The error code, if applicable. Should only be set when the Reason is ERROR. * @return {ErrorCode} */ - String getErrorCode(); + ErrorCode getErrorCode(); + + /** + * 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/javasdk/ErrorCode.java b/src/main/java/dev/openfeature/javasdk/ErrorCode.java index 9b0c74d7..7b54ce56 100644 --- a/src/main/java/dev/openfeature/javasdk/ErrorCode.java +++ b/src/main/java/dev/openfeature/javasdk/ErrorCode.java @@ -1,5 +1,5 @@ package dev.openfeature.javasdk; public enum ErrorCode { - PROVIDER_NOT_READY, FLAG_NOT_FOUND, PARSE_ERROR, TYPE_MISMATCH, GENERAL + PROVIDER_NOT_READY, FLAG_NOT_FOUND, PARSE_ERROR, TYPE_MISMATCH, TARGETING_KEY_MISSING, INVALID_CONTEXT, GENERAL } diff --git a/src/main/java/dev/openfeature/javasdk/FlagEvaluationDetails.java b/src/main/java/dev/openfeature/javasdk/FlagEvaluationDetails.java index 2c5c25ec..0440cf5b 100644 --- a/src/main/java/dev/openfeature/javasdk/FlagEvaluationDetails.java +++ b/src/main/java/dev/openfeature/javasdk/FlagEvaluationDetails.java @@ -14,8 +14,9 @@ public class FlagEvaluationDetails implements BaseEvaluation { private String flagKey; private T value; @Nullable private String variant; - private Reason reason; - @Nullable private String errorCode; + @Nullable private String reason; + private ErrorCode errorCode; + @Nullable private String errorMessage; /** * Generate detail payload from the provider response. diff --git a/src/main/java/dev/openfeature/javasdk/NoOpProvider.java b/src/main/java/dev/openfeature/javasdk/NoOpProvider.java index ad3c1c98..ef7dccd7 100644 --- a/src/main/java/dev/openfeature/javasdk/NoOpProvider.java +++ b/src/main/java/dev/openfeature/javasdk/NoOpProvider.java @@ -25,7 +25,7 @@ public ProviderEvaluation getBooleanEvaluation(String key, Boolean defa return ProviderEvaluation.builder() .value(defaultValue) .variant(PASSED_IN_DEFAULT) - .reason(Reason.DEFAULT) + .reason(Reason.DEFAULT.toString()) .build(); } @@ -34,7 +34,7 @@ public ProviderEvaluation getStringEvaluation(String key, String default return ProviderEvaluation.builder() .value(defaultValue) .variant(PASSED_IN_DEFAULT) - .reason(Reason.DEFAULT) + .reason(Reason.DEFAULT.toString()) .build(); } @@ -43,7 +43,7 @@ public ProviderEvaluation getIntegerEvaluation(String key, Integer defa return ProviderEvaluation.builder() .value(defaultValue) .variant(PASSED_IN_DEFAULT) - .reason(Reason.DEFAULT) + .reason(Reason.DEFAULT.toString()) .build(); } @@ -52,7 +52,7 @@ public ProviderEvaluation getDoubleEvaluation(String key, Double default return ProviderEvaluation.builder() .value(defaultValue) .variant(PASSED_IN_DEFAULT) - .reason(Reason.DEFAULT) + .reason(Reason.DEFAULT.toString()) .build(); } @@ -62,7 +62,7 @@ public ProviderEvaluation getObjectEvaluation(String key, Value defaultVa return ProviderEvaluation.builder() .value(defaultValue) .variant(PASSED_IN_DEFAULT) - .reason(Reason.DEFAULT) + .reason(Reason.DEFAULT.toString()) .build(); } } diff --git a/src/main/java/dev/openfeature/javasdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/javasdk/OpenFeatureClient.java index 44c43396..361e8bc3 100644 --- a/src/main/java/dev/openfeature/javasdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/javasdk/OpenFeatureClient.java @@ -7,6 +7,7 @@ import java.util.Map; import dev.openfeature.javasdk.exceptions.GeneralError; +import dev.openfeature.javasdk.exceptions.OpenFeatureError; import dev.openfeature.javasdk.internal.ObjectUtils; import lombok.Getter; import lombok.Setter; @@ -94,9 +95,14 @@ private FlagEvaluationDetails evaluateFlag(FlagValueType type, String key if (details == null) { details = FlagEvaluationDetails.builder().build(); } + if (e instanceof OpenFeatureError) { + details.setErrorCode(((OpenFeatureError)e).getErrorCode()); + } else { + details.setErrorCode(ErrorCode.GENERAL); + } + details.setErrorMessage(e.getMessage()); details.setValue(defaultValue); - details.setReason(Reason.ERROR); - details.setErrorCode(e.getMessage()); + details.setReason(Reason.ERROR.toString()); hookSupport.errorHooks(type, hookCtx, e, mergedHooks, hints); } finally { hookSupport.afterAllHooks(type, hookCtx, mergedHooks, hints); diff --git a/src/main/java/dev/openfeature/javasdk/ProviderEvaluation.java b/src/main/java/dev/openfeature/javasdk/ProviderEvaluation.java index e2d884cd..df939134 100644 --- a/src/main/java/dev/openfeature/javasdk/ProviderEvaluation.java +++ b/src/main/java/dev/openfeature/javasdk/ProviderEvaluation.java @@ -9,6 +9,7 @@ public class ProviderEvaluation implements BaseEvaluation { T value; @Nullable String variant; - Reason reason; - @Nullable String errorCode; + @Nullable private String reason; + ErrorCode errorCode; + @Nullable private String errorMessage; } diff --git a/src/main/java/dev/openfeature/javasdk/exceptions/FlagNotFoundError.java b/src/main/java/dev/openfeature/javasdk/exceptions/FlagNotFoundError.java index 6aa2d7ed..c91971ae 100644 --- a/src/main/java/dev/openfeature/javasdk/exceptions/FlagNotFoundError.java +++ b/src/main/java/dev/openfeature/javasdk/exceptions/FlagNotFoundError.java @@ -7,5 +7,5 @@ @StandardException public class FlagNotFoundError extends OpenFeatureError { private static final long serialVersionUID = 1L; - @Getter private final ErrorCode errorCode = ErrorCode.GENERAL; + @Getter private final ErrorCode errorCode = ErrorCode.FLAG_NOT_FOUND; } diff --git a/src/main/java/dev/openfeature/javasdk/exceptions/InvalidContextError.java b/src/main/java/dev/openfeature/javasdk/exceptions/InvalidContextError.java new file mode 100644 index 00000000..e8487054 --- /dev/null +++ b/src/main/java/dev/openfeature/javasdk/exceptions/InvalidContextError.java @@ -0,0 +1,13 @@ +package dev.openfeature.javasdk.exceptions; + +import dev.openfeature.javasdk.ErrorCode; +import lombok.Getter; +import lombok.experimental.StandardException; + +@StandardException +public class InvalidContextError extends OpenFeatureError { + private static final long serialVersionUID = 1L; + + @Getter private final ErrorCode errorCode = ErrorCode.INVALID_CONTEXT; + +} diff --git a/src/main/java/dev/openfeature/javasdk/exceptions/TargetingKeyMissingError.java b/src/main/java/dev/openfeature/javasdk/exceptions/TargetingKeyMissingError.java new file mode 100644 index 00000000..7e914d29 --- /dev/null +++ b/src/main/java/dev/openfeature/javasdk/exceptions/TargetingKeyMissingError.java @@ -0,0 +1,13 @@ +package dev.openfeature.javasdk.exceptions; + +import dev.openfeature.javasdk.ErrorCode; +import lombok.Getter; +import lombok.experimental.StandardException; + +@StandardException +public class TargetingKeyMissingError extends OpenFeatureError { + private static final long serialVersionUID = 1L; + + @Getter private final ErrorCode errorCode = ErrorCode.TARGETING_KEY_MISSING; + +} diff --git a/src/test/java/dev/openfeature/javasdk/AlwaysBrokenProvider.java b/src/test/java/dev/openfeature/javasdk/AlwaysBrokenProvider.java index f69a1400..044f3ce7 100644 --- a/src/test/java/dev/openfeature/javasdk/AlwaysBrokenProvider.java +++ b/src/test/java/dev/openfeature/javasdk/AlwaysBrokenProvider.java @@ -1,39 +1,41 @@ package dev.openfeature.javasdk; +import dev.openfeature.javasdk.exceptions.FlagNotFoundError; public class AlwaysBrokenProvider implements FeatureProvider { + @Override public Metadata getMetadata() { return new Metadata() { @Override public String getName() { - throw new NotImplementedException("BORK"); + throw new FlagNotFoundError(TestConstants.BROKEN_MESSAGE); } }; } @Override public ProviderEvaluation getBooleanEvaluation(String key, Boolean defaultValue, EvaluationContext ctx) { - throw new NotImplementedException("BORK"); + throw new FlagNotFoundError(TestConstants.BROKEN_MESSAGE); } @Override public ProviderEvaluation getStringEvaluation(String key, String defaultValue, EvaluationContext ctx) { - throw new NotImplementedException("BORK"); + throw new FlagNotFoundError(TestConstants.BROKEN_MESSAGE); } @Override public ProviderEvaluation getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx) { - throw new NotImplementedException("BORK"); + throw new FlagNotFoundError(TestConstants.BROKEN_MESSAGE); } @Override public ProviderEvaluation getDoubleEvaluation(String key, Double defaultValue, EvaluationContext ctx) { - throw new NotImplementedException("BORK"); + throw new FlagNotFoundError(TestConstants.BROKEN_MESSAGE); } @Override public ProviderEvaluation getObjectEvaluation(String key, Value defaultValue, EvaluationContext invocationContext) { - throw new NotImplementedException("BORK"); + throw new FlagNotFoundError(TestConstants.BROKEN_MESSAGE); } } diff --git a/src/test/java/dev/openfeature/javasdk/DeveloperExperienceTest.java b/src/test/java/dev/openfeature/javasdk/DeveloperExperienceTest.java index 3e238e31..abd1d95a 100644 --- a/src/test/java/dev/openfeature/javasdk/DeveloperExperienceTest.java +++ b/src/test/java/dev/openfeature/javasdk/DeveloperExperienceTest.java @@ -85,8 +85,9 @@ class DeveloperExperienceTest implements HookFixtures { api.setProvider(new AlwaysBrokenProvider()); Client client = api.getClient(); FlagEvaluationDetails retval = client.getBooleanDetails(flagKey, false); - assertEquals("BORK", retval.getErrorCode()); - assertEquals(Reason.ERROR, retval.getReason()); + assertEquals(ErrorCode.FLAG_NOT_FOUND, retval.getErrorCode()); + assertEquals(TestConstants.BROKEN_MESSAGE, retval.getErrorMessage()); + assertEquals(Reason.ERROR.toString(), retval.getReason()); assertFalse(retval.getValue()); } } diff --git a/src/test/java/dev/openfeature/javasdk/FlagEvaluationSpecTest.java b/src/test/java/dev/openfeature/javasdk/FlagEvaluationSpecTest.java index 2efeec12..f2ef69df 100644 --- a/src/test/java/dev/openfeature/javasdk/FlagEvaluationSpecTest.java +++ b/src/test/java/dev/openfeature/javasdk/FlagEvaluationSpecTest.java @@ -183,14 +183,16 @@ private Client _client() { } @Specification(number="1.4.9", 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.7", text="In cases of abnormal execution, the evaluation details structure's error code field MUST contain a string identifying an error occurred during flag evaluation and the nature of the error.") + @Specification(number="1.4.7", text="In cases of abnormal execution, the `evaluation details` structure's `error code` field **MUST** contain an `error code`.") + @Specification(number="1.4.12", 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() { OpenFeatureAPI api = OpenFeatureAPI.getInstance(); api.setProvider(new AlwaysBrokenProvider()); Client c = api.getClient(); assertFalse(c.getBooleanValue("key", false)); FlagEvaluationDetails details = c.getBooleanDetails("key", false); - assertEquals("BORK", details.getErrorCode()); + assertEquals(ErrorCode.FLAG_NOT_FOUND, details.getErrorCode()); + assertEquals(TestConstants.BROKEN_MESSAGE, details.getErrorMessage()); } @Specification(number="1.4.10", text="In the case of abnormal execution, the client SHOULD log an informative error message.") @@ -200,8 +202,8 @@ private Client _client() { api.setProvider(new AlwaysBrokenProvider()); Client c = api.getClient(); FlagEvaluationDetails result = c.getBooleanDetails("test", false); - assertEquals(Reason.ERROR, result.getReason()); - assertThat(TEST_LOGGER.getLoggingEvents()).contains(LoggingEvent.error("Unable to correctly evaluate flag with key {} due to exception {}", "test", "BORK")); + assertEquals(Reason.ERROR.toString(), result.getReason()); + assertThat(TEST_LOGGER.getLoggingEvents()).contains(LoggingEvent.error("Unable to correctly evaluate flag with key {} due to exception {}", "test", TestConstants.BROKEN_MESSAGE)); } @Specification(number="1.2.2", text="The client interface MUST define a metadata member or accessor, containing an immutable name field or accessor of type string, which corresponds to the name value supplied during client creation.") @@ -221,7 +223,7 @@ private Client _client() { api.setProvider(new AlwaysBrokenProvider()); Client c = api.getClient(); FlagEvaluationDetails result = c.getBooleanDetails("test", false); - assertEquals(Reason.ERROR, result.getReason()); + assertEquals(Reason.ERROR.toString(), result.getReason()); } @Specification(number="3.2.1", text="The API, Client and invocation MUST have a method for supplying evaluation context.") diff --git a/src/test/java/dev/openfeature/javasdk/ProviderSpecTest.java b/src/test/java/dev/openfeature/javasdk/ProviderSpecTest.java index b5d0c587..846d0d48 100644 --- a/src/test/java/dev/openfeature/javasdk/ProviderSpecTest.java +++ b/src/test/java/dev/openfeature/javasdk/ProviderSpecTest.java @@ -41,11 +41,10 @@ public class ProviderSpecTest { } - @Specification(number="2.6", text="The provider SHOULD populate the flag resolution structure's " + - "reason field with a string indicating the semantic reason for the returned flag value.") + @Specification(number="2.6", text="The `provider` SHOULD populate the `flag resolution` structure's `reason` field with `\"DEFAULT\",` `\"TARGETING_MATCH\"`, `\"SPLIT\"`, `\"DISABLED\"`, `\"UNKNOWN\"`, `\"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 EvaluationContext()); - assertEquals(Reason.DEFAULT, result.getReason()); + assertEquals(Reason.DEFAULT.toString(), result.getReason()); } @Specification(number="2.7", text="In cases of normal execution, the provider MUST NOT populate " + @@ -55,9 +54,9 @@ public class ProviderSpecTest { assertNull(result.getErrorCode()); } - @Specification(number="2.8", text="In cases of abnormal execution, the provider MUST indicate an " + - "error using the idioms of the implementation language, with an associated error code having possible " + - "values PROVIDER_NOT_READY, FLAG_NOT_FOUND, PARSE_ERROR, TYPE_MISMATCH, or GENERAL.") + @Specification(number="2.8", 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.11", text="In cases of normal execution, the `provider` **MUST NOT** populate the `flag resolution` structure's `error message` field, or otherwise must populate it with a null or falsy value.") + @Specification(number="2.12", text="In cases of abnormal execution, the `evaluation 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() {} @Specification(number="2.5", text="In cases of normal execution, the provider SHOULD populate the " + diff --git a/src/test/java/dev/openfeature/javasdk/TestConstants.java b/src/test/java/dev/openfeature/javasdk/TestConstants.java new file mode 100644 index 00000000..945c32f6 --- /dev/null +++ b/src/test/java/dev/openfeature/javasdk/TestConstants.java @@ -0,0 +1,5 @@ +package dev.openfeature.javasdk; + +public class TestConstants { + public static final String BROKEN_MESSAGE = "This is borked."; +} diff --git a/src/test/java/dev/openfeature/javasdk/integration/StepDefinitions.java b/src/test/java/dev/openfeature/javasdk/integration/StepDefinitions.java index 7cdea962..a7d9f91e 100644 --- a/src/test/java/dev/openfeature/javasdk/integration/StepDefinitions.java +++ b/src/test/java/dev/openfeature/javasdk/integration/StepDefinitions.java @@ -2,11 +2,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assumptions.assumeFalse; import dev.openfeature.contrib.providers.flagd.FlagdProvider; import dev.openfeature.javasdk.Client; -import dev.openfeature.javasdk.ErrorCode; import dev.openfeature.javasdk.EvaluationContext; import dev.openfeature.javasdk.FlagEvaluationDetails; import dev.openfeature.javasdk.OpenFeatureAPI; @@ -132,7 +130,7 @@ public void the_resolved_boolean_value_should_be_the_variant_should_be_and_the_r String expectedVariant, String expectedReason) { assertEquals(Boolean.valueOf(expectedValue), booleanFlagDetails.getValue()); assertEquals(expectedVariant, booleanFlagDetails.getVariant()); - assertEquals(Reason.valueOf(expectedReason), booleanFlagDetails.getReason()); + assertEquals(expectedReason, booleanFlagDetails.getReason()); } // string details @@ -147,7 +145,7 @@ public void the_resolved_string_value_should_be_the_variant_should_be_and_the_re String expectedVariant, String expectedReason) { assertEquals(expectedValue, this.stringFlagDetails.getValue()); assertEquals(expectedVariant, this.stringFlagDetails.getVariant()); - assertEquals(Reason.valueOf(expectedReason), this.stringFlagDetails.getReason()); + assertEquals(expectedReason, this.stringFlagDetails.getReason()); } // integer details @@ -161,7 +159,7 @@ public void the_resolved_integer_value_should_be_the_variant_should_be_and_the_r String expectedVariant, String expectedReason) { assertEquals(expectedValue, this.intFlagDetails.getValue()); assertEquals(expectedVariant, this.intFlagDetails.getVariant()); - assertEquals(Reason.valueOf(expectedReason), this.intFlagDetails.getReason()); + assertEquals(expectedReason, this.intFlagDetails.getReason()); } // float/double details @@ -175,7 +173,7 @@ public void the_resolved_float_value_should_be_the_variant_should_be_and_the_rea String expectedVariant, String expectedReason) { assertEquals(expectedValue, this.doubleFlagDetails.getValue()); assertEquals(expectedVariant, this.doubleFlagDetails.getVariant()); - assertEquals(Reason.valueOf(expectedReason), this.doubleFlagDetails.getReason()); + assertEquals(expectedReason, this.doubleFlagDetails.getReason()); } // object details @@ -198,7 +196,7 @@ public void the_resolved_object_value_should_be_contain_fields_and_with_values_a @Then("the variant should be {string}, and the reason should be {string}") public void the_variant_should_be_and_the_reason_should_be(String expectedVariant, String expectedReason) { assertEquals(expectedVariant, this.objectFlagDetails.getVariant()); - assertEquals(Reason.valueOf(expectedReason), this.objectFlagDetails.getReason()); + assertEquals(expectedReason, this.objectFlagDetails.getReason()); } /* @@ -255,8 +253,9 @@ 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, notFoundDetails.getReason()); - assertTrue(notFoundDetails.getErrorCode().contains(errorCode)); + assertEquals(Reason.ERROR.toString(), notFoundDetails.getReason()); + assertTrue(notFoundDetails.getErrorMessage().contains(errorCode)); + // TODO: add errorCode assertion once flagd provider is updated. } // type mismatch @@ -275,8 +274,9 @@ 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, typeErrorDetails.getReason()); - assertTrue(typeErrorDetails.getErrorCode().contains(errorCode)); + assertEquals(Reason.ERROR.toString(), typeErrorDetails.getReason()); + assertTrue(typeErrorDetails.getErrorMessage().contains(errorCode)); + // TODO: add errorCode assertion once flagd provider is updated. } } From fe9f22bb86d0d0170d5cd2c7b3a450b0d11af5d7 Mon Sep 17 00:00:00 2001 From: Justin Abrahms Date: Fri, 30 Sep 2022 19:35:33 -0700 Subject: [PATCH 04/63] chore: add CODEOWNERS (#85) Create CODEOWNERS refs https://github.com/open-feature/java-sdk/issues/83 Signed-off-by: Justin Abrahms Signed-off-by: Justin Abrahms Signed-off-by: Bhandari, Pramesh(AWF) --- CODEOWNERS | 1 + 1 file changed, 1 insertion(+) create mode 100644 CODEOWNERS diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 00000000..07c3c7b0 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1 @@ +@open-feature/java-maintainers From ec80de973850537d3a3bcdf60876f4194cc8cbf1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Oct 2022 02:38:43 +0000 Subject: [PATCH 05/63] chore: Configure Renovate (#86) chore(deps): add renovate.json Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- renovate.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 renovate.json diff --git a/renovate.json b/renovate.json new file mode 100644 index 00000000..39a2b6e9 --- /dev/null +++ b/renovate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:base" + ] +} From 982ca5f970ba776ac1aed018032295b9f9149b82 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 30 Sep 2022 22:48:17 -0700 Subject: [PATCH 06/63] chore(deps): update dependency com.github.spotbugs:spotbugs to v4.7.2 (#87) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 1be3d653..b4275703 100644 --- a/pom.xml +++ b/pom.xml @@ -52,7 +52,7 @@ com.github.spotbugs spotbugs - 4.7.1 + 4.7.2 compile @@ -390,7 +390,7 @@ com.github.spotbugs spotbugs - 4.7.1 + 4.7.2 From 8f0ffe5de274adfaced73add395c58f92510f0da Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Oct 2022 05:49:51 +0000 Subject: [PATCH 07/63] chore(deps): update dependency com.github.spotbugs:spotbugs-maven-plugin to v4.7.2.0 (#88) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b4275703..b241cee2 100644 --- a/pom.xml +++ b/pom.xml @@ -374,7 +374,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.7.0.0 + 4.7.2.0 spotbugs-exclusions.xml From 98fd93224090f2480d4002180543a22bd60b5559 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 30 Sep 2022 22:55:20 -0700 Subject: [PATCH 08/63] chore(deps): update dependency org.apache.maven.plugins:maven-javadoc-plugin to v3.4.1 (#90) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b241cee2..34f307d8 100644 --- a/pom.xml +++ b/pom.xml @@ -324,7 +324,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.4.0 + 3.4.1 true From b2c7e21f72a71d0fa4b9e054fe644039613b5fae Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Oct 2022 05:57:00 +0000 Subject: [PATCH 09/63] chore(deps): update dependency org.sonatype.plugins:nexus-staging-maven-plugin to v1.6.13 (#91) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 34f307d8..f2dbfeb8 100644 --- a/pom.xml +++ b/pom.xml @@ -296,7 +296,7 @@ org.sonatype.plugins nexus-staging-maven-plugin - 1.6.7 + 1.6.13 true ossrh From 9aa82138b568df88f0587c24be15ce4cee06105f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Oct 2022 08:42:05 -0700 Subject: [PATCH 10/63] fix(deps): update junit5 monorepo (#92) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index f2dbfeb8..f1e00406 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ UTF-8 1.8 ${maven.compiler.source} - 5.8.1 + 5.9.1 **/integration/*.java @@ -115,7 +115,7 @@ org.junit.platform junit-platform-suite - 1.9.0 + 1.9.1 test @@ -162,7 +162,7 @@ org.junit junit-bom - 5.9.0 + 5.9.1 pom import From 4e0e3769b9012a204c45750c31320b211930300e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Oct 2022 15:43:54 +0000 Subject: [PATCH 11/63] chore(deps): update dependency org.apache.maven.plugins:maven-pmd-plugin to v3.19.0 (#97) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f1e00406..0b9f10e3 100644 --- a/pom.xml +++ b/pom.xml @@ -359,7 +359,7 @@ org.apache.maven.plugins maven-pmd-plugin - 3.13.0 + 3.19.0 run-pmd From c06bae2058eb4171ca03fcc7da96597bfa360cb0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Oct 2022 14:01:13 -0700 Subject: [PATCH 12/63] fix(deps): update dependency io.cucumber:cucumber-bom to v7.8.0 (#100) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0b9f10e3..685a32ef 100644 --- a/pom.xml +++ b/pom.xml @@ -154,7 +154,7 @@ io.cucumber cucumber-bom - 7.5.0 + 7.8.0 pom import From df24b820b713cb5468d9efdfcb468920e6dfdfcc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Oct 2022 14:28:47 -0700 Subject: [PATCH 13/63] chore(deps): update dependency org.mockito:mockito-core to v4.8.0 (#99) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 685a32ef..666a255f 100644 --- a/pom.xml +++ b/pom.xml @@ -66,7 +66,7 @@ org.mockito mockito-core - 4.6.1 + 4.8.0 test From d6851a75167eb4d040334d6bc9de2d079c8d9b0b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Oct 2022 15:27:22 -0700 Subject: [PATCH 14/63] chore(deps): update codecov/codecov-action action to v3 (#102) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- .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 44a32e48..4481d77b 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@v2 + uses: codecov/codecov-action@v3 with: flags: unittests # optional name: coverage # optional diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 84ebee9c..08a8bca4 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -37,7 +37,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify # -P integration-test - add this back once we have a compatible flagd - name: Upload coverage to Codecov - uses: codecov/codecov-action@v2 + uses: codecov/codecov-action@v3 with: flags: unittests # optional name: coverage # optional From 7a69afa9cac9685217c9ffac28fdf8090bae9410 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Oct 2022 22:28:51 +0000 Subject: [PATCH 15/63] chore(deps): update dependency org.apache.maven.plugins:maven-gpg-plugin to v1.6 (#96) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Justin Abrahms Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 666a255f..376675eb 100644 --- a/pom.xml +++ b/pom.xml @@ -343,7 +343,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.5 + 1.6 sign-artifacts From c06ba6ae2f8c8e5255dd7e16e791ca82d9e0664b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Oct 2022 19:50:45 -0700 Subject: [PATCH 16/63] chore(deps): update dependency org.apache.maven.plugins:maven-source-plugin to v3 (#105) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 376675eb..d16337ce 100644 --- a/pom.xml +++ b/pom.xml @@ -310,7 +310,7 @@ org.apache.maven.plugins maven-source-plugin - 2.2.1 + 3.2.1 attach-sources From e1fb35eb82d5a8f3d5e382787ac15aafc0aa1967 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Oct 2022 19:52:18 -0700 Subject: [PATCH 17/63] chore(deps): update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.10.1 (#95) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d16337ce..11444c62 100644 --- a/pom.xml +++ b/pom.xml @@ -203,7 +203,7 @@ maven-compiler-plugin - 3.8.1 + 3.10.1 From d03aae869fea497c5f26e1b85533bfabea7a26c2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Oct 2022 20:47:44 -0700 Subject: [PATCH 18/63] chore(deps): update dependency org.apache.maven.plugins:maven-gpg-plugin to v3 (#104) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 11444c62..59fcd4c8 100644 --- a/pom.xml +++ b/pom.xml @@ -343,7 +343,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.6 + 3.0.1 sign-artifacts From 8119817e050981aa07ec8381cacfee7b2038bf02 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Oct 2022 20:58:59 -0700 Subject: [PATCH 19/63] chore(deps): update dependency org.apache.maven.plugins:maven-checkstyle-plugin to v3.2.0 (#94) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 59fcd4c8..7c15cec3 100644 --- a/pom.xml +++ b/pom.xml @@ -407,7 +407,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.1.2 + 3.2.0 checkstyle.xml UTF-8 From 02e2e519f5e15d9f5bff59c89a3b14505ab10721 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Oct 2022 21:11:09 -0700 Subject: [PATCH 20/63] chore(deps): update actions/cache action to v3 (#101) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- .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 4481d77b..ed30bdbf 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@v2 + uses: actions/cache@v3 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 08a8bca4..3b7430a0 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -26,7 +26,7 @@ jobs: cache: maven - name: Cache local Maven repository - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} From a7acae2ab3aa21ee6493c6cc69bf4c0c02ab86ad Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Oct 2022 21:40:12 -0700 Subject: [PATCH 21/63] chore(deps): update dependency com.puppycrawl.tools:checkstyle to v8.45.1 (#93) * chore(deps): update dependency com.puppycrawl.tools:checkstyle to v8.45.1 * scope property went away in the latest version https://github.com/jshiell/checkstyle-idea/issues/525#issuecomment-832084505 Signed-off-by: Justin Abrahms * scope wasn't deleted on the other one Signed-off-by: Justin Abrahms Signed-off-by: Justin Abrahms Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Justin Abrahms Signed-off-by: Bhandari, Pramesh(AWF) --- checkstyle.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/checkstyle.xml b/checkstyle.xml index 9e524577..a52e1bf7 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -280,7 +280,7 @@ value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/> - + diff --git a/pom.xml b/pom.xml index 7c15cec3..7d9cae27 100644 --- a/pom.xml +++ b/pom.xml @@ -419,7 +419,7 @@ com.puppycrawl.tools checkstyle - 8.31 + 8.45.1 From f177f92f20045ac0c803878f632fd484d3343dbb Mon Sep 17 00:00:00 2001 From: Justin Abrahms Date: Wed, 5 Oct 2022 11:46:04 -0700 Subject: [PATCH 22/63] refactor!: Change the package name. Everyone knows it's java (or it doesn't matter) (#111) * Change the package name. Everyone knows it's java (or it doesn't matter) Fixes #82 Signed-off-by: Justin Abrahms * Missed 2 strings Signed-off-by: Justin Abrahms * remove broken flagd import until changes absorbed Signed-off-by: Todd Baert Signed-off-by: Justin Abrahms Signed-off-by: Todd Baert Co-authored-by: Todd Baert Signed-off-by: Bhandari, Pramesh(AWF) --- README.md | 10 +++++----- pom.xml | 13 ++---------- release-please-config.json | 4 ++-- spotbugs-exclusions.xml | 6 +++--- .../{javasdk => sdk}/BaseEvaluation.java | 2 +- .../{javasdk => sdk}/BooleanHook.java | 2 +- .../openfeature/{javasdk => sdk}/Client.java | 2 +- .../{javasdk => sdk}/DoubleHook.java | 2 +- .../{javasdk => sdk}/ErrorCode.java | 2 +- .../{javasdk => sdk}/EvaluationContext.java | 2 +- .../{javasdk => sdk}/FeatureProvider.java | 2 +- .../{javasdk => sdk}/Features.java | 2 +- .../FlagEvaluationDetails.java | 2 +- .../FlagEvaluationOptions.java | 2 +- .../{javasdk => sdk}/FlagValueType.java | 2 +- .../openfeature/{javasdk => sdk}/Hook.java | 2 +- .../{javasdk => sdk}/HookContext.java | 2 +- .../{javasdk => sdk}/HookSupport.java | 2 +- .../{javasdk => sdk}/IntegerHook.java | 2 +- .../{javasdk => sdk}/Metadata.java | 2 +- .../{javasdk => sdk}/NoOpProvider.java | 2 +- .../{javasdk => sdk}/OpenFeatureAPI.java | 2 +- .../{javasdk => sdk}/OpenFeatureClient.java | 8 ++++---- .../{javasdk => sdk}/ProviderEvaluation.java | 2 +- .../openfeature/{javasdk => sdk}/Reason.java | 2 +- .../{javasdk => sdk}/StringHook.java | 2 +- .../{javasdk => sdk}/Structure.java | 4 ++-- .../openfeature/{javasdk => sdk}/Value.java | 2 +- .../exceptions/FlagNotFoundError.java | 4 ++-- .../exceptions/GeneralError.java | 4 ++-- .../exceptions/InvalidContextError.java | 4 ++-- .../exceptions/OpenFeatureError.java | 4 ++-- .../exceptions/ParseError.java | 4 ++-- .../exceptions/TargetingKeyMissingError.java | 4 ++-- .../exceptions/TypeMismatchError.java | 4 ++-- .../exceptions/ValueNotConvertableError.java | 4 ++-- .../internal/ObjectUtils.java | 2 +- .../AlwaysBrokenProvider.java | 4 ++-- .../DeveloperExperienceTest.java | 4 ++-- .../{javasdk => sdk}/DoSomethingProvider.java | 2 +- .../{javasdk => sdk}/EvalContextTest.java | 2 +- .../FlagEvaluationSpecTest.java | 4 ++-- .../{javasdk => sdk}/HookContextTest.java | 2 +- .../{javasdk => sdk}/HookSpecTest.java | 4 ++-- .../{javasdk => sdk}/HookSupportTest.java | 4 ++-- .../{javasdk => sdk}/MetadataTest.java | 2 +- .../{javasdk => sdk}/NoOpProviderTest.java | 2 +- .../NotImplementedException.java | 2 +- .../OpenFeatureClientTest.java | 4 ++-- .../{javasdk => sdk}/ProviderSpecTest.java | 2 +- .../{javasdk => sdk}/Specification.java | 2 +- .../{javasdk => sdk}/Specifications.java | 2 +- .../{javasdk => sdk}/StructureTest.java | 2 +- .../{javasdk => sdk}/TestConstants.java | 2 +- .../{javasdk => sdk}/ValueTest.java | 2 +- .../fixtures/HookFixtures.java | 4 ++-- .../integration/RunCucumberTest.java | 2 +- .../integration/StepDefinitions.java | 20 +++++++++---------- .../internal/ObjectUtilsTest.java | 4 ++-- 59 files changed, 96 insertions(+), 105 deletions(-) rename src/main/java/dev/openfeature/{javasdk => sdk}/BaseEvaluation.java (96%) rename src/main/java/dev/openfeature/{javasdk => sdk}/BooleanHook.java (86%) rename src/main/java/dev/openfeature/{javasdk => sdk}/Client.java (96%) rename src/main/java/dev/openfeature/{javasdk => sdk}/DoubleHook.java (85%) rename src/main/java/dev/openfeature/{javasdk => sdk}/ErrorCode.java (81%) rename src/main/java/dev/openfeature/{javasdk => sdk}/EvaluationContext.java (99%) rename src/main/java/dev/openfeature/{javasdk => sdk}/FeatureProvider.java (96%) rename src/main/java/dev/openfeature/{javasdk => sdk}/Features.java (99%) rename src/main/java/dev/openfeature/{javasdk => sdk}/FlagEvaluationDetails.java (97%) rename src/main/java/dev/openfeature/{javasdk => sdk}/FlagEvaluationOptions.java (89%) rename src/main/java/dev/openfeature/{javasdk => sdk}/FlagValueType.java (70%) rename src/main/java/dev/openfeature/{javasdk => sdk}/Hook.java (98%) rename src/main/java/dev/openfeature/{javasdk => sdk}/HookContext.java (97%) rename src/main/java/dev/openfeature/{javasdk => sdk}/HookSupport.java (99%) rename src/main/java/dev/openfeature/{javasdk => sdk}/IntegerHook.java (86%) rename src/main/java/dev/openfeature/{javasdk => sdk}/Metadata.java (77%) rename src/main/java/dev/openfeature/{javasdk => sdk}/NoOpProvider.java (98%) rename src/main/java/dev/openfeature/{javasdk => sdk}/OpenFeatureAPI.java (97%) rename src/main/java/dev/openfeature/{javasdk => sdk}/OpenFeatureClient.java (98%) rename src/main/java/dev/openfeature/{javasdk => sdk}/ProviderEvaluation.java (90%) rename src/main/java/dev/openfeature/{javasdk => sdk}/Reason.java (72%) rename src/main/java/dev/openfeature/{javasdk => sdk}/StringHook.java (85%) rename src/main/java/dev/openfeature/{javasdk => sdk}/Structure.java (97%) rename src/main/java/dev/openfeature/{javasdk => sdk}/Value.java (99%) rename src/main/java/dev/openfeature/{javasdk => sdk}/exceptions/FlagNotFoundError.java (76%) rename src/main/java/dev/openfeature/{javasdk => sdk}/exceptions/GeneralError.java (75%) rename src/main/java/dev/openfeature/{javasdk => sdk}/exceptions/InvalidContextError.java (76%) rename src/main/java/dev/openfeature/{javasdk => sdk}/exceptions/OpenFeatureError.java (73%) rename src/main/java/dev/openfeature/{javasdk => sdk}/exceptions/ParseError.java (75%) rename src/main/java/dev/openfeature/{javasdk => sdk}/exceptions/TargetingKeyMissingError.java (77%) rename src/main/java/dev/openfeature/{javasdk => sdk}/exceptions/TypeMismatchError.java (76%) rename src/main/java/dev/openfeature/{javasdk => sdk}/exceptions/ValueNotConvertableError.java (76%) rename src/main/java/dev/openfeature/{javasdk => sdk}/internal/ObjectUtils.java (97%) rename src/test/java/dev/openfeature/{javasdk => sdk}/AlwaysBrokenProvider.java (93%) rename src/test/java/dev/openfeature/{javasdk => sdk}/DeveloperExperienceTest.java (97%) rename src/test/java/dev/openfeature/{javasdk => sdk}/DoSomethingProvider.java (98%) rename src/test/java/dev/openfeature/{javasdk => sdk}/EvalContextTest.java (99%) rename src/test/java/dev/openfeature/{javasdk => sdk}/FlagEvaluationSpecTest.java (99%) rename src/test/java/dev/openfeature/{javasdk => sdk}/HookContextTest.java (96%) rename src/test/java/dev/openfeature/{javasdk => sdk}/HookSpecTest.java (99%) rename src/test/java/dev/openfeature/{javasdk => sdk}/HookSupportTest.java (97%) rename src/test/java/dev/openfeature/{javasdk => sdk}/MetadataTest.java (94%) rename src/test/java/dev/openfeature/{javasdk => sdk}/NoOpProviderTest.java (97%) rename src/test/java/dev/openfeature/{javasdk => sdk}/NotImplementedException.java (86%) rename src/test/java/dev/openfeature/{javasdk => sdk}/OpenFeatureClientTest.java (93%) rename src/test/java/dev/openfeature/{javasdk => sdk}/ProviderSpecTest.java (99%) rename src/test/java/dev/openfeature/{javasdk => sdk}/Specification.java (82%) rename src/test/java/dev/openfeature/{javasdk => sdk}/Specifications.java (67%) rename src/test/java/dev/openfeature/{javasdk => sdk}/StructureTest.java (98%) rename src/test/java/dev/openfeature/{javasdk => sdk}/TestConstants.java (75%) rename src/test/java/dev/openfeature/{javasdk => sdk}/ValueTest.java (99%) rename src/test/java/dev/openfeature/{javasdk => sdk}/fixtures/HookFixtures.java (87%) rename src/test/java/dev/openfeature/{javasdk => sdk}/integration/RunCucumberTest.java (91%) rename src/test/java/dev/openfeature/{javasdk => sdk}/integration/StepDefinitions.java (96%) rename src/test/java/dev/openfeature/{javasdk => sdk}/internal/ObjectUtilsTest.java (96%) diff --git a/README.md b/README.md index b3232710..b6a501ad 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # OpenFeature SDK for Java -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.openfeature/javasdk/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.openfeature/javasdk) -[![javadoc](https://javadoc.io/badge2/dev.openfeature/javasdk/javadoc.svg)](https://javadoc.io/doc/dev.openfeature/javasdk) +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.openfeature/sdk/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.openfeature/sdk) +[![javadoc](https://javadoc.io/badge2/dev.openfeature/sdk/javadoc.svg)](https://javadoc.io/doc/dev.openfeature/sdk) [![Project Status: WIP – Initial development is in progress, but there has not yet been a stable, usable release suitable for the public.](https://www.repostatus.org/badges/latest/wip.svg)](https://www.repostatus.org/#wip) [![Specification](https://img.shields.io/static/v1?label=Specification&message=v0.5.0&color=yellow)](https://github.com/open-feature/spec/tree/v0.5.0) [![Known Vulnerabilities](https://snyk.io/test/github/open-feature/java-sdk/badge.svg)](https://snyk.io/test/github/open-feature/java-sdk) @@ -20,7 +20,7 @@ This library is intended to be used in server-side contexts and has not been eva While `Boolean` provides the simplest introduction, we offer a variety of flag types. ```java -import dev.openfeature.javasdk.Structure; +import dev.openfeature.sdk.Structure; class MyClass { public UI booleanExample() { @@ -65,7 +65,7 @@ class MyClass { ```xml dev.openfeature - javasdk + sdk 0.2.2 ``` @@ -90,7 +90,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:javasdk:0.2.2' + implementation 'dev.openfeature:sdk:0.2.2' } ``` diff --git a/pom.xml b/pom.xml index 7d9cae27..9d23198a 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 dev.openfeature - javasdk + sdk 0.2.2 @@ -137,15 +137,6 @@ 31.1-jre test - - - dev.openfeature.contrib.providers - flagd - - 0.3.2 - test - - @@ -271,7 +262,7 @@ ${project.build.directory}/coverage-reports/jacoco-ut.exec - dev/openfeature/javasdk/exceptions/** + dev/openfeature/sdk/exceptions/** diff --git a/release-please-config.json b/release-please-config.json index bf0d675b..97d02271 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -2,7 +2,7 @@ "bootstrap-sha": "c701a6c4ebbe1170a25ca7636a31508b9628831c", "packages": { ".": { - "package-name": "dev.openfeature.javasdk", + "package-name": "dev.openfeature.sdk", "release-type": "simple", "bump-minor-pre-major": true, "bump-patch-for-minor-pre-major": true, @@ -13,4 +13,4 @@ ] } } -} \ No newline at end of file +} diff --git a/spotbugs-exclusions.xml b/spotbugs-exclusions.xml index 59e92ca8..8675964d 100644 --- a/spotbugs-exclusions.xml +++ b/spotbugs-exclusions.xml @@ -6,18 +6,18 @@ - + - + - + diff --git a/src/main/java/dev/openfeature/javasdk/BaseEvaluation.java b/src/main/java/dev/openfeature/sdk/BaseEvaluation.java similarity index 96% rename from src/main/java/dev/openfeature/javasdk/BaseEvaluation.java rename to src/main/java/dev/openfeature/sdk/BaseEvaluation.java index f0524e06..ed6e9351 100644 --- a/src/main/java/dev/openfeature/javasdk/BaseEvaluation.java +++ b/src/main/java/dev/openfeature/sdk/BaseEvaluation.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; /** * This is a common interface between the evaluation results that providers return and what is given to the end users. diff --git a/src/main/java/dev/openfeature/javasdk/BooleanHook.java b/src/main/java/dev/openfeature/sdk/BooleanHook.java similarity index 86% rename from src/main/java/dev/openfeature/javasdk/BooleanHook.java rename to src/main/java/dev/openfeature/sdk/BooleanHook.java index fd2d7399..26fff41c 100644 --- a/src/main/java/dev/openfeature/javasdk/BooleanHook.java +++ b/src/main/java/dev/openfeature/sdk/BooleanHook.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; public interface BooleanHook extends Hook { diff --git a/src/main/java/dev/openfeature/javasdk/Client.java b/src/main/java/dev/openfeature/sdk/Client.java similarity index 96% rename from src/main/java/dev/openfeature/javasdk/Client.java rename to src/main/java/dev/openfeature/sdk/Client.java index 9ea6e9e1..07015a63 100644 --- a/src/main/java/dev/openfeature/javasdk/Client.java +++ b/src/main/java/dev/openfeature/sdk/Client.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import java.util.List; diff --git a/src/main/java/dev/openfeature/javasdk/DoubleHook.java b/src/main/java/dev/openfeature/sdk/DoubleHook.java similarity index 85% rename from src/main/java/dev/openfeature/javasdk/DoubleHook.java rename to src/main/java/dev/openfeature/sdk/DoubleHook.java index 0e80cad5..2ec179d9 100644 --- a/src/main/java/dev/openfeature/javasdk/DoubleHook.java +++ b/src/main/java/dev/openfeature/sdk/DoubleHook.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; public interface DoubleHook extends Hook { diff --git a/src/main/java/dev/openfeature/javasdk/ErrorCode.java b/src/main/java/dev/openfeature/sdk/ErrorCode.java similarity index 81% rename from src/main/java/dev/openfeature/javasdk/ErrorCode.java rename to src/main/java/dev/openfeature/sdk/ErrorCode.java index 7b54ce56..2acf31ef 100644 --- a/src/main/java/dev/openfeature/javasdk/ErrorCode.java +++ b/src/main/java/dev/openfeature/sdk/ErrorCode.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; public enum ErrorCode { PROVIDER_NOT_READY, FLAG_NOT_FOUND, PARSE_ERROR, TYPE_MISMATCH, TARGETING_KEY_MISSING, INVALID_CONTEXT, GENERAL diff --git a/src/main/java/dev/openfeature/javasdk/EvaluationContext.java b/src/main/java/dev/openfeature/sdk/EvaluationContext.java similarity index 99% rename from src/main/java/dev/openfeature/javasdk/EvaluationContext.java rename to src/main/java/dev/openfeature/sdk/EvaluationContext.java index f7f11ade..ed65ad9e 100644 --- a/src/main/java/dev/openfeature/javasdk/EvaluationContext.java +++ b/src/main/java/dev/openfeature/sdk/EvaluationContext.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import java.time.Instant; import java.util.List; diff --git a/src/main/java/dev/openfeature/javasdk/FeatureProvider.java b/src/main/java/dev/openfeature/sdk/FeatureProvider.java similarity index 96% rename from src/main/java/dev/openfeature/javasdk/FeatureProvider.java rename to src/main/java/dev/openfeature/sdk/FeatureProvider.java index 0938185e..77e9cd67 100644 --- a/src/main/java/dev/openfeature/javasdk/FeatureProvider.java +++ b/src/main/java/dev/openfeature/sdk/FeatureProvider.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/dev/openfeature/javasdk/Features.java b/src/main/java/dev/openfeature/sdk/Features.java similarity index 99% rename from src/main/java/dev/openfeature/javasdk/Features.java rename to src/main/java/dev/openfeature/sdk/Features.java index 79bd403f..ba25021a 100644 --- a/src/main/java/dev/openfeature/javasdk/Features.java +++ b/src/main/java/dev/openfeature/sdk/Features.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; /** * An API for the type-specific fetch methods offered to users. diff --git a/src/main/java/dev/openfeature/javasdk/FlagEvaluationDetails.java b/src/main/java/dev/openfeature/sdk/FlagEvaluationDetails.java similarity index 97% rename from src/main/java/dev/openfeature/javasdk/FlagEvaluationDetails.java rename to src/main/java/dev/openfeature/sdk/FlagEvaluationDetails.java index 0440cf5b..d9c85be4 100644 --- a/src/main/java/dev/openfeature/javasdk/FlagEvaluationDetails.java +++ b/src/main/java/dev/openfeature/sdk/FlagEvaluationDetails.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import lombok.Builder; import lombok.Data; diff --git a/src/main/java/dev/openfeature/javasdk/FlagEvaluationOptions.java b/src/main/java/dev/openfeature/sdk/FlagEvaluationOptions.java similarity index 89% rename from src/main/java/dev/openfeature/javasdk/FlagEvaluationOptions.java rename to src/main/java/dev/openfeature/sdk/FlagEvaluationOptions.java index ea10b855..81408be9 100644 --- a/src/main/java/dev/openfeature/javasdk/FlagEvaluationOptions.java +++ b/src/main/java/dev/openfeature/sdk/FlagEvaluationOptions.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import java.util.HashMap; import java.util.List; diff --git a/src/main/java/dev/openfeature/javasdk/FlagValueType.java b/src/main/java/dev/openfeature/sdk/FlagValueType.java similarity index 70% rename from src/main/java/dev/openfeature/javasdk/FlagValueType.java rename to src/main/java/dev/openfeature/sdk/FlagValueType.java index 16b080c6..62ca412f 100644 --- a/src/main/java/dev/openfeature/javasdk/FlagValueType.java +++ b/src/main/java/dev/openfeature/sdk/FlagValueType.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; public enum FlagValueType { STRING, INTEGER, DOUBLE, OBJECT, BOOLEAN; diff --git a/src/main/java/dev/openfeature/javasdk/Hook.java b/src/main/java/dev/openfeature/sdk/Hook.java similarity index 98% rename from src/main/java/dev/openfeature/javasdk/Hook.java rename to src/main/java/dev/openfeature/sdk/Hook.java index 4466c9bd..3856af26 100644 --- a/src/main/java/dev/openfeature/javasdk/Hook.java +++ b/src/main/java/dev/openfeature/sdk/Hook.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import java.util.Map; import java.util.Optional; diff --git a/src/main/java/dev/openfeature/javasdk/HookContext.java b/src/main/java/dev/openfeature/sdk/HookContext.java similarity index 97% rename from src/main/java/dev/openfeature/javasdk/HookContext.java rename to src/main/java/dev/openfeature/sdk/HookContext.java index 584db160..26b14f79 100644 --- a/src/main/java/dev/openfeature/javasdk/HookContext.java +++ b/src/main/java/dev/openfeature/sdk/HookContext.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import lombok.Builder; import lombok.NonNull; diff --git a/src/main/java/dev/openfeature/javasdk/HookSupport.java b/src/main/java/dev/openfeature/sdk/HookSupport.java similarity index 99% rename from src/main/java/dev/openfeature/javasdk/HookSupport.java rename to src/main/java/dev/openfeature/sdk/HookSupport.java index d78243b0..6e29eae3 100644 --- a/src/main/java/dev/openfeature/javasdk/HookSupport.java +++ b/src/main/java/dev/openfeature/sdk/HookSupport.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import java.util.*; import java.util.function.Consumer; diff --git a/src/main/java/dev/openfeature/javasdk/IntegerHook.java b/src/main/java/dev/openfeature/sdk/IntegerHook.java similarity index 86% rename from src/main/java/dev/openfeature/javasdk/IntegerHook.java rename to src/main/java/dev/openfeature/sdk/IntegerHook.java index 41453a7a..a178904d 100644 --- a/src/main/java/dev/openfeature/javasdk/IntegerHook.java +++ b/src/main/java/dev/openfeature/sdk/IntegerHook.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; public interface IntegerHook extends Hook { diff --git a/src/main/java/dev/openfeature/javasdk/Metadata.java b/src/main/java/dev/openfeature/sdk/Metadata.java similarity index 77% rename from src/main/java/dev/openfeature/javasdk/Metadata.java rename to src/main/java/dev/openfeature/sdk/Metadata.java index fb6122b8..7e614c27 100644 --- a/src/main/java/dev/openfeature/javasdk/Metadata.java +++ b/src/main/java/dev/openfeature/sdk/Metadata.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; /** * Holds identifying information about a given entity. diff --git a/src/main/java/dev/openfeature/javasdk/NoOpProvider.java b/src/main/java/dev/openfeature/sdk/NoOpProvider.java similarity index 98% rename from src/main/java/dev/openfeature/javasdk/NoOpProvider.java rename to src/main/java/dev/openfeature/sdk/NoOpProvider.java index ef7dccd7..00abedc8 100644 --- a/src/main/java/dev/openfeature/javasdk/NoOpProvider.java +++ b/src/main/java/dev/openfeature/sdk/NoOpProvider.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import lombok.Getter; diff --git a/src/main/java/dev/openfeature/javasdk/OpenFeatureAPI.java b/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java similarity index 97% rename from src/main/java/dev/openfeature/javasdk/OpenFeatureAPI.java rename to src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java index 76bb3cb3..5918fa08 100644 --- a/src/main/java/dev/openfeature/javasdk/OpenFeatureAPI.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import lombok.Getter; import lombok.Setter; diff --git a/src/main/java/dev/openfeature/javasdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java similarity index 98% rename from src/main/java/dev/openfeature/javasdk/OpenFeatureClient.java rename to src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index 361e8bc3..957afc88 100644 --- a/src/main/java/dev/openfeature/javasdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import java.util.ArrayList; import java.util.Arrays; @@ -6,9 +6,9 @@ import java.util.List; import java.util.Map; -import dev.openfeature.javasdk.exceptions.GeneralError; -import dev.openfeature.javasdk.exceptions.OpenFeatureError; -import dev.openfeature.javasdk.internal.ObjectUtils; +import dev.openfeature.sdk.exceptions.GeneralError; +import dev.openfeature.sdk.exceptions.OpenFeatureError; +import dev.openfeature.sdk.internal.ObjectUtils; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; diff --git a/src/main/java/dev/openfeature/javasdk/ProviderEvaluation.java b/src/main/java/dev/openfeature/sdk/ProviderEvaluation.java similarity index 90% rename from src/main/java/dev/openfeature/javasdk/ProviderEvaluation.java rename to src/main/java/dev/openfeature/sdk/ProviderEvaluation.java index df939134..3f2b69bc 100644 --- a/src/main/java/dev/openfeature/javasdk/ProviderEvaluation.java +++ b/src/main/java/dev/openfeature/sdk/ProviderEvaluation.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import lombok.Builder; import lombok.Data; diff --git a/src/main/java/dev/openfeature/javasdk/Reason.java b/src/main/java/dev/openfeature/sdk/Reason.java similarity index 72% rename from src/main/java/dev/openfeature/javasdk/Reason.java rename to src/main/java/dev/openfeature/sdk/Reason.java index a916693d..107665bc 100644 --- a/src/main/java/dev/openfeature/javasdk/Reason.java +++ b/src/main/java/dev/openfeature/sdk/Reason.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; public enum Reason { DISABLED, SPLIT, TARGETING_MATCH, DEFAULT, UNKNOWN, ERROR diff --git a/src/main/java/dev/openfeature/javasdk/StringHook.java b/src/main/java/dev/openfeature/sdk/StringHook.java similarity index 85% rename from src/main/java/dev/openfeature/javasdk/StringHook.java rename to src/main/java/dev/openfeature/sdk/StringHook.java index 42ad2fd1..15ee5238 100644 --- a/src/main/java/dev/openfeature/javasdk/StringHook.java +++ b/src/main/java/dev/openfeature/sdk/StringHook.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; public interface StringHook extends Hook { diff --git a/src/main/java/dev/openfeature/javasdk/Structure.java b/src/main/java/dev/openfeature/sdk/Structure.java similarity index 97% rename from src/main/java/dev/openfeature/javasdk/Structure.java rename to src/main/java/dev/openfeature/sdk/Structure.java index 87491e66..70c98b77 100644 --- a/src/main/java/dev/openfeature/javasdk/Structure.java +++ b/src/main/java/dev/openfeature/sdk/Structure.java @@ -1,10 +1,10 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import java.time.Instant; import java.util.*; import java.util.stream.Collectors; -import dev.openfeature.javasdk.exceptions.ValueNotConvertableError; +import dev.openfeature.sdk.exceptions.ValueNotConvertableError; import lombok.EqualsAndHashCode; import lombok.ToString; diff --git a/src/main/java/dev/openfeature/javasdk/Value.java b/src/main/java/dev/openfeature/sdk/Value.java similarity index 99% rename from src/main/java/dev/openfeature/javasdk/Value.java rename to src/main/java/dev/openfeature/sdk/Value.java index abadd606..1caaf52e 100644 --- a/src/main/java/dev/openfeature/javasdk/Value.java +++ b/src/main/java/dev/openfeature/sdk/Value.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import java.time.Instant; import java.util.List; diff --git a/src/main/java/dev/openfeature/javasdk/exceptions/FlagNotFoundError.java b/src/main/java/dev/openfeature/sdk/exceptions/FlagNotFoundError.java similarity index 76% rename from src/main/java/dev/openfeature/javasdk/exceptions/FlagNotFoundError.java rename to src/main/java/dev/openfeature/sdk/exceptions/FlagNotFoundError.java index c91971ae..78a5077d 100644 --- a/src/main/java/dev/openfeature/javasdk/exceptions/FlagNotFoundError.java +++ b/src/main/java/dev/openfeature/sdk/exceptions/FlagNotFoundError.java @@ -1,6 +1,6 @@ -package dev.openfeature.javasdk.exceptions; +package dev.openfeature.sdk.exceptions; -import dev.openfeature.javasdk.ErrorCode; +import dev.openfeature.sdk.ErrorCode; import lombok.Getter; import lombok.experimental.StandardException; diff --git a/src/main/java/dev/openfeature/javasdk/exceptions/GeneralError.java b/src/main/java/dev/openfeature/sdk/exceptions/GeneralError.java similarity index 75% rename from src/main/java/dev/openfeature/javasdk/exceptions/GeneralError.java rename to src/main/java/dev/openfeature/sdk/exceptions/GeneralError.java index a9ebaa32..3b0e57e8 100644 --- a/src/main/java/dev/openfeature/javasdk/exceptions/GeneralError.java +++ b/src/main/java/dev/openfeature/sdk/exceptions/GeneralError.java @@ -1,6 +1,6 @@ -package dev.openfeature.javasdk.exceptions; +package dev.openfeature.sdk.exceptions; -import dev.openfeature.javasdk.ErrorCode; +import dev.openfeature.sdk.ErrorCode; import lombok.Getter; import lombok.experimental.StandardException; diff --git a/src/main/java/dev/openfeature/javasdk/exceptions/InvalidContextError.java b/src/main/java/dev/openfeature/sdk/exceptions/InvalidContextError.java similarity index 76% rename from src/main/java/dev/openfeature/javasdk/exceptions/InvalidContextError.java rename to src/main/java/dev/openfeature/sdk/exceptions/InvalidContextError.java index e8487054..150c851a 100644 --- a/src/main/java/dev/openfeature/javasdk/exceptions/InvalidContextError.java +++ b/src/main/java/dev/openfeature/sdk/exceptions/InvalidContextError.java @@ -1,6 +1,6 @@ -package dev.openfeature.javasdk.exceptions; +package dev.openfeature.sdk.exceptions; -import dev.openfeature.javasdk.ErrorCode; +import dev.openfeature.sdk.ErrorCode; import lombok.Getter; import lombok.experimental.StandardException; diff --git a/src/main/java/dev/openfeature/javasdk/exceptions/OpenFeatureError.java b/src/main/java/dev/openfeature/sdk/exceptions/OpenFeatureError.java similarity index 73% rename from src/main/java/dev/openfeature/javasdk/exceptions/OpenFeatureError.java rename to src/main/java/dev/openfeature/sdk/exceptions/OpenFeatureError.java index 65ac44fb..c831bb5e 100644 --- a/src/main/java/dev/openfeature/javasdk/exceptions/OpenFeatureError.java +++ b/src/main/java/dev/openfeature/sdk/exceptions/OpenFeatureError.java @@ -1,6 +1,6 @@ -package dev.openfeature.javasdk.exceptions; +package dev.openfeature.sdk.exceptions; -import dev.openfeature.javasdk.ErrorCode; +import dev.openfeature.sdk.ErrorCode; import lombok.experimental.StandardException; @StandardException diff --git a/src/main/java/dev/openfeature/javasdk/exceptions/ParseError.java b/src/main/java/dev/openfeature/sdk/exceptions/ParseError.java similarity index 75% rename from src/main/java/dev/openfeature/javasdk/exceptions/ParseError.java rename to src/main/java/dev/openfeature/sdk/exceptions/ParseError.java index 63b3f364..3aa5ad90 100644 --- a/src/main/java/dev/openfeature/javasdk/exceptions/ParseError.java +++ b/src/main/java/dev/openfeature/sdk/exceptions/ParseError.java @@ -1,6 +1,6 @@ -package dev.openfeature.javasdk.exceptions; +package dev.openfeature.sdk.exceptions; -import dev.openfeature.javasdk.ErrorCode; +import dev.openfeature.sdk.ErrorCode; import lombok.Getter; import lombok.experimental.StandardException; diff --git a/src/main/java/dev/openfeature/javasdk/exceptions/TargetingKeyMissingError.java b/src/main/java/dev/openfeature/sdk/exceptions/TargetingKeyMissingError.java similarity index 77% rename from src/main/java/dev/openfeature/javasdk/exceptions/TargetingKeyMissingError.java rename to src/main/java/dev/openfeature/sdk/exceptions/TargetingKeyMissingError.java index 7e914d29..e1886c90 100644 --- a/src/main/java/dev/openfeature/javasdk/exceptions/TargetingKeyMissingError.java +++ b/src/main/java/dev/openfeature/sdk/exceptions/TargetingKeyMissingError.java @@ -1,6 +1,6 @@ -package dev.openfeature.javasdk.exceptions; +package dev.openfeature.sdk.exceptions; -import dev.openfeature.javasdk.ErrorCode; +import dev.openfeature.sdk.ErrorCode; import lombok.Getter; import lombok.experimental.StandardException; diff --git a/src/main/java/dev/openfeature/javasdk/exceptions/TypeMismatchError.java b/src/main/java/dev/openfeature/sdk/exceptions/TypeMismatchError.java similarity index 76% rename from src/main/java/dev/openfeature/javasdk/exceptions/TypeMismatchError.java rename to src/main/java/dev/openfeature/sdk/exceptions/TypeMismatchError.java index 4055a691..08ab8012 100644 --- a/src/main/java/dev/openfeature/javasdk/exceptions/TypeMismatchError.java +++ b/src/main/java/dev/openfeature/sdk/exceptions/TypeMismatchError.java @@ -1,6 +1,6 @@ -package dev.openfeature.javasdk.exceptions; +package dev.openfeature.sdk.exceptions; -import dev.openfeature.javasdk.ErrorCode; +import dev.openfeature.sdk.ErrorCode; import lombok.Getter; import lombok.experimental.StandardException; diff --git a/src/main/java/dev/openfeature/javasdk/exceptions/ValueNotConvertableError.java b/src/main/java/dev/openfeature/sdk/exceptions/ValueNotConvertableError.java similarity index 76% rename from src/main/java/dev/openfeature/javasdk/exceptions/ValueNotConvertableError.java rename to src/main/java/dev/openfeature/sdk/exceptions/ValueNotConvertableError.java index 1cbff419..443bea76 100644 --- a/src/main/java/dev/openfeature/javasdk/exceptions/ValueNotConvertableError.java +++ b/src/main/java/dev/openfeature/sdk/exceptions/ValueNotConvertableError.java @@ -1,6 +1,6 @@ -package dev.openfeature.javasdk.exceptions; +package dev.openfeature.sdk.exceptions; -import dev.openfeature.javasdk.ErrorCode; +import dev.openfeature.sdk.ErrorCode; import lombok.Getter; import lombok.experimental.StandardException; diff --git a/src/main/java/dev/openfeature/javasdk/internal/ObjectUtils.java b/src/main/java/dev/openfeature/sdk/internal/ObjectUtils.java similarity index 97% rename from src/main/java/dev/openfeature/javasdk/internal/ObjectUtils.java rename to src/main/java/dev/openfeature/sdk/internal/ObjectUtils.java index c9de51f1..2318bdc4 100644 --- a/src/main/java/dev/openfeature/javasdk/internal/ObjectUtils.java +++ b/src/main/java/dev/openfeature/sdk/internal/ObjectUtils.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk.internal; +package dev.openfeature.sdk.internal; import java.util.*; import java.util.function.Supplier; diff --git a/src/test/java/dev/openfeature/javasdk/AlwaysBrokenProvider.java b/src/test/java/dev/openfeature/sdk/AlwaysBrokenProvider.java similarity index 93% rename from src/test/java/dev/openfeature/javasdk/AlwaysBrokenProvider.java rename to src/test/java/dev/openfeature/sdk/AlwaysBrokenProvider.java index 044f3ce7..4beb28c3 100644 --- a/src/test/java/dev/openfeature/javasdk/AlwaysBrokenProvider.java +++ b/src/test/java/dev/openfeature/sdk/AlwaysBrokenProvider.java @@ -1,6 +1,6 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; -import dev.openfeature.javasdk.exceptions.FlagNotFoundError; +import dev.openfeature.sdk.exceptions.FlagNotFoundError; public class AlwaysBrokenProvider implements FeatureProvider { diff --git a/src/test/java/dev/openfeature/javasdk/DeveloperExperienceTest.java b/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java similarity index 97% rename from src/test/java/dev/openfeature/javasdk/DeveloperExperienceTest.java rename to src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java index abd1d95a..bb0825b0 100644 --- a/src/test/java/dev/openfeature/javasdk/DeveloperExperienceTest.java +++ b/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -8,7 +8,7 @@ import org.junit.jupiter.api.Test; -import dev.openfeature.javasdk.fixtures.HookFixtures; +import dev.openfeature.sdk.fixtures.HookFixtures; import java.util.Arrays; diff --git a/src/test/java/dev/openfeature/javasdk/DoSomethingProvider.java b/src/test/java/dev/openfeature/sdk/DoSomethingProvider.java similarity index 98% rename from src/test/java/dev/openfeature/javasdk/DoSomethingProvider.java rename to src/test/java/dev/openfeature/sdk/DoSomethingProvider.java index 1fd6d9dc..37fd20f4 100644 --- a/src/test/java/dev/openfeature/javasdk/DoSomethingProvider.java +++ b/src/test/java/dev/openfeature/sdk/DoSomethingProvider.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; public class DoSomethingProvider implements FeatureProvider { diff --git a/src/test/java/dev/openfeature/javasdk/EvalContextTest.java b/src/test/java/dev/openfeature/sdk/EvalContextTest.java similarity index 99% rename from src/test/java/dev/openfeature/javasdk/EvalContextTest.java rename to src/test/java/dev/openfeature/sdk/EvalContextTest.java index 3cb20788..4a974e4e 100644 --- a/src/test/java/dev/openfeature/javasdk/EvalContextTest.java +++ b/src/test/java/dev/openfeature/sdk/EvalContextTest.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/dev/openfeature/javasdk/FlagEvaluationSpecTest.java b/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java similarity index 99% rename from src/test/java/dev/openfeature/javasdk/FlagEvaluationSpecTest.java rename to src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java index f2ef69df..fda13ddf 100644 --- a/src/test/java/dev/openfeature/javasdk/FlagEvaluationSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -16,7 +16,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; -import dev.openfeature.javasdk.fixtures.HookFixtures; +import dev.openfeature.sdk.fixtures.HookFixtures; import uk.org.lidalia.slf4jtest.LoggingEvent; import uk.org.lidalia.slf4jtest.TestLogger; import uk.org.lidalia.slf4jtest.TestLoggerFactory; diff --git a/src/test/java/dev/openfeature/javasdk/HookContextTest.java b/src/test/java/dev/openfeature/sdk/HookContextTest.java similarity index 96% rename from src/test/java/dev/openfeature/javasdk/HookContextTest.java rename to src/test/java/dev/openfeature/sdk/HookContextTest.java index 0d2dd2a7..6b28c1de 100644 --- a/src/test/java/dev/openfeature/javasdk/HookContextTest.java +++ b/src/test/java/dev/openfeature/sdk/HookContextTest.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import org.junit.jupiter.api.Test; diff --git a/src/test/java/dev/openfeature/javasdk/HookSpecTest.java b/src/test/java/dev/openfeature/sdk/HookSpecTest.java similarity index 99% rename from src/test/java/dev/openfeature/javasdk/HookSpecTest.java rename to src/test/java/dev/openfeature/sdk/HookSpecTest.java index e67a8faf..1c3e45ab 100644 --- a/src/test/java/dev/openfeature/javasdk/HookSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSpecTest.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.fail; @@ -26,7 +26,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.InOrder; -import dev.openfeature.javasdk.fixtures.HookFixtures; +import dev.openfeature.sdk.fixtures.HookFixtures; import lombok.SneakyThrows; public class HookSpecTest implements HookFixtures { diff --git a/src/test/java/dev/openfeature/javasdk/HookSupportTest.java b/src/test/java/dev/openfeature/sdk/HookSupportTest.java similarity index 97% rename from src/test/java/dev/openfeature/javasdk/HookSupportTest.java rename to src/test/java/dev/openfeature/sdk/HookSupportTest.java index 3b952584..e846707a 100644 --- a/src/test/java/dev/openfeature/javasdk/HookSupportTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSupportTest.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -14,7 +14,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; -import dev.openfeature.javasdk.fixtures.HookFixtures; +import dev.openfeature.sdk.fixtures.HookFixtures; class HookSupportTest implements HookFixtures { diff --git a/src/test/java/dev/openfeature/javasdk/MetadataTest.java b/src/test/java/dev/openfeature/sdk/MetadataTest.java similarity index 94% rename from src/test/java/dev/openfeature/javasdk/MetadataTest.java rename to src/test/java/dev/openfeature/sdk/MetadataTest.java index bbca73f7..944f45e3 100644 --- a/src/test/java/dev/openfeature/javasdk/MetadataTest.java +++ b/src/test/java/dev/openfeature/sdk/MetadataTest.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import org.junit.jupiter.api.Test; diff --git a/src/test/java/dev/openfeature/javasdk/NoOpProviderTest.java b/src/test/java/dev/openfeature/sdk/NoOpProviderTest.java similarity index 97% rename from src/test/java/dev/openfeature/javasdk/NoOpProviderTest.java rename to src/test/java/dev/openfeature/sdk/NoOpProviderTest.java index 0853a295..2f34cd7d 100644 --- a/src/test/java/dev/openfeature/javasdk/NoOpProviderTest.java +++ b/src/test/java/dev/openfeature/sdk/NoOpProviderTest.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/dev/openfeature/javasdk/NotImplementedException.java b/src/test/java/dev/openfeature/sdk/NotImplementedException.java similarity index 86% rename from src/test/java/dev/openfeature/javasdk/NotImplementedException.java rename to src/test/java/dev/openfeature/sdk/NotImplementedException.java index 149de019..09d7bcbb 100644 --- a/src/test/java/dev/openfeature/javasdk/NotImplementedException.java +++ b/src/test/java/dev/openfeature/sdk/NotImplementedException.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; public class NotImplementedException extends RuntimeException { diff --git a/src/test/java/dev/openfeature/javasdk/OpenFeatureClientTest.java b/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java similarity index 93% rename from src/test/java/dev/openfeature/javasdk/OpenFeatureClientTest.java rename to src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java index 06509ccc..14446c1a 100644 --- a/src/test/java/dev/openfeature/javasdk/OpenFeatureClientTest.java +++ b/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java @@ -1,8 +1,8 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import java.util.*; -import dev.openfeature.javasdk.fixtures.HookFixtures; +import dev.openfeature.sdk.fixtures.HookFixtures; import org.junit.jupiter.api.*; import uk.org.lidalia.slf4jext.Level; import uk.org.lidalia.slf4jtest.*; diff --git a/src/test/java/dev/openfeature/javasdk/ProviderSpecTest.java b/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java similarity index 99% rename from src/test/java/dev/openfeature/javasdk/ProviderSpecTest.java rename to src/test/java/dev/openfeature/sdk/ProviderSpecTest.java index 846d0d48..5e642421 100644 --- a/src/test/java/dev/openfeature/javasdk/ProviderSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; diff --git a/src/test/java/dev/openfeature/javasdk/Specification.java b/src/test/java/dev/openfeature/sdk/Specification.java similarity index 82% rename from src/test/java/dev/openfeature/javasdk/Specification.java rename to src/test/java/dev/openfeature/sdk/Specification.java index 3d8bbd1c..061e45ec 100644 --- a/src/test/java/dev/openfeature/javasdk/Specification.java +++ b/src/test/java/dev/openfeature/sdk/Specification.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import java.lang.annotation.Repeatable; diff --git a/src/test/java/dev/openfeature/javasdk/Specifications.java b/src/test/java/dev/openfeature/sdk/Specifications.java similarity index 67% rename from src/test/java/dev/openfeature/javasdk/Specifications.java rename to src/test/java/dev/openfeature/sdk/Specifications.java index 1c3a5dd1..f10d90a5 100644 --- a/src/test/java/dev/openfeature/javasdk/Specifications.java +++ b/src/test/java/dev/openfeature/sdk/Specifications.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; public @interface Specifications { Specification[] value(); diff --git a/src/test/java/dev/openfeature/javasdk/StructureTest.java b/src/test/java/dev/openfeature/sdk/StructureTest.java similarity index 98% rename from src/test/java/dev/openfeature/javasdk/StructureTest.java rename to src/test/java/dev/openfeature/sdk/StructureTest.java index eccb23c3..8170ea3d 100644 --- a/src/test/java/dev/openfeature/javasdk/StructureTest.java +++ b/src/test/java/dev/openfeature/sdk/StructureTest.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotSame; diff --git a/src/test/java/dev/openfeature/javasdk/TestConstants.java b/src/test/java/dev/openfeature/sdk/TestConstants.java similarity index 75% rename from src/test/java/dev/openfeature/javasdk/TestConstants.java rename to src/test/java/dev/openfeature/sdk/TestConstants.java index 945c32f6..e9786eb8 100644 --- a/src/test/java/dev/openfeature/javasdk/TestConstants.java +++ b/src/test/java/dev/openfeature/sdk/TestConstants.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; public class TestConstants { public static final String BROKEN_MESSAGE = "This is borked."; diff --git a/src/test/java/dev/openfeature/javasdk/ValueTest.java b/src/test/java/dev/openfeature/sdk/ValueTest.java similarity index 99% rename from src/test/java/dev/openfeature/javasdk/ValueTest.java rename to src/test/java/dev/openfeature/sdk/ValueTest.java index 12210321..f8bebb21 100644 --- a/src/test/java/dev/openfeature/javasdk/ValueTest.java +++ b/src/test/java/dev/openfeature/sdk/ValueTest.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk; +package dev.openfeature.sdk; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; diff --git a/src/test/java/dev/openfeature/javasdk/fixtures/HookFixtures.java b/src/test/java/dev/openfeature/sdk/fixtures/HookFixtures.java similarity index 87% rename from src/test/java/dev/openfeature/javasdk/fixtures/HookFixtures.java rename to src/test/java/dev/openfeature/sdk/fixtures/HookFixtures.java index 35cb9b72..1d1de1ef 100644 --- a/src/test/java/dev/openfeature/javasdk/fixtures/HookFixtures.java +++ b/src/test/java/dev/openfeature/sdk/fixtures/HookFixtures.java @@ -1,6 +1,6 @@ -package dev.openfeature.javasdk.fixtures; +package dev.openfeature.sdk.fixtures; -import dev.openfeature.javasdk.*; +import dev.openfeature.sdk.*; import static org.mockito.Mockito.spy; diff --git a/src/test/java/dev/openfeature/javasdk/integration/RunCucumberTest.java b/src/test/java/dev/openfeature/sdk/integration/RunCucumberTest.java similarity index 91% rename from src/test/java/dev/openfeature/javasdk/integration/RunCucumberTest.java rename to src/test/java/dev/openfeature/sdk/integration/RunCucumberTest.java index 65c86c29..6a13ed29 100644 --- a/src/test/java/dev/openfeature/javasdk/integration/RunCucumberTest.java +++ b/src/test/java/dev/openfeature/sdk/integration/RunCucumberTest.java @@ -1,4 +1,4 @@ -package dev.openfeature.javasdk.integration; +package dev.openfeature.sdk.integration; import org.junit.platform.suite.api.ConfigurationParameter; import org.junit.platform.suite.api.IncludeEngines; diff --git a/src/test/java/dev/openfeature/javasdk/integration/StepDefinitions.java b/src/test/java/dev/openfeature/sdk/integration/StepDefinitions.java similarity index 96% rename from src/test/java/dev/openfeature/javasdk/integration/StepDefinitions.java rename to src/test/java/dev/openfeature/sdk/integration/StepDefinitions.java index a7d9f91e..39147565 100644 --- a/src/test/java/dev/openfeature/javasdk/integration/StepDefinitions.java +++ b/src/test/java/dev/openfeature/sdk/integration/StepDefinitions.java @@ -1,16 +1,16 @@ -package dev.openfeature.javasdk.integration; +package dev.openfeature.sdk.integration; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import dev.openfeature.contrib.providers.flagd.FlagdProvider; -import dev.openfeature.javasdk.Client; -import dev.openfeature.javasdk.EvaluationContext; -import dev.openfeature.javasdk.FlagEvaluationDetails; -import dev.openfeature.javasdk.OpenFeatureAPI; -import dev.openfeature.javasdk.Reason; -import dev.openfeature.javasdk.Structure; -import dev.openfeature.javasdk.Value; +// import dev.openfeature.contrib.providers.flagd.FlagdProvider; +import dev.openfeature.sdk.Client; +import dev.openfeature.sdk.EvaluationContext; +import dev.openfeature.sdk.FlagEvaluationDetails; +import dev.openfeature.sdk.OpenFeatureAPI; +import dev.openfeature.sdk.Reason; +import dev.openfeature.sdk.Structure; +import dev.openfeature.sdk.Value; import io.cucumber.java.BeforeAll; import io.cucumber.java.en.Then; import io.cucumber.java.en.When; @@ -44,7 +44,7 @@ public class StepDefinitions { @BeforeAll() public static void setup() { - OpenFeatureAPI.getInstance().setProvider(new FlagdProvider()); + // OpenFeatureAPI.getInstance().setProvider(new FlagdProvider()); client = OpenFeatureAPI.getInstance().getClient(); } diff --git a/src/test/java/dev/openfeature/javasdk/internal/ObjectUtilsTest.java b/src/test/java/dev/openfeature/sdk/internal/ObjectUtilsTest.java similarity index 96% rename from src/test/java/dev/openfeature/javasdk/internal/ObjectUtilsTest.java rename to src/test/java/dev/openfeature/sdk/internal/ObjectUtilsTest.java index 9c283260..c4525e74 100644 --- a/src/test/java/dev/openfeature/javasdk/internal/ObjectUtilsTest.java +++ b/src/test/java/dev/openfeature/sdk/internal/ObjectUtilsTest.java @@ -1,10 +1,10 @@ -package dev.openfeature.javasdk.internal; +package dev.openfeature.sdk.internal; import java.util.*; import org.junit.jupiter.api.*; -import static dev.openfeature.javasdk.internal.ObjectUtils.defaultIfNull; +import static dev.openfeature.sdk.internal.ObjectUtils.defaultIfNull; import static org.assertj.core.api.Assertions.assertThat; class ObjectUtilsTest { From ed91c5698bbb5ed3a72c15bbbe96672891b11069 Mon Sep 17 00:00:00 2001 From: Justin Abrahms Date: Wed, 5 Oct 2022 12:02:59 -0700 Subject: [PATCH 23/63] chore: Write perms should be as tightly scoped as possible. (#107) * Add a dependabot file to keep deps up to date Signed-off-by: Justin Abrahms * Move write permissions to the specific job, rather than globally Signed-off-by: Justin Abrahms * Run code scanning (slow auto-build) weekly Signed-off-by: Justin Abrahms Signed-off-by: Justin Abrahms Signed-off-by: Bhandari, Pramesh(AWF) --- .github/dependabot.yml | 14 +++++++ .github/workflows/merge.yml | 3 +- .github/workflows/pullrequest.yml | 3 +- .github/workflows/static-code-scanning.yaml | 41 +++++++++++++++++++++ 4 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/static-code-scanning.yaml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..fb167d17 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +version: 2 +updates: + + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + + # Maintain dependencies for npm + - package-ecosystem: "maven" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index ed30bdbf..302f788c 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -12,13 +12,14 @@ on: branches: [ master, main ] permissions: - packages: write contents: read jobs: build: runs-on: ubuntu-latest + permissions: + packages: write steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 3b7430a0..bbe1d8dd 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -3,7 +3,6 @@ on: pull_request: branches: [ master, main ] permissions: - packages: write contents: read jobs: @@ -15,6 +14,8 @@ jobs: ports: - 8013:8013 + permissions: + packages: write steps: - name: Check out the code uses: actions/checkout@v3 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml new file mode 100644 index 00000000..4cc4b6b3 --- /dev/null +++ b/.github/workflows/static-code-scanning.yaml @@ -0,0 +1,41 @@ +name: "Code Scanning - Action" + +# Docs for this at https://github.com/github/codeql-action#usage + +on: + schedule: + # ┌───────────── minute (0 - 59) + # │ ┌───────────── hour (0 - 23) + # │ │ ┌───────────── day of the month (1 - 31) + # │ │ │ ┌───────────── month (1 - 12 or JAN-DEC) + # │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT) + # │ │ │ │ │ + # │ │ │ │ │ + # │ │ │ │ │ + # * * * * * + - cron: '30 1 * * 1' + +jobs: + CodeQL-Build: + # CodeQL runs on ubuntu-latest, windows-latest, and macos-latest + runs-on: ubuntu-latest + + permissions: + # required for all workflows + security-events: write + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: java + + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 From ce423db4ec6cb1a7eb64a3e787aa4bb8c751d576 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Wed, 5 Oct 2022 15:09:08 -0400 Subject: [PATCH 24/63] chore: fix dependabot pr titles (#118) Signed-off-by: Todd Baert Signed-off-by: Todd Baert Signed-off-by: Bhandari, Pramesh(AWF) --- .github/dependabot.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index fb167d17..e39eec8c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -10,5 +10,7 @@ updates: # Maintain dependencies for npm - package-ecosystem: "maven" directory: "/" + commit-message: + prefix: "chore" schedule: interval: "weekly" From 4795ea0a73f3b0f599f474e16bb58262c5e373fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Oct 2022 15:37:45 -0400 Subject: [PATCH 25/63] chore: Bump cucumber-bom from 7.8.0 to 7.8.1 (#115) Bump cucumber-bom from 7.8.0 to 7.8.1 Bumps [cucumber-bom](https://github.com/cucumber/cucumber-jvm) from 7.8.0 to 7.8.1. - [Release notes](https://github.com/cucumber/cucumber-jvm/releases) - [Changelog](https://github.com/cucumber/cucumber-jvm/blob/main/CHANGELOG.md) - [Commits](https://github.com/cucumber/cucumber-jvm/compare/v7.8.0...v7.8.1) --- updated-dependencies: - dependency-name: io.cucumber:cucumber-bom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9d23198a..3233c4c8 100644 --- a/pom.xml +++ b/pom.xml @@ -145,7 +145,7 @@ io.cucumber cucumber-bom - 7.8.0 + 7.8.1 pom import From d7797577b33217d5a81fda52278d83ac73448a71 Mon Sep 17 00:00:00 2001 From: Justin Abrahms Date: Wed, 5 Oct 2022 19:06:47 -0700 Subject: [PATCH 26/63] chore: add SAST scanning (#108) * add SAST scanning Refs #84 Signed-off-by: Justin Abrahms * Java scanning only Signed-off-by: Justin Abrahms * Try codeql on the normal build to see how much longer it is. Signed-off-by: Justin Abrahms Signed-off-by: Justin Abrahms Signed-off-by: Bhandari, Pramesh(AWF) --- .github/workflows/pullrequest.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index bbe1d8dd..a1df30c7 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -19,6 +19,7 @@ jobs: steps: - name: Check out the code uses: actions/checkout@v3 + - name: Set up JDK 8 uses: actions/setup-java@v3 with: @@ -26,6 +27,11 @@ jobs: distribution: 'temurin' cache: maven + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: java + - name: Cache local Maven repository uses: actions/cache@v3 with: @@ -44,3 +50,6 @@ jobs: name: coverage # optional fail_ci_if_error: true # optional (default = false) verbose: true # optional (default = false) + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 From 9cf1e25728d20c6b6a3b64c6f6863a668c723e8a Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Thu, 6 Oct 2022 01:32:29 -0400 Subject: [PATCH 27/63] feat!: use evaluation context interface (#112) * POC - use evaluation context interface Signed-off-by: Todd Baert * make .merge non-static Signed-off-by: Todd Baert * improve naming Signed-off-by: Todd Baert * add @override Signed-off-by: Todd Baert * Update src/main/java/dev/openfeature/sdk/EvaluationContext.java Co-authored-by: Justin Abrahms Signed-off-by: Todd Baert * Update src/main/java/dev/openfeature/sdk/MutableContext.java Co-authored-by: Justin Abrahms Signed-off-by: Todd Baert * address PR feedback Signed-off-by: Todd Baert Signed-off-by: Todd Baert Co-authored-by: Justin Abrahms Signed-off-by: Bhandari, Pramesh(AWF) --- .../openfeature/sdk/EvaluationContext.java | 131 ++------------ .../java/dev/openfeature/sdk/HookSupport.java | 43 ++--- .../dev/openfeature/sdk/MutableContext.java | 148 ++++++++++++++++ .../dev/openfeature/sdk/MutableStructure.java | 164 ++++++++++++++++++ .../dev/openfeature/sdk/NoOpProvider.java | 2 +- .../openfeature/sdk/OpenFeatureClient.java | 65 +++---- .../java/dev/openfeature/sdk/Structure.java | 158 ++--------------- .../sdk/DeveloperExperienceTest.java | 4 +- .../dev/openfeature/sdk/EvalContextTest.java | 42 ++--- .../sdk/FlagEvaluationSpecTest.java | 42 ++--- .../dev/openfeature/sdk/HookContextTest.java | 2 +- .../dev/openfeature/sdk/HookSpecTest.java | 36 ++-- .../dev/openfeature/sdk/HookSupportTest.java | 8 +- .../dev/openfeature/sdk/ProviderSpecTest.java | 22 +-- .../dev/openfeature/sdk/StructureTest.java | 8 +- .../java/dev/openfeature/sdk/ValueTest.java | 4 +- .../sdk/integration/StepDefinitions.java | 9 +- 17 files changed, 483 insertions(+), 405 deletions(-) create mode 100644 src/main/java/dev/openfeature/sdk/MutableContext.java create mode 100644 src/main/java/dev/openfeature/sdk/MutableStructure.java diff --git a/src/main/java/dev/openfeature/sdk/EvaluationContext.java b/src/main/java/dev/openfeature/sdk/EvaluationContext.java index ed65ad9e..d613c700 100644 --- a/src/main/java/dev/openfeature/sdk/EvaluationContext.java +++ b/src/main/java/dev/openfeature/sdk/EvaluationContext.java @@ -1,130 +1,21 @@ package dev.openfeature.sdk; -import java.time.Instant; -import java.util.List; - -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; -import lombok.experimental.Delegate; - -@ToString +/** + * The EvaluationContext is a container for arbitrary contextual data + * that can be used as a basis for dynamic evaluation. + */ @SuppressWarnings("PMD.BeanMembersShouldSerialize") -public class EvaluationContext { - - @Setter @Getter private String targetingKey; - @Delegate(excludes = HideDelegateAddMethods.class) private final Structure structure = new Structure(); - - public EvaluationContext() { - super(); - this.targetingKey = ""; - } - - public EvaluationContext(String targetingKey) { - this(); - this.targetingKey = targetingKey; - } +public interface EvaluationContext extends Structure { + String getTargetingKey(); + + void setTargetingKey(String targetingKey); /** - * Merges two EvaluationContext objects with the second overriding the first in + * Merges this EvaluationContext object with the second overriding the this in * case of conflict. * - * @param ctx1 base context - * @param ctx2 overriding context + * @param overridingContext overriding context * @return resulting merged context */ - public static EvaluationContext merge(EvaluationContext ctx1, EvaluationContext ctx2) { - EvaluationContext ec = new EvaluationContext(); - if (ctx1 == null) { - return ctx2; - } else if (ctx2 == null) { - return ctx1; - } - - ec.structure.attributes.putAll(ctx1.structure.attributes); - ec.structure.attributes.putAll(ctx2.structure.attributes); - - if (ctx1.getTargetingKey() != null && !ctx1.getTargetingKey().trim().equals("")) { - ec.setTargetingKey(ctx1.getTargetingKey()); - } - - if (ctx2.getTargetingKey() != null && !ctx2.getTargetingKey().trim().equals("")) { - ec.setTargetingKey(ctx2.getTargetingKey()); - } - - return ec; - } - - // override @Delegate methods so that we can use "add" methods and still return EvaluationContext, not Structure - public EvaluationContext add(String key, Boolean value) { - this.structure.add(key, value); - return this; - } - - public EvaluationContext add(String key, String value) { - this.structure.add(key, value); - return this; - } - - public EvaluationContext add(String key, Integer value) { - this.structure.add(key, value); - return this; - } - - public EvaluationContext add(String key, Double value) { - this.structure.add(key, value); - return this; - } - - public EvaluationContext add(String key, Instant value) { - this.structure.add(key, value); - return this; - } - - public EvaluationContext add(String key, Structure value) { - this.structure.add(key, value); - return this; - } - - public EvaluationContext add(String key, List value) { - this.structure.add(key, value); - return this; - } - - /** - * Hidden class to tell Lombok not to copy these methods over via delegation. - */ - private static class HideDelegateAddMethods { - public Structure add(String ignoredKey, Boolean ignoredValue) { - return null; - } - - public Structure add(String ignoredKey, Double ignoredValue) { - return null; - } - - public Structure add(String ignoredKey, String ignoredValue) { - return null; - } - - public Structure add(String ignoredKey, Value ignoredValue) { - return null; - } - - public Structure add(String ignoredKey, Integer ignoredValue) { - return null; - } - - public Structure add(String ignoredKey, List ignoredValue) { - return null; - } - - public Structure add(String ignoredKey, Structure ignoredValue) { - return null; - } - - public Structure add(String ignoredKey, Instant ignoredValue) { - return null; - } - } + EvaluationContext merge(EvaluationContext overridingContext); } diff --git a/src/main/java/dev/openfeature/sdk/HookSupport.java b/src/main/java/dev/openfeature/sdk/HookSupport.java index 6e29eae3..eb2b4078 100644 --- a/src/main/java/dev/openfeature/sdk/HookSupport.java +++ b/src/main/java/dev/openfeature/sdk/HookSupport.java @@ -11,46 +11,44 @@ @Slf4j @RequiredArgsConstructor -@SuppressWarnings({"unchecked", "rawtypes"}) +@SuppressWarnings({ "unchecked", "rawtypes" }) class HookSupport { public void errorHooks(FlagValueType flagValueType, HookContext hookCtx, Exception e, List hooks, - Map hints) { + Map hints) { executeHooks(flagValueType, hooks, "error", hook -> hook.error(hookCtx, e, hints)); } public void afterAllHooks(FlagValueType flagValueType, HookContext hookCtx, List hooks, - Map hints) { + Map hints) { executeHooks(flagValueType, hooks, "finally", hook -> hook.finallyAfter(hookCtx, hints)); } public void afterHooks(FlagValueType flagValueType, HookContext hookContext, FlagEvaluationDetails details, - List hooks, Map hints) { + List hooks, Map hints) { executeHooksUnchecked(flagValueType, hooks, hook -> hook.after(hookContext, details, hints)); } private void executeHooks( FlagValueType flagValueType, List hooks, String hookMethod, - Consumer> hookCode - ) { + Consumer> hookCode) { if (hooks != null) { hooks - .stream() - .filter(hook -> hook.supportsFlagValueType(flagValueType)) - .forEach(hook -> executeChecked(hook, hookCode, hookMethod)); + .stream() + .filter(hook -> hook.supportsFlagValueType(flagValueType)) + .forEach(hook -> executeChecked(hook, hookCode, hookMethod)); } } private void executeHooksUnchecked( FlagValueType flagValueType, List hooks, - Consumer> hookCode - ) { + Consumer> hookCode) { if (hooks != null) { hooks - .stream() - .filter(hook -> hook.supportsFlagValueType(flagValueType)) - .forEach(hookCode::accept); + .stream() + .filter(hook -> hook.supportsFlagValueType(flagValueType)) + .forEach(hookCode::accept); } } @@ -63,13 +61,16 @@ private void executeChecked(Hook hook, Consumer> hookCode, String } public EvaluationContext beforeHooks(FlagValueType flagValueType, HookContext hookCtx, List hooks, - Map hints) { + Map hints) { Stream result = callBeforeHooks(flagValueType, hookCtx, hooks, hints); - return EvaluationContext.merge(hookCtx.getCtx(), collectContexts(result)); + return hookCtx.getCtx().merge( + result.reduce(hookCtx.getCtx(), (EvaluationContext accumulated, EvaluationContext current) -> { + return accumulated.merge(current); + })); } private Stream callBeforeHooks(FlagValueType flagValueType, HookContext hookCtx, - List hooks, Map hints) { + List hooks, Map hints) { // These traverse backwards from normal. List reversedHooks = IntStream .range(0, hooks.size()) @@ -86,12 +87,4 @@ private Stream callBeforeHooks(FlagValueType flagValueType, H .map(Optional::get) .map(EvaluationContext.class::cast); } - - //for whatever reason, an error `error: incompatible types: invalid method reference` is thrown on compilation - // with javac - //when the reduce call is appended directly as stream call chain above. moving it to its own method works however... - private EvaluationContext collectContexts(Stream result) { - return result - .reduce(new EvaluationContext(), EvaluationContext::merge, EvaluationContext::merge); - } } diff --git a/src/main/java/dev/openfeature/sdk/MutableContext.java b/src/main/java/dev/openfeature/sdk/MutableContext.java new file mode 100644 index 00000000..b11503c2 --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/MutableContext.java @@ -0,0 +1,148 @@ +package dev.openfeature.sdk; + +import java.time.Instant; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.Delegate; + +/** + * The EvaluationContext is a container for arbitrary contextual data + * that can be used as a basis for dynamic evaluation. + * The MutableContext is an EvaluationContext implementation which is not threadsafe, and whose attributes can + * be modified after instantiation. + */ +@ToString +@SuppressWarnings("PMD.BeanMembersShouldSerialize") +public class MutableContext implements EvaluationContext { + + @Setter() @Getter private String targetingKey; + @Delegate(excludes = HideDelegateAddMethods.class) private final MutableStructure structure; + + public MutableContext() { + this.structure = new MutableStructure(); + this.targetingKey = ""; + } + + public MutableContext(String targetingKey) { + this(); + this.targetingKey = targetingKey; + } + + public MutableContext(Map attributes) { + this.structure = new MutableStructure(attributes); + this.targetingKey = ""; + } + + public MutableContext(String targetingKey, Map attributes) { + this(attributes); + this.targetingKey = targetingKey; + } + + // override @Delegate methods so that we can use "add" methods and still return MutableContext, not Structure + public MutableContext add(String key, Boolean value) { + this.structure.add(key, value); + return this; + } + + public MutableContext add(String key, String value) { + this.structure.add(key, value); + return this; + } + + public MutableContext add(String key, Integer value) { + this.structure.add(key, value); + return this; + } + + public MutableContext add(String key, Double value) { + this.structure.add(key, value); + return this; + } + + public MutableContext add(String key, Instant value) { + this.structure.add(key, value); + return this; + } + + public MutableContext add(String key, Structure value) { + this.structure.add(key, value); + return this; + } + + public MutableContext add(String key, List value) { + this.structure.add(key, value); + return this; + } + + /** + * Merges this EvaluationContext objects with the second overriding the this in + * case of conflict. + * + * @param overridingContext overriding context + * @return resulting merged context + */ + @Override + public EvaluationContext merge(EvaluationContext overridingContext) { + if (overridingContext == null) { + return new MutableContext(this.asMap()); + } + + Map merged = new HashMap(); + + merged.putAll(this.asMap()); + merged.putAll(overridingContext.asMap()); + EvaluationContext ec = new MutableContext(merged); + + if (this.getTargetingKey() != null && !this.getTargetingKey().trim().equals("")) { + ec.setTargetingKey(this.getTargetingKey()); + } + + if (overridingContext.getTargetingKey() != null && !overridingContext.getTargetingKey().trim().equals("")) { + ec.setTargetingKey(overridingContext.getTargetingKey()); + } + + return ec; + } + + /** + * Hidden class to tell Lombok not to copy these methods over via delegation. + */ + private static class HideDelegateAddMethods { + public MutableStructure add(String ignoredKey, Boolean ignoredValue) { + return null; + } + + public MutableStructure add(String ignoredKey, Double ignoredValue) { + return null; + } + + public MutableStructure add(String ignoredKey, String ignoredValue) { + return null; + } + + public MutableStructure add(String ignoredKey, Value ignoredValue) { + return null; + } + + public MutableStructure add(String ignoredKey, Integer ignoredValue) { + return null; + } + + public MutableStructure add(String ignoredKey, List ignoredValue) { + return null; + } + + public MutableStructure add(String ignoredKey, MutableStructure ignoredValue) { + return null; + } + + public MutableStructure add(String ignoredKey, Instant ignoredValue) { + return null; + } + } +} diff --git a/src/main/java/dev/openfeature/sdk/MutableStructure.java b/src/main/java/dev/openfeature/sdk/MutableStructure.java new file mode 100644 index 00000000..99e741df --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/MutableStructure.java @@ -0,0 +1,164 @@ +package dev.openfeature.sdk; + +import java.time.Instant; +import java.util.*; +import java.util.stream.Collectors; + +import dev.openfeature.sdk.exceptions.ValueNotConvertableError; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +/** + * {@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 + * be modified after instantiation. + */ +@ToString +@EqualsAndHashCode +@SuppressWarnings("PMD.BeanMembersShouldSerialize") +public class MutableStructure implements Structure { + + protected final Map attributes; + + public MutableStructure() { + this.attributes = new HashMap<>(); + } + + public MutableStructure(Map attributes) { + this.attributes = new HashMap<>(attributes); + } + + @Override + public Set keySet() { + return this.attributes.keySet(); + } + + // getters + @Override + public Value getValue(String key) { + return this.attributes.get(key); + } + + // adders + public MutableStructure add(String key, Value value) { + attributes.put(key, value); + return this; + } + + public MutableStructure add(String key, Boolean value) { + attributes.put(key, new Value(value)); + return this; + } + + public MutableStructure add(String key, String value) { + attributes.put(key, new Value(value)); + return this; + } + + public MutableStructure add(String key, Integer value) { + attributes.put(key, new Value(value)); + return this; + } + + public MutableStructure add(String key, Double value) { + attributes.put(key, new Value(value)); + return this; + } + + /** + * Add date-time relevant key. + * + * @param key feature key + * @param value date-time value + * @return Structure + */ + public MutableStructure add(String key, Instant value) { + attributes.put(key, new Value(value)); + return this; + } + + public MutableStructure add(String key, Structure value) { + attributes.put(key, new Value(value)); + return this; + } + + public MutableStructure add(String key, List value) { + attributes.put(key, new Value(value)); + return this; + } + + /** + * Get all values. + * + * @return all attributes on the structure + */ + @Override + public Map asMap() { + return new HashMap<>(this.attributes); + } + + /** + * Get all values, with primitives types. + * + * @return all attributes on the structure into a Map + */ + @Override + public Map asObjectMap() { + return attributes + .entrySet() + .stream() + .collect(Collectors.toMap( + Map.Entry::getKey, + e -> convertValue(getValue(e.getKey())) + )); + } + + /** + * convertValue is converting the object type Value in a primitive type. + * @param value - Value object to convert + * @return an Object containing the primitive type. + */ + private Object convertValue(Value value) { + if (value.isBoolean()) { + return value.asBoolean(); + } + + if (value.isNumber()) { + Double valueAsDouble = value.asDouble(); + if (valueAsDouble == Math.floor(valueAsDouble) && !Double.isInfinite(valueAsDouble)) { + return value.asInteger(); + } + return valueAsDouble; + } + + if (value.isString()) { + return value.asString(); + } + + if (value.isInstant()) { + return value.asInstant(); + } + + if (value.isList()) { + return value.asList() + .stream() + .map(this::convertValue) + .collect(Collectors.toList()); + } + + if (value.isStructure()) { + Structure s = value.asStructure(); + return s.asMap() + .keySet() + .stream() + .collect( + Collectors.toMap( + key -> key, + key -> convertValue(s.getValue(key)) + ) + ); + } + throw new ValueNotConvertableError(); + } +} diff --git a/src/main/java/dev/openfeature/sdk/NoOpProvider.java b/src/main/java/dev/openfeature/sdk/NoOpProvider.java index 00abedc8..c2e841a5 100644 --- a/src/main/java/dev/openfeature/sdk/NoOpProvider.java +++ b/src/main/java/dev/openfeature/sdk/NoOpProvider.java @@ -58,7 +58,7 @@ public ProviderEvaluation getDoubleEvaluation(String key, Double default @Override public ProviderEvaluation getObjectEvaluation(String key, Value defaultValue, - EvaluationContext invocationContext) { + EvaluationContext invocationContext) { return ProviderEvaluation.builder() .value(defaultValue) .variant(PASSED_IN_DEFAULT) diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index 957afc88..0f99e494 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -14,7 +14,7 @@ import lombok.extern.slf4j.Slf4j; @Slf4j -@SuppressWarnings({"PMD.DataflowAnomalyAnalysis", "PMD.BeanMembersShouldSerialize", "unchecked", "rawtypes"}) +@SuppressWarnings({ "PMD.DataflowAnomalyAnalysis", "PMD.BeanMembersShouldSerialize", "unchecked", "rawtypes" }) public class OpenFeatureClient implements Client { private final OpenFeatureAPI openfeatureApi; @@ -31,10 +31,12 @@ public class OpenFeatureClient implements Client { private EvaluationContext evaluationContext; /** - * Client for evaluating the flag. There may be multiples of these floating around. + * Client for evaluating the flag. There may be multiples of these floating + * around. + * * @param openFeatureAPI Backing global singleton - * @param name Name of the client (used by observability tools). - * @param version Version of the client (used by observability tools). + * @param name Name of the client (used by observability tools). + * @param version Version of the client (used by observability tools). */ public OpenFeatureClient(OpenFeatureAPI openFeatureAPI, String name, String version) { this.openfeatureApi = openFeatureAPI; @@ -50,11 +52,11 @@ public void addHooks(Hook... hooks) { } 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()); + () -> FlagEvaluationOptions.builder().build()); Map hints = Collections.unmodifiableMap(flagOptions.getHookHints()); - ctx = ObjectUtils.defaultIfNull(ctx, () -> new EvaluationContext()); + ctx = ObjectUtils.defaultIfNull(ctx, () -> new MutableContext()); FeatureProvider provider = ObjectUtils.defaultIfNull(openfeatureApi.getProvider(), () -> { log.debug("No provider configured, using no-op provider."); return new NoOpProvider(); @@ -67,23 +69,23 @@ private FlagEvaluationDetails evaluateFlag(FlagValueType type, String key try { hookCtx = HookContext.from(key, type, this.getMetadata(), - openfeatureApi.getProvider().getMetadata(), ctx, defaultValue); + openfeatureApi.getProvider().getMetadata(), ctx, defaultValue); mergedHooks = ObjectUtils.merge(provider.getProviderHooks(), flagOptions.getHooks(), clientHooks, - openfeatureApi.getApiHooks()); + openfeatureApi.getApiHooks()); EvaluationContext ctxFromHook = hookSupport.beforeHooks(type, hookCtx, mergedHooks, hints); - EvaluationContext invocationCtx = EvaluationContext.merge(ctx, ctxFromHook); + EvaluationContext invocationCtx = ctx.merge(ctxFromHook); // merge of: API.context, client.context, invocation.context - EvaluationContext mergedCtx = EvaluationContext.merge( - EvaluationContext.merge( - openfeatureApi.getEvaluationContext(), - this.getEvaluationContext() - ), - invocationCtx - ); + EvaluationContext apiContext = openfeatureApi.getEvaluationContext() != null + ? openfeatureApi.getEvaluationContext() + : new MutableContext(); + EvaluationContext clientContext = openfeatureApi.getEvaluationContext() != null + ? this.getEvaluationContext() + : new MutableContext(); + EvaluationContext mergedCtx = apiContext.merge(clientContext.merge(invocationCtx)); ProviderEvaluation providerEval = (ProviderEvaluation) createProviderEvaluation(type, key, defaultValue, provider, mergedCtx); @@ -96,7 +98,7 @@ private FlagEvaluationDetails evaluateFlag(FlagValueType type, String key details = FlagEvaluationDetails.builder().build(); } if (e instanceof OpenFeatureError) { - details.setErrorCode(((OpenFeatureError)e).getErrorCode()); + details.setErrorCode(((OpenFeatureError) e).getErrorCode()); } else { details.setErrorCode(ErrorCode.GENERAL); } @@ -116,8 +118,7 @@ private ProviderEvaluation createProviderEvaluation( String key, T defaultValue, FeatureProvider provider, - EvaluationContext invocationContext - ) { + EvaluationContext invocationContext) { switch (type) { case BOOLEAN: return provider.getBooleanEvaluation(key, (Boolean) defaultValue, invocationContext); @@ -146,13 +147,13 @@ 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(); } @Override public FlagEvaluationDetails getBooleanDetails(String key, Boolean defaultValue) { - return getBooleanDetails(key, defaultValue, new EvaluationContext()); + return getBooleanDetails(key, defaultValue, null); } @Override @@ -162,7 +163,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); } @@ -178,7 +179,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(); } @@ -194,7 +195,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); } @@ -210,13 +211,13 @@ 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(); } @Override public FlagEvaluationDetails getIntegerDetails(String key, Integer defaultValue) { - return getIntegerDetails(key, defaultValue, new EvaluationContext()); + return getIntegerDetails(key, defaultValue, null); } @Override @@ -226,7 +227,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); } @@ -242,7 +243,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(); } @@ -258,7 +259,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); } @@ -285,13 +286,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 70c98b77..5c67551f 100644 --- a/src/main/java/dev/openfeature/sdk/Structure.java +++ b/src/main/java/dev/openfeature/sdk/Structure.java @@ -1,161 +1,41 @@ package dev.openfeature.sdk; -import java.time.Instant; -import java.util.*; -import java.util.stream.Collectors; - -import dev.openfeature.sdk.exceptions.ValueNotConvertableError; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -// Note: We don't accept instances of T for EC b/c walking arbitrary objects to serialize them isn't quite a straight -// forward for providers. They may not have access to tools like Jackson or Gson. +import java.util.Map; +import java.util.Set; /** - * {@link Structure} represents a potentially nested object type which is used to pass complex objects via - * {@link EvaluationContext}. + * {@link Structure} represents a potentially nested object type which is used to represent + * structured data. */ -@ToString -@EqualsAndHashCode @SuppressWarnings("PMD.BeanMembersShouldSerialize") -public class Structure { - - protected final Map attributes; - - public Structure() { - this.attributes = new HashMap<>(); - } - - public Structure(Map attributes) { - this.attributes = new HashMap<>(attributes); - } - - public Set keySet() { - return this.attributes.keySet(); - } - - // getters - public Value getValue(String key) { - return this.attributes.get(key); - } - - // adders - public Structure add(String key, Value value) { - attributes.put(key, value); - return this; - } - - public Structure add(String key, Boolean value) { - attributes.put(key, new Value(value)); - return this; - } - - public Structure add(String key, String value) { - attributes.put(key, new Value(value)); - return this; - } - - public Structure add(String key, Integer value) { - attributes.put(key, new Value(value)); - return this; - } - - public Structure add(String key, Double value) { - attributes.put(key, new Value(value)); - return this; - } - +public interface Structure { + /** - * Add date-time relevant key. + * Get all keys. * - * @param key feature key - * @param value date-time value - * @return Structure + * @return the set of keys */ - public Structure add(String key, Instant value) { - attributes.put(key, new Value(value)); - return this; - } - - public Structure add(String key, Structure value) { - attributes.put(key, new Value(value)); - return this; - } - - public Structure add(String key, List value) { - attributes.put(key, new Value(value)); - return this; - } + Set keySet(); /** - * Get all values. + * Get the value indexed by key. * - * @return all attributes on the structure + * @param key String the key. + * @return the Value */ - public Map asMap() { - return new HashMap<>(this.attributes); - } + Value getValue(String key); /** - * Get all values, with primitives types. + * Get all values, as a map of Values. * * @return all attributes on the structure into a Map */ - public Map asObjectMap() { - return attributes - .entrySet() - .stream() - .collect(Collectors.toMap( - Map.Entry::getKey, - e -> convertValue(getValue(e.getKey())) - )); - } + Map asMap(); /** - * convertValue is converting the object type Value in a primitive type. - * @param value - Value object to convert - * @return an Object containing the primitive type. + * Get all values, with as a map of Object. + * + * @return all attributes on the structure into a Map */ - private Object convertValue(Value value) { - if (value.isBoolean()) { - return value.asBoolean(); - } - - if (value.isNumber()) { - Double valueAsDouble = value.asDouble(); - if (valueAsDouble == Math.floor(valueAsDouble) && !Double.isInfinite(valueAsDouble)) { - return value.asInteger(); - } - return valueAsDouble; - } - - if (value.isString()) { - return value.asString(); - } - - if (value.isInstant()) { - return value.asInstant(); - } - - if (value.isList()) { - return value.asList() - .stream() - .map(this::convertValue) - .collect(Collectors.toList()); - } - - if (value.isStructure()) { - Structure s = value.asStructure(); - return s.asMap() - .keySet() - .stream() - .collect( - Collectors.toMap( - key -> key, - key -> convertValue(s.getValue(key)) - ) - ); - } - throw new ValueNotConvertableError(); - } + Map asObjectMap(); } diff --git a/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java b/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java index bb0825b0..454f1670 100644 --- a/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java +++ b/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java @@ -61,7 +61,7 @@ class DeveloperExperienceTest implements HookFixtures { /** * As an application author, you probably know special things about your users. You can communicate these to the - * provider via {@link EvaluationContext} + * provider via {@link MutableContext} */ @Test void providingContext() { @@ -69,7 +69,7 @@ class DeveloperExperienceTest implements HookFixtures { api.setProvider(new NoOpProvider()); Client client = api.getClient(); - EvaluationContext ctx = new EvaluationContext() + MutableContext ctx = new MutableContext() .add("int-val", 3) .add("double-val", 4.0) .add("str-val", "works") diff --git a/src/test/java/dev/openfeature/sdk/EvalContextTest.java b/src/test/java/dev/openfeature/sdk/EvalContextTest.java index 4a974e4e..ba31b4b3 100644 --- a/src/test/java/dev/openfeature/sdk/EvalContextTest.java +++ b/src/test/java/dev/openfeature/sdk/EvalContextTest.java @@ -15,16 +15,16 @@ public class EvalContextTest { 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 EvaluationContext(); + MutableContext ec = new MutableContext(); ec.setTargetingKey("targeting-key"); assertEquals("targeting-key", ec.getTargetingKey()); } - @Specification(number="3.1.2", text="The evaluation context MUST support the inclusion of " + + @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() { - EvaluationContext ec = new EvaluationContext(); + MutableContext ec = new MutableContext(); ec.add("str", "test"); assertEquals("test", ec.getValue("str").asString()); @@ -44,8 +44,8 @@ public class EvalContextTest { "custom fields, having keys of type `string`, and " + "values of type `boolean | string | number | datetime | structure`.") @Test void eval_context_structure_array() { - EvaluationContext ec = new EvaluationContext(); - ec.add("obj", new Structure().add("val1", 1).add("val2", "2")); + MutableContext ec = new MutableContext(); + ec.add("obj", new MutableStructure().add("val1", 1).add("val2", "2")); ec.add("arr", new ArrayList(){{ add(new Value("one")); add(new Value("two")); @@ -62,7 +62,7 @@ public class EvalContextTest { @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() { - EvaluationContext ec = new EvaluationContext(); + MutableContext ec = new MutableContext(); ec.add("str", "test"); ec.add("str2", "test2"); @@ -76,7 +76,7 @@ public class EvalContextTest { Instant dt = Instant.now(); ec.add("dt", dt); - ec.add("obj", new Structure().add("val1", 1).add("val2", "2")); + ec.add("obj", new MutableStructure().add("val1", 1).add("val2", "2")); Map foundStr = ec.asMap(); assertEquals(ec.getValue("str").asString(), foundStr.get("str").asString()); @@ -97,7 +97,7 @@ public class EvalContextTest { @Specification(number="3.1.4", text="The evaluation context fields MUST have an unique key.") @Test void unique_key_across_types() { - EvaluationContext ec = new EvaluationContext(); + MutableContext ec = new MutableContext(); ec.add("key", "val"); ec.add("key", "val2"); assertEquals("val2", ec.getValue("key").asString()); @@ -107,20 +107,20 @@ public class EvalContextTest { } @Test void can_chain_attribute_addition() { - EvaluationContext ec = new EvaluationContext(); - EvaluationContext out = ec.add("str", "test") + MutableContext ec = new MutableContext(); + MutableContext out = ec.add("str", "test") .add("int", 4) .add("bool", false) - .add("str", new Structure()); - assertEquals(EvaluationContext.class, out.getClass()); + .add("str", new MutableStructure()); + assertEquals(MutableContext.class, out.getClass()); } @Test void can_add_key_with_null() { - EvaluationContext ec = new EvaluationContext() + MutableContext ec = new MutableContext() .add("Boolean", (Boolean)null) .add("String", (String)null) .add("Double", (Double)null) - .add("Structure", (Structure)null) + .add("Structure", (MutableStructure)null) .add("List", (List)null) .add("Instant", (Instant)null); assertEquals(6, ec.asMap().size()); @@ -134,25 +134,25 @@ public class EvalContextTest { @Test void merge_targeting_key() { String key1 = "key1"; - EvaluationContext ctx1 = new EvaluationContext(key1); - EvaluationContext ctx2 = new EvaluationContext(); + EvaluationContext ctx1 = new MutableContext(key1); + EvaluationContext ctx2 = new MutableContext(); - EvaluationContext ctxMerged = EvaluationContext.merge(ctx1, ctx2); + EvaluationContext ctxMerged = ctx1.merge(ctx2); assertEquals(key1, ctxMerged.getTargetingKey()); String key2 = "key2"; ctx2.setTargetingKey(key2); - ctxMerged = EvaluationContext.merge(ctx1, ctx2); + ctxMerged = ctx1.merge(ctx2); assertEquals(key2, ctxMerged.getTargetingKey()); ctx2.setTargetingKey(" "); - ctxMerged = EvaluationContext.merge(ctx1, ctx2); + ctxMerged = ctx1.merge(ctx2); assertEquals(key1, ctxMerged.getTargetingKey()); } @Test void asObjectMap() { String key1 = "key1"; - EvaluationContext ctx = new EvaluationContext(key1); + MutableContext ctx = new MutableContext(key1); ctx.add("stringItem", "stringValue"); ctx.add("boolItem", false); ctx.add("integerItem", 1); @@ -172,7 +172,7 @@ public class EvalContextTest { structureValue.put("structIntegerItem", new Value(1)); structureValue.put("structDoubleItem", new Value(1.2)); structureValue.put("structInstantItem", new Value(Instant.ofEpochSecond(1663331342))); - Structure structure = new Structure(structureValue); + Structure structure = new MutableStructure(structureValue); ctx.add("structureItem", structure); diff --git a/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java b/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java index fda13ddf..75b6e5bb 100644 --- a/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java @@ -100,24 +100,24 @@ private Client _client() { String key = "key"; assertEquals(true, c.getBooleanValue(key, false)); - assertEquals(true, c.getBooleanValue(key, false, new EvaluationContext())); - assertEquals(true, c.getBooleanValue(key, false, new EvaluationContext(), FlagEvaluationOptions.builder().build())); + assertEquals(true, c.getBooleanValue(key, false, new MutableContext())); + assertEquals(true, c.getBooleanValue(key, false, new MutableContext(), FlagEvaluationOptions.builder().build())); assertEquals("gnirts-ym", c.getStringValue(key, "my-string")); - assertEquals("gnirts-ym", c.getStringValue(key, "my-string", new EvaluationContext())); - assertEquals("gnirts-ym", c.getStringValue(key, "my-string", new EvaluationContext(), FlagEvaluationOptions.builder().build())); + assertEquals("gnirts-ym", c.getStringValue(key, "my-string", new MutableContext())); + assertEquals("gnirts-ym", c.getStringValue(key, "my-string", new MutableContext(), FlagEvaluationOptions.builder().build())); assertEquals(400, c.getIntegerValue(key, 4)); - assertEquals(400, c.getIntegerValue(key, 4, new EvaluationContext())); - assertEquals(400, c.getIntegerValue(key, 4, new EvaluationContext(), FlagEvaluationOptions.builder().build())); + assertEquals(400, c.getIntegerValue(key, 4, new MutableContext())); + assertEquals(400, c.getIntegerValue(key, 4, new MutableContext(), FlagEvaluationOptions.builder().build())); assertEquals(40.0, c.getDoubleValue(key, .4)); - assertEquals(40.0, c.getDoubleValue(key, .4, new EvaluationContext())); - assertEquals(40.0, c.getDoubleValue(key, .4, new EvaluationContext(), FlagEvaluationOptions.builder().build())); + assertEquals(40.0, c.getDoubleValue(key, .4, new MutableContext())); + assertEquals(40.0, c.getDoubleValue(key, .4, new MutableContext(), FlagEvaluationOptions.builder().build())); assertEquals(null, c.getObjectValue(key, new Value())); - assertEquals(null, c.getObjectValue(key, new Value(), new EvaluationContext())); - assertEquals(null, c.getObjectValue(key, new Value(), new EvaluationContext(), FlagEvaluationOptions.builder().build())); + assertEquals(null, c.getObjectValue(key, new Value(), new MutableContext())); + assertEquals(null, c.getObjectValue(key, new Value(), new MutableContext(), FlagEvaluationOptions.builder().build())); } @Specification(number="1.4.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.") @@ -138,8 +138,8 @@ private Client _client() { .variant(null) .build(); assertEquals(bd, c.getBooleanDetails(key, true)); - assertEquals(bd, c.getBooleanDetails(key, true, new EvaluationContext())); - assertEquals(bd, c.getBooleanDetails(key, true, new EvaluationContext(), FlagEvaluationOptions.builder().build())); + assertEquals(bd, c.getBooleanDetails(key, true, new MutableContext())); + assertEquals(bd, c.getBooleanDetails(key, true, new MutableContext(), FlagEvaluationOptions.builder().build())); FlagEvaluationDetails sd = FlagEvaluationDetails.builder() .flagKey(key) @@ -147,24 +147,24 @@ private Client _client() { .variant(null) .build(); assertEquals(sd, c.getStringDetails(key, "test")); - assertEquals(sd, c.getStringDetails(key, "test", new EvaluationContext())); - assertEquals(sd, c.getStringDetails(key, "test", new EvaluationContext(), FlagEvaluationOptions.builder().build())); + assertEquals(sd, c.getStringDetails(key, "test", new MutableContext())); + assertEquals(sd, c.getStringDetails(key, "test", new MutableContext(), FlagEvaluationOptions.builder().build())); FlagEvaluationDetails id = FlagEvaluationDetails.builder() .flagKey(key) .value(400) .build(); assertEquals(id, c.getIntegerDetails(key, 4)); - assertEquals(id, c.getIntegerDetails(key, 4, new EvaluationContext())); - assertEquals(id, c.getIntegerDetails(key, 4, new EvaluationContext(), FlagEvaluationOptions.builder().build())); + assertEquals(id, c.getIntegerDetails(key, 4, new MutableContext())); + assertEquals(id, c.getIntegerDetails(key, 4, new MutableContext(), FlagEvaluationOptions.builder().build())); FlagEvaluationDetails dd = FlagEvaluationDetails.builder() .flagKey(key) .value(40.0) .build(); assertEquals(dd, c.getDoubleDetails(key, .4)); - assertEquals(dd, c.getDoubleDetails(key, .4, new EvaluationContext())); - assertEquals(dd, c.getDoubleDetails(key, .4, new EvaluationContext(), FlagEvaluationOptions.builder().build())); + assertEquals(dd, c.getDoubleDetails(key, .4, new MutableContext())); + assertEquals(dd, c.getDoubleDetails(key, .4, new MutableContext(), FlagEvaluationOptions.builder().build())); // TODO: Structure detail tests. } @@ -233,20 +233,20 @@ private Client _client() { DoSomethingProvider provider = new DoSomethingProvider(); api.setProvider(provider); - EvaluationContext apiCtx = new EvaluationContext(); + MutableContext apiCtx = new MutableContext(); apiCtx.add("common", "1"); apiCtx.add("common2", "1"); apiCtx.add("api", "2"); api.setEvaluationContext(apiCtx); Client c = api.getClient(); - EvaluationContext clientCtx = new EvaluationContext(); + MutableContext clientCtx = new MutableContext(); clientCtx.add("common", "3"); clientCtx.add("common2", "3"); clientCtx.add("client", "4"); c.setEvaluationContext(clientCtx); - EvaluationContext invocationCtx = new EvaluationContext(); + MutableContext invocationCtx = new MutableContext(); clientCtx.add("common", "5"); clientCtx.add("invocation", "6"); diff --git a/src/test/java/dev/openfeature/sdk/HookContextTest.java b/src/test/java/dev/openfeature/sdk/HookContextTest.java index 6b28c1de..e27d0ab5 100644 --- a/src/test/java/dev/openfeature/sdk/HookContextTest.java +++ b/src/test/java/dev/openfeature/sdk/HookContextTest.java @@ -15,7 +15,7 @@ class HookContextTest { FlagValueType.BOOLEAN, meta, meta, - new EvaluationContext(), + new MutableContext(), false ); diff --git a/src/test/java/dev/openfeature/sdk/HookSpecTest.java b/src/test/java/dev/openfeature/sdk/HookSpecTest.java index 1c3e45ab..d028cc6c 100644 --- a/src/test/java/dev/openfeature/sdk/HookSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSpecTest.java @@ -103,7 +103,7 @@ void emptyApiHooks() { HookContext.builder() .flagKey("key") .type(FlagValueType.INTEGER) - .ctx(new EvaluationContext()) + .ctx(new MutableContext()) .build(); fail("Missing default value shouldn't be valid"); } catch (NullPointerException e) { @@ -115,7 +115,7 @@ void emptyApiHooks() { HookContext.builder() .flagKey("key") .type(FlagValueType.INTEGER) - .ctx(new EvaluationContext()) + .ctx(new MutableContext()) .defaultValue(1) .build(); } catch (NullPointerException e) { @@ -130,7 +130,7 @@ void emptyApiHooks() { HookContext.builder() .flagKey("key") .type(FlagValueType.INTEGER) - .ctx(new EvaluationContext()) + .ctx(new MutableContext()) .defaultValue(1) .build(); @@ -138,7 +138,7 @@ void emptyApiHooks() { HookContext.builder() .flagKey("key") .type(FlagValueType.INTEGER) - .ctx(new EvaluationContext()) + .ctx(new MutableContext()) .providerMetadata(new NoOpProvider().getMetadata()) .defaultValue(1) .build(); @@ -147,7 +147,7 @@ void emptyApiHooks() { HookContext.builder() .flagKey("key") .type(FlagValueType.INTEGER) - .ctx(new EvaluationContext()) + .ctx(new MutableContext()) .defaultValue(1) .clientMetadata(OpenFeatureAPI.getInstance().getClient().getMetadata()) .build(); @@ -160,7 +160,7 @@ void emptyApiHooks() { Client client = api.getClient(); Hook evalHook = mockBooleanHook(); - client.getBooleanValue("key", false, new EvaluationContext(), + client.getBooleanValue("key", false, new MutableContext(), FlagEvaluationOptions.builder().hook(evalHook).build()); verify(evalHook, times(1)).before(any(), any()); @@ -366,7 +366,7 @@ public void finallyAfter(HookContext ctx, Map hints) { hh.put(hintKey, "My hint value"); hh = Collections.unmodifiableMap(hh); - client.getBooleanValue("key", false, new EvaluationContext(), FlagEvaluationOptions.builder() + client.getBooleanValue("key", false, new MutableContext(), FlagEvaluationOptions.builder() .hook(mutatingHook) .hookHints(hh) .build()); @@ -391,7 +391,7 @@ public void finallyAfter(HookContext ctx, Map hints) { OpenFeatureAPI api = OpenFeatureAPI.getInstance(); api.setProvider(provider); Client client = api.getClient(); - client.getBooleanValue("key", false, new EvaluationContext(), + client.getBooleanValue("key", false, new MutableContext(), FlagEvaluationOptions.builder().hook(hook).build()); order.verify(hook).before(any(), any()); @@ -406,7 +406,7 @@ public void finallyAfter(HookContext ctx, Map hints) { Hook hook = mockBooleanHook(); doThrow(RuntimeException.class).when(hook).before(any(), any()); Client client = getClient(null); - Boolean value = client.getBooleanValue("key", false, new EvaluationContext(), + Boolean value = client.getBooleanValue("key", false, new MutableContext(), FlagEvaluationOptions.builder().hook(hook).build()); verify(hook, times(1)).before(any(), any()); verify(hook, times(1)).error(any(), any(), any()); @@ -418,7 +418,7 @@ public void finallyAfter(HookContext ctx, Map hints) { Hook hook = mockBooleanHook(); doThrow(RuntimeException.class).when(hook).after(any(), any(), any()); Client client = getClient(null); - client.getBooleanValue("key", false, new EvaluationContext(), + client.getBooleanValue("key", false, new MutableContext(), FlagEvaluationOptions.builder().hook(hook).build()); verify(hook, times(1)).after(any(), any(), any()); verify(hook, times(1)).error(any(), any(), any()); @@ -431,7 +431,7 @@ public void finallyAfter(HookContext ctx, Map hints) { Client client = getClient(null); - client.getBooleanValue("key", false, new EvaluationContext(), + client.getBooleanValue("key", false, new MutableContext(), FlagEvaluationOptions.builder() .hook(hook2) .hook(hook) @@ -447,7 +447,7 @@ public void finallyAfter(HookContext ctx, Map hints) { @Specification(number = "4.1.4", text = "The evaluation context MUST be mutable only within the before hook.") @Specification(number = "4.3.3", text = "Any evaluation context returned from a before hook MUST be passed to subsequent before hooks (via HookContext).") @Test void beforeContextUpdated() { - EvaluationContext ctx = new EvaluationContext(); + MutableContext ctx = new MutableContext(); Hook hook = mockBooleanHook(); when(hook.before(any(), any())).thenReturn(Optional.of(ctx)); Hook hook2 = mockBooleanHook(); @@ -472,11 +472,11 @@ public void finallyAfter(HookContext ctx, Map hints) { @Specification(number="4.3.4", text="When before hooks have finished executing, any resulting evaluation context MUST be merged with the existing evaluation context.") @Test void mergeHappensCorrectly() { - EvaluationContext hookCtx = new EvaluationContext(); + MutableContext hookCtx = new MutableContext(); hookCtx.add("test", "works"); hookCtx.add("another", "exists"); - EvaluationContext invocationCtx = new EvaluationContext(); + MutableContext invocationCtx = new MutableContext(); invocationCtx.add("something", "here"); invocationCtx.add("test", "broken"); @@ -496,9 +496,9 @@ public void finallyAfter(HookContext ctx, Map hints) { .hook(hook) .build()); - ArgumentCaptor captor = ArgumentCaptor.forClass(EvaluationContext.class); + ArgumentCaptor captor = ArgumentCaptor.forClass(MutableContext.class); verify(provider).getBooleanEvaluation(any(), any(), captor.capture()); - EvaluationContext ec = captor.getValue(); + MutableContext ec = captor.getValue(); assertEquals("works", ec.getValue("test").asString()); assertEquals("exists", ec.getValue("another").asString()); assertEquals("here", ec.getValue("something").asString()); @@ -513,7 +513,7 @@ public void finallyAfter(HookContext ctx, Map hints) { InOrder order = inOrder(hook, hook2); Client client = getClient(null); - client.getBooleanValue("key", false, new EvaluationContext(), + client.getBooleanValue("key", false, new MutableContext(), FlagEvaluationOptions.builder() .hook(hook2) .hook(hook) @@ -533,7 +533,7 @@ public void finallyAfter(HookContext ctx, Map hints) { InOrder order = inOrder(hook, hook2); Client client = getClient(null); - client.getBooleanValue("key", false, new EvaluationContext(), + client.getBooleanValue("key", false, new MutableContext(), FlagEvaluationOptions.builder() .hook(hook2) .hook(hook) diff --git a/src/test/java/dev/openfeature/sdk/HookSupportTest.java b/src/test/java/dev/openfeature/sdk/HookSupportTest.java index e846707a..d787bb0c 100644 --- a/src/test/java/dev/openfeature/sdk/HookSupportTest.java +++ b/src/test/java/dev/openfeature/sdk/HookSupportTest.java @@ -21,7 +21,7 @@ class HookSupportTest implements HookFixtures { @Test @DisplayName("should merge EvaluationContexts on before hooks correctly") void shouldMergeEvaluationContextsOnBeforeHooksCorrectly() { - EvaluationContext baseContext = new EvaluationContext(); + MutableContext baseContext = new MutableContext(); baseContext.add("baseKey", "baseValue"); HookContext hookContext = new HookContext<>("flagKey", FlagValueType.STRING, "defaultValue", baseContext, () -> "client", () -> "provider"); Hook hook1 = mockStringHook(); @@ -43,7 +43,7 @@ void shouldMergeEvaluationContextsOnBeforeHooksCorrectly() { void shouldAlwaysCallGenericHook(FlagValueType flagValueType) { Hook genericHook = mockGenericHook(); HookSupport hookSupport = new HookSupport(); - EvaluationContext baseContext = new EvaluationContext(); + MutableContext baseContext = new MutableContext(); IllegalStateException expectedException = new IllegalStateException("All fine, just a test"); HookContext hookContext = new HookContext<>("flagKey", flagValueType, createDefaultValue(flagValueType), baseContext, () -> "client", () -> "provider"); @@ -75,8 +75,8 @@ private Object createDefaultValue(FlagValueType flagValueType) { } } - private EvaluationContext evaluationContextWithValue(String key, String value) { - EvaluationContext result = new EvaluationContext(); + private MutableContext evaluationContextWithValue(String key, String value) { + MutableContext result = new MutableContext(); result.add(key, value); return result; } diff --git a/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java b/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java index 5e642421..27cc64e8 100644 --- a/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java @@ -24,33 +24,33 @@ public class ProviderSpecTest { @Specification(number="2.9.1", text="The flag resolution 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 EvaluationContext()); + ProviderEvaluation int_result = p.getIntegerEvaluation("key", 4, new MutableContext()); assertNotNull(int_result.getValue()); - ProviderEvaluation double_result = p.getDoubleEvaluation("key", 0.4, new EvaluationContext()); + ProviderEvaluation double_result = p.getDoubleEvaluation("key", 0.4, new MutableContext()); assertNotNull(double_result.getValue()); - ProviderEvaluation string_result = p.getStringEvaluation("key", "works", new EvaluationContext()); + ProviderEvaluation string_result = p.getStringEvaluation("key", "works", new MutableContext()); assertNotNull(string_result.getValue()); - ProviderEvaluation boolean_result = p.getBooleanEvaluation("key", false, new EvaluationContext()); + ProviderEvaluation boolean_result = p.getBooleanEvaluation("key", false, new MutableContext()); assertNotNull(boolean_result.getValue()); - ProviderEvaluation object_result = p.getObjectEvaluation("key", new Value(), new EvaluationContext()); + ProviderEvaluation object_result = p.getObjectEvaluation("key", new Value(), new MutableContext()); assertNotNull(object_result.getValue()); } @Specification(number="2.6", text="The `provider` SHOULD populate the `flag resolution` structure's `reason` field with `\"DEFAULT\",` `\"TARGETING_MATCH\"`, `\"SPLIT\"`, `\"DISABLED\"`, `\"UNKNOWN\"`, `\"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 EvaluationContext()); + ProviderEvaluation result = p.getBooleanEvaluation("key", false, new MutableContext()); assertEquals(Reason.DEFAULT.toString(), result.getReason()); } @Specification(number="2.7", text="In cases of normal execution, the provider MUST NOT populate " + "the flag resolution 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 EvaluationContext()); + ProviderEvaluation result = p.getBooleanEvaluation("key", false, new MutableContext()); assertNull(result.getErrorCode()); } @@ -62,16 +62,16 @@ public class ProviderSpecTest { @Specification(number="2.5", text="In cases of normal execution, the provider SHOULD populate the " + "flag resolution 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 EvaluationContext()); + ProviderEvaluation int_result = p.getIntegerEvaluation("key", 4, new MutableContext()); assertNotNull(int_result.getReason()); - ProviderEvaluation double_result = p.getDoubleEvaluation("key", 0.4, new EvaluationContext()); + ProviderEvaluation double_result = p.getDoubleEvaluation("key", 0.4, new MutableContext()); assertNotNull(double_result.getReason()); - ProviderEvaluation string_result = p.getStringEvaluation("key", "works", new EvaluationContext()); + ProviderEvaluation string_result = p.getStringEvaluation("key", "works", new MutableContext()); assertNotNull(string_result.getReason()); - ProviderEvaluation boolean_result = p.getBooleanEvaluation("key", false, new EvaluationContext()); + ProviderEvaluation boolean_result = p.getBooleanEvaluation("key", false, new MutableContext()); assertNotNull(boolean_result.getReason()); } diff --git a/src/test/java/dev/openfeature/sdk/StructureTest.java b/src/test/java/dev/openfeature/sdk/StructureTest.java index 8170ea3d..f05f9302 100644 --- a/src/test/java/dev/openfeature/sdk/StructureTest.java +++ b/src/test/java/dev/openfeature/sdk/StructureTest.java @@ -14,7 +14,7 @@ public class StructureTest { @Test public void noArgShouldContainEmptyAttributes() { - Structure structure = new Structure(); + MutableStructure structure = new MutableStructure(); assertEquals(0, structure.asMap().keySet().size()); } @@ -25,7 +25,7 @@ public class StructureTest { put(KEY, new Value(KEY)); } }; - Structure structure = new Structure(map); + MutableStructure structure = new MutableStructure(map); assertEquals(KEY, structure.asMap().get(KEY).asString()); assertNotSame(structure.asMap(), map); // should be a copy } @@ -45,11 +45,11 @@ public class StructureTest { int INT_VAL = 13; double DOUBLE_VAL = .5; Instant DATE_VAL = Instant.now(); - Structure STRUCT_VAL = new Structure(); + MutableStructure STRUCT_VAL = new MutableStructure(); List LIST_VAL = new ArrayList(); Value VALUE_VAL = new Value(); - Structure structure = new Structure(); + MutableStructure structure = new MutableStructure(); structure.add(BOOL_KEY, BOOL_VAL); structure.add(STRING_KEY, STRING_VAL); structure.add(INT_KEY, INT_VAL); diff --git a/src/test/java/dev/openfeature/sdk/ValueTest.java b/src/test/java/dev/openfeature/sdk/ValueTest.java index f8bebb21..cf25e7b3 100644 --- a/src/test/java/dev/openfeature/sdk/ValueTest.java +++ b/src/test/java/dev/openfeature/sdk/ValueTest.java @@ -24,7 +24,7 @@ public class ValueTest { list.add(true); list.add("val"); list.add(.5); - list.add(new Structure()); + list.add(new MutableStructure()); list.add(new ArrayList()); list.add(Instant.now()); @@ -96,7 +96,7 @@ class Something {} @Test public void structureShouldContainStructure() { String INNER_KEY = "key"; String INNER_VALUE = "val"; - Structure innerValue = new Structure().add(INNER_KEY, INNER_VALUE); + MutableStructure innerValue = new MutableStructure().add(INNER_KEY, INNER_VALUE); Value value = new Value(innerValue); assertTrue(value.isStructure()); assertEquals(INNER_VALUE, value.asStructure().getValue(INNER_KEY).asString()); diff --git a/src/test/java/dev/openfeature/sdk/integration/StepDefinitions.java b/src/test/java/dev/openfeature/sdk/integration/StepDefinitions.java index 39147565..3513bddc 100644 --- a/src/test/java/dev/openfeature/sdk/integration/StepDefinitions.java +++ b/src/test/java/dev/openfeature/sdk/integration/StepDefinitions.java @@ -5,8 +5,9 @@ // import dev.openfeature.contrib.providers.flagd.FlagdProvider; import dev.openfeature.sdk.Client; -import dev.openfeature.sdk.EvaluationContext; import dev.openfeature.sdk.FlagEvaluationDetails; +import dev.openfeature.sdk.MutableStructure; +import dev.openfeature.sdk.MutableContext; import dev.openfeature.sdk.OpenFeatureAPI; import dev.openfeature.sdk.Reason; import dev.openfeature.sdk.Structure; @@ -32,7 +33,7 @@ public class StepDefinitions { private String contextAwareFlagKey; private String contextAwareDefaultValue; - private EvaluationContext context; + private MutableContext context; private String contextAwareValue; private String notFoundFlagKey; @@ -206,7 +207,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) { - this.context = new EvaluationContext() + this.context = new MutableContext() .add(field1, value1) .add(field2, value2) .add(field3, value3) @@ -229,7 +230,7 @@ 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 EvaluationContext()); + new MutableContext()); assertEquals(expected, emptyContextValue); } From 4d462930a2decfbaabf65e02ce4cbebb76a35554 Mon Sep 17 00:00:00 2001 From: Justin Abrahms Date: Thu, 6 Oct 2022 07:31:35 -0700 Subject: [PATCH 28/63] feat: Support for generating CycloneDX sboms (#119) Signed-off-by: Justin Abrahms Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/pom.xml b/pom.xml index 3233c4c8..5131a84e 100644 --- a/pom.xml +++ b/pom.xml @@ -164,6 +164,32 @@ + + org.cyclonedx + cyclonedx-maven-plugin + 2.7.0 + + library + 1.3 + true + true + true + true + true + false + false + all + + + + package + + makeAggregateBom + + + + + maven-dependency-plugin 3.3.0 From 1ab5ef1e635b59a9301691618c4d5bca8cbd48fe Mon Sep 17 00:00:00 2001 From: Step Security Bot Date: Thu, 6 Oct 2022 09:29:47 -0700 Subject: [PATCH 29/63] chore: [StepSecurity] ci: Harden GitHub Actions (#120) * [StepSecurity] ci: Harden GitHub Actions in release.yml * [StepSecurity] ci: Harden GitHub Actions in static-code-scanning.yaml * [StepSecurity] ci: Harden GitHub Actions in lint-pr.yml * [StepSecurity] ci: Harden GitHub Actions in merge.yml * [StepSecurity] ci: Harden GitHub Actions in pullrequest.yml Signed-off-by: Bhandari, Pramesh(AWF) --- .github/workflows/lint-pr.yml | 8 +++++++- .github/workflows/merge.yml | 8 ++++---- .github/workflows/pullrequest.yml | 12 ++++++------ .github/workflows/release.yml | 12 +++++++++--- .github/workflows/static-code-scanning.yaml | 11 +++++++---- 5 files changed, 33 insertions(+), 18 deletions(-) diff --git a/.github/workflows/lint-pr.yml b/.github/workflows/lint-pr.yml index 376bf574..0433b4e4 100644 --- a/.github/workflows/lint-pr.yml +++ b/.github/workflows/lint-pr.yml @@ -7,11 +7,17 @@ on: - edited - synchronize +permissions: # added using https://github.com/step-security/secure-workflows + contents: read + jobs: main: + permissions: + pull-requests: read # for amannn/action-semantic-pull-request to analyze PRs + statuses: write # for amannn/action-semantic-pull-request to mark status of analyzed PR name: Validate PR title runs-on: ubuntu-latest steps: - - uses: amannn/action-semantic-pull-request@v4 + - uses: amannn/action-semantic-pull-request@505e44b4f33b4c801f063838b3f053990ee46ea7 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index 302f788c..4bf50eaa 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -22,9 +22,9 @@ jobs: packages: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b - name: Set up JDK 8 - uses: actions/setup-java@v3 + uses: actions/setup-java@a18c333f3f14249953dab3e186e5e21bf3390f1d with: java-version: '8' distribution: 'temurin' @@ -34,7 +34,7 @@ jobs: server-password: ${{ secrets.OSSRH_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@v3 + uses: actions/cache@56461b9eb0f8438fd15c7a9968e3c9ebb18ceff1 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} @@ -51,7 +51,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 with: flags: unittests # optional name: coverage # optional diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index a1df30c7..127798c2 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -18,22 +18,22 @@ jobs: packages: write steps: - name: Check out the code - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b - name: Set up JDK 8 - uses: actions/setup-java@v3 + uses: actions/setup-java@a18c333f3f14249953dab3e186e5e21bf3390f1d with: java-version: '8' distribution: 'temurin' cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@e0e5ded33cabb451ae0a9768fc7b0410bad9ad44 with: languages: java - name: Cache local Maven repository - uses: actions/cache@v3 + uses: actions/cache@56461b9eb0f8438fd15c7a9968e3c9ebb18ceff1 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} @@ -44,7 +44,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify # -P integration-test - add this back once we have a compatible flagd - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 with: flags: unittests # optional name: coverage # optional @@ -52,4 +52,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@e0e5ded33cabb451ae0a9768fc7b0410bad9ad44 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bbabd794..24cdb807 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,13 +7,19 @@ on: branches: - main name: Run Release Please +permissions: # added using https://github.com/step-security/secure-workflows + contents: read + jobs: release-please: + 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 # Release-please creates a PR that tracks all changes steps: - - uses: google-github-actions/release-please-action@v3 + - uses: google-github-actions/release-please-action@069d7229d7b10308de85bc606a91e0033e259c8e id: release with: command: manifest @@ -23,10 +29,10 @@ jobs: # These steps are only run if this was a merged release-please PR - name: checkout if: ${{ steps.release.outputs.releases_created }} - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b - name: Set up JDK 8 if: ${{ steps.release.outputs.releases_created }} - uses: actions/setup-java@v3 + uses: actions/setup-java@a18c333f3f14249953dab3e186e5e21bf3390f1d with: java-version: '8' distribution: 'temurin' diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 4cc4b6b3..1c12fc53 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -15,6 +15,9 @@ on: # * * * * * - cron: '30 1 * * 1' +permissions: # added using https://github.com/step-security/secure-workflows + contents: read + jobs: CodeQL-Build: # CodeQL runs on ubuntu-latest, windows-latest, and macos-latest @@ -26,16 +29,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@e0e5ded33cabb451ae0a9768fc7b0410bad9ad44 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@e0e5ded33cabb451ae0a9768fc7b0410bad9ad44 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@e0e5ded33cabb451ae0a9768fc7b0410bad9ad44 From 778e0993bb3228ab5b6f101fb03bb797987e8f94 Mon Sep 17 00:00:00 2001 From: Justin Abrahms Date: Thu, 6 Oct 2022 12:01:55 -0700 Subject: [PATCH 30/63] chore: I don't think we use that permission? (#123) I don't think we use that permission? Signed-off-by: Justin Abrahms Signed-off-by: Bhandari, Pramesh(AWF) --- .github/workflows/pullrequest.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 127798c2..e8a0a9ce 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -14,8 +14,6 @@ jobs: ports: - 8013:8013 - permissions: - packages: write steps: - name: Check out the code uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b From bff5e0ddc852611ea90fefb8fbb0194253b369fd Mon Sep 17 00:00:00 2001 From: Justin Abrahms Date: Thu, 6 Oct 2022 13:33:11 -0700 Subject: [PATCH 31/63] chore: Document where to find our SBOMs (#124) Signed-off-by: Bhandari, Pramesh(AWF) --- .clomonitor.yml | 12 ++++++++++++ README.md | 4 ++++ 2 files changed, 16 insertions(+) create mode 100644 .clomonitor.yml diff --git a/.clomonitor.yml b/.clomonitor.yml new file mode 100644 index 00000000..9d41bb50 --- /dev/null +++ b/.clomonitor.yml @@ -0,0 +1,12 @@ + +# CLOMonitor metadata file +# This file must be located at the root of the repository + +# Checks exemptions + +# Check identifiers are here https://github.com/cncf/clomonitor/blob/main/docs/checks.md#exemptions (look for "id") +exemptions: + - check: signed_releases + reason: "Our releases are signed on Maven Central" + - check: artifacthub_badge + reason: "Java library, not a k8s thing. We use Maven Central" diff --git a/README.md b/README.md index b6a501ad..68df0fa1 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,10 @@ The continuous integration runs a set of [gherkin integration tests](https://git See [releasing](./docs/release.md). +### Software Bill of Materials (SBOM) + +We publish SBOMs with all of our releases as of 0.3.0. You can find them in Maven Central alongside the artifacts. + ## Contributors Thanks so much to our contributors. From 0282a83c4346364fe0e0d8c37d16d141372bbf8b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 6 Oct 2022 13:59:08 -0700 Subject: [PATCH 32/63] chore(deps): update actions/cache digest to a3f5edc (#121) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- .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 4bf50eaa..94171124 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -34,7 +34,7 @@ jobs: server-password: ${{ secrets.OSSRH_PASSWORD }} - name: Cache local Maven repository - uses: actions/cache@56461b9eb0f8438fd15c7a9968e3c9ebb18ceff1 + uses: actions/cache@a3f5edc2378b2e43203912210dc88effa160f032 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index e8a0a9ce..aa367c7d 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -31,7 +31,7 @@ jobs: languages: java - name: Cache local Maven repository - uses: actions/cache@56461b9eb0f8438fd15c7a9968e3c9ebb18ceff1 + uses: actions/cache@a3f5edc2378b2e43203912210dc88effa160f032 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} From bc8a16d482df8dd7357d1e7e159b0877eb30cff3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 6 Oct 2022 21:02:36 +0000 Subject: [PATCH 33/63] chore(deps): update actions/setup-java digest to e150063 (#125) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- .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 94171124..2b313b77 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -24,7 +24,7 @@ jobs: steps: - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b - name: Set up JDK 8 - uses: actions/setup-java@a18c333f3f14249953dab3e186e5e21bf3390f1d + uses: actions/setup-java@e150063ee446b60ce2e35b040e81846da9001576 with: java-version: '8' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index aa367c7d..60d739dc 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -19,7 +19,7 @@ jobs: uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b - name: Set up JDK 8 - uses: actions/setup-java@a18c333f3f14249953dab3e186e5e21bf3390f1d + uses: actions/setup-java@e150063ee446b60ce2e35b040e81846da9001576 with: java-version: '8' distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 24cdb807..08a9f1ee 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,7 +32,7 @@ jobs: uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b - name: Set up JDK 8 if: ${{ steps.release.outputs.releases_created }} - uses: actions/setup-java@a18c333f3f14249953dab3e186e5e21bf3390f1d + uses: actions/setup-java@e150063ee446b60ce2e35b040e81846da9001576 with: java-version: '8' distribution: 'temurin' From 8cbd040a3bfbede727d6924dfbdbd50731779033 Mon Sep 17 00:00:00 2001 From: Justin Abrahms Date: Thu, 6 Oct 2022 18:54:15 -0700 Subject: [PATCH 34/63] chore: Remove more perms (#130) Signed-off-by: Bhandari, Pramesh(AWF) --- .github/workflows/merge.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index 2b313b77..8c75412a 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -18,8 +18,6 @@ jobs: build: runs-on: ubuntu-latest - permissions: - packages: write steps: - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b From 6563a6e4525b4f3e8aeb388b2093a655c48c0ddc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 7 Oct 2022 03:20:13 -0700 Subject: [PATCH 35/63] chore(deps): update dependency org.cyclonedx:cyclonedx-maven-plugin to v2.7.1 (#128) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5131a84e..dda7af66 100644 --- a/pom.xml +++ b/pom.xml @@ -167,7 +167,7 @@ org.cyclonedx cyclonedx-maven-plugin - 2.7.0 + 2.7.1 library 1.3 From 574169d187c454f23d4f3320e1d89ea4969f9cf4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 7 Oct 2022 10:23:44 +0000 Subject: [PATCH 36/63] chore(deps): update github/codeql-action digest to 3d39294 (#127) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 60d739dc..2499cc74 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -26,7 +26,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@e0e5ded33cabb451ae0a9768fc7b0410bad9ad44 + uses: github/codeql-action/init@3d392940475e4c472e143ff2fd41aaffb1178094 with: languages: java @@ -50,4 +50,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e0e5ded33cabb451ae0a9768fc7b0410bad9ad44 + uses: github/codeql-action/analyze@3d392940475e4c472e143ff2fd41aaffb1178094 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 1c12fc53..55ad6f9a 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@e0e5ded33cabb451ae0a9768fc7b0410bad9ad44 + uses: github/codeql-action/init@3d392940475e4c472e143ff2fd41aaffb1178094 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@e0e5ded33cabb451ae0a9768fc7b0410bad9ad44 + uses: github/codeql-action/autobuild@3d392940475e4c472e143ff2fd41aaffb1178094 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e0e5ded33cabb451ae0a9768fc7b0410bad9ad44 + uses: github/codeql-action/analyze@3d392940475e4c472e143ff2fd41aaffb1178094 From 0c8d0b0b94c4391273d3afb5ee91d0d934b2a45f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Oct 2022 06:50:25 -0700 Subject: [PATCH 37/63] chore(deps): update codecov/codecov-action digest to e0fbd59 (#126) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- .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 8c75412a..d5da62e9 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@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 + uses: codecov/codecov-action@e0fbd592d323cb2991fb586fdd260734fcb41fcb with: flags: unittests # optional name: coverage # optional diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 2499cc74..e7c873ea 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -42,7 +42,7 @@ jobs: run: mvn --batch-mode --update-snapshots verify # -P integration-test - add this back once we have a compatible flagd - name: Upload coverage to Codecov - uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 + uses: codecov/codecov-action@e0fbd592d323cb2991fb586fdd260734fcb41fcb with: flags: unittests # optional name: coverage # optional From 177fddcc6f6495cfa573cc7ab67a9c7687bd2de6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Oct 2022 06:59:40 -0700 Subject: [PATCH 38/63] chore: Bump actions/checkout from 3.0.2 to 3.1.0 (#139) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.0.2 to 3.1.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/2541b1294d2704b0964813337f33b291d3f8596b...93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- .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 d5da62e9..35513e58 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - name: Set up JDK 8 uses: actions/setup-java@e150063ee446b60ce2e35b040e81846da9001576 with: diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index e7c873ea..4f4380de 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Check out the code - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b + uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - name: Set up JDK 8 uses: actions/setup-java@e150063ee446b60ce2e35b040e81846da9001576 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 08a9f1ee..ea48f3d5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,7 +29,7 @@ jobs: # These steps are only run if this was a merged release-please PR - name: checkout if: ${{ steps.release.outputs.releases_created }} - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b + uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - name: Set up JDK 8 if: ${{ steps.release.outputs.releases_created }} uses: actions/setup-java@e150063ee446b60ce2e35b040e81846da9001576 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 55ad6f9a..6a3f48a4 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@2541b1294d2704b0964813337f33b291d3f8596b + uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL From 89fce963e3a378fe6b653bfd9c71899080777cf0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Oct 2022 12:09:19 -0700 Subject: [PATCH 39/63] chore: Bump actions/setup-java from e150063ee446b60ce2e35b040e81846da9001576 to a82e6d00200608b0b4c131bc9a89f7349786bd33 (#140) chore: Bump actions/setup-java Bumps [actions/setup-java](https://github.com/actions/setup-java) from e150063ee446b60ce2e35b040e81846da9001576 to a82e6d00200608b0b4c131bc9a89f7349786bd33. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/e150063ee446b60ce2e35b040e81846da9001576...a82e6d00200608b0b4c131bc9a89f7349786bd33) --- updated-dependencies: - dependency-name: actions/setup-java dependency-type: direct:production ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- .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 35513e58..593227e2 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -22,7 +22,7 @@ jobs: steps: - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - name: Set up JDK 8 - uses: actions/setup-java@e150063ee446b60ce2e35b040e81846da9001576 + uses: actions/setup-java@a82e6d00200608b0b4c131bc9a89f7349786bd33 with: java-version: '8' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 4f4380de..d69ca15b 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -19,7 +19,7 @@ jobs: uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - name: Set up JDK 8 - uses: actions/setup-java@e150063ee446b60ce2e35b040e81846da9001576 + uses: actions/setup-java@a82e6d00200608b0b4c131bc9a89f7349786bd33 with: java-version: '8' distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ea48f3d5..d2ce4a9b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,7 +32,7 @@ jobs: uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - name: Set up JDK 8 if: ${{ steps.release.outputs.releases_created }} - uses: actions/setup-java@e150063ee446b60ce2e35b040e81846da9001576 + uses: actions/setup-java@a82e6d00200608b0b4c131bc9a89f7349786bd33 with: java-version: '8' distribution: 'temurin' From ae464883fe4dacb046c61c021e9bed04c05ea7df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Oct 2022 19:12:18 +0000 Subject: [PATCH 40/63] chore: bump spotbugs-maven-plugin from 4.7.2.0 to 4.7.2.1 (#136) Bumps [spotbugs-maven-plugin](https://github.com/spotbugs/spotbugs-maven-plugin) from 4.7.2.0 to 4.7.2.1. - [Release notes](https://github.com/spotbugs/spotbugs-maven-plugin/releases) - [Commits](https://github.com/spotbugs/spotbugs-maven-plugin/compare/spotbugs-maven-plugin-4.7.2.0...spotbugs-maven-plugin-4.7.2.1) --- updated-dependencies: - dependency-name: com.github.spotbugs:spotbugs-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Justin Abrahms Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index dda7af66..2ad9b80b 100644 --- a/pom.xml +++ b/pom.xml @@ -391,7 +391,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.7.2.0 + 4.7.2.1 spotbugs-exclusions.xml From 561d98a7892121aa1484ca8d01b1f1fa12260642 Mon Sep 17 00:00:00 2001 From: Michael Beemer Date: Tue, 11 Oct 2022 14:46:37 -0400 Subject: [PATCH 41/63] chore: exclude component in git tag (#143) Signed-off-by: Michael Beemer Signed-off-by: Michael Beemer Signed-off-by: Bhandari, Pramesh(AWF) --- release-please-config.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/release-please-config.json b/release-please-config.json index 97d02271..6ebfa182 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -4,6 +4,8 @@ ".": { "package-name": "dev.openfeature.sdk", "release-type": "simple", + "monorepo-tags": false, + "include-component-in-tag": false, "bump-minor-pre-major": true, "bump-patch-for-minor-pre-major": true, "versioning": "default", @@ -13,4 +15,4 @@ ] } } -} +} \ No newline at end of file From fe013faf52c2f64df00c1ff7058a433a8d0d58ba Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Oct 2022 15:09:32 -0700 Subject: [PATCH 42/63] chore(deps): update dependency org.cyclonedx:cyclonedx-maven-plugin to v2.7.2 (#141) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2ad9b80b..e15949da 100644 --- a/pom.xml +++ b/pom.xml @@ -167,7 +167,7 @@ org.cyclonedx cyclonedx-maven-plugin - 2.7.1 + 2.7.2 library 1.3 From ae140c724546981db065cfdaf7aa2db8f2d24fcf Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Tue, 11 Oct 2022 18:43:50 -0400 Subject: [PATCH 43/63] feat!: add rw locks to client/api, hook accessor name (#131) * fix: add read/write locks to client/api Signed-off-by: Todd Baert * dont lock entire evaluation Signed-off-by: Todd Baert * add tests Signed-off-by: Todd Baert * fixup comment Signed-off-by: Todd Baert * fixup pom comment Signed-off-by: Todd Baert * increase lock granularity, imporove tests Signed-off-by: Todd Baert * fix spotbugs Signed-off-by: Todd Baert * remove commented test Signed-off-by: Todd Baert Signed-off-by: Todd Baert Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 18 +++ spotbugs-exclusions.xml | 17 ++- src/main/java/dev/openfeature/sdk/Client.java | 2 +- .../dev/openfeature/sdk/OpenFeatureAPI.java | 91 +++++++++--- .../openfeature/sdk/OpenFeatureClient.java | 77 +++++++--- .../sdk/internal/AutoCloseableLock.java | 10 ++ .../AutoCloseableReentrantReadWriteLock.java | 28 ++++ .../sdk/DeveloperExperienceTest.java | 36 ++++- .../openfeature/sdk/DoSomethingProvider.java | 3 +- .../sdk/FlagEvaluationSpecTest.java | 12 +- .../java/dev/openfeature/sdk/LockingTest.java | 132 ++++++++++++++++++ .../sdk/OpenFeatureClientTest.java | 2 +- 12 files changed, 379 insertions(+), 49 deletions(-) create mode 100644 src/main/java/dev/openfeature/sdk/internal/AutoCloseableLock.java create mode 100644 src/main/java/dev/openfeature/sdk/internal/AutoCloseableReentrantReadWriteLock.java create mode 100644 src/test/java/dev/openfeature/sdk/LockingTest.java diff --git a/pom.xml b/pom.xml index e15949da..443da5ce 100644 --- a/pom.xml +++ b/pom.xml @@ -164,6 +164,21 @@ + + org.codehaus.mojo + build-helper-maven-plugin + 3.3.0 + + + validate + get-cpu-count + + cpu-count + + + + + org.cyclonedx cyclonedx-maven-plugin @@ -231,6 +246,9 @@ ${surefireArgLine} + + ${cpu.count} + false ${testExclusions} diff --git a/spotbugs-exclusions.xml b/spotbugs-exclusions.xml index 8675964d..673bf4b5 100644 --- a/spotbugs-exclusions.xml +++ b/spotbugs-exclusions.xml @@ -9,11 +9,26 @@ - + + + + + + + + + + + + + + + + diff --git a/src/main/java/dev/openfeature/sdk/Client.java b/src/main/java/dev/openfeature/sdk/Client.java index 07015a63..a4ccf26f 100644 --- a/src/main/java/dev/openfeature/sdk/Client.java +++ b/src/main/java/dev/openfeature/sdk/Client.java @@ -32,5 +32,5 @@ public interface Client extends Features { * Fetch the hooks associated to this client. * @return A list of {@link Hook}s. */ - List getClientHooks(); + List getHooks(); } diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java b/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java index 5918fa08..e85f4e13 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java @@ -1,43 +1,41 @@ package dev.openfeature.sdk; -import lombok.Getter; -import lombok.Setter; - -import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import javax.annotation.Nullable; + +import dev.openfeature.sdk.internal.AutoCloseableLock; +import dev.openfeature.sdk.internal.AutoCloseableReentrantReadWriteLock; + /** * A global singleton which holds base configuration for the OpenFeature library. * Configuration here will be shared across all {@link Client}s. */ public class OpenFeatureAPI { - private static OpenFeatureAPI api; - @Getter - @Setter + // package-private multi-read/single-write lock + static AutoCloseableReentrantReadWriteLock hooksLock = new AutoCloseableReentrantReadWriteLock(); + static AutoCloseableReentrantReadWriteLock providerLock = new AutoCloseableReentrantReadWriteLock(); + static AutoCloseableReentrantReadWriteLock contextLock = new AutoCloseableReentrantReadWriteLock(); private FeatureProvider provider; - @Getter - @Setter private EvaluationContext evaluationContext; - @Getter private List apiHooks; - public OpenFeatureAPI() { + private OpenFeatureAPI() { this.apiHooks = new ArrayList<>(); } + private static class SingletonHolder { + private static final OpenFeatureAPI INSTANCE = new OpenFeatureAPI(); + } + /** * Provisions the {@link OpenFeatureAPI} singleton (if needed) and returns it. * @return The singleton instance. */ public static OpenFeatureAPI getInstance() { - synchronized (OpenFeatureAPI.class) { - if (api == null) { - api = new OpenFeatureAPI(); - } - } - return api; + return SingletonHolder.INSTANCE; } public Metadata getProviderMetadata() { @@ -56,11 +54,66 @@ public Client getClient(@Nullable String name, @Nullable String version) { return new OpenFeatureClient(this, name, version); } + /** + * {@inheritDoc} + */ + public void setEvaluationContext(EvaluationContext evaluationContext) { + try (AutoCloseableLock __ = contextLock.writeLockAutoCloseable()) { + this.evaluationContext = evaluationContext; + } + } + + /** + * {@inheritDoc} + */ + public EvaluationContext getEvaluationContext() { + try (AutoCloseableLock __ = contextLock.readLockAutoCloseable()) { + return this.evaluationContext; + } + } + + /** + * {@inheritDoc} + */ + public void setProvider(FeatureProvider provider) { + try (AutoCloseableLock __ = providerLock.writeLockAutoCloseable()) { + this.provider = provider; + } + } + + /** + * {@inheritDoc} + */ + public FeatureProvider getProvider() { + try (AutoCloseableLock __ = providerLock.readLockAutoCloseable()) { + return this.provider; + } + } + + /** + * {@inheritDoc} + */ public void addHooks(Hook... hooks) { - this.apiHooks.addAll(Arrays.asList(hooks)); + try (AutoCloseableLock __ = hooksLock.writeLockAutoCloseable()) { + this.apiHooks.addAll(Arrays.asList(hooks)); + } } + /** + * {@inheritDoc} + */ + public List getHooks() { + try (AutoCloseableLock __ = hooksLock.readLockAutoCloseable()) { + return this.apiHooks; + } + } + + /** + * {@inheritDoc} + */ public void clearHooks() { - this.apiHooks.clear(); + try (AutoCloseableLock __ = hooksLock.writeLockAutoCloseable()) { + this.apiHooks.clear(); + } } } diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index 0f99e494..3759ecea 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -8,9 +8,10 @@ import dev.openfeature.sdk.exceptions.GeneralError; import dev.openfeature.sdk.exceptions.OpenFeatureError; +import dev.openfeature.sdk.internal.AutoCloseableLock; +import dev.openfeature.sdk.internal.AutoCloseableReentrantReadWriteLock; import dev.openfeature.sdk.internal.ObjectUtils; import lombok.Getter; -import lombok.Setter; import lombok.extern.slf4j.Slf4j; @Slf4j @@ -22,12 +23,10 @@ public class OpenFeatureClient implements Client { private final String name; @Getter private final String version; - @Getter private final List clientHooks; private final HookSupport hookSupport; - - @Getter - @Setter + AutoCloseableReentrantReadWriteLock hooksLock = new AutoCloseableReentrantReadWriteLock(); + AutoCloseableReentrantReadWriteLock contextLock = new AutoCloseableReentrantReadWriteLock(); private EvaluationContext evaluationContext; /** @@ -46,9 +45,44 @@ public OpenFeatureClient(OpenFeatureAPI openFeatureAPI, String name, String vers this.hookSupport = new HookSupport(); } + /** + * {@inheritDoc} + */ @Override public void addHooks(Hook... hooks) { - this.clientHooks.addAll(Arrays.asList(hooks)); + try (AutoCloseableLock __ = this.hooksLock.writeLockAutoCloseable()) { + this.clientHooks.addAll(Arrays.asList(hooks)); + } + } + + /** + * {@inheritDoc} + */ + @Override + public List getHooks() { + try (AutoCloseableLock __ = this.hooksLock.readLockAutoCloseable()) { + return this.clientHooks; + } + } + + /** + * {@inheritDoc} + */ + @Override + public void setEvaluationContext(EvaluationContext evaluationContext) { + try (AutoCloseableLock __ = contextLock.writeLockAutoCloseable()) { + this.evaluationContext = evaluationContext; + } + } + + /** + * {@inheritDoc} + */ + @Override + public EvaluationContext getEvaluationContext() { + try (AutoCloseableLock __ = contextLock.readLockAutoCloseable()) { + return this.evaluationContext; + } } private FlagEvaluationDetails evaluateFlag(FlagValueType type, String key, T defaultValue, @@ -57,34 +91,41 @@ private FlagEvaluationDetails evaluateFlag(FlagValueType type, String key () -> FlagEvaluationOptions.builder().build()); Map hints = Collections.unmodifiableMap(flagOptions.getHookHints()); ctx = ObjectUtils.defaultIfNull(ctx, () -> new MutableContext()); - FeatureProvider provider = ObjectUtils.defaultIfNull(openfeatureApi.getProvider(), () -> { - log.debug("No provider configured, using no-op provider."); - return new NoOpProvider(); - }); + FlagEvaluationDetails details = null; List mergedHooks = null; HookContext hookCtx = null; + FeatureProvider provider = null; try { + final EvaluationContext apiContext; + final EvaluationContext clientContext; - hookCtx = HookContext.from(key, type, this.getMetadata(), - openfeatureApi.getProvider().getMetadata(), ctx, defaultValue); + // openfeatureApi.getProvider() must be called once to maintain a consistent reference + provider = ObjectUtils.defaultIfNull(openfeatureApi.getProvider(), () -> { + log.debug("No provider configured, using no-op provider."); + return new NoOpProvider(); + }); mergedHooks = ObjectUtils.merge(provider.getProviderHooks(), flagOptions.getHooks(), clientHooks, - openfeatureApi.getApiHooks()); + openfeatureApi.getHooks()); - EvaluationContext ctxFromHook = hookSupport.beforeHooks(type, hookCtx, mergedHooks, hints); - - EvaluationContext invocationCtx = ctx.merge(ctxFromHook); + hookCtx = HookContext.from(key, type, this.getMetadata(), + provider.getMetadata(), ctx, defaultValue); // merge of: API.context, client.context, invocation.context - EvaluationContext apiContext = openfeatureApi.getEvaluationContext() != null + apiContext = openfeatureApi.getEvaluationContext() != null ? openfeatureApi.getEvaluationContext() : new MutableContext(); - EvaluationContext clientContext = openfeatureApi.getEvaluationContext() != null + clientContext = openfeatureApi.getEvaluationContext() != null ? this.getEvaluationContext() : new MutableContext(); + + EvaluationContext ctxFromHook = hookSupport.beforeHooks(type, hookCtx, mergedHooks, hints); + + EvaluationContext invocationCtx = ctx.merge(ctxFromHook); + EvaluationContext mergedCtx = apiContext.merge(clientContext.merge(invocationCtx)); ProviderEvaluation providerEval = (ProviderEvaluation) createProviderEvaluation(type, key, diff --git a/src/main/java/dev/openfeature/sdk/internal/AutoCloseableLock.java b/src/main/java/dev/openfeature/sdk/internal/AutoCloseableLock.java new file mode 100644 index 00000000..41fb5dc9 --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/internal/AutoCloseableLock.java @@ -0,0 +1,10 @@ +package dev.openfeature.sdk.internal; + +public interface AutoCloseableLock extends AutoCloseable { + + /** + * Override the exception in AutoClosable. + */ + @Override + void close(); +} diff --git a/src/main/java/dev/openfeature/sdk/internal/AutoCloseableReentrantReadWriteLock.java b/src/main/java/dev/openfeature/sdk/internal/AutoCloseableReentrantReadWriteLock.java new file mode 100644 index 00000000..92827ef6 --- /dev/null +++ b/src/main/java/dev/openfeature/sdk/internal/AutoCloseableReentrantReadWriteLock.java @@ -0,0 +1,28 @@ +package dev.openfeature.sdk.internal; + +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * A utility class that wraps a multi-read/single-write lock construct as AutoCloseable, so it can + * be used in a try-with-resources. + */ +public class AutoCloseableReentrantReadWriteLock extends ReentrantReadWriteLock { + + /** + * Get the single write lock as an AutoCloseableLock. + * @return unlock method ref + */ + public AutoCloseableLock writeLockAutoCloseable() { + this.writeLock().lock(); + return this.writeLock()::unlock; + } + + /** + * 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/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java b/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java index 454f1670..12e03abe 100644 --- a/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java +++ b/src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java @@ -6,12 +6,14 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import java.util.Arrays; +import java.util.Map; +import java.util.Optional; + import org.junit.jupiter.api.Test; import dev.openfeature.sdk.fixtures.HookFixtures; -import java.util.Arrays; - class DeveloperExperienceTest implements HookFixtures { transient String flagKey = "mykey"; @@ -90,4 +92,34 @@ class DeveloperExperienceTest implements HookFixtures { assertEquals(Reason.ERROR.toString(), retval.getReason()); assertFalse(retval.getValue()); } + + @Test + void providerLockedPerTransaction() throws InterruptedException { + + class MutatingHook implements Hook { + + @Override + // change the provider during a before hook - this should not impact the evaluation in progress + public Optional before(HookContext ctx, Map hints) { + OpenFeatureAPI.getInstance().setProvider(new NoOpProvider()); + return Optional.empty(); + } + } + + final String defaultValue = "string-value"; + final OpenFeatureAPI api = OpenFeatureAPI.getInstance(); + final Client client = api.getClient(); + api.setProvider(new DoSomethingProvider()); + 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); + + api.clearHooks(); + + // subsequent evaluations should now use new provider set by hook + String noOpValue = client.getStringValue("val", defaultValue); + assertEquals(noOpValue, defaultValue); + } } diff --git a/src/test/java/dev/openfeature/sdk/DoSomethingProvider.java b/src/test/java/dev/openfeature/sdk/DoSomethingProvider.java index 37fd20f4..d87fa374 100644 --- a/src/test/java/dev/openfeature/sdk/DoSomethingProvider.java +++ b/src/test/java/dev/openfeature/sdk/DoSomethingProvider.java @@ -2,6 +2,7 @@ public class DoSomethingProvider implements FeatureProvider { + public static final String name = "Something"; private EvaluationContext savedContext; public EvaluationContext getMergedContext() { @@ -10,7 +11,7 @@ public EvaluationContext getMergedContext() { @Override public Metadata getMetadata() { - return () -> "test"; + return () -> name; } @Override diff --git a/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java b/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java index 75b6e5bb..0bf9a6d4 100644 --- a/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/FlagEvaluationSpecTest.java @@ -53,7 +53,7 @@ private Client _client() { @Test void provider_metadata() { OpenFeatureAPI api = OpenFeatureAPI.getInstance(); api.setProvider(new DoSomethingProvider()); - assertEquals("test", api.getProviderMetadata().getName()); + assertEquals(DoSomethingProvider.name, api.getProviderMetadata().getName()); } @Specification(number="1.1.3", 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.") @@ -63,12 +63,12 @@ private Client _client() { OpenFeatureAPI api = OpenFeatureAPI.getInstance(); api.addHooks(h1); - assertEquals(1, api.getApiHooks().size()); - assertEquals(h1, api.getApiHooks().get(0)); + assertEquals(1, api.getHooks().size()); + assertEquals(h1, api.getHooks().get(0)); api.addHooks(h2); - assertEquals(2, api.getApiHooks().size()); - assertEquals(h2, api.getApiHooks().get(1)); + assertEquals(2, api.getHooks().size()); + assertEquals(h2, api.getHooks().get(1)); } @Specification(number="1.1.5", text="The API MUST provide a function for creating a client which accepts the following options: - name (optional): A logical string identifier for the client.") @@ -85,7 +85,7 @@ private Client _client() { Hook m2 = mock(Hook.class); c.addHooks(m1); c.addHooks(m2); - List hooks = c.getClientHooks(); + List hooks = c.getHooks(); assertEquals(2, hooks.size()); assertTrue(hooks.contains(m1)); assertTrue(hooks.contains(m2)); diff --git a/src/test/java/dev/openfeature/sdk/LockingTest.java b/src/test/java/dev/openfeature/sdk/LockingTest.java new file mode 100644 index 00000000..1a8dac9c --- /dev/null +++ b/src/test/java/dev/openfeature/sdk/LockingTest.java @@ -0,0 +1,132 @@ +package dev.openfeature.sdk; + +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import dev.openfeature.sdk.internal.AutoCloseableReentrantReadWriteLock; + +class LockingTest { + + private static OpenFeatureAPI api; + private OpenFeatureClient client; + private AutoCloseableReentrantReadWriteLock apiContextLock; + private AutoCloseableReentrantReadWriteLock apiHooksLock; + private AutoCloseableReentrantReadWriteLock apiProviderLock; + private AutoCloseableReentrantReadWriteLock clientContextLock; + private AutoCloseableReentrantReadWriteLock clientHooksLock; + + @BeforeAll + static void beforeAll() { + api = OpenFeatureAPI.getInstance(); + } + + @BeforeEach + void beforeEach() { + client = (OpenFeatureClient) api.getClient(); + + apiContextLock = setupLock(apiContextLock, mockInnerReadLock(), mockInnerWriteLock()); + apiProviderLock = setupLock(apiProviderLock, mockInnerReadLock(), mockInnerWriteLock()); + apiHooksLock = setupLock(apiHooksLock, mockInnerReadLock(), mockInnerWriteLock()); + OpenFeatureAPI.contextLock = apiContextLock; + OpenFeatureAPI.providerLock = apiProviderLock; + OpenFeatureAPI.hooksLock = apiHooksLock; + + clientContextLock = setupLock(clientContextLock, mockInnerReadLock(), mockInnerWriteLock()); + clientHooksLock = setupLock(clientHooksLock, mockInnerReadLock(), mockInnerWriteLock()); + client.contextLock = clientContextLock; + client.hooksLock = clientHooksLock; + } + + @Test + void addHooksShouldWriteLockAndUnlock() { + client.addHooks(new Hook() { + }); + verify(clientHooksLock.writeLock()).lock(); + verify(clientHooksLock.writeLock()).unlock(); + + api.addHooks(new Hook() { + }); + verify(apiHooksLock.writeLock()).lock(); + verify(apiHooksLock.writeLock()).unlock(); + } + + @Test + void getHooksShouldReadLockAndUnlock() { + client.getHooks(); + verify(clientHooksLock.readLock()).lock(); + verify(clientHooksLock.readLock()).unlock(); + + api.getHooks(); + verify(apiHooksLock.readLock()).lock(); + verify(apiHooksLock.readLock()).unlock(); + } + + @Test + void setContextShouldWriteLockAndUnlock() { + client.setEvaluationContext(new MutableContext()); + verify(clientContextLock.writeLock()).lock(); + verify(clientContextLock.writeLock()).unlock(); + + api.setEvaluationContext(new MutableContext()); + verify(apiContextLock.writeLock()).lock(); + verify(apiContextLock.writeLock()).unlock(); + } + + @Test + void getContextShouldReadLockAndUnlock() { + client.getEvaluationContext(); + verify(clientContextLock.readLock()).lock(); + verify(clientContextLock.readLock()).unlock(); + + api.getEvaluationContext(); + verify(apiContextLock.readLock()).lock(); + verify(apiContextLock.readLock()).unlock(); + } + + @Test + void setProviderShouldWriteLockAndUnlock() { + api.setProvider(new DoSomethingProvider()); + verify(apiProviderLock.writeLock()).lock(); + verify(apiProviderLock.writeLock()).unlock(); + } + + @Test + void clearHooksShouldWriteLockAndUnlock() { + api.clearHooks(); + verify(apiHooksLock.writeLock()).lock(); + verify(apiHooksLock.writeLock()).unlock(); + } + + private static ReentrantReadWriteLock.ReadLock mockInnerReadLock() { + ReentrantReadWriteLock.ReadLock readLockMock = mock(ReentrantReadWriteLock.ReadLock.class); + doNothing().when(readLockMock).lock(); + doNothing().when(readLockMock).unlock(); + return readLockMock; + } + + private static ReentrantReadWriteLock.WriteLock mockInnerWriteLock() { + ReentrantReadWriteLock.WriteLock writeLockMock = mock(ReentrantReadWriteLock.WriteLock.class); + doNothing().when(writeLockMock).lock(); + doNothing().when(writeLockMock).unlock(); + return writeLockMock; + } + + private AutoCloseableReentrantReadWriteLock setupLock(AutoCloseableReentrantReadWriteLock lock, + AutoCloseableReentrantReadWriteLock.ReadLock readlock, + AutoCloseableReentrantReadWriteLock.WriteLock writeLock) { + lock = mock(AutoCloseableReentrantReadWriteLock.class); + when(lock.readLockAutoCloseable()).thenCallRealMethod(); + when(lock.readLock()).thenReturn(readlock); + when(lock.writeLockAutoCloseable()).thenCallRealMethod(); + when(lock.writeLock()).thenReturn(writeLock); + return lock; + } +} \ No newline at end of file diff --git a/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java b/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java index 14446c1a..eab962ac 100644 --- a/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java +++ b/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java @@ -20,7 +20,7 @@ void shouldNotThrowExceptionIfHookHasDifferentTypeArgumentThanHookContext() { TEST_LOGGER.clear(); OpenFeatureAPI api = mock(OpenFeatureAPI.class); when(api.getProvider()).thenReturn(new DoSomethingProvider()); - when(api.getApiHooks()).thenReturn(Arrays.asList(mockBooleanHook(), mockStringHook())); + when(api.getHooks()).thenReturn(Arrays.asList(mockBooleanHook(), mockStringHook())); OpenFeatureClient client = new OpenFeatureClient(api, "name", "version"); From 3bf31edb22e37f58c6d608bb0ced691f08796524 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Oct 2022 22:51:30 -0700 Subject: [PATCH 44/63] chore(deps): update actions/setup-java digest to 3617c43 (#132) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- .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 593227e2..de522b9e 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -22,7 +22,7 @@ jobs: steps: - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - name: Set up JDK 8 - uses: actions/setup-java@a82e6d00200608b0b4c131bc9a89f7349786bd33 + uses: actions/setup-java@3617c43588448d532250f5c331dffcca90e398f1 with: java-version: '8' distribution: 'temurin' diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index d69ca15b..5417c3ad 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -19,7 +19,7 @@ jobs: uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - name: Set up JDK 8 - uses: actions/setup-java@a82e6d00200608b0b4c131bc9a89f7349786bd33 + uses: actions/setup-java@3617c43588448d532250f5c331dffcca90e398f1 with: java-version: '8' distribution: 'temurin' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d2ce4a9b..91774e9a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,7 +32,7 @@ jobs: uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - name: Set up JDK 8 if: ${{ steps.release.outputs.releases_created }} - uses: actions/setup-java@a82e6d00200608b0b4c131bc9a89f7349786bd33 + uses: actions/setup-java@3617c43588448d532250f5c331dffcca90e398f1 with: java-version: '8' distribution: 'temurin' From 4750fb0e65baa7b1266987724f39fcc1f9e0ae50 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Oct 2022 06:00:04 +0000 Subject: [PATCH 45/63] chore(deps): update amannn/action-semantic-pull-request digest to b314c1b (#135) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Justin Abrahms Signed-off-by: Bhandari, Pramesh(AWF) --- .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 0433b4e4..83e8cd8a 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@505e44b4f33b4c801f063838b3f053990ee46ea7 + - uses: amannn/action-semantic-pull-request@b314c1bec341c714425c0aa43e142b35c12759a0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 5be7507b53b103c35e804c75a5e17004242a4999 Mon Sep 17 00:00:00 2001 From: Justin Abrahms Date: Wed, 12 Oct 2022 06:30:33 -0700 Subject: [PATCH 46/63] chore: Remove dependabot. I like renovate better (#142) Signed-off-by: Bhandari, Pramesh(AWF) --- .github/dependabot.yml | 16 ---------------- pom.xml | 2 +- 2 files changed, 1 insertion(+), 17 deletions(-) delete mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index e39eec8c..00000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,16 +0,0 @@ -version: 2 -updates: - - # Maintain dependencies for GitHub Actions - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "weekly" - - # Maintain dependencies for npm - - package-ecosystem: "maven" - directory: "/" - commit-message: - prefix: "chore" - schedule: - interval: "weekly" diff --git a/pom.xml b/pom.xml index 443da5ce..dfc9433b 100644 --- a/pom.xml +++ b/pom.xml @@ -204,7 +204,7 @@ - + maven-dependency-plugin 3.3.0 From a900e9a93109ef3107459ca1821a5ffc58f719bf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Oct 2022 10:04:50 -0400 Subject: [PATCH 47/63] chore(deps): update amannn/action-semantic-pull-request digest to 7c194c2 (#144) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- .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 83e8cd8a..5d63a004 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@b314c1bec341c714425c0aa43e142b35c12759a0 + - uses: amannn/action-semantic-pull-request@7c194c28652f0faf98ad437c6cf291406d387b43 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From ae4b242ea3a769286d592fcb574b7bbdfab656e2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Oct 2022 21:21:04 -0700 Subject: [PATCH 48/63] chore(deps): update github/codeql-action digest to 44edb7c (#133) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 5417c3ad..ac2c7f28 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -26,7 +26,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@3d392940475e4c472e143ff2fd41aaffb1178094 + uses: github/codeql-action/init@160e3fe79abafb7364f7ec77d84506b10b7a1fa4 with: languages: java @@ -50,4 +50,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3d392940475e4c472e143ff2fd41aaffb1178094 + uses: github/codeql-action/analyze@160e3fe79abafb7364f7ec77d84506b10b7a1fa4 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 6a3f48a4..14096eb6 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@3d392940475e4c472e143ff2fd41aaffb1178094 + uses: github/codeql-action/init@160e3fe79abafb7364f7ec77d84506b10b7a1fa4 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@3d392940475e4c472e143ff2fd41aaffb1178094 + uses: github/codeql-action/autobuild@160e3fe79abafb7364f7ec77d84506b10b7a1fa4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3d392940475e4c472e143ff2fd41aaffb1178094 + uses: github/codeql-action/analyze@160e3fe79abafb7364f7ec77d84506b10b7a1fa4 From 4e7fa028a051e8e0c28ce17a2d4038a2d02f3c4a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Oct 2022 21:31:19 -0700 Subject: [PATCH 49/63] chore(deps): update actions/checkout digest to 8230315 (#122) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- .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 de522b9e..e278b3b4 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: actions/checkout@8230315d06ad95c617244d2f265d237a1682d445 - name: Set up JDK 8 uses: actions/setup-java@3617c43588448d532250f5c331dffcca90e398f1 with: diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index ac2c7f28..c771202e 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Check out the code - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + uses: actions/checkout@8230315d06ad95c617244d2f265d237a1682d445 - name: Set up JDK 8 uses: actions/setup-java@3617c43588448d532250f5c331dffcca90e398f1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 91774e9a..01841f20 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,7 +29,7 @@ jobs: # These steps are only run if this was a merged release-please PR - name: checkout if: ${{ steps.release.outputs.releases_created }} - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + uses: actions/checkout@8230315d06ad95c617244d2f265d237a1682d445 - name: Set up JDK 8 if: ${{ steps.release.outputs.releases_created }} uses: actions/setup-java@3617c43588448d532250f5c331dffcca90e398f1 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index 14096eb6..fc7ed70b 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@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + uses: actions/checkout@8230315d06ad95c617244d2f265d237a1682d445 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL From 2ba2c5a829dd8662eac78fc0805dbe1d0657d5d4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 13 Oct 2022 06:03:51 +0000 Subject: [PATCH 50/63] chore(main): release 0.3.0 (#114) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Justin Abrahms Signed-off-by: Bhandari, Pramesh(AWF) --- .release-please-manifest.json | 2 +- CHANGELOG.md | 35 +++++++++++++++++++++++++++++++++++ README.md | 4 ++-- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 9a316268..64c0d41e 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"0.2.2"} \ No newline at end of file +{".":"0.3.0"} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index f025cfa8..91c28a74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,40 @@ # Changelog +## [0.3.0](https://github.com/open-feature/java-sdk/compare/v0.2.2...v0.3.0) (2022-10-13) + + +### ⚠ BREAKING CHANGES + +* add rw locks to client/api, hook accessor name (#131) +* use evaluation context interface (#112) +* Change the package name. Everyone knows it's java (or it doesn't matter) (#111) +* errorCode as enum, reason as string (#80) +* use value for object resolver +* use instant not zoneddatetime + +### Features + +* Add asObjectMap to get the EvaluationContext as Map ([#75](https://github.com/open-feature/java-sdk/issues/75)) ([2eec1a5](https://github.com/open-feature/java-sdk/commit/2eec1a5519b9efab7d7f9dc8b1cbd84d9218368b)) +* add object to value wrapper ([0152a1e](https://github.com/open-feature/java-sdk/commit/0152a1eef93ea1b5253ddae78718a9805c98aaf7)) +* add rw locks to client/api, hook accessor name ([#131](https://github.com/open-feature/java-sdk/issues/131)) ([2192932](https://github.com/open-feature/java-sdk/commit/21929328630eba00be741392457f68bacf59f376)) +* errorCode as enum, reason as string ([#80](https://github.com/open-feature/java-sdk/issues/80)) ([84f220d](https://github.com/open-feature/java-sdk/commit/84f220d8139035a1222d13b2dd6f8b048932c192)) +* Support for generating CycloneDX sboms ([#119](https://github.com/open-feature/java-sdk/issues/119)) ([9647c3f](https://github.com/open-feature/java-sdk/commit/9647c3f04d8ace10a9d512bfe30fd9ef2c5631d1)) +* use evaluation context interface ([#112](https://github.com/open-feature/java-sdk/issues/112)) ([e9732b5](https://github.com/open-feature/java-sdk/commit/e9732b582dc9e3fa7be51c834e1afe7ad890c4e3)) +* use instant not zoneddatetime ([3e62414](https://github.com/open-feature/java-sdk/commit/3e6241422266825f267043e4acd116803c4939b0)) +* use value for object resolver ([5d26247](https://github.com/open-feature/java-sdk/commit/5d262470e8ec47d2af35f0aabe55e8c969e992ac)) + + +### Bug Fixes + +* **deps:** update dependency io.cucumber:cucumber-bom to v7.8.0 ([#100](https://github.com/open-feature/java-sdk/issues/100)) ([5e96d14](https://github.com/open-feature/java-sdk/commit/5e96d140c1195a1e8eb175feae3ec29db4439367)) +* **deps:** update junit5 monorepo ([#92](https://github.com/open-feature/java-sdk/issues/92)) ([8ca655a](https://github.com/open-feature/java-sdk/commit/8ca655a788273c61e5270ce7bf175064f42d605d)) +* isList check in Value checks type of list ([#70](https://github.com/open-feature/java-sdk/issues/70)) ([81ab071](https://github.com/open-feature/java-sdk/commit/81ab0710ea56af65eb65c7f95832b8f58c559a51)) + + +### Code Refactoring + +* Change the package name. Everyone knows it's java (or it doesn't matter) ([#111](https://github.com/open-feature/java-sdk/issues/111)) ([6eeeddd](https://github.com/open-feature/java-sdk/commit/6eeeddd2ea8040b47d1fd507b68d42c3bce52db4)) + ## [0.2.2](https://github.com/open-feature/java-sdk/compare/dev.openfeature.javasdk-v0.2.1...dev.openfeature.javasdk-v0.2.2) (2022-09-20) diff --git a/README.md b/README.md index 68df0fa1..d50baea2 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ class MyClass { dev.openfeature sdk - 0.2.2 + 0.3.0 ``` @@ -90,7 +90,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:0.2.2' + implementation 'dev.openfeature:sdk:0.3.0' } ``` diff --git a/pom.xml b/pom.xml index dfc9433b..53284bd2 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ dev.openfeature sdk - 0.2.2 + 0.3.0 UTF-8 diff --git a/version.txt b/version.txt index ee1372d3..0d91a54c 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.2.2 +0.3.0 From c24bfb48443680a235a1793c4cc2a7c8852e5bd7 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Thu, 13 Oct 2022 12:55:03 -0400 Subject: [PATCH 51/63] chore: re-enable integration tests (#146) Update test harness and re-enable integration test profile Signed-off-by: Bhandari, Pramesh(AWF) --- .github/workflows/pullrequest.yml | 2 +- pom.xml | 7 +++++++ .../dev/openfeature/sdk/integration/StepDefinitions.java | 4 ++-- test-harness | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index c771202e..c0845d22 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -39,7 +39,7 @@ jobs: ${{ runner.os }}-maven- - name: Build with Maven - run: mvn --batch-mode --update-snapshots verify # -P integration-test - add this back once we have a compatible flagd + run: mvn --batch-mode --update-snapshots verify -P integration-test - name: Upload coverage to Codecov uses: codecov/codecov-action@e0fbd592d323cb2991fb586fdd260734fcb41fcb diff --git a/pom.xml b/pom.xml index 53284bd2..ef772a35 100644 --- a/pom.xml +++ b/pom.xml @@ -137,6 +137,13 @@ 31.1-jre test + + + dev.openfeature.contrib.providers + flagd + 0.4.1 + test + diff --git a/src/test/java/dev/openfeature/sdk/integration/StepDefinitions.java b/src/test/java/dev/openfeature/sdk/integration/StepDefinitions.java index 3513bddc..892dc34f 100644 --- a/src/test/java/dev/openfeature/sdk/integration/StepDefinitions.java +++ b/src/test/java/dev/openfeature/sdk/integration/StepDefinitions.java @@ -3,7 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -// import dev.openfeature.contrib.providers.flagd.FlagdProvider; +import dev.openfeature.contrib.providers.flagd.FlagdProvider; import dev.openfeature.sdk.Client; import dev.openfeature.sdk.FlagEvaluationDetails; import dev.openfeature.sdk.MutableStructure; @@ -45,7 +45,7 @@ public class StepDefinitions { @BeforeAll() public static void setup() { - // OpenFeatureAPI.getInstance().setProvider(new FlagdProvider()); + OpenFeatureAPI.getInstance().setProvider(new FlagdProvider()); client = OpenFeatureAPI.getInstance().getClient(); } diff --git a/test-harness b/test-harness index e7379cd0..5153eac7 160000 --- a/test-harness +++ b/test-harness @@ -1 +1 @@ -Subproject commit e7379cd0070f8907cacdc535184f8f626bf25e01 +Subproject commit 5153eac71dc47413da4326bdb49a94e573b99578 From bdb0e091b46fc115e1cb4ab88d2549bb0786fa90 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 13 Oct 2022 17:34:08 +0000 Subject: [PATCH 52/63] chore(deps): update actions/cache digest to 9b0c1fc (#145) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Justin Abrahms Signed-off-by: Bhandari, Pramesh(AWF) --- .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 e278b3b4..0709f406 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@a3f5edc2378b2e43203912210dc88effa160f032 + uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index c0845d22..8ccc6ab7 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -31,7 +31,7 @@ jobs: languages: java - name: Cache local Maven repository - uses: actions/cache@a3f5edc2378b2e43203912210dc88effa160f032 + uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} From 5c31280c143d235233f34933519531ea03c19483 Mon Sep 17 00:00:00 2001 From: Robert Grassian <89157164+rgrassian-split@users.noreply.github.com> Date: Thu, 13 Oct 2022 16:24:25 -0700 Subject: [PATCH 53/63] fix: merge eval context (#149) fix merge eval context Signed-off-by: Robert Grassian Signed-off-by: Robert Grassian Signed-off-by: Bhandari, Pramesh(AWF) --- .../openfeature/sdk/OpenFeatureClient.java | 2 +- .../sdk/OpenFeatureClientTest.java | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java index 3759ecea..827c9215 100644 --- a/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java +++ b/src/main/java/dev/openfeature/sdk/OpenFeatureClient.java @@ -118,7 +118,7 @@ private FlagEvaluationDetails evaluateFlag(FlagValueType type, String key apiContext = openfeatureApi.getEvaluationContext() != null ? openfeatureApi.getEvaluationContext() : new MutableContext(); - clientContext = openfeatureApi.getEvaluationContext() != null + clientContext = this.getEvaluationContext() != null ? this.getEvaluationContext() : new MutableContext(); diff --git a/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java b/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java index eab962ac..f4c6f100 100644 --- a/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java +++ b/src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java @@ -29,4 +29,30 @@ void shouldNotThrowExceptionIfHookHasDifferentTypeArgumentThanHookContext() { assertThat(actual.getValue()).isTrue(); assertThat(TEST_LOGGER.getLoggingEvents()).filteredOn(event -> event.getLevel().equals(Level.ERROR)).isEmpty(); } + + @Test + void mergeContextTest() { + TEST_LOGGER.clear(); + + String flag = "feature key"; + boolean defaultValue = false; + String targetingKey = "targeting key"; + EvaluationContext ctx = new MutableContext(targetingKey); + + OpenFeatureAPI api = mock(OpenFeatureAPI.class); + FeatureProvider mockProvider = mock(FeatureProvider.class); + // this makes it so that true is returned only if the targeting key set at the client level is honored + when(mockProvider.getBooleanEvaluation( + eq(flag), eq(defaultValue), argThat( + context -> context.getTargetingKey().equals(targetingKey)))).thenReturn(ProviderEvaluation.builder() + .value(true).build()); + when(api.getProvider()).thenReturn(mockProvider); + + OpenFeatureClient client = new OpenFeatureClient(api, "name", "version"); + client.setEvaluationContext(ctx); + + FlagEvaluationDetails result = client.getBooleanDetails(flag, defaultValue); + + assertThat(result.getValue()).isTrue(); + } } From da01751531e34a84c811cf18cbceb9aed97d9466 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 14 Oct 2022 13:19:36 +0000 Subject: [PATCH 54/63] chore(main): release 0.3.1 (#150) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ README.md | 4 ++-- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 64c0d41e..5675f452 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"0.3.0"} \ No newline at end of file +{".":"0.3.1"} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 91c28a74..271e6d8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [0.3.1](https://github.com/open-feature/java-sdk/compare/v0.3.0...v0.3.1) (2022-10-13) + + +### Bug Fixes + +* merge eval context ([#149](https://github.com/open-feature/java-sdk/issues/149)) ([fad0f35](https://github.com/open-feature/java-sdk/commit/fad0f35fc8a6469672ef67820f1850f20741b66a)) + ## [0.3.0](https://github.com/open-feature/java-sdk/compare/v0.2.2...v0.3.0) (2022-10-13) diff --git a/README.md b/README.md index d50baea2..6b786c7c 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ class MyClass { dev.openfeature sdk - 0.3.0 + 0.3.1 ``` @@ -90,7 +90,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:0.3.0' + implementation 'dev.openfeature:sdk:0.3.1' } ``` diff --git a/pom.xml b/pom.xml index ef772a35..d8b5b4bb 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ dev.openfeature sdk - 0.3.0 + 0.3.1 UTF-8 diff --git a/version.txt b/version.txt index 0d91a54c..9e11b32f 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.3.0 +0.3.1 From 79f92be0bd9953d8f22bc72bd34d91f9ca475968 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 16 Oct 2022 12:40:16 -0700 Subject: [PATCH 55/63] chore(deps): update github/codeql-action digest to 297ec80 (#147) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- .github/workflows/pullrequest.yml | 4 ++-- .github/workflows/static-code-scanning.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 8ccc6ab7..291be791 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -26,7 +26,7 @@ jobs: cache: maven - name: Initialize CodeQL - uses: github/codeql-action/init@160e3fe79abafb7364f7ec77d84506b10b7a1fa4 + uses: github/codeql-action/init@297ec80a468c234608046f51ee8c65da128a1e94 with: languages: java @@ -50,4 +50,4 @@ jobs: verbose: true # optional (default = false) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@160e3fe79abafb7364f7ec77d84506b10b7a1fa4 + uses: github/codeql-action/analyze@297ec80a468c234608046f51ee8c65da128a1e94 diff --git a/.github/workflows/static-code-scanning.yaml b/.github/workflows/static-code-scanning.yaml index fc7ed70b..4686704e 100644 --- a/.github/workflows/static-code-scanning.yaml +++ b/.github/workflows/static-code-scanning.yaml @@ -33,12 +33,12 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@160e3fe79abafb7364f7ec77d84506b10b7a1fa4 + uses: github/codeql-action/init@297ec80a468c234608046f51ee8c65da128a1e94 with: languages: java - name: Autobuild - uses: github/codeql-action/autobuild@160e3fe79abafb7364f7ec77d84506b10b7a1fa4 + uses: github/codeql-action/autobuild@297ec80a468c234608046f51ee8c65da128a1e94 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@160e3fe79abafb7364f7ec77d84506b10b7a1fa4 + uses: github/codeql-action/analyze@297ec80a468c234608046f51ee8c65da128a1e94 From 6392d071cddbbdec8e54880409572e60371df056 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Mon, 17 Oct 2022 17:05:26 -0400 Subject: [PATCH 56/63] chore: update test/spec association numbers, badge (#156) * chore: update test/spec association numbers Signed-off-by: Todd Baert * chore: update spec tag Signed-off-by: Todd Baert Signed-off-by: Todd Baert Signed-off-by: Bhandari, Pramesh(AWF) --- README.md | 2 +- .../dev/openfeature/sdk/ProviderSpecTest.java | 24 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 6b786c7c..3a8c9377 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.openfeature/sdk/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.openfeature/sdk) [![javadoc](https://javadoc.io/badge2/dev.openfeature/sdk/javadoc.svg)](https://javadoc.io/doc/dev.openfeature/sdk) [![Project Status: WIP – Initial development is in progress, but there has not yet been a stable, usable release suitable for the public.](https://www.repostatus.org/badges/latest/wip.svg)](https://www.repostatus.org/#wip) -[![Specification](https://img.shields.io/static/v1?label=Specification&message=v0.5.0&color=yellow)](https://github.com/open-feature/spec/tree/v0.5.0) +[![v0.5.1](https://img.shields.io/static/v1?label=Specification&message=v0.5.1&color=yellow)](https://github.com/open-feature/spec/tree/v0.5.1) [![Known Vulnerabilities](https://snyk.io/test/github/open-feature/java-sdk/badge.svg)](https://snyk.io/test/github/open-feature/java-sdk) [![on-merge](https://github.com/open-feature/java-sdk/actions/workflows/merge.yml/badge.svg)](https://github.com/open-feature/java-sdk/actions/workflows/merge.yml) [![codecov](https://codecov.io/gh/open-feature/java-sdk/branch/main/graph/badge.svg?token=XMS9L7PBY1)](https://codecov.io/gh/open-feature/java-sdk) diff --git a/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java b/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java index 27cc64e8..23d8bc2b 100644 --- a/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java +++ b/src/test/java/dev/openfeature/sdk/ProviderSpecTest.java @@ -8,20 +8,20 @@ public class ProviderSpecTest { NoOpProvider p = new NoOpProvider(); - @Specification(number="2.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.3.1", text="The feature provider interface MUST define methods for typed " + + @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.4", text="In cases of normal execution, the provider MUST populate the " + + @Specification(number="2.2.3", text="In cases of normal execution, the provider MUST populate the " + "flag resolution structure's value field with the resolved flag value.") - @Specification(number="2.2", text="The feature provider interface MUST define methods to resolve " + + @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 flag resolution structure.") - @Specification(number="2.9.1", text="The flag resolution structure SHOULD accept a generic " + + @Specification(number="2.2.8.1", text="The flag resolution 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 MutableContext()); @@ -41,25 +41,25 @@ public class ProviderSpecTest { } - @Specification(number="2.6", text="The `provider` SHOULD populate the `flag resolution` structure's `reason` field with `\"DEFAULT\",` `\"TARGETING_MATCH\"`, `\"SPLIT\"`, `\"DISABLED\"`, `\"UNKNOWN\"`, `\"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 `flag resolution` structure's `reason` field with `\"DEFAULT\",` `\"TARGETING_MATCH\"`, `\"SPLIT\"`, `\"DISABLED\"`, `\"UNKNOWN\"`, `\"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 MutableContext()); assertEquals(Reason.DEFAULT.toString(), result.getReason()); } - @Specification(number="2.7", text="In cases of normal execution, the provider MUST NOT populate " + + @Specification(number="2.2.6", text="In cases of normal execution, the provider MUST NOT populate " + "the flag resolution 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 MutableContext()); assertNull(result.getErrorCode()); } - @Specification(number="2.8", 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.11", text="In cases of normal execution, the `provider` **MUST NOT** populate the `flag resolution` structure's `error message` field, or otherwise must populate it with a null or falsy value.") - @Specification(number="2.12", text="In cases of abnormal execution, the `evaluation 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 `flag resolution` 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 `evaluation 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() {} - @Specification(number="2.5", text="In cases of normal execution, the provider SHOULD populate the " + + @Specification(number="2.2.4", text="In cases of normal execution, the provider SHOULD populate the " + "flag resolution 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 MutableContext()); @@ -75,7 +75,7 @@ public class ProviderSpecTest { assertNotNull(boolean_result.getReason()); } - @Specification(number="2.10", 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="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()); From 10dff7ec1196b30ace8cb66e39c2fe976d3c1eac Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Oct 2022 00:03:52 -0700 Subject: [PATCH 57/63] chore(deps): update actions/cache digest to 2b04a41 (#158) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- .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 0709f406..231fad90 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@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 + uses: actions/cache@2b04a41915d2fed6cec2aa74821ba81689ff0816 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 291be791..bccace75 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -31,7 +31,7 @@ jobs: languages: java - name: Cache local Maven repository - uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 + uses: actions/cache@2b04a41915d2fed6cec2aa74821ba81689ff0816 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} From 1b2f4d9fed473b0dc4868bf44f05440938c84243 Mon Sep 17 00:00:00 2001 From: Michael Beemer Date: Wed, 19 Oct 2022 14:16:55 -0400 Subject: [PATCH 58/63] chore(security): [Snyk] Security upgrade com.github.spotbugs:spotbugs from 4.7.2 to 4.7.3 (#157) fix: pom.xml to reduce vulnerabilities The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JAVA-ORGAPACHECOMMONS-3043138 Co-authored-by: snyk-bot Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index d8b5b4bb..ae998cb0 100644 --- a/pom.xml +++ b/pom.xml @@ -52,7 +52,7 @@ com.github.spotbugs spotbugs - 4.7.2 + 4.7.3 compile @@ -432,7 +432,7 @@ com.github.spotbugs spotbugs - 4.7.2 + 4.7.3 @@ -484,7 +484,7 @@ integration-test - + From 09dd513ba45e7d64f71b3d5a9d72e737e549fa89 Mon Sep 17 00:00:00 2001 From: Todd Baert Date: Tue, 25 Oct 2022 11:45:34 -0400 Subject: [PATCH 59/63] chore: Add docs link (#165) Signed-off-by: Todd Baert Signed-off-by: Todd Baert Signed-off-by: Bhandari, Pramesh(AWF) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 3a8c9377..3890e310 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,8 @@ class MyClass { } ``` +For complete documentation, visit: https://docs.openfeature.dev/docs/category/concepts + ## Requirements - Java 8+ From e8317a4ca2dddd416432c888ca4d11e820530145 Mon Sep 17 00:00:00 2001 From: Justin Abrahms Date: Tue, 25 Oct 2022 09:15:01 -0700 Subject: [PATCH 60/63] chore: Mark project as active. (#167) Mark project as active. Signed-off-by: Justin Abrahms Signed-off-by: Justin Abrahms Signed-off-by: Bhandari, Pramesh(AWF) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3890e310..ba86f433 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.openfeature/sdk/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.openfeature/sdk) [![javadoc](https://javadoc.io/badge2/dev.openfeature/sdk/javadoc.svg)](https://javadoc.io/doc/dev.openfeature/sdk) -[![Project Status: WIP – Initial development is in progress, but there has not yet been a stable, usable release suitable for the public.](https://www.repostatus.org/badges/latest/wip.svg)](https://www.repostatus.org/#wip) +[![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) [![v0.5.1](https://img.shields.io/static/v1?label=Specification&message=v0.5.1&color=yellow)](https://github.com/open-feature/spec/tree/v0.5.1) [![Known Vulnerabilities](https://snyk.io/test/github/open-feature/java-sdk/badge.svg)](https://snyk.io/test/github/open-feature/java-sdk) [![on-merge](https://github.com/open-feature/java-sdk/actions/workflows/merge.yml/badge.svg)](https://github.com/open-feature/java-sdk/actions/workflows/merge.yml) From b7f847f777c2b325408f92664c9bd0e601b6b10c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 25 Oct 2022 11:21:02 -0700 Subject: [PATCH 61/63] chore(main): release 1.0.0 (#168) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ README.md | 4 ++-- pom.xml | 2 +- version.txt | 2 +- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 5675f452..0878d456 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"0.3.1"} \ No newline at end of file +{".":"1.0.0"} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 271e6d8f..88757015 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.0.0](https://github.com/open-feature/java-sdk/compare/v0.3.1...v1.0.0) (2022-10-25) + + +### Miscellaneous Chores + +* release 1.0.0 ([#163](https://github.com/open-feature/java-sdk/issues/163)) ([c9ba9c9](https://github.com/open-feature/java-sdk/commit/c9ba9c9275ad4417a206b148e830fa78d265adb6)) + ## [0.3.1](https://github.com/open-feature/java-sdk/compare/v0.3.0...v0.3.1) (2022-10-13) diff --git a/README.md b/README.md index ba86f433..51591d0c 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ For complete documentation, visit: https://docs.openfeature.dev/docs/category/co dev.openfeature sdk - 0.3.1 + 1.0.0 ``` @@ -92,7 +92,7 @@ If you would like snapshot builds, this is the relevant repository information: ```groovy dependencies { - implementation 'dev.openfeature:sdk:0.3.1' + implementation 'dev.openfeature:sdk:1.0.0' } ``` diff --git a/pom.xml b/pom.xml index ae998cb0..bd7f8299 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ dev.openfeature sdk - 0.3.1 + 1.0.0 UTF-8 diff --git a/version.txt b/version.txt index 9e11b32f..3eefcb9d 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.3.1 +1.0.0 From 0d9166825ad47f43f62bccb0eecf863d7d7cf46a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Oct 2022 15:34:48 -0400 Subject: [PATCH 62/63] chore(deps): update actions/cache digest to 8bec1e4 (#159) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: Bhandari, Pramesh(AWF) --- .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 231fad90..6224db69 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@2b04a41915d2fed6cec2aa74821ba81689ff0816 + uses: actions/cache@8bec1e4cc329270e6364af0aee38d62e50012e62 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index bccace75..7ce69a71 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -31,7 +31,7 @@ jobs: languages: java - name: Cache local Maven repository - uses: actions/cache@2b04a41915d2fed6cec2aa74821ba81689ff0816 + uses: actions/cache@8bec1e4cc329270e6364af0aee38d62e50012e62 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} From 83860cb65d3eb3b243438374323bef1fbacb3936 Mon Sep 17 00:00:00 2001 From: "Bhandari, Pramesh(AWF)" Date: Thu, 3 Nov 2022 15:58:48 -0700 Subject: [PATCH 63/63] changes spotbug scope to provided. Signed-off-by: Bhandari, Pramesh(AWF) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bd7f8299..9036fe00 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ com.github.spotbugs spotbugs 4.7.3 - compile + provided