Skip to content

Commit

Permalink
fix: add context field in the payload (#135)
Browse files Browse the repository at this point in the history
* add context field in the payload

* throw on context being in data
  • Loading branch information
vahidlazio authored May 30, 2024
1 parent 87407c7 commit 7f09f3e
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 16 deletions.
8 changes: 6 additions & 2 deletions src/main/java/com/spotify/confidence/Confidence.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,13 @@ public void track(String eventName) {
}

@Override
public void track(String eventName, ConfidenceValue.Struct message) {
public void track(String eventName, ConfidenceValue.Struct data) {
if (data.asMap().containsKey("context")) {
throw new Exceptions.InvalidContextInMessaageError(
"Field 'context' is not allowed in event's data");
}
try {
client().emit(eventName, getContext(), Optional.of(message));
client().emit(eventName, getContext(), Optional.of(data));
} catch (IllegalStateException e) {
// swallow this exception
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/spotify/confidence/EventSender.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

@Beta
public interface EventSender extends Contextual {
public void track(String eventName, ConfidenceValue.Struct message);
public void track(String eventName, ConfidenceValue.Struct data);

public void track(String eventName);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import java.util.Optional;

interface EventSenderEngine extends Closeable {
void emit(String name, ConfidenceValue.Struct context, Optional<ConfidenceValue.Struct> message);
void emit(String name, ConfidenceValue.Struct context, Optional<ConfidenceValue.Struct> data);

void flush();
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,13 @@ class EventSenderEngineImpl implements EventSenderEngine {

@Override
public void emit(
String name, ConfidenceValue.Struct context, Optional<ConfidenceValue.Struct> message) {
String name, ConfidenceValue.Struct context, Optional<ConfidenceValue.Struct> data) {
if (intakeClosed) {
log.warn("EventSenderEngine is closed, dropping event {}", name);
return;
}
final Event event =
EventUploader.event(name, context, message).setEventTime(clock.getTimestamp()).build();
EventUploader.event(name, context, data).setEventTime(clock.getTimestamp()).build();
if (estimatedMemoryConsumption.get() + event.getSerializedSize() > maxMemoryConsumption) {
log.warn("EventSenderEngine is overloaded, dropping event {}", name);
return;
Expand Down
14 changes: 9 additions & 5 deletions src/main/java/com/spotify/confidence/EventUploader.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@

import com.google.protobuf.Struct;
import com.spotify.confidence.events.v1.Event;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;

interface EventUploader {
static Event.Builder event(
String name, ConfidenceValue.Struct context, Optional<ConfidenceValue.Struct> message) {
String name, ConfidenceValue.Struct context, Optional<ConfidenceValue.Struct> data) {
final Map<String, ConfidenceValue> map = new HashMap<>(Map.of());
final ConfidenceValue.Struct dataStruct = data.orElse(ConfidenceValue.Struct.EMPTY);
map.putAll(dataStruct.asMap());
map.put("context", context);

return Event.newBuilder()
.setEventDefinition(EventSenderEngineImpl.EVENT_NAME_PREFIX + name)
.setPayload(
Struct.newBuilder()
.putAllFields(context.asProtoMap())
.putAllFields(message.orElse(ConfidenceValue.Struct.EMPTY).asProtoMap()));
.setPayload(Struct.newBuilder().putAllFields(ConfidenceValue.of(map).asProtoMap()));
}

CompletableFuture<Boolean> upload(List<Event> events);
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/com/spotify/confidence/Exceptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ public ParseError(String message) {
}
}

public static class InvalidContextInMessaageError extends RuntimeException {
public InvalidContextInMessaageError(String message) {
super(message);
}
}

public static class IllegalValueType extends Exception {
public IllegalValueType(String message) {
super(message);
Expand Down
11 changes: 11 additions & 0 deletions src/test/java/com/spotify/confidence/ConfidenceContextTest.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.spotify.confidence;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;

import com.google.common.collect.ImmutableMap;
import java.util.Map;
import org.junit.jupiter.api.Test;

public class ConfidenceContextTest {
Expand All @@ -11,6 +13,15 @@ public class ConfidenceContextTest {
private final ResolverClientTestUtils.FakeFlagResolverClient fakeFlagResolverClient =
new ResolverClientTestUtils.FakeFlagResolverClient();

@Test
public void testThrowInvalidContextInMessage() {
final Confidence root = Confidence.create(fakeEngine, fakeFlagResolverClient);
assertThrows(
Exceptions.InvalidContextInMessaageError.class,
() ->
root.track("hello", ConfidenceValue.of(Map.of("context", ConfidenceValue.NULL_VALUE))));
}

@Test
public void getContextContainsParentContextValues() {
final Confidence root = Confidence.create(fakeEngine, fakeFlagResolverClient);
Expand Down
14 changes: 13 additions & 1 deletion src/test/java/com/spotify/confidence/EventSenderEngineTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,19 @@ public void testOverlappingKeysInPayload() throws InterruptedException {
"a",
Value.newBuilder().setNumberValue(0).build(),
"message",
Value.newBuilder().setNumberValue(1).build()))
Value.newBuilder().setNumberValue(1).build(),
"context",
Value.newBuilder()
.setStructValue(
Struct.newBuilder()
.putAllFields(
Map.of(
"a",
Value.newBuilder().setNumberValue(2).build(),
"message",
Value.newBuilder().setNumberValue(3).build()))
.build())
.build()))
.build());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public void close() throws IOException {

@Override
public void emit(
String name, ConfidenceValue.Struct context, Optional<ConfidenceValue.Struct> message) {
events.add(event(name, context, message).setEventTime(clock.getTimestamp()).build());
String name, ConfidenceValue.Struct context, Optional<ConfidenceValue.Struct> data) {
events.add(event(name, context, data).setEventTime(clock.getTimestamp()).build());
}

@Override
Expand Down
16 changes: 14 additions & 2 deletions src/test/java/com/spotify/confidence/GrpcEventUploaderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,13 @@ public void testMapsSingleEventBatchToProtobuf() throws ExecutionException, Inte

final Map<String, com.google.protobuf.Value> fieldsMap = protoEvent.getPayload().getFieldsMap();
assertThat(fieldsMap.get("messageKey").getStringValue()).isEqualTo("value_1");
assertThat(fieldsMap.get("contextKey").getStringValue()).isEqualTo("value_1");
assertThat(
fieldsMap
.get("context")
.getStructValue()
.getFieldsOrThrow("contextKey")
.getStringValue())
.isEqualTo("value_1");
}

@Test
Expand Down Expand Up @@ -130,7 +136,13 @@ public void testMapsMultiEventBatchToProtobuf() {
final Map<String, com.google.protobuf.Value> fieldsMap =
protoEvent.getPayload().getFieldsMap();
assertThat(fieldsMap.get("messageKey").getStringValue()).isEqualTo("value_m" + (i + 1));
assertThat(fieldsMap.get("contextKey").getStringValue()).isEqualTo("value_c" + (i + 1));
assertThat(
fieldsMap
.get("context")
.getStructValue()
.getFieldsOrThrow("contextKey")
.getStringValue())
.isEqualTo("value_c" + (i + 1));
}
}

Expand Down

0 comments on commit 7f09f3e

Please sign in to comment.