feat: Add asObjectMap to get the EvaluationContext as Map<String,Object> (#75)
* Add asObjectMap to get the EvaluationContext as Map<String,Object> Signed-off-by: Thomas Poignant <thomas.poignant@gofeatureflag.org> * Fix liniting issue Signed-off-by: Thomas Poignant <thomas.poignant@gofeatureflag.org> * fix PMD issue Signed-off-by: Thomas Poignant <thomas.poignant@gofeatureflag.org> Signed-off-by: Thomas Poignant <thomas.poignant@gofeatureflag.org>
This commit is contained in:
parent
5db90f1a38
commit
2eec1a5519
|
|
@ -1,11 +1,10 @@
|
||||||
package dev.openfeature.javasdk;
|
package dev.openfeature.javasdk;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.stream.Collectors;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
|
import dev.openfeature.javasdk.exceptions.ValueNotConvertableError;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
|
||||||
|
|
@ -96,4 +95,67 @@ public class Structure {
|
||||||
public Map<String, Value> asMap() {
|
public Map<String, Value> asMap() {
|
||||||
return new HashMap<>(this.attributes);
|
return new HashMap<>(this.attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all values, with primitives types.
|
||||||
|
*
|
||||||
|
* @return all attributes on the structure into a Map
|
||||||
|
*/
|
||||||
|
public Map<String, Object> 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package dev.openfeature.javasdk.exceptions;
|
||||||
|
|
||||||
|
import dev.openfeature.javasdk.ErrorCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.experimental.StandardException;
|
||||||
|
|
||||||
|
@StandardException
|
||||||
|
public class ValueNotConvertableError extends OpenFeatureError {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
@Getter
|
||||||
|
private final ErrorCode errorCode = ErrorCode.GENERAL;
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
@ -148,4 +149,55 @@ public class EvalContextTest {
|
||||||
ctxMerged = EvaluationContext.merge(ctx1, ctx2);
|
ctxMerged = EvaluationContext.merge(ctx1, ctx2);
|
||||||
assertEquals(key1, ctxMerged.getTargetingKey());
|
assertEquals(key1, ctxMerged.getTargetingKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test void asObjectMap() {
|
||||||
|
String key1 = "key1";
|
||||||
|
EvaluationContext ctx = new EvaluationContext(key1);
|
||||||
|
ctx.add("stringItem", "stringValue");
|
||||||
|
ctx.add("boolItem", false);
|
||||||
|
ctx.add("integerItem", 1);
|
||||||
|
ctx.add("doubleItem", 1.2);
|
||||||
|
ctx.add("instantItem", Instant.ofEpochSecond(1663331342));
|
||||||
|
List<Value> listItem = new ArrayList<>();
|
||||||
|
listItem.add(new Value("item1"));
|
||||||
|
listItem.add(new Value("item2"));
|
||||||
|
ctx.add("listItem", listItem);
|
||||||
|
List<Value> listItem2 = new ArrayList<>();
|
||||||
|
listItem2.add(new Value(true));
|
||||||
|
listItem2.add(new Value(false));
|
||||||
|
ctx.add("listItem2", listItem2);
|
||||||
|
Map<String, Value> structureValue = new HashMap<>();
|
||||||
|
structureValue.put("structStringItem", new Value("stringValue"));
|
||||||
|
structureValue.put("structBoolItem", new Value(false));
|
||||||
|
structureValue.put("structIntegerItem", new Value(1));
|
||||||
|
structureValue.put("structDoubleItem", new Value(1.2));
|
||||||
|
structureValue.put("structInstantItem", new Value(Instant.ofEpochSecond(1663331342)));
|
||||||
|
Structure structure = new Structure(structureValue);
|
||||||
|
ctx.add("structureItem", structure);
|
||||||
|
|
||||||
|
|
||||||
|
Map<String, Object> want = new HashMap<>();
|
||||||
|
want.put("stringItem", "stringValue");
|
||||||
|
want.put("boolItem", false);
|
||||||
|
want.put("integerItem", 1);
|
||||||
|
want.put("doubleItem", 1.2);
|
||||||
|
want.put("instantItem", Instant.ofEpochSecond(1663331342));
|
||||||
|
List<String> wantListItem = new ArrayList<>();
|
||||||
|
wantListItem.add("item1");
|
||||||
|
wantListItem.add("item2");
|
||||||
|
want.put("listItem", wantListItem);
|
||||||
|
List<Boolean> wantListItem2 = new ArrayList<>();
|
||||||
|
wantListItem2.add(true);
|
||||||
|
wantListItem2.add(false);
|
||||||
|
want.put("listItem2", wantListItem2);
|
||||||
|
Map<String, Object> wantStructureValue = new HashMap<>();
|
||||||
|
wantStructureValue.put("structStringItem", "stringValue");
|
||||||
|
wantStructureValue.put("structBoolItem", false);
|
||||||
|
wantStructureValue.put("structIntegerItem", 1);
|
||||||
|
wantStructureValue.put("structDoubleItem", 1.2);
|
||||||
|
wantStructureValue.put("structInstantItem", Instant.ofEpochSecond(1663331342));
|
||||||
|
want.put("structureItem",wantStructureValue);
|
||||||
|
|
||||||
|
assertEquals(want,ctx.asObjectMap());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue