Skip to content

Commit 724c8c1

Browse files
committed
fixup: further improve immutability and add release please
Signed-off-by: Simon Schrottner <[email protected]>
1 parent f146499 commit 724c8c1

File tree

78 files changed

+1245
-1392
lines changed

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

.github/workflows/release.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ jobs:
2424
id: release
2525
with:
2626
token: ${{secrets.RELEASE_PLEASE_ACTION_TOKEN}}
27+
prerelease: ${{ github.ref == 'refs/heads/beta' }}
28+
prerelease-type: "beta"
2729
outputs:
2830
release_created: ${{ fromJSON(steps.release.outputs.paths_released)[0] != null }} # if we have a single release path, do the release
2931

.release-please-manifest.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
{".":"1.16.0"}
1+
{
2+
"./sdk": "2.0.0-beta",
3+
"./api": "0.0.0-beta"
4+
}

openfeature-api/src/main/java/dev/openfeature/api/BaseEvaluation.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,6 @@ public interface BaseEvaluation<T> {
4141
* @return {String}
4242
*/
4343
String getErrorMessage();
44+
45+
Metadata getFlagMetadata();
4446
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package dev.openfeature.api;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
import java.util.Objects;
6+
7+
/**
8+
* Represents an evaluation event.
9+
* This class is immutable and thread-safe.
10+
*/
11+
class DefaultEvaluationEvent implements EvaluationEvent {
12+
13+
private final String name;
14+
private final Map<String, Object> attributes;
15+
16+
/**
17+
* Private constructor - use builder() to create instances.
18+
*/
19+
private DefaultEvaluationEvent(String name, Map<String, Object> attributes) {
20+
this.name = name;
21+
this.attributes = attributes != null ? new HashMap<>(attributes) : new HashMap<>();
22+
}
23+
24+
/**
25+
* Gets the name of the evaluation event.
26+
*
27+
* @return the event name
28+
*/
29+
@Override
30+
public String getName() {
31+
return name;
32+
}
33+
34+
/**
35+
* Gets a copy of the event attributes.
36+
*
37+
* @return a new map containing the event attributes
38+
*/
39+
@Override
40+
public Map<String, Object> getAttributes() {
41+
return new HashMap<>(attributes);
42+
}
43+
44+
public static Builder builder() {
45+
return new Builder();
46+
}
47+
48+
@Override
49+
public boolean equals(Object obj) {
50+
if (this == obj) {
51+
return true;
52+
}
53+
if (obj == null || getClass() != obj.getClass()) {
54+
return false;
55+
}
56+
DefaultEvaluationEvent that = (DefaultEvaluationEvent) obj;
57+
return Objects.equals(name, that.name) && Objects.equals(attributes, that.attributes);
58+
}
59+
60+
@Override
61+
public int hashCode() {
62+
return Objects.hash(name, attributes);
63+
}
64+
65+
@Override
66+
public String toString() {
67+
return "EvaluationEvent{" + "name='" + name + '\'' + ", attributes=" + attributes + '}';
68+
}
69+
70+
/**
71+
* Builder class for creating instances of EvaluationEvent.
72+
*/
73+
public static class Builder {
74+
private String name;
75+
private Map<String, Object> attributes = new HashMap<>();
76+
77+
public Builder name(String name) {
78+
this.name = name;
79+
return this;
80+
}
81+
82+
public Builder attributes(Map<String, Object> attributes) {
83+
this.attributes = attributes != null ? new HashMap<>(attributes) : new HashMap<>();
84+
return this;
85+
}
86+
87+
public Builder attribute(String key, Object value) {
88+
this.attributes.put(key, value);
89+
return this;
90+
}
91+
92+
public EvaluationEvent build() {
93+
return new DefaultEvaluationEvent(name, attributes);
94+
}
95+
}
96+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package dev.openfeature.api;
2+
3+
import java.util.Objects;
4+
5+
/**
6+
* Contains information about how the provider resolved a flag, including the
7+
* resolved value.
8+
*
9+
* @param <T> the type of the flag being evaluated.
10+
*/
11+
class DefaultFlagEvaluationDetails<T> implements FlagEvaluationDetails<T> {
12+
13+
private final String flagKey;
14+
private final T value;
15+
private final String variant;
16+
private final String reason;
17+
private final ErrorCode errorCode;
18+
private final String errorMessage;
19+
private final Metadata flagMetadata;
20+
21+
/**
22+
* Private constructor for builder pattern only.
23+
*/
24+
DefaultFlagEvaluationDetails() {
25+
this(null, null, null, null, null, null, null);
26+
}
27+
28+
/**
29+
* Private constructor for immutable FlagEvaluationDetails.
30+
*
31+
* @param flagKey the flag key
32+
* @param value the resolved value
33+
* @param variant the variant identifier
34+
* @param reason the reason for the evaluation result
35+
* @param errorCode the error code if applicable
36+
* @param errorMessage the error message if applicable
37+
* @param flagMetadata metadata associated with the flag
38+
*/
39+
DefaultFlagEvaluationDetails(
40+
String flagKey,
41+
T value,
42+
String variant,
43+
String reason,
44+
ErrorCode errorCode,
45+
String errorMessage,
46+
Metadata flagMetadata) {
47+
this.flagKey = flagKey;
48+
this.value = value;
49+
this.variant = variant;
50+
this.reason = reason;
51+
this.errorCode = errorCode;
52+
this.errorMessage = errorMessage;
53+
this.flagMetadata = flagMetadata != null ? flagMetadata : Metadata.EMPTY;
54+
}
55+
56+
public String getFlagKey() {
57+
return flagKey;
58+
}
59+
60+
public T getValue() {
61+
return value;
62+
}
63+
64+
public String getVariant() {
65+
return variant;
66+
}
67+
68+
public String getReason() {
69+
return reason;
70+
}
71+
72+
public ErrorCode getErrorCode() {
73+
return errorCode;
74+
}
75+
76+
public String getErrorMessage() {
77+
return errorMessage;
78+
}
79+
80+
public Metadata getFlagMetadata() {
81+
return flagMetadata;
82+
}
83+
84+
@Override
85+
public boolean equals(Object obj) {
86+
if (this == obj) {
87+
return true;
88+
}
89+
if (obj == null || getClass() != obj.getClass()) {
90+
return false;
91+
}
92+
FlagEvaluationDetails<?> that = (FlagEvaluationDetails<?>) obj;
93+
return Objects.equals(flagKey, that.getFlagKey())
94+
&& Objects.equals(value, that.getValue())
95+
&& Objects.equals(variant, that.getVariant())
96+
&& Objects.equals(reason, that.getReason())
97+
&& errorCode == that.getErrorCode()
98+
&& Objects.equals(errorMessage, that.getErrorMessage())
99+
&& Objects.equals(flagMetadata, that.getFlagMetadata());
100+
}
101+
102+
@Override
103+
public int hashCode() {
104+
return Objects.hash(flagKey, value, variant, reason, errorCode, errorMessage, flagMetadata);
105+
}
106+
107+
@Override
108+
public String toString() {
109+
return "FlagEvaluationDetails{" + "flagKey='"
110+
+ flagKey + '\'' + ", value="
111+
+ value + ", variant='"
112+
+ variant + '\'' + ", reason='"
113+
+ reason + '\'' + ", errorCode="
114+
+ errorCode + ", errorMessage='"
115+
+ errorMessage + '\'' + ", flagMetadata="
116+
+ flagMetadata + '}';
117+
}
118+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package dev.openfeature.api;
2+
3+
import java.util.Objects;
4+
5+
/**
6+
* Contains information about how the a flag was evaluated, including the resolved value.
7+
*
8+
* @param <T> the type of the flag being evaluated.
9+
*/
10+
class DefaultProviderEvaluation<T> implements ProviderEvaluation<T> {
11+
private final T value;
12+
private final String variant;
13+
private final String reason;
14+
private final ErrorCode errorCode;
15+
private final String errorMessage;
16+
private final Metadata flagMetadata;
17+
18+
/**
19+
* Private constructor for builder pattern only.
20+
*/
21+
DefaultProviderEvaluation() {
22+
this(null, null, null, null, null, null);
23+
}
24+
25+
/**
26+
* Private constructor for immutable ProviderEvaluation.
27+
*
28+
* @param value the resolved value
29+
* @param variant the variant identifier
30+
* @param reason the reason for the evaluation result
31+
* @param errorCode the error code if applicable
32+
* @param errorMessage the error message if applicable
33+
* @param flagMetadata metadata associated with the flag
34+
*/
35+
DefaultProviderEvaluation(
36+
T value, String variant, String reason, ErrorCode errorCode, String errorMessage, Metadata flagMetadata) {
37+
this.value = value;
38+
this.variant = variant;
39+
this.reason = reason;
40+
this.errorCode = errorCode;
41+
this.errorMessage = errorMessage;
42+
this.flagMetadata = flagMetadata != null ? flagMetadata : Metadata.EMPTY;
43+
}
44+
45+
public T getValue() {
46+
return value;
47+
}
48+
49+
public String getVariant() {
50+
return variant;
51+
}
52+
53+
public String getReason() {
54+
return reason;
55+
}
56+
57+
public ErrorCode getErrorCode() {
58+
return errorCode;
59+
}
60+
61+
public String getErrorMessage() {
62+
return errorMessage;
63+
}
64+
65+
public Metadata getFlagMetadata() {
66+
return flagMetadata;
67+
}
68+
69+
@Override
70+
public boolean equals(Object obj) {
71+
if (this == obj) {
72+
return true;
73+
}
74+
if (obj == null || getClass() != obj.getClass()) {
75+
return false;
76+
}
77+
ProviderEvaluation<?> that = (ProviderEvaluation<?>) obj;
78+
return Objects.equals(value, that.getValue())
79+
&& Objects.equals(variant, that.getVariant())
80+
&& Objects.equals(reason, that.getReason())
81+
&& errorCode == that.getErrorCode()
82+
&& Objects.equals(errorMessage, that.getErrorMessage())
83+
&& Objects.equals(flagMetadata, that.getFlagMetadata());
84+
}
85+
86+
@Override
87+
public int hashCode() {
88+
return Objects.hash(value, variant, reason, errorCode, errorMessage, flagMetadata);
89+
}
90+
91+
@Override
92+
public String toString() {
93+
return "ProviderEvaluation{" + "value="
94+
+ value + ", variant='"
95+
+ variant + '\'' + ", reason='"
96+
+ reason + '\'' + ", errorCode="
97+
+ errorCode + ", errorMessage='"
98+
+ errorMessage + '\'' + ", flagMetadata="
99+
+ flagMetadata + '}';
100+
}
101+
}

openfeature-api/src/main/java/dev/openfeature/api/EvaluationContext.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,22 @@ public interface EvaluationContext extends Structure {
1818
*/
1919
EvaluationContext EMPTY = new ImmutableContext();
2020

21+
static EvaluationContext immutableOf(Map<String, Value> attributes) {
22+
return new ImmutableContext(attributes);
23+
}
24+
25+
static EvaluationContext immutableOf(String targetingKey, Map<String, Value> attributes) {
26+
return new ImmutableContext(targetingKey, attributes);
27+
}
28+
29+
static ImmutableContextBuilder immutableBuilder() {
30+
return new ImmutableContext.Builder();
31+
}
32+
33+
static ImmutableContextBuilder immutableBuilder(EvaluationContext original) {
34+
return new ImmutableContext.Builder().attributes(original.asMap()).targetingKey(original.getTargetingKey());
35+
}
36+
2137
String getTargetingKey();
2238

2339
/**

0 commit comments

Comments
 (0)