Skip to content

Commit 3ed5166

Browse files
fix: [flagd]NPE of flagd due to null context value (#259)
Signed-off-by: Kavindu Dodanduwa <[email protected]>
1 parent 2c632ed commit 3ed5166

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/FlagdProvider.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import com.google.protobuf.Descriptors.FieldDescriptor;
1717
import com.google.protobuf.Message;
1818

19+
import com.google.protobuf.NullValue;
1920
import dev.openfeature.flagd.grpc.Schema.EventStreamRequest;
2021
import dev.openfeature.flagd.grpc.Schema.EventStreamResponse;
2122
import dev.openfeature.flagd.grpc.Schema.ResolveBooleanRequest;
@@ -386,7 +387,7 @@ private com.google.protobuf.Value convertPrimitive(Value value) {
386387
} else if (value.isNumber()) {
387388
builder.setNumberValue(value.asDouble());
388389
} else {
389-
builder.setNullValue(null);
390+
builder.setNullValue(NullValue.NULL_VALUE);
390391
}
391392
return builder.build();
392393
}
@@ -509,7 +510,7 @@ private Boolean cacheAvailable() {
509510

510511
return available;
511512
}
512-
513+
513514
// a generic resolve method that takes a resolverRef and an optional converter lambda to transform the result
514515
private <ValT extends Object, ReqT extends Message, ResT extends Message> ProviderEvaluation<ValT> resolve(
515516
String key, EvaluationContext ctx, ReqT request, Function<ReqT, ResT> resolverRef,

providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/FlagdProviderTest.java

+31
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package dev.openfeature.contrib.providers.flagd;
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertNotEquals;
45
import static org.junit.jupiter.api.Assertions.assertTrue;
56
import static org.mockito.ArgumentMatchers.any;
67
import static org.mockito.ArgumentMatchers.anyInt;
@@ -375,6 +376,36 @@ void context_is_parsed_and_passed_to_grpc_service() {
375376
assertEquals(DEFAULT.toString(), booleanDetails.getReason());
376377
}
377378

379+
@Test
380+
// Validates null handling - https://github.com/open-feature/java-sdk-contrib/issues/258
381+
void null_context_handling(){
382+
// given
383+
final String flagA = "flagA";
384+
final boolean defaultVariant = false;
385+
final boolean expectedVariant = true;
386+
387+
final MutableContext context = new MutableContext();
388+
context.add("key", (String) null);
389+
390+
final ServiceBlockingStub serviceBlockingStubMock = mock(ServiceBlockingStub.class);
391+
final ServiceStub serviceStubMock = mock(ServiceStub.class);
392+
393+
// when
394+
when(serviceBlockingStubMock.withDeadlineAfter(anyLong(), any(TimeUnit.class)))
395+
.thenReturn(serviceBlockingStubMock);
396+
when(serviceBlockingStubMock.resolveBoolean(any()))
397+
.thenReturn(ResolveBooleanResponse.newBuilder().setValue(expectedVariant).build());
398+
399+
OpenFeatureAPI.getInstance()
400+
.setProvider(new FlagdProvider(serviceBlockingStubMock, serviceStubMock, "lru", 10, 1));
401+
402+
// then
403+
final Boolean evaluation = api.getClient().getBooleanValue(flagA, defaultVariant, context);
404+
405+
assertNotEquals(evaluation, defaultVariant);
406+
assertEquals(evaluation, expectedVariant);
407+
}
408+
378409
@Test
379410
void set_deadline_deadline_send_in_grpc() {
380411
long deadline = 1300;

0 commit comments

Comments
 (0)