Skip to content

Commit 5e69573

Browse files
Determine pubsub event timestamp correctly in retry-timeout. (GoogleCloudPlatform#3770)
In the retry-timeout sample for GCF java11, we should determine the event timestamp from the Context parameter, not from properties of the passed-in PubSub object. Fixes GoogleCloudPlatform#3734.
1 parent 6d40623 commit 5e69573

File tree

2 files changed

+16
-36
lines changed

2 files changed

+16
-36
lines changed

functions/concepts/retry-timeout/src/main/java/functions/RetryTimeout.java

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import com.google.cloud.functions.BackgroundFunction;
2222
import com.google.cloud.functions.Context;
2323
import com.google.gson.Gson;
24-
import com.google.gson.JsonObject;
2524
import functions.eventpojos.PubSubMessage;
2625
import java.time.Duration;
2726
import java.time.ZoneOffset;
@@ -42,25 +41,19 @@ public class RetryTimeout implements BackgroundFunction<PubSubMessage> {
4241
@Override
4342
public void accept(PubSubMessage message, Context context) {
4443
ZonedDateTime utcNow = ZonedDateTime.now(ZoneOffset.UTC);
45-
ZonedDateTime timestamp = utcNow;
44+
ZonedDateTime timestamp = ZonedDateTime.parse(context.timestamp());
4645

47-
String data = message.getData();
48-
JsonObject body = gson.fromJson(data, JsonObject.class);
49-
if (body != null && body.has("timestamp")) {
50-
String tz = body.get("timestamp").getAsString();
51-
timestamp = ZonedDateTime.parse(tz);
52-
}
5346
long eventAge = Duration.between(timestamp, utcNow).toMillis();
5447

5548
// Ignore events that are too old
5649
if (eventAge > MAX_EVENT_AGE) {
57-
logger.info(String.format("Dropping event %s.", data));
50+
logger.info(String.format("Dropping event with timestamp %s.", timestamp));
5851
return;
5952
}
6053

6154
// Process events that are recent enough
6255
// To retry this invocation, throw an exception here
63-
logger.info(String.format("Processing event %s.", data));
56+
logger.info(String.format("Processing event with timestamp %s.", timestamp));
6457
}
6558
}
6659
// [END functions_tips_infinite_retries]

functions/concepts/retry-timeout/src/test/java/functions/RetryTimeoutTest.java

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,23 @@
1717
package functions;
1818

1919
import static com.google.common.truth.Truth.assertThat;
20+
import static org.mockito.Mockito.mock;
21+
import static org.mockito.Mockito.when;
2022

23+
import com.google.cloud.functions.Context;
2124
import com.google.common.testing.TestLogHandler;
2225
import com.google.gson.Gson;
2326
import functions.eventpojos.PubSubMessage;
2427
import java.time.Instant;
2528
import java.time.ZoneOffset;
2629
import java.time.ZonedDateTime;
27-
import java.util.Map;
2830
import java.util.logging.Logger;
2931
import org.junit.After;
3032
import org.junit.Before;
3133
import org.junit.BeforeClass;
3234
import org.junit.Test;
3335
import org.junit.runner.RunWith;
3436
import org.junit.runners.JUnit4;
35-
import org.mockito.MockitoAnnotations;
3637

3738
@RunWith(JUnit4.class)
3839
public class RetryTimeoutTest {
@@ -52,8 +53,6 @@ public static void beforeClass() {
5253

5354
@Before
5455
public void beforeTest() {
55-
MockitoAnnotations.initMocks(this);
56-
5756
LOG_HANDLER.clear();
5857
}
5958

@@ -65,41 +64,29 @@ public void afterTest() {
6564

6665
@Test
6766
public void retryTimeout_handlesRetryMsg() {
68-
String timestampData = gson.toJson(Map.of(
69-
"timestamp", ZonedDateTime.now(ZoneOffset.UTC).toString()));
67+
ZonedDateTime timestamp = ZonedDateTime.now(ZoneOffset.UTC);
68+
Context mockContext = mock(Context.class);
69+
when(mockContext.timestamp()).thenReturn(timestamp.toString());
7070

7171
PubSubMessage pubsubMessage = new PubSubMessage();
72-
pubsubMessage.setData(timestampData);
7372

74-
new RetryTimeout().accept(pubsubMessage, null);
73+
new RetryTimeout().accept(pubsubMessage, mockContext);
7574

7675
String logMessage = LOG_HANDLER.getStoredLogRecords().get(0).getMessage();
77-
assertThat(String.format("Processing event %s.", timestampData)).isEqualTo(logMessage);
76+
assertThat(logMessage).contains("Processing event with timestamp " + timestamp);
7877
}
7978

8079
@Test
8180
public void retryTimeout_handlesStopMsg() {
82-
String timestamp = ZonedDateTime.ofInstant(Instant.ofEpochMilli(0), ZoneOffset.UTC).toString();
83-
String timestampData = gson.toJson(Map.of("timestamp", timestamp));
84-
85-
86-
PubSubMessage pubsubMessage = new PubSubMessage();
87-
pubsubMessage.setData(timestampData);
88-
89-
new RetryTimeout().accept(pubsubMessage, null);
81+
ZonedDateTime timestamp = ZonedDateTime.ofInstant(Instant.ofEpochMilli(0), ZoneOffset.UTC);
82+
Context mockContext = mock(Context.class);
83+
when(mockContext.timestamp()).thenReturn(timestamp.toString());
9084

91-
String logMessage = LOG_HANDLER.getStoredLogRecords().get(0).getMessage();
92-
assertThat(String.format("Dropping event %s.", timestampData)).isEqualTo(logMessage);
93-
}
94-
95-
@Test
96-
public void retryTimeout_handlesEmptyMsg() {
9785
PubSubMessage pubsubMessage = new PubSubMessage();
98-
pubsubMessage.setData("");
9986

100-
new RetryTimeout().accept(new PubSubMessage(), null);
87+
new RetryTimeout().accept(pubsubMessage, mockContext);
10188

10289
String logMessage = LOG_HANDLER.getStoredLogRecords().get(0).getMessage();
103-
assertThat("Processing event null.").isEqualTo(logMessage);
90+
assertThat(logMessage).contains("Dropping event with timestamp " + timestamp);
10491
}
10592
}

0 commit comments

Comments
 (0)