Commit 422997a
committed
fixup: further improve immutability and add release please
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
diff --git c/.github/workflows/release.yml i/.github/workflows/release.yml
index f130b89..4cf2d50 100644
--- c/.github/workflows/release.yml
+++ i/.github/workflows/release.yml
@@ -24,6 +24,8 @@ jobs:
id: release
with:
token: ${{secrets.RELEASE_PLEASE_ACTION_TOKEN}}
+ prerelease: ${{ github.ref == 'refs/heads/beta' }}
+ prerelease-type: "beta"
outputs:
release_created: ${{ fromJSON(steps.release.outputs.paths_released)[0] != null }} # if we have a single release path, do the release
diff --git c/.release-please-manifest.json i/.release-please-manifest.json
index b0c1905..f6ebfaa 100644
--- c/.release-please-manifest.json
+++ i/.release-please-manifest.json
@@ -1 +1,4 @@
-{".":"1.18.0"}
+{
+ "./sdk": "2.0.0-beta",
+ "./api": "0.0.0-beta"
+}
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/BaseEvaluation.java i/openfeature-api/src/main/java/dev/openfeature/api/BaseEvaluation.java
index e9df678..443e5d1 100644
--- c/openfeature-api/src/main/java/dev/openfeature/api/BaseEvaluation.java
+++ i/openfeature-api/src/main/java/dev/openfeature/api/BaseEvaluation.java
@@ -41,4 +41,6 @@ public interface BaseEvaluation<T> {
* @return {String}
*/
String getErrorMessage();
+
+ Metadata getFlagMetadata();
}
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/DefaultEvaluationEvent.java i/openfeature-api/src/main/java/dev/openfeature/api/DefaultEvaluationEvent.java
new file mode 100644
index 0000000..a1f7726
--- /dev/null
+++ i/openfeature-api/src/main/java/dev/openfeature/api/DefaultEvaluationEvent.java
@@ -0,0 +1,96 @@
+package dev.openfeature.api;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Represents an evaluation event.
+ * This class is immutable and thread-safe.
+ */
+class DefaultEvaluationEvent implements EvaluationEvent {
+
+ private final String name;
+ private final Map<String, Object> attributes;
+
+ /**
+ * Private constructor - use builder() to create instances.
+ */
+ private DefaultEvaluationEvent(String name, Map<String, Object> attributes) {
+ this.name = name;
+ this.attributes = attributes != null ? new HashMap<>(attributes) : new HashMap<>();
+ }
+
+ /**
+ * Gets the name of the evaluation event.
+ *
+ * @return the event name
+ */
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Gets a copy of the event attributes.
+ *
+ * @return a new map containing the event attributes
+ */
+ @Override
+ public Map<String, Object> getAttributes() {
+ return new HashMap<>(attributes);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ DefaultEvaluationEvent that = (DefaultEvaluationEvent) obj;
+ return Objects.equals(name, that.name) && Objects.equals(attributes, that.attributes);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, attributes);
+ }
+
+ @Override
+ public String toString() {
+ return "EvaluationEvent{" + "name='" + name + '\'' + ", attributes=" + attributes + '}';
+ }
+
+ /**
+ * Builder class for creating instances of EvaluationEvent.
+ */
+ public static class Builder {
+ private String name;
+ private Map<String, Object> attributes = new HashMap<>();
+
+ public Builder name(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public Builder attributes(Map<String, Object> attributes) {
+ this.attributes = attributes != null ? new HashMap<>(attributes) : new HashMap<>();
+ return this;
+ }
+
+ public Builder attribute(String key, Object value) {
+ this.attributes.put(key, value);
+ return this;
+ }
+
+ public EvaluationEvent build() {
+ return new DefaultEvaluationEvent(name, attributes);
+ }
+ }
+}
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/DefaultFlagEvaluationDetails.java i/openfeature-api/src/main/java/dev/openfeature/api/DefaultFlagEvaluationDetails.java
new file mode 100644
index 0000000..19a4e22
--- /dev/null
+++ i/openfeature-api/src/main/java/dev/openfeature/api/DefaultFlagEvaluationDetails.java
@@ -0,0 +1,118 @@
+package dev.openfeature.api;
+
+import java.util.Objects;
+
+/**
+ * Contains information about how the provider resolved a flag, including the
+ * resolved value.
+ *
+ * @param <T> the type of the flag being evaluated.
+ */
+class DefaultFlagEvaluationDetails<T> implements FlagEvaluationDetails<T> {
+
+ private final String flagKey;
+ private final T value;
+ private final String variant;
+ private final String reason;
+ private final ErrorCode errorCode;
+ private final String errorMessage;
+ private final Metadata flagMetadata;
+
+ /**
+ * Private constructor for builder pattern only.
+ */
+ DefaultFlagEvaluationDetails() {
+ this(null, null, null, null, null, null, null);
+ }
+
+ /**
+ * Private constructor for immutable FlagEvaluationDetails.
+ *
+ * @param flagKey the flag key
+ * @param value the resolved value
+ * @param variant the variant identifier
+ * @param reason the reason for the evaluation result
+ * @param errorCode the error code if applicable
+ * @param errorMessage the error message if applicable
+ * @param flagMetadata metadata associated with the flag
+ */
+ DefaultFlagEvaluationDetails(
+ String flagKey,
+ T value,
+ String variant,
+ String reason,
+ ErrorCode errorCode,
+ String errorMessage,
+ Metadata flagMetadata) {
+ this.flagKey = flagKey;
+ this.value = value;
+ this.variant = variant;
+ this.reason = reason;
+ this.errorCode = errorCode;
+ this.errorMessage = errorMessage;
+ this.flagMetadata = flagMetadata != null ? flagMetadata : Metadata.EMPTY;
+ }
+
+ public String getFlagKey() {
+ return flagKey;
+ }
+
+ public T getValue() {
+ return value;
+ }
+
+ public String getVariant() {
+ return variant;
+ }
+
+ public String getReason() {
+ return reason;
+ }
+
+ public ErrorCode getErrorCode() {
+ return errorCode;
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public Metadata getFlagMetadata() {
+ return flagMetadata;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ FlagEvaluationDetails<?> that = (FlagEvaluationDetails<?>) obj;
+ return Objects.equals(flagKey, that.getFlagKey())
+ && Objects.equals(value, that.getValue())
+ && Objects.equals(variant, that.getVariant())
+ && Objects.equals(reason, that.getReason())
+ && errorCode == that.getErrorCode()
+ && Objects.equals(errorMessage, that.getErrorMessage())
+ && Objects.equals(flagMetadata, that.getFlagMetadata());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(flagKey, value, variant, reason, errorCode, errorMessage, flagMetadata);
+ }
+
+ @Override
+ public String toString() {
+ return "FlagEvaluationDetails{" + "flagKey='"
+ + flagKey + '\'' + ", value="
+ + value + ", variant='"
+ + variant + '\'' + ", reason='"
+ + reason + '\'' + ", errorCode="
+ + errorCode + ", errorMessage='"
+ + errorMessage + '\'' + ", flagMetadata="
+ + flagMetadata + '}';
+ }
+}
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/DefaultProviderEvaluation.java i/openfeature-api/src/main/java/dev/openfeature/api/DefaultProviderEvaluation.java
new file mode 100644
index 0000000..93e6169
--- /dev/null
+++ i/openfeature-api/src/main/java/dev/openfeature/api/DefaultProviderEvaluation.java
@@ -0,0 +1,101 @@
+package dev.openfeature.api;
+
+import java.util.Objects;
+
+/**
+ * Contains information about how the a flag was evaluated, including the resolved value.
+ *
+ * @param <T> the type of the flag being evaluated.
+ */
+class DefaultProviderEvaluation<T> implements ProviderEvaluation<T> {
+ private final T value;
+ private final String variant;
+ private final String reason;
+ private final ErrorCode errorCode;
+ private final String errorMessage;
+ private final Metadata flagMetadata;
+
+ /**
+ * Private constructor for builder pattern only.
+ */
+ DefaultProviderEvaluation() {
+ this(null, null, null, null, null, null);
+ }
+
+ /**
+ * Private constructor for immutable ProviderEvaluation.
+ *
+ * @param value the resolved value
+ * @param variant the variant identifier
+ * @param reason the reason for the evaluation result
+ * @param errorCode the error code if applicable
+ * @param errorMessage the error message if applicable
+ * @param flagMetadata metadata associated with the flag
+ */
+ DefaultProviderEvaluation(
+ T value, String variant, String reason, ErrorCode errorCode, String errorMessage, Metadata flagMetadata) {
+ this.value = value;
+ this.variant = variant;
+ this.reason = reason;
+ this.errorCode = errorCode;
+ this.errorMessage = errorMessage;
+ this.flagMetadata = flagMetadata != null ? flagMetadata : Metadata.EMPTY;
+ }
+
+ public T getValue() {
+ return value;
+ }
+
+ public String getVariant() {
+ return variant;
+ }
+
+ public String getReason() {
+ return reason;
+ }
+
+ public ErrorCode getErrorCode() {
+ return errorCode;
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public Metadata getFlagMetadata() {
+ return flagMetadata;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ ProviderEvaluation<?> that = (ProviderEvaluation<?>) obj;
+ return Objects.equals(value, that.getValue())
+ && Objects.equals(variant, that.getVariant())
+ && Objects.equals(reason, that.getReason())
+ && errorCode == that.getErrorCode()
+ && Objects.equals(errorMessage, that.getErrorMessage())
+ && Objects.equals(flagMetadata, that.getFlagMetadata());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(value, variant, reason, errorCode, errorMessage, flagMetadata);
+ }
+
+ @Override
+ public String toString() {
+ return "ProviderEvaluation{" + "value="
+ + value + ", variant='"
+ + variant + '\'' + ", reason='"
+ + reason + '\'' + ", errorCode="
+ + errorCode + ", errorMessage='"
+ + errorMessage + '\'' + ", flagMetadata="
+ + flagMetadata + '}';
+ }
+}
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/EvaluationContext.java i/openfeature-api/src/main/java/dev/openfeature/api/EvaluationContext.java
index 39ca965..86c1570 100644
--- c/openfeature-api/src/main/java/dev/openfeature/api/EvaluationContext.java
+++ i/openfeature-api/src/main/java/dev/openfeature/api/EvaluationContext.java
@@ -18,6 +18,22 @@ public interface EvaluationContext extends Structure {
*/
EvaluationContext EMPTY = new ImmutableContext();
+ static EvaluationContext immutableOf(Map<String, Value> attributes) {
+ return new ImmutableContext(attributes);
+ }
+
+ static EvaluationContext immutableOf(String targetingKey, Map<String, Value> attributes) {
+ return new ImmutableContext(targetingKey, attributes);
+ }
+
+ static ImmutableContextBuilder immutableBuilder() {
+ return new ImmutableContext.Builder();
+ }
+
+ static ImmutableContextBuilder immutableBuilder(EvaluationContext original) {
+ return new ImmutableContext.Builder().attributes(original.asMap()).targetingKey(original.getTargetingKey());
+ }
+
String getTargetingKey();
/**
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/EvaluationEvent.java i/openfeature-api/src/main/java/dev/openfeature/api/EvaluationEvent.java
index f915a59..f8d90f9 100644
--- c/openfeature-api/src/main/java/dev/openfeature/api/EvaluationEvent.java
+++ i/openfeature-api/src/main/java/dev/openfeature/api/EvaluationEvent.java
@@ -1,94 +1,13 @@
package dev.openfeature.api;
-import java.util.HashMap;
import java.util.Map;
-import java.util.Objects;
/**
* Represents an evaluation event.
* This class is immutable and thread-safe.
*/
-public class EvaluationEvent {
+public interface EvaluationEvent {
+ String getName();
- private final String name;
- private final Map<String, Object> attributes;
-
- /**
- * Private constructor - use builder() to create instances.
- */
- private EvaluationEvent(String name, Map<String, Object> attributes) {
- this.name = name;
- this.attributes = attributes != null ? new HashMap<>(attributes) : new HashMap<>();
- }
-
- /**
- * Gets the name of the evaluation event.
- *
- * @return the event name
- */
- public String getName() {
- return name;
- }
-
- /**
- * Gets a copy of the event attributes.
- *
- * @return a new map containing the event attributes
- */
- public Map<String, Object> getAttributes() {
- return new HashMap<>(attributes);
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- EvaluationEvent that = (EvaluationEvent) obj;
- return Objects.equals(name, that.name) && Objects.equals(attributes, that.attributes);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(name, attributes);
- }
-
- @Override
- public String toString() {
- return "EvaluationEvent{" + "name='" + name + '\'' + ", attributes=" + attributes + '}';
- }
-
- /**
- * Builder class for creating instances of EvaluationEvent.
- */
- public static class Builder {
- private String name;
- private Map<String, Object> attributes = new HashMap<>();
-
- public Builder name(String name) {
- this.name = name;
- return this;
- }
-
- public Builder attributes(Map<String, Object> attributes) {
- this.attributes = attributes != null ? new HashMap<>(attributes) : new HashMap<>();
- return this;
- }
-
- public Builder attribute(String key, Object value) {
- this.attributes.put(key, value);
- return this;
- }
-
- public EvaluationEvent build() {
- return new EvaluationEvent(name, attributes);
- }
- }
+ Map<String, Object> getAttributes();
}
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/EventDetails.java i/openfeature-api/src/main/java/dev/openfeature/api/EventDetails.java
index d40a480..4263d95 100644
--- c/openfeature-api/src/main/java/dev/openfeature/api/EventDetails.java
+++ i/openfeature-api/src/main/java/dev/openfeature/api/EventDetails.java
@@ -62,7 +62,7 @@ public class EventDetails implements EventDetailsInterface {
}
@Override
- public ImmutableMetadata getEventMetadata() {
+ public Metadata getEventMetadata() {
return providerEventDetails.getEventMetadata();
}
@@ -180,7 +180,7 @@ public class EventDetails implements EventDetailsInterface {
* @param eventMetadata metadata associated with the event
* @return this builder
*/
- public Builder eventMetadata(ImmutableMetadata eventMetadata) {
+ public Builder eventMetadata(Metadata eventMetadata) {
ensureProviderEventDetailsBuilder();
this.providerEventDetails = ProviderEventDetails.builder()
.flagsChanged(getProviderEventDetailsOrEmpty().getFlagsChanged())
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/EventDetailsInterface.java i/openfeature-api/src/main/java/dev/openfeature/api/EventDetailsInterface.java
index 9663e1b..c94f54c 100644
--- c/openfeature-api/src/main/java/dev/openfeature/api/EventDetailsInterface.java
+++ i/openfeature-api/src/main/java/dev/openfeature/api/EventDetailsInterface.java
@@ -29,7 +29,7 @@ public interface EventDetailsInterface {
*
* @return event metadata, or null if none
*/
- ImmutableMetadata getEventMetadata();
+ Metadata getEventMetadata();
/**
* Gets the error code associated with this event.
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/FeatureProvider.java i/openfeature-api/src/main/java/dev/openfeature/api/FeatureProvider.java
index ab86447..500dfb2 100644
--- c/openfeature-api/src/main/java/dev/openfeature/api/FeatureProvider.java
+++ i/openfeature-api/src/main/java/dev/openfeature/api/FeatureProvider.java
@@ -9,7 +9,7 @@ import java.util.List;
* should implement {@link EventProvider}
*/
public interface FeatureProvider {
- Metadata getMetadata();
+ ProviderMetadata getMetadata();
default List<Hook> getProviderHooks() {
return new ArrayList<>();
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/FlagEvaluationDetails.java i/openfeature-api/src/main/java/dev/openfeature/api/FlagEvaluationDetails.java
index 16fec99..71b1114 100644
--- c/openfeature-api/src/main/java/dev/openfeature/api/FlagEvaluationDetails.java
+++ i/openfeature-api/src/main/java/dev/openfeature/api/FlagEvaluationDetails.java
@@ -1,178 +1,44 @@
package dev.openfeature.api;
-import java.util.Objects;
-
/**
* Contains information about how the provider resolved a flag, including the
* resolved value.
*
* @param <T> the type of the flag being evaluated.
*/
-public class FlagEvaluationDetails<T> implements BaseEvaluation<T> {
+public interface FlagEvaluationDetails<T> extends BaseEvaluation<T> {
- private final String flagKey;
- private final T value;
- private final String variant;
- private final String reason;
- private final ErrorCode errorCode;
- private final String errorMessage;
- private final ImmutableMetadata flagMetadata;
+ FlagEvaluationDetails<?> EMPTY = new DefaultFlagEvaluationDetails<>();
- /**
- * Private constructor for builder pattern only.
- */
- private FlagEvaluationDetails() {
- this(null, null, null, null, null, null, null);
+ String getFlagKey();
+
+ static <T> FlagEvaluationDetails<T> of(String key, T value, Reason reason) {
+ return of(key, value, null, reason);
}
- /**
- * Private constructor for immutable FlagEvaluationDetails.
- *
- * @param flagKey the flag key
- * @param value the resolved value
- * @param variant the variant identifier
- * @param reason the reason for the evaluation result
- * @param errorCode the error code if applicable
- * @param errorMessage the error message if applicable
- * @param flagMetadata metadata associated with the flag
- */
- private FlagEvaluationDetails(
- String flagKey,
+ static <T> FlagEvaluationDetails<T> of(String key, T value, String variant, Reason reason) {
+ return of(key, value, variant, reason, null, null, null);
+ }
+
+ static <T> FlagEvaluationDetails<T> of(
+ String key,
+ T value,
+ String variant,
+ Reason reason,
+ ErrorCode errorCode,
+ String errorMessage,
+ Metadata flagMetadata) {
+ return of(key, value, variant, reason.toString(), errorCode, errorMessage, flagMetadata);
+ }
+
+ static <T> FlagEvaluationDetails<T> of(
+ String key,
T value,
String variant,
String reason,
ErrorCode errorCode,
String errorMessage,
- ImmutableMetadata flagMetadata) {
- this.flagKey = flagKey;
- this.value = value;
- this.variant = variant;
- this.reason = reason;
- this.errorCode = errorCode;
- this.errorMessage = errorMessage;
- this.flagMetadata = flagMetadata != null
- ? flagMetadata
- : ImmutableMetadata.builder().build();
- }
-
- public String getFlagKey() {
- return flagKey;
- }
-
- public T getValue() {
- return value;
- }
-
- public String getVariant() {
- return variant;
- }
-
- public String getReason() {
- return reason;
- }
-
- public ErrorCode getErrorCode() {
- return errorCode;
- }
-
- public String getErrorMessage() {
- return errorMessage;
- }
-
- public ImmutableMetadata getFlagMetadata() {
- return flagMetadata;
- }
-
- public static <T> Builder<T> builder() {
- return new Builder<>();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- FlagEvaluationDetails<?> that = (FlagEvaluationDetails<?>) obj;
- return Objects.equals(flagKey, that.flagKey)
- && Objects.equals(value, that.value)
- && Objects.equals(variant, that.variant)
- && Objects.equals(reason, that.reason)
- && errorCode == that.errorCode
- && Objects.equals(errorMessage, that.errorMessage)
- && Objects.equals(flagMetadata, that.flagMetadata);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(flagKey, value, variant, reason, errorCode, errorMessage, flagMetadata);
- }
-
- @Override
- public String toString() {
- return "FlagEvaluationDetails{" + "flagKey='"
- + flagKey + '\'' + ", value="
- + value + ", variant='"
- + variant + '\'' + ", reason='"
- + reason + '\'' + ", errorCode="
- + errorCode + ", errorMessage='"
- + errorMessage + '\'' + ", flagMetadata="
- + flagMetadata + '}';
- }
-
- /**
- * Builder class for creating instances of FlagEvaluationDetails.
- *
- * @param <T> the type of the flag value
- */
- public static class Builder<T> {
- private String flagKey;
- private T value;
- private String variant;
- private String reason;
- private ErrorCode errorCode;
- private String errorMessage;
- private ImmutableMetadata flagMetadata = ImmutableMetadata.builder().build();
-
- public Builder<T> flagKey(String flagKey) {
- this.flagKey = flagKey;
- return this;
- }
-
- public Builder<T> value(T value) {
- this.value = value;
- return this;
- }
-
- public Builder<T> variant(String variant) {
- this.variant = variant;
- return this;
- }
-
- public Builder<T> reason(String reason) {
- this.reason = reason;
- return this;
- }
-
- public Builder<T> errorCode(ErrorCode errorCode) {
- this.errorCode = errorCode;
- return this;
- }
-
- public Builder<T> errorMessage(String errorMessage) {
- this.errorMessage = errorMessage;
- return this;
- }
-
- public Builder<T> flagMetadata(ImmutableMetadata flagMetadata) {
- this.flagMetadata = flagMetadata;
- return this;
- }
-
- public FlagEvaluationDetails<T> build() {
- return new FlagEvaluationDetails<>(flagKey, value, variant, reason, errorCode, errorMessage, flagMetadata);
- }
+ Metadata flagMetadata) {
+ return new DefaultFlagEvaluationDetails<>(key, value, variant, reason, errorCode, errorMessage, flagMetadata);
}
}
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/HookContext.java i/openfeature-api/src/main/java/dev/openfeature/api/HookContext.java
index 722569f..5ac4700 100644
--- c/openfeature-api/src/main/java/dev/openfeature/api/HookContext.java
+++ i/openfeature-api/src/main/java/dev/openfeature/api/HookContext.java
@@ -13,7 +13,7 @@ public final class HookContext<T> {
private final T defaultValue;
private final EvaluationContext ctx;
private final ClientMetadata clientMetadata;
- private final Metadata providerMetadata;
+ private final ProviderMetadata providerMetadata;
private HookContext(Builder<T> builder) {
this.flagKey = Objects.requireNonNull(builder.flagKey, "flagKey cannot be null");
@@ -44,7 +44,7 @@ public final class HookContext<T> {
return clientMetadata;
}
- public Metadata getProviderMetadata() {
+ public ProviderMetadata getProviderMetadata() {
return providerMetadata;
}
@@ -97,7 +97,7 @@ public final class HookContext<T> {
private T defaultValue;
private EvaluationContext ctx;
private ClientMetadata clientMetadata;
- private Metadata providerMetadata;
+ private ProviderMetadata providerMetadata;
private Builder() {}
@@ -126,7 +126,7 @@ public final class HookContext<T> {
return this;
}
- public Builder<T> providerMetadata(Metadata providerMetadata) {
+ public Builder<T> providerMetadata(ProviderMetadata providerMetadata) {
this.providerMetadata = providerMetadata;
return this;
}
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/ImmutableContext.java i/openfeature-api/src/main/java/dev/openfeature/api/ImmutableContext.java
index a2ddf01..a676022 100644
--- c/openfeature-api/src/main/java/dev/openfeature/api/ImmutableContext.java
+++ i/openfeature-api/src/main/java/dev/openfeature/api/ImmutableContext.java
@@ -1,11 +1,9 @@
package dev.openfeature.api;
-import dev.openfeature.api.internal.ExcludeFromGeneratedCoverageReport;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
-import java.util.function.Function;
/**
* The EvaluationContext is a container for arbitrary contextual data
@@ -15,7 +13,7 @@ import java.util.function.Function;
* not be modified after instantiation.
*/
@SuppressWarnings("PMD.BeanMembersShouldSerialize")
-public final class ImmutableContext implements EvaluationContext {
+final class ImmutableContext implements EvaluationContext {
private final ImmutableStructure structure;
@@ -23,7 +21,7 @@ public final class ImmutableContext implements EvaluationContext {
* Create an immutable context with an empty targeting_key and attributes
* provided.
*/
- public ImmutableContext() {
+ ImmutableContext() {
this(new HashMap<>());
}
@@ -32,7 +30,7 @@ public final class ImmutableContext implements EvaluationContext {
*
* @param targetingKey targeting key
*/
- public ImmutableContext(String targetingKey) {
+ ImmutableContext(String targetingKey) {
this(targetingKey, new HashMap<>());
}
@@ -41,7 +39,7 @@ public final class ImmutableContext implements EvaluationContext {
*
* @param attributes evaluation context attributes
*/
- public ImmutableContext(Map<String, Value> attributes) {
+ ImmutableContext(Map<String, Value> attributes) {
this(null, attributes);
}
@@ -51,7 +49,7 @@ public final class ImmutableContext implements EvaluationContext {
* @param targetingKey targeting key
* @param attributes evaluation context attributes
*/
- public ImmutableContext(String targetingKey, Map<String, Value> attributes) {
+ ImmutableContext(String targetingKey, Map<String, Value> attributes) {
if (targetingKey != null && !targetingKey.trim().isEmpty()) {
this.structure = new ImmutableStructure(targetingKey, attributes);
} else {
@@ -142,32 +140,23 @@ public final class ImmutableContext implements EvaluationContext {
return "ImmutableContext{" + "structure=" + structure + '}';
}
- /**
- * Returns a builder for creating ImmutableContext instances.
- *
- * @return a builder for ImmutableContext
- */
- public static Builder builder() {
- return new Builder();
- }
-
/**
* Returns a builder initialized with the current state of this object.
*
* @return a builder for ImmutableContext
*/
- public Builder toBuilder() {
- return builder().targetingKey(this.getTargetingKey()).attributes(this.structure.asMap());
+ public ImmutableContextBuilder toBuilder() {
+ return new Builder().targetingKey(this.getTargetingKey()).attributes(this.structure.asMap());
}
/**
* Builder class for creating instances of ImmutableContext.
*/
- public static class Builder {
+ static class Builder implements ImmutableContextBuilder {
private String targetingKey;
private final Map<String, Value> attributes;
- private Builder() {
+ Builder() {
this.attributes = new HashMap<>();
}
@@ -177,7 +166,8 @@ public final class ImmutableContext implements EvaluationContext {
* @param targetingKey the targeting key
* @return this builder
*/
- public Builder targetingKey(String targetingKey) {
+ @Override
+ public ImmutableContextBuilder targetingKey(String targetingKey) {
this.targetingKey = targetingKey;
return this;
}
@@ -188,7 +178,8 @@ public final class ImmutableContext implements EvaluationContext {
* @param attributes map of attributes
* @return this builder
*/
- public Builder attributes(Map<String, Value> attributes) {
+ @Override
+ public ImmutableContextBuilder attributes(Map<String, Value> attributes) {
if (attributes != null) {
this.attributes.clear();
this.attributes.putAll(attributes);
@@ -203,7 +194,8 @@ public final class ImmutableContext implements EvaluationContext {
* @param value attribute value
* @return this builder
*/
- public Builder add(final String key, final String value) {
+ @Override
+ public ImmutableContextBuilder add(final String key, final String value) {
attributes.put(key, Value.objectToValue(value));
return this;
}
@@ -215,7 +207,8 @@ public final class ImmutableContext implements EvaluationContext {
* @param value attribute value
* @return this builder
*/
- public Builder add(final String key, final Integer value) {
+ @Override
+ public ImmutableContextBuilder add(final String key, final Integer value) {
attributes.put(key, Value.objectToValue(value));
return this;
}
@@ -227,7 +220,8 @@ public final class ImmutableContext implements EvaluationContext {
* @param value attribute value
* @return this builder
*/
- public Builder add(final String key, final Long value) {
+ @Override
+ public ImmutableContextBuilder add(final String key, final Long value) {
attributes.put(key, Value.objectToValue(value));
return this;
}
@@ -239,7 +233,8 @@ public final class ImmutableContext implements EvaluationContext {
* @param value attribute value
* @return this builder
*/
- public Builder add(final String key, final Float value) {
+ @Override
+ public ImmutableContextBuilder add(final String key, final Float value) {
attributes.put(key, Value.objectToValue(value));
return this;
}
@@ -251,7 +246,8 @@ public final class ImmutableContext implements EvaluationContext {
* @param value attribute value
* @return this builder
*/
- public Builder add(final String key, final Double value) {
+ @Override
+ public ImmutableContextBuilder add(final String key, final Double value) {
attributes.put(key, Value.objectToValue(value));
return this;
}
@@ -263,7 +259,8 @@ public final class ImmutableContext implements EvaluationContext {
* @param value attribute value
* @return this builder
*/
- public Builder add(final String key, final Boolean value) {
+ @Override
+ public ImmutableContextBuilder add(final String key, final Boolean value) {
attributes.put(key, Value.objectToValue(value));
return this;
}
@@ -275,7 +272,8 @@ public final class ImmutableContext implements EvaluationContext {
* @param value attribute value
* @return this builder
*/
- public Builder add(final String key, final Structure value) {
+ @Override
+ public ImmutableContextBuilder add(final String key, final Structure value) {
attributes.put(key, Value.objectToValue(value));
return this;
}
@@ -287,7 +285,8 @@ public final class ImmutableContext implements EvaluationContext {
* @param value attribute value
* @return this builder
*/
- public Builder add(final String key, final Value value) {
+ @Override
+ public ImmutableContextBuilder add(final String key, final Value value) {
attributes.put(key, value);
return this;
}
@@ -297,19 +296,9 @@ public final class ImmutableContext implements EvaluationContext {
*
* @return a new ImmutableContext instance
*/
+ @Override
public ImmutableContext build() {
return new ImmutableContext(targetingKey, new HashMap<>(attributes));
}
}
-
- @SuppressWarnings("all")
- private static class DelegateExclusions {
- @ExcludeFromGeneratedCoverageReport
- public <T extends Structure> Map<String, Value> merge(
- Function<Map<String, Value>, Structure> newStructure,
- Map<String, Value> base,
- Map<String, Value> overriding) {
- return null;
- }
- }
}
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/ImmutableContextBuilder.java i/openfeature-api/src/main/java/dev/openfeature/api/ImmutableContextBuilder.java
new file mode 100644
index 0000000..89744c5
--- /dev/null
+++ i/openfeature-api/src/main/java/dev/openfeature/api/ImmutableContextBuilder.java
@@ -0,0 +1,30 @@
+package dev.openfeature.api;
+
+import java.util.Map;
+
+/**
+ * Builder class for creating instances of ImmutableContext.
+ */
+public interface ImmutableContextBuilder {
+ ImmutableContextBuilder targetingKey(String targetingKey);
+
+ ImmutableContextBuilder attributes(Map<String, Value> attributes);
+
+ ImmutableContextBuilder add(String key, String value);
+
+ ImmutableContextBuilder add(String key, Integer value);
+
+ ImmutableContextBuilder add(String key, Long value);
+
+ ImmutableContextBuilder add(String key, Float value);
+
+ ImmutableContextBuilder add(String key, Double value);
+
+ ImmutableContextBuilder add(String key, Boolean value);
+
+ ImmutableContextBuilder add(String key, Structure value);
+
+ ImmutableContextBuilder add(String key, Value value);
+
+ EvaluationContext build();
+}
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/ImmutableMetadata.java i/openfeature-api/src/main/java/dev/openfeature/api/ImmutableMetadata.java
index 6536033..49d2a6f 100644
--- c/openfeature-api/src/main/java/dev/openfeature/api/ImmutableMetadata.java
+++ i/openfeature-api/src/main/java/dev/openfeature/api/ImmutableMetadata.java
@@ -12,14 +12,16 @@ import org.slf4j.LoggerFactory;
* Immutable Flag Metadata representation. Implementation is backed by a {@link Map} and immutability is provided
* through builder and accessors.
*/
-public class ImmutableMetadata extends AbstractStructure {
+final class ImmutableMetadata extends AbstractStructure implements Metadata {
private static final Logger log = LoggerFactory.getLogger(ImmutableMetadata.class);
- private ImmutableMetadata(Map<String, Value> attributes) {
+ ImmutableMetadata(Map<String, Value> attributes) {
super(attributes);
}
+ ImmutableMetadata() {}
+
@Override
public Set<String> keySet() {
return attributes.keySet();
@@ -33,6 +35,7 @@ public class ImmutableMetadata extends AbstractStructure {
/**
* Generic value retrieval for the given key.
*/
+ @Override
public <T> T getValue(final String key, final Class<T> type) {
Value value = getValue(key);
if (value == null) {
@@ -60,6 +63,7 @@ public class ImmutableMetadata extends AbstractStructure {
*
* @param key flag metadata key to retrieve
*/
+ @Override
public String getString(final String key) {
Value value = getValue(key);
return value != null && value.isString() ? value.asString() : null;
@@ -71,6 +75,7 @@ public class ImmutableMetadata extends AbstractStructure {
*
* @param key flag metadata key to retrieve
*/
+ @Override
public Integer getInteger(final String key) {
Value value = getValue(key);
if (value != null && value.isNumber()) {
@@ -88,6 +93,7 @@ public class ImmutableMetadata extends AbstractStructure {
*
* @param key flag metadata key to retrieve
*/
+ @Override
public Long getLong(final String key) {
Value value = getValue(key);
if (value != null && value.isNumber()) {
@@ -105,6 +111,7 @@ public class ImmutableMetadata extends AbstractStructure {
*
* @param key flag metadata key to retrieve
*/
+ @Override
public Float getFloat(final String key) {
Value value = getValue(key);
if (value != null && value.isNumber()) {
@@ -122,6 +129,7 @@ public class ImmutableMetadata extends AbstractStructure {
*
* @param key flag metadata key to retrieve
*/
+ @Override
public Double getDouble(final String key) {
Value value = getValue(key);
if (value != null && value.isNumber()) {
@@ -139,6 +147,7 @@ public class ImmutableMetadata extends AbstractStructure {
*
* @param key flag metadata key to retrieve
*/
+ @Override
public Boolean getBoolean(final String key) {
Value value = getValue(key);
return value != null && value.isBoolean() ? value.asBoolean() : null;
@@ -148,10 +157,12 @@ public class ImmutableMetadata extends AbstractStructure {
* Returns an unmodifiable map of metadata as primitive objects.
* This provides backward compatibility for the original ImmutableMetadata API.
*/
+ @Override
public Map<String, Object> asUnmodifiableObjectMap() {
return Collections.unmodifiableMap(asObjectMap());
}
+ @Override
public boolean isNotEmpty() {
return !isEmpty();
}
@@ -176,19 +187,12 @@ public class ImmutableMetadata extends AbstractStructure {
}
/**
- * Obtain a builder for {@link ImmutableMetadata}.
+ * Immutable builder for {@link Metadata}.
*/
- public static Builder builder() {
- return new Builder();
- }
-
- /**
- * Immutable builder for {@link ImmutableMetadata}.
- */
- public static class Builder {
+ public static class Builder implements ImmutableMetadataBuilder {
private final Map<String, Value> attributes;
- private Builder() {
+ Builder() {
attributes = new HashMap<>();
}
@@ -198,7 +202,8 @@ public class ImmutableMetadata extends AbstractStructure {
* @param key flag metadata key to add
* @param value flag metadata value to add
*/
- public Builder addString(final String key, final String value) {
+ @Override
+ public ImmutableMetadataBuilder add(final String key, final String value) {
attributes.put(key, Value.objectToValue(value));
return this;
}
@@ -209,7 +214,8 @@ public class ImmutableMetadata extends AbstractStructure {
* @param key flag metadata key to add
* @param value flag metadata value to add
*/
- public Builder addInteger(final String key, final Integer value) {
+ @Override
+ public ImmutableMetadataBuilder add(final String key, final Integer value) {
attributes.put(key, Value.objectToValue(value));
return this;
}
@@ -220,7 +226,8 @@ public class ImmutableMetadata extends AbstractStructure {
* @param key flag metadata key to add
* @param value flag metadata value to add
*/
- public Builder addLong(final String key, final Long value) {
+ @Override
+ public ImmutableMetadataBuilder add(final String key, final Long value) {
attributes.put(key, Value.objectToValue(value));
return this;
}
@@ -231,7 +238,8 @@ public class ImmutableMetadata extends AbstractStructure {
* @param key flag metadata key to add
* @param value flag metadata value to add
*/
- public Builder addFloat(final String key, final Float value) {
+ @Override
+ public ImmutableMetadataBuilder add(final String key, final Float value) {
attributes.put(key, Value.objectToValue(value));
return this;
}
@@ -242,7 +250,8 @@ public class ImmutableMetadata extends AbstractStructure {
* @param key flag metadata key to add
* @param value flag metadata value to add
*/
- public Builder addDouble(final String key, final Double value) {
+ @Override
+ public ImmutableMetadataBuilder add(final String key, final Double value) {
attributes.put(key, Value.objectToValue(value));
return this;
}
@@ -253,15 +262,17 @@ public class ImmutableMetadata extends AbstractStructure {
* @param key flag metadata key to add
* @param value flag metadata value to add
*/
- public Builder addBoolean(final String key, final Boolean value) {
+ @Override
+ public ImmutableMetadataBuilder add(final String key, final Boolean value) {
attributes.put(key, Value.objectToValue(value));
return this;
}
/**
- * Retrieve {@link ImmutableMetadata} with provided key,value pairs.
+ * Retrieve {@link Metadata} with provided key,value pairs.
*/
- public ImmutableMetadata build() {
+ @Override
+ public Metadata build() {
return new ImmutableMetadata(new HashMap<>(this.attributes));
}
}
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/ImmutableMetadataBuilder.java i/openfeature-api/src/main/java/dev/openfeature/api/ImmutableMetadataBuilder.java
new file mode 100644
index 0000000..81909ba
--- /dev/null
+++ i/openfeature-api/src/main/java/dev/openfeature/api/ImmutableMetadataBuilder.java
@@ -0,0 +1,20 @@
+package dev.openfeature.api;
+
+/**
+ * Immutable builder for {@link Metadata}.
+ */
+public interface ImmutableMetadataBuilder {
+ ImmutableMetadataBuilder add(String key, String value);
+
+ ImmutableMetadataBuilder add(String key, Integer value);
+
+ ImmutableMetadataBuilder add(String key, Long value);
+
+ ImmutableMetadataBuilder add(String key, Float value);
+
+ ImmutableMetadataBuilder add(String key, Double value);
+
+ ImmutableMetadataBuilder add(String key, Boolean value);
+
+ Metadata build();
+}
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/Metadata.java i/openfeature-api/src/main/java/dev/openfeature/api/Metadata.java
index c665f0e..bbaa527 100644
--- c/openfeature-api/src/main/java/dev/openfeature/api/Metadata.java
+++ i/openfeature-api/src/main/java/dev/openfeature/api/Metadata.java
@@ -1,8 +1,43 @@
package dev.openfeature.api;
+import java.util.Map;
+import java.util.Set;
+
/**
- * Holds identifying information about a given entity.
+ * Flag Metadata representation.
*/
-public interface Metadata {
- String getName();
+public interface Metadata extends Structure {
+
+ Metadata EMPTY = new ImmutableMetadata();
+
+ static ImmutableMetadataBuilder immutableBuilder() {
+ return new ImmutableMetadata.Builder();
+ }
+
+ @Override
+ Set<String> keySet();
+
+ @Override
+ Value getValue(String key);
+
+ <T> T getValue(String key, Class<T> type);
+
+ @Override
+ Map<String, Value> asMap();
+
+ String getString(String key);
+
+ Integer getInteger(String key);
+
+ Long getLong(String key);
+
+ Float getFloat(String key);
+
+ Double getDouble(String key);
+
+ Boolean getBoolean(String key);
+
+ Map<String, Object> asUnmodifiableObjectMap();
+
+ boolean isNotEmpty();
}
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/MutableContext.java i/openfeature-api/src/main/java/dev/openfeature/api/MutableContext.java
index b6e178b..767ef9a 100644
--- c/openfeature-api/src/main/java/dev/openfeature/api/MutableContext.java
+++ i/openfeature-api/src/main/java/dev/openfeature/api/MutableContext.java
@@ -1,13 +1,11 @@
package dev.openfeature.api;
-import dev.openfeature.api.internal.ExcludeFromGeneratedCoverageReport;
import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
-import java.util.function.Function;
/**
* The EvaluationContext is a container for arbitrary contextual data
@@ -173,52 +171,4 @@ public class MutableContext implements EvaluationContext {
public String toString() {
return "MutableContext{" + "structure=" + structure + '}';
}
-
- /**
- * Hidden class to tell Lombok not to copy these methods over via delegation.
- */
- @SuppressWarnings("all")
- private static class DelegateExclusions {
-
- @ExcludeFromGeneratedCoverageReport
- public <T extends Structure> Map<String, Value> merge(
- Function<Map<String, Value>, Structure> newStructure,
- Map<String, Value> base,
- Map<String, Value> overriding) {
-
- return null;
- }
-
- 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<Value> ignoredValue) {
- return null;
- }
-
- public MutableStructure add(String ignoredKey, Structure ignoredValue) {
- return null;
- }
-
- public MutableStructure add(String ignoredKey, Instant ignoredValue) {
- return null;
- }
- }
}
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/OpenFeatureCore.java i/openfeature-api/src/main/java/dev/openfeature/api/OpenFeatureCore.java
index 22254e8..cb72e12 100644
--- c/openfeature-api/src/main/java/dev/openfeature/api/OpenFeatureCore.java
+++ i/openfeature-api/src/main/java/dev/openfeature/api/OpenFeatureCore.java
@@ -98,7 +98,7 @@ public interface OpenFeatureCore {
*
* @return the provider metadata
*/
- Metadata getProviderMetadata();
+ ProviderMetadata getProviderMetadata();
/**
* Get metadata about a registered provider using the client name.
@@ -107,5 +107,5 @@ public interface OpenFeatureCore {
* @param domain an identifier which logically binds clients with providers
* @return the provider metadata
*/
- Metadata getProviderMetadata(String domain);
+ ProviderMetadata getProviderMetadata(String domain);
}
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/ProviderEvaluation.java i/openfeature-api/src/main/java/dev/openfeature/api/ProviderEvaluation.java
index 66d991c..8ae6d72 100644
--- c/openfeature-api/src/main/java/dev/openfeature/api/ProviderEvaluation.java
+++ i/openfeature-api/src/main/java/dev/openfeature/api/ProviderEvaluation.java
@@ -1,160 +1,22 @@
package dev.openfeature.api;
-import java.util.Objects;
-
/**
* Contains information about how the a flag was evaluated, including the resolved value.
*
* @param <T> the type of the flag being evaluated.
*/
-public class ProviderEvaluation<T> implements BaseEvaluation<T> {
- private final T value;
- private final String variant;
- private final String reason;
- private final ErrorCode errorCode;
- private final String errorMessage;
- private final ImmutableMetadata flagMetadata;
+public interface ProviderEvaluation<T> extends BaseEvaluation<T> {
- /**
- * Private constructor for builder pattern only.
- */
- private ProviderEvaluation() {
- this(null, null, null, null, null, null);
+ static <T> ProviderEvaluation<T> of(T value, String variant, String reason, Metadata flagMetadata) {
+ return of(value, variant, reason, null, null, flagMetadata);
}
- /**
- * Private constructor for immutable ProviderEvaluation.
- *
- * @param value the resolved value
- * @param variant the variant identifier
- * @param reason the reason for the evaluation result
- * @param errorCode the error code if applicable
- * @param errorMessage the error message if applicable
- * @param flagMetadata metadata associated with the flag
- */
- private ProviderEvaluation(
- T value,
- String variant,
- String reason,
- ErrorCode errorCode,
- String errorMessage,
- ImmutableMetadata flagMetadata) {
- this.value = value;
- this.variant = variant;
- this.reason = reason;
- this.errorCode = errorCode;
- this.errorMessage = errorMessage;
- this.flagMetadata = flagMetadata != null
- ? flagMetadata
- : ImmutableMetadata.builder().build();
+ static <T> ProviderEvaluation<T> of(
+ T value, String variant, String reason, ErrorCode errorCode, String errorMessage, Metadata flagMetadata) {
+ return new DefaultProviderEvaluation<T>(value, variant, reason, errorCode, errorMessage, flagMetadata);
}
- public T getValue() {
- return value;
- }
-
- public String getVariant() {
- return variant;
- }
-
- public String getReason() {
- return reason;
- }
-
- public ErrorCode getErrorCode() {
- return errorCode;
- }
-
- public String getErrorMessage() {
- return errorMessage;
- }
-
- public ImmutableMetadata getFlagMetadata() {
- return flagMetadata;
- }
-
- public static <T> Builder<T> builder() {
- return new Builder<>();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- ProviderEvaluation<?> that = (ProviderEvaluation<?>) obj;
- return Objects.equals(value, that.value)
- && Objects.equals(variant, that.variant)
- && Objects.equals(reason, that.reason)
- && errorCode == that.errorCode
- && Objects.equals(errorMessage, that.errorMessage)
- && Objects.equals(flagMetadata, that.flagMetadata);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(value, variant, reason, errorCode, errorMessage, flagMetadata);
- }
-
- @Override
- public String toString() {
- return "ProviderEvaluation{" + "value="
- + value + ", variant='"
- + variant + '\'' + ", reason='"
- + reason + '\'' + ", errorCode="
- + errorCode + ", errorMessage='"
- + errorMessage + '\'' + ", flagMetadata="
- + flagMetadata + '}';
- }
-
- /**
- * Builder class for creating instances of ProviderEvaluation.
- *
- * @param <T> the type of the evaluation value
- */
- public static class Builder<T> {
- private T value;
- private String variant;
- private String reason;
- private ErrorCode errorCode;
- private String errorMessage;
- private ImmutableMetadata flagMetadata = ImmutableMetadata.builder().build();
-
- public Builder<T> value(T value) {
- this.value = value;
- return this;
- }
-
- public Builder<T> variant(String variant) {
- this.variant = variant;
- return this;
- }
-
- public Builder<T> reason(String reason) {
- this.reason = reason;
- return this;
- }
-
- public Builder<T> errorCode(ErrorCode errorCode) {
- this.errorCode = errorCode;
- return this;
- }
-
- public Builder<T> errorMessage(String errorMessage) {
- this.errorMessage = errorMessage;
- return this;
- }
-
- public Builder<T> flagMetadata(ImmutableMetadata flagMetadata) {
- this.flagMetadata = flagMetadata;
- return this;
- }
-
- public ProviderEvaluation<T> build() {
- return new ProviderEvaluation<>(value, variant, reason, errorCode, errorMessage, flagMetadata);
- }
+ static <T> ProviderEvaluation<T> of(ErrorCode errorCode, String errorMessage) {
+ return of(null, null, Reason.ERROR.toString(), errorCode, errorMessage, null);
}
}
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/ProviderEventDetails.java i/openfeature-api/src/main/java/dev/openfeature/api/ProviderEventDetails.java
index a20ffa5..2ffc219 100644
--- c/openfeature-api/src/main/java/dev/openfeature/api/ProviderEventDetails.java
+++ i/openfeature-api/src/main/java/dev/openfeature/api/ProviderEventDetails.java
@@ -11,7 +11,7 @@ import java.util.Objects;
public class ProviderEventDetails implements EventDetailsInterface {
private final List<String> flagsChanged;
private final String message;
- private final ImmutableMetadata eventMetadata;
+ private final Metadata eventMetadata;
private final ErrorCode errorCode;
/**
@@ -33,7 +33,7 @@ public class ProviderEventDetails implements EventDetailsInterface {
* @param errorCode error code (should be populated for PROVIDER_ERROR events)
*/
private ProviderEventDetails(
- List<String> flagsChanged, String message, ImmutableMetadata eventMetadata, ErrorCode errorCode) {
+ List<String> flagsChanged, String message, Metadata eventMetadata, ErrorCode errorCode) {
this.flagsChanged = flagsChanged != null ? List.copyOf(flagsChanged) : null;
this.message = message;
this.eventMetadata = eventMetadata;
@@ -48,7 +48,7 @@ public class ProviderEventDetails implements EventDetailsInterface {
return message;
}
- public ImmutableMetadata getEventMetadata() {
+ public Metadata getEventMetadata() {
return eventMetadata;
}
@@ -108,7 +108,7 @@ public class ProviderEventDetails implements EventDetailsInterface {
public static class Builder {
private List<String> flagsChanged;
private String message;
- private ImmutableMetadata eventMetadata;
+ private Metadata eventMetadata;
private ErrorCode errorCode;
private Builder() {}
@@ -123,7 +123,7 @@ public class ProviderEventDetails implements EventDetailsInterface {
return this;
}
- public Builder eventMetadata(ImmutableMetadata eventMetadata) {
+ public Builder eventMetadata(Metadata eventMetadata) {
this.eventMetadata = eventMetadata;
return this;
}
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/ProviderMetadata.java i/openfeature-api/src/main/java/dev/openfeature/api/ProviderMetadata.java
new file mode 100644
index 0000000..be970f9
--- /dev/null
+++ i/openfeature-api/src/main/java/dev/openfeature/api/ProviderMetadata.java
@@ -0,0 +1,8 @@
+package dev.openfeature.api;
+
+/**
+ * Holds identifying information about a given entity.
+ */
+public interface ProviderMetadata {
+ String getName();
+}
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/Telemetry.java i/openfeature-api/src/main/java/dev/openfeature/api/Telemetry.java
index 457010a..89a57d7 100644
--- c/openfeature-api/src/main/java/dev/openfeature/api/Telemetry.java
+++ i/openfeature-api/src/main/java/dev/openfeature/api/Telemetry.java
@@ -41,7 +41,7 @@ public class Telemetry {
*/
public static EvaluationEvent createEvaluationEvent(
HookContext<?> hookContext, FlagEvaluationDetails<?> evaluationDetails) {
- EvaluationEvent.Builder evaluationEventBuilder = EvaluationEvent.builder()
+ DefaultEvaluationEvent.Builder evaluationEventBuilder = DefaultEvaluationEvent.builder()
.name(FLAG_EVALUATION_EVENT_NAME)
.attribute(TELEMETRY_KEY, hookContext.getFlagKey())
.attribute(TELEMETRY_PROVIDER, hookContext.getProviderMetadata().getName());
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/internal/noop/NoOpClient.java i/openfeature-api/src/main/java/dev/openfeature/api/internal/noop/NoOpClient.java
index 040215e..08c29ec 100644
--- c/openfeature-api/src/main/java/dev/openfeature/api/internal/noop/NoOpClient.java
+++ i/openfeature-api/src/main/java/dev/openfeature/api/internal/noop/NoOpClient.java
@@ -58,11 +58,7 @@ public class NoOpClient implements Client {
@Override
public FlagEvaluationDetails<Boolean> getBooleanDetails(String key, Boolean defaultValue) {
- return FlagEvaluationDetails.<Boolean>builder()
- .flagKey(key)
- .value(defaultValue)
- .reason(Reason.DEFAULT.toString())
- .build();
+ return FlagEvaluationDetails.of(key, defaultValue, Reason.DEFAULT);
}
@Override
@@ -94,11 +90,7 @@ public class NoOpClient implements Client {
@Override
public FlagEvaluationDetails<String> getStringDetails(String key, String defaultValue) {
- return FlagEvaluationDetails.<String>builder()
- .flagKey(key)
- .value(defaultValue)
- .reason(Reason.DEFAULT.toString())
- .build();
+ return FlagEvaluationDetails.of(key, defaultValue, Reason.DEFAULT);
}
@Override
@@ -130,11 +122,7 @@ public class NoOpClient implements Client {
@Override
public FlagEvaluationDetails<Integer> getIntegerDetails(String key, Integer defaultValue) {
- return FlagEvaluationDetails.<Integer>builder()
- .flagKey(key)
- .value(defaultValue)
- .reason(Reason.DEFAULT.toString())
- .build();
+ return FlagEvaluationDetails.of(key, defaultValue, Reason.DEFAULT);
}
@Override
@@ -166,11 +154,7 @@ public class NoOpClient implements Client {
@Override
public FlagEvaluationDetails<Double> getDoubleDetails(String key, Double defaultValue) {
- return FlagEvaluationDetails.<Double>builder()
- .flagKey(key)
- .value(defaultValue)
- .reason(Reason.DEFAULT.toString())
- .build();
+ return FlagEvaluationDetails.of(key, defaultValue, Reason.DEFAULT);
}
@Override
@@ -202,11 +186,7 @@ public class NoOpClient implements Client {
@Override
public FlagEvaluationDetails<Value> getObjectDetails(String key, Value defaultValue) {
- return FlagEvaluationDetails.<Value>builder()
- .flagKey(key)
- .value(defaultValue)
- .reason(Reason.DEFAULT.toString())
- .build();
+ return FlagEvaluationDetails.of(key, defaultValue, Reason.DEFAULT);
}
@Override
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/internal/noop/NoOpOpenFeatureAPI.java i/openfeature-api/src/main/java/dev/openfeature/api/internal/noop/NoOpOpenFeatureAPI.java
index d2a4a4d..fbd07b3 100644
--- c/openfeature-api/src/main/java/dev/openfeature/api/internal/noop/NoOpOpenFeatureAPI.java
+++ i/openfeature-api/src/main/java/dev/openfeature/api/internal/noop/NoOpOpenFeatureAPI.java
@@ -5,9 +5,9 @@ import dev.openfeature.api.EvaluationContext;
import dev.openfeature.api.EventDetails;
import dev.openfeature.api.FeatureProvider;
import dev.openfeature.api.Hook;
-import dev.openfeature.api.Metadata;
import dev.openfeature.api.OpenFeatureAPI;
import dev.openfeature.api.ProviderEvent;
+import dev.openfeature.api.ProviderMetadata;
import dev.openfeature.api.TransactionContextPropagator;
import dev.openfeature.api.exceptions.OpenFeatureError;
import dev.openfeature.api.internal.ExcludeFromGeneratedCoverageReport;
@@ -76,12 +76,12 @@ public class NoOpOpenFeatureAPI extends OpenFeatureAPI {
}
@Override
- public Metadata getProviderMetadata() {
+ public ProviderMetadata getProviderMetadata() {
return () -> "No-op Provider";
}
@Override
- public Metadata getProviderMetadata(String domain) {
+ public ProviderMetadata getProviderMetadata(String domain) {
return getProviderMetadata();
}
diff --git c/openfeature-api/src/main/java/dev/openfeature/api/internal/noop/NoOpProvider.java i/openfeature-api/src/main/java/dev/openfeature/api/internal/noop/NoOpProvider.java
index a1fac57..a0c66a5 100644
--- c/openfeature-api/src/main/java/dev/openfeature/api/internal/noop/NoOpProvider.java
+++ i/openfeature-api/src/main/java/dev/openfeature/api/internal/noop/NoOpProvider.java
@@ -2,8 +2,8 @@ package dev.openfeature.api.internal.noop;
import dev.openfeature.api.EvaluationContext;
import dev.openfeature.api.FeatureProvider;
-import dev.openfeature.api.Metadata;
import dev.openfeature.api.ProviderEvaluation;
+import dev.openfeature.api.ProviderMetadata;
import dev.openfeature.api.ProviderState;
import dev.openfeature.api.Reason;
import dev.openfeature.api.Value;
@@ -31,53 +31,33 @@ public class NoOpProvider implements FeatureProvider {
}
@Override
- public Metadata getMetadata() {
+ public ProviderMetadata getMetadata() {
return () -> name;
}
@Override
public ProviderEvaluation<Boolean> getBooleanEvaluation(String key, Boolean defaultValue, EvaluationContext ctx) {
- return ProviderEvaluation.<Boolean>builder()
- .value(defaultValue)
- .variant(PASSED_IN_DEFAULT)
- .reason(Reason.DEFAULT.toString())
- .build();
+ return ProviderEvaluation.of(defaultValue, PASSED_IN_DEFAULT, Reason.DEFAULT.toString(), null);
}
@Override
public ProviderEvaluation<String> getStringEvaluation(String key, String defaultValue, EvaluationContext ctx) {
- return ProviderEvaluation.<String>builder()
- .value(defaultValue)
- .variant(PASSED_IN_DEFAULT)
- .reason(Reason.DEFAULT.toString())
- .build();
+ return ProviderEvaluation.of(defaultValue, PASSED_IN_DEFAULT, Reason.DEFAULT.toString(), null);
}
@Override
public ProviderEvaluation<Integer> getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx) {
- return ProviderEvaluation.<Integer>builder()
- .value(defaultValue)
- .variant(PASSED_IN_DEFAULT)
- .reason(Reason.DEFAULT.toString())
- .build();
+ return ProviderEvaluation.of(defaultValue, PASSED_…1 parent 2a3a4ad commit 422997a
File tree
78 files changed
+1245
-1392
lines changed- .github/workflows
- openfeature-api/src
- main/java/dev/openfeature/api
- internal/noop
- test/java/dev/openfeature/api
- openfeature-sdk/src
- main/java/dev/openfeature/sdk
- providers/memory
- test/java/dev/openfeature/sdk
- benchmark
- e2e
- steps
- fixtures
- hooks/logging
- providers/memory
- testutils
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
78 files changed
+1245
-1392
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| 27 | + | |
| 28 | + | |
27 | 29 | | |
28 | 30 | | |
29 | 31 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
Lines changed: 2 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
41 | 41 | | |
42 | 42 | | |
43 | 43 | | |
| 44 | + | |
| 45 | + | |
44 | 46 | | |
Lines changed: 96 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
Lines changed: 118 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
Lines changed: 101 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
Lines changed: 16 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
21 | 37 | | |
22 | 38 | | |
23 | 39 | | |
| |||
0 commit comments