Skip to content

Commit 275b855

Browse files
committed
✨ feat: Improvements from review
1 parent 3fe96e8 commit 275b855

File tree

8 files changed

+134
-4
lines changed

8 files changed

+134
-4
lines changed

chart/templates/microblog-service.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ spec:
7272
value: {{ quote .Values.microblogService.deployment.container.env.RAG_SERVICE_PORT }}
7373
- name: RAG_SERVICE_ENABLED
7474
value: {{ .Values.ragService.enabled | quote }}
75-
- name : FEEDBACK_INGESTION_SERVICE_ADDRESS
75+
- name: FEEDBACK_INGESTION_SERVICE_ADDRESS
7676
value: {{ quote .Values.microblogService.deployment.container.env.FEEDBACK_INGESTION_SERVICE_ADDRESS }}
7777
- name: FEEDBACK_INGESTION_SERVICE_PORT
7878
value: {{ quote .Values.microblogService.deployment.container.env.FEEDBACK_INGESTION_SERVICE_PORT }}

src/feedback-ingestion-service/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ periodically sends a request to the RAG service to ingest a batch of feedback da
1818
which will generate the jar in ```build/libs```
1919
- Start the application by running:
2020
```
21-
java -jar build/libs/microblog-service-{{VERSION}}.jar
21+
java -jar build/libs/feedback-ingestion-service-{{VERSION}}.jar
2222
```
2323
- The feedback ingestion service should then be accessible on [localhost:8080](http://localhost:8080).
2424

src/feedback-ingestion-service/src/main/java/org/dynatrace/feedbackingestionservice/utils/UserFeedbackValidator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public static Boolean validateUserFeedback(UserFeedback userFeedback) {
88
return false;
99
}
1010

11-
if ( userFeedback.getText().isEmpty()) {
11+
if (userFeedback.getText().isEmpty()) {
1212
return false;
1313
}
1414

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package org.dynatrace.feedbackingestionservice.buffer;
2+
3+
import org.dynatrace.feedbackingestionservice.dto.UserFeedback;
4+
import org.dynatrace.feedbackingestionservice.ragservice.RAGServiceClient;
5+
import org.junit.jupiter.api.Test;
6+
import org.mockito.ArgumentCaptor;
7+
8+
import java.io.IOException;
9+
import java.util.List;
10+
11+
import static org.junit.jupiter.api.Assertions.assertEquals;
12+
import static org.mockito.ArgumentMatchers.anyList;
13+
import static org.mockito.Mockito.*;
14+
15+
class FeedbackBufferTest {
16+
17+
private static UserFeedback feedback(String text, String label) {
18+
return new UserFeedback(text, label);
19+
}
20+
21+
@Test
22+
void doesNotIngest_whenBelowThreshold() throws IOException {
23+
RAGServiceClient client = mock(RAGServiceClient.class);
24+
FeedbackBuffer buffer = new FeedbackBuffer(client);
25+
26+
buffer.addToQueue(feedback("spam text", "spam"));
27+
buffer.addToQueue(feedback("hello", "not_spam"));
28+
29+
verify(client, never()).ingestUserFeedbackBatchToRAGKnowledgeBase(anyList());
30+
assertEquals(2, buffer.getSize());
31+
}
32+
33+
@Test
34+
void ingestsOnce_whenThresholdReached() throws IOException {
35+
RAGServiceClient client = mock(RAGServiceClient.class);
36+
FeedbackBuffer buffer = new FeedbackBuffer(client);
37+
38+
for (int i = 0; i < 100; i++) {
39+
buffer.addToQueue(feedback("text", "not_spam"));
40+
}
41+
42+
ArgumentCaptor<List<UserFeedback>> captor = ArgumentCaptor.forClass(List.class);
43+
verify(client, times(1)).ingestUserFeedbackBatchToRAGKnowledgeBase(captor.capture());
44+
assertEquals(100, captor.getValue().size());
45+
assertEquals(0, buffer.getSize());
46+
}
47+
48+
@Test
49+
void flushedQueue_whenItemsAreIngested() throws IOException {
50+
RAGServiceClient client = mock(RAGServiceClient.class);
51+
FeedbackBuffer buffer = new FeedbackBuffer(client);
52+
53+
for (int i = 0; i < 50; i++) {
54+
buffer.addToQueue(feedback("text", "not_spam"));
55+
}
56+
57+
verify(client, never()).ingestUserFeedbackBatchToRAGKnowledgeBase(anyList());
58+
assertEquals(50, buffer.getSize());
59+
60+
buffer.processBatchInQueue();
61+
62+
ArgumentCaptor<List<UserFeedback>> captor = ArgumentCaptor.forClass(List.class);
63+
verify(client, times(1)).ingestUserFeedbackBatchToRAGKnowledgeBase(captor.capture());
64+
assertEquals(50, captor.getValue().size());
65+
assertEquals(0, buffer.getSize());
66+
}
67+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package org.dynatrace.feedbackingestionservice.utils;
2+
3+
import org.dynatrace.feedbackingestionservice.dto.UserFeedback;
4+
import org.junit.jupiter.api.Test;
5+
6+
import static org.junit.jupiter.api.Assertions.*;
7+
8+
class UserFeedbackValidatorTest {
9+
10+
private static UserFeedback feedback(String text, String label) {
11+
return new UserFeedback(text, label);
12+
}
13+
14+
@Test
15+
void returnsFalse_whenUserFeedbackIsNull() {
16+
assertFalse(UserFeedbackValidator.validateUserFeedback(null));
17+
}
18+
19+
@Test
20+
void returnsFalse_whenTextIsNull() {
21+
assertFalse(UserFeedbackValidator.validateUserFeedback(feedback(null, "spam")));
22+
}
23+
24+
@Test
25+
void returnsFalse_whenLabelIsNull() {
26+
assertFalse(UserFeedbackValidator.validateUserFeedback(feedback("hello", null)));
27+
}
28+
29+
@Test
30+
void returnsFalse_whenTextIsEmpty() {
31+
assertFalse(UserFeedbackValidator.validateUserFeedback(feedback("", "spam")));
32+
}
33+
34+
@Test
35+
void returnsFalse_whenLabelIsInvalid() {
36+
assertFalse(UserFeedbackValidator.validateUserFeedback(feedback("hello", "invalid_label")));
37+
}
38+
39+
@Test
40+
void returnsTrue_whenLabelIsSpam() {
41+
assertTrue(UserFeedbackValidator.validateUserFeedback(feedback("hello", "spam")));
42+
}
43+
44+
@Test
45+
void returnsTrue_whenLabelIsNotSpam() {
46+
assertTrue(UserFeedbackValidator.validateUserFeedback(feedback("hello", "not_spam")));
47+
}
48+
}
49+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
mock-maker-subclass
2+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.dynatrace.microblog.exceptions;
2+
3+
public class SpamIngestionFailedException extends RuntimeException {
4+
public SpamIngestionFailedException(String message) {
5+
super(message);
6+
}
7+
}

src/microblog-service/src/main/java/org/dynatrace/microblog/redis/RedisClient.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.dynatrace.microblog.dto.Post;
2424
import org.dynatrace.microblog.dto.SpamPredictionRatings;
2525
import org.dynatrace.microblog.dto.User;
26+
import org.dynatrace.microblog.exceptions.SpamIngestionFailedException;
2627
import org.dynatrace.microblog.exceptions.InvalidJwtException;
2728
import org.dynatrace.microblog.exceptions.UserNotFoundException;
2829
import org.dynatrace.microblog.feedbackingestionservice.FeedbackIngestionServiceClient;
@@ -177,6 +178,10 @@ public void processUserSpamFeedback(@NotNull String postId, FeedbackIngestionSer
177178
isSpamUserLabel = !isSpamUserLabel;
178179
}
179180
String postText = jedis.hget(getCombinedKey(POST_KEY_PREFIX, postId), "body");
181+
if (postText == null) {
182+
logger.warn("Post body for post with id {} is null, skipping spam feedback ingestion", postId);
183+
return;
184+
}
180185
String userLabel = isSpamUserLabel ? "spam" : "not_spam";
181186

182187
if (feedbackIngestionServiceClient.addNewSpamKnowledgeToIngestQueue(postText, userLabel)) {
@@ -185,7 +190,7 @@ public void processUserSpamFeedback(@NotNull String postId, FeedbackIngestionSer
185190
}
186191
} catch (IOException e) {
187192
logger.error("Error processing user spam feedback for post with id {}", postId, e);
188-
throw new RuntimeException(e);
193+
throw new SpamIngestionFailedException(e.getMessage());
189194
}
190195
}
191196

0 commit comments

Comments
 (0)