chore: fix jacoco coverage minimum, throw in memory provider (#561)
chore: fix codecov, throw in memory provider Signed-off-by: Todd Baert <todd.baert@dynatrace.com>
This commit is contained in:
parent
94a5a869d8
commit
1f28921fec
|
|
@ -0,0 +1,12 @@
|
||||||
|
package dev.openfeature.sdk.exceptions;
|
||||||
|
|
||||||
|
import dev.openfeature.sdk.ErrorCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.experimental.StandardException;
|
||||||
|
|
||||||
|
@SuppressWarnings("checkstyle:MissingJavadocType")
|
||||||
|
@StandardException
|
||||||
|
public class ProviderNotReadyError extends OpenFeatureError {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
@Getter private final ErrorCode errorCode = ErrorCode.PROVIDER_NOT_READY;
|
||||||
|
}
|
||||||
|
|
@ -1,26 +1,29 @@
|
||||||
package dev.openfeature.sdk.providers.memory;
|
package dev.openfeature.sdk.providers.memory;
|
||||||
|
|
||||||
import dev.openfeature.sdk.Value;
|
import java.util.ArrayList;
|
||||||
import dev.openfeature.sdk.Metadata;
|
import java.util.Arrays;
|
||||||
import dev.openfeature.sdk.EventProvider;
|
import java.util.HashMap;
|
||||||
import dev.openfeature.sdk.ProviderState;
|
import java.util.HashSet;
|
||||||
import dev.openfeature.sdk.ProviderEventDetails;
|
import java.util.Map;
|
||||||
import dev.openfeature.sdk.ErrorCode;
|
import java.util.Set;
|
||||||
|
|
||||||
import dev.openfeature.sdk.EvaluationContext;
|
import dev.openfeature.sdk.EvaluationContext;
|
||||||
|
import dev.openfeature.sdk.EventProvider;
|
||||||
|
import dev.openfeature.sdk.Metadata;
|
||||||
import dev.openfeature.sdk.ProviderEvaluation;
|
import dev.openfeature.sdk.ProviderEvaluation;
|
||||||
|
import dev.openfeature.sdk.ProviderEventDetails;
|
||||||
|
import dev.openfeature.sdk.ProviderState;
|
||||||
import dev.openfeature.sdk.Reason;
|
import dev.openfeature.sdk.Reason;
|
||||||
|
import dev.openfeature.sdk.Value;
|
||||||
|
import dev.openfeature.sdk.exceptions.FlagNotFoundError;
|
||||||
|
import dev.openfeature.sdk.exceptions.GeneralError;
|
||||||
import dev.openfeature.sdk.exceptions.OpenFeatureError;
|
import dev.openfeature.sdk.exceptions.OpenFeatureError;
|
||||||
|
import dev.openfeature.sdk.exceptions.ProviderNotReadyError;
|
||||||
|
import dev.openfeature.sdk.exceptions.TypeMismatchError;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In-memory provider.
|
* In-memory provider.
|
||||||
*/
|
*/
|
||||||
|
|
@ -87,68 +90,52 @@ public class InMemoryProvider extends EventProvider {
|
||||||
@Override
|
@Override
|
||||||
public ProviderEvaluation<Boolean> getBooleanEvaluation(String key, Boolean defaultValue,
|
public ProviderEvaluation<Boolean> getBooleanEvaluation(String key, Boolean defaultValue,
|
||||||
EvaluationContext evaluationContext) {
|
EvaluationContext evaluationContext) {
|
||||||
return getEvaluation(key, defaultValue, evaluationContext, Boolean.class);
|
return getEvaluation(key, evaluationContext, Boolean.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProviderEvaluation<String> getStringEvaluation(String key, String defaultValue,
|
public ProviderEvaluation<String> getStringEvaluation(String key, String defaultValue,
|
||||||
EvaluationContext evaluationContext) {
|
EvaluationContext evaluationContext) {
|
||||||
return getEvaluation(key, defaultValue, evaluationContext, String.class);
|
return getEvaluation(key, evaluationContext, String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProviderEvaluation<Integer> getIntegerEvaluation(String key, Integer defaultValue,
|
public ProviderEvaluation<Integer> getIntegerEvaluation(String key, Integer defaultValue,
|
||||||
EvaluationContext evaluationContext) {
|
EvaluationContext evaluationContext) {
|
||||||
return getEvaluation(key, defaultValue, evaluationContext, Integer.class);
|
return getEvaluation(key, evaluationContext, Integer.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProviderEvaluation<Double> getDoubleEvaluation(String key, Double defaultValue,
|
public ProviderEvaluation<Double> getDoubleEvaluation(String key, Double defaultValue,
|
||||||
EvaluationContext evaluationContext) {
|
EvaluationContext evaluationContext) {
|
||||||
return getEvaluation(key, defaultValue, evaluationContext, Double.class);
|
return getEvaluation(key, evaluationContext, Double.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@Override
|
@Override
|
||||||
public ProviderEvaluation<Value> getObjectEvaluation(String key, Value defaultValue,
|
public ProviderEvaluation<Value> getObjectEvaluation(String key, Value defaultValue,
|
||||||
EvaluationContext evaluationContext) {
|
EvaluationContext evaluationContext) {
|
||||||
return getEvaluation(key, defaultValue, evaluationContext, Value.class);
|
return getEvaluation(key, evaluationContext, Value.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> ProviderEvaluation<T> getEvaluation(
|
private <T> ProviderEvaluation<T> getEvaluation(
|
||||||
String key, T defaultValue, EvaluationContext evaluationContext, Class<?> expectedType
|
String key, EvaluationContext evaluationContext, Class<?> expectedType
|
||||||
) throws OpenFeatureError {
|
) throws OpenFeatureError {
|
||||||
if (!ProviderState.READY.equals(state)) {
|
if (!ProviderState.READY.equals(state)) {
|
||||||
ErrorCode errorCode = ErrorCode.PROVIDER_NOT_READY;
|
if (ProviderState.NOT_READY.equals(state)) {
|
||||||
if (ProviderState.ERROR.equals(state)) {
|
throw new ProviderNotReadyError("provider not yet initialized");
|
||||||
errorCode = ErrorCode.GENERAL;
|
|
||||||
}
|
}
|
||||||
return ProviderEvaluation.<T>builder()
|
throw new GeneralError("unknown error");
|
||||||
.errorCode(errorCode)
|
|
||||||
.reason(errorCode.name())
|
|
||||||
.value(defaultValue)
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
Flag<?> flag = flags.get(key);
|
Flag<?> flag = flags.get(key);
|
||||||
if (flag == null) {
|
if (flag == null) {
|
||||||
return ProviderEvaluation.<T>builder()
|
throw new FlagNotFoundError("flag " + key + "not found");
|
||||||
.value(defaultValue)
|
|
||||||
.reason(Reason.ERROR.toString())
|
|
||||||
.errorMessage(ErrorCode.FLAG_NOT_FOUND.name())
|
|
||||||
.errorCode(ErrorCode.FLAG_NOT_FOUND)
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
T value;
|
T value;
|
||||||
if (flag.getContextEvaluator() != null) {
|
if (flag.getContextEvaluator() != null) {
|
||||||
value = (T) flag.getContextEvaluator().evaluate(flag, evaluationContext);
|
value = (T) flag.getContextEvaluator().evaluate(flag, evaluationContext);
|
||||||
} else if (!expectedType.isInstance(flag.getVariants().get(flag.getDefaultVariant()))) {
|
} else if (!expectedType.isInstance(flag.getVariants().get(flag.getDefaultVariant()))) {
|
||||||
return ProviderEvaluation.<T>builder()
|
throw new TypeMismatchError("flag " + key + "is not of expected type");
|
||||||
.value(defaultValue)
|
|
||||||
.variant(flag.getDefaultVariant())
|
|
||||||
.reason(Reason.ERROR.toString())
|
|
||||||
.errorMessage(ErrorCode.TYPE_MISMATCH.name())
|
|
||||||
.errorCode(ErrorCode.TYPE_MISMATCH)
|
|
||||||
.build();
|
|
||||||
} else {
|
} else {
|
||||||
value = (T) flag.getVariants().get(flag.getDefaultVariant());
|
value = (T) flag.getVariants().get(flag.getDefaultVariant());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -271,7 +271,6 @@ public class StepDefinitions {
|
||||||
@Then("the reason should indicate an error and the error code should indicate a missing flag with {string}")
|
@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) {
|
public void the_reason_should_indicate_an_error_and_the_error_code_should_be_flag_not_found(String errorCode) {
|
||||||
assertEquals(Reason.ERROR.toString(), notFoundDetails.getReason());
|
assertEquals(Reason.ERROR.toString(), notFoundDetails.getReason());
|
||||||
assertTrue(notFoundDetails.getErrorMessage().contains(errorCode));
|
|
||||||
assertTrue(notFoundDetails.getErrorCode().name().equals(errorCode));
|
assertTrue(notFoundDetails.getErrorCode().name().equals(errorCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -292,7 +291,6 @@ public class StepDefinitions {
|
||||||
@Then("the reason should indicate an error and the error code should indicate a type mismatch with {string}")
|
@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) {
|
public void the_reason_should_indicate_an_error_and_the_error_code_should_be_type_mismatch(String errorCode) {
|
||||||
assertEquals(Reason.ERROR.toString(), typeErrorDetails.getReason());
|
assertEquals(Reason.ERROR.toString(), typeErrorDetails.getReason());
|
||||||
assertTrue(typeErrorDetails.getErrorMessage().contains(errorCode));
|
|
||||||
assertTrue(typeErrorDetails.getErrorCode().name().equals(errorCode));
|
assertTrue(typeErrorDetails.getErrorCode().name().equals(errorCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,22 @@ package dev.openfeature.sdk.providers.memory;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import dev.openfeature.sdk.Client;
|
import dev.openfeature.sdk.Client;
|
||||||
|
import dev.openfeature.sdk.ImmutableContext;
|
||||||
import dev.openfeature.sdk.OpenFeatureAPI;
|
import dev.openfeature.sdk.OpenFeatureAPI;
|
||||||
import dev.openfeature.sdk.Value;
|
import dev.openfeature.sdk.Value;
|
||||||
|
import dev.openfeature.sdk.exceptions.FlagNotFoundError;
|
||||||
|
import dev.openfeature.sdk.exceptions.TypeMismatchError;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.omg.CORBA.DynAnyPackage.TypeMismatch;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static dev.openfeature.sdk.Structure.mapToStructure;
|
import static dev.openfeature.sdk.Structure.mapToStructure;
|
||||||
import static dev.openfeature.sdk.testutils.TestFlagsUtils.buildFlags;
|
import static dev.openfeature.sdk.testutils.TestFlagsUtils.buildFlags;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
|
|
@ -81,4 +86,17 @@ class InMemoryProviderTest {
|
||||||
assertEquals(expectedObject, client.getObjectValue("object-flag", new Value(true)));
|
assertEquals(expectedObject, client.getObjectValue("object-flag", new Value(true)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void notFound() {
|
||||||
|
assertThrows(FlagNotFoundError.class, () -> {
|
||||||
|
provider.getBooleanEvaluation("not-found-flag", false, new ImmutableContext());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void typeMismatch() {
|
||||||
|
assertThrows(TypeMismatchError.class, () -> {
|
||||||
|
provider.getBooleanEvaluation("string-flag", false, new ImmutableContext());
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue