Skip to content

Commit 1c4a014

Browse files
authored
feat: enable converting CloudEvent requests to Background Event requests (GoogleCloudPlatform#123)
This enables backwards compatability for GCF Background Functions with newer CloudEvent-based eventing systems and brings FF Java up-to-date with conformance tests.
1 parent 51d6503 commit 1c4a014

25 files changed

+812
-66
lines changed

.github/workflows/conformance.yaml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,28 @@ jobs:
3434
run: (cd invoker/ && mvn install)
3535

3636
- name: Run HTTP conformance tests
37-
uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.0.0
37+
uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.2.1
3838
with:
39+
version: 'v1.2.1'
3940
functionType: 'http'
4041
useBuildpacks: false
4142
cmd: "'mvn -f invoker/conformance/pom.xml function:run -Drun.functionTarget=com.google.cloud.functions.conformance.HttpConformanceFunction'"
4243
startDelay: 10
4344

4445
- name: Run background event conformance tests
45-
uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.0.0
46+
uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.2.1
4647
with:
48+
version: 'v1.2.1'
4749
functionType: 'legacyevent'
4850
useBuildpacks: false
49-
validateMapping: false
51+
validateMapping: true
5052
cmd: "'mvn -f invoker/conformance/pom.xml function:run -Drun.functionTarget=com.google.cloud.functions.conformance.BackgroundEventConformanceFunction'"
5153
startDelay: 10
5254

5355
- name: Run cloudevent conformance tests
54-
uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.0.0
56+
uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.2.1
5557
with:
58+
version: 'v1.2.1'
5659
functionType: 'cloudevent'
5760
useBuildpacks: false
5861
validateMapping: true

invoker/conformance/pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@
3434
<artifactId>gson</artifactId>
3535
<version>2.8.6</version>
3636
</dependency>
37+
<dependency>
38+
<groupId>io.cloudevents</groupId>
39+
<artifactId>cloudevents-core</artifactId>
40+
<version>2.2.0</version>
41+
</dependency>
42+
<dependency>
43+
<groupId>io.cloudevents</groupId>
44+
<artifactId>cloudevents-json-jackson</artifactId>
45+
<version>2.2.0</version>
46+
</dependency>
3747
</dependencies>
3848

3949
<build>

invoker/conformance/src/main/java/com/google/cloud/functions/conformance/BackgroundEventConformanceFunction.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,12 @@ private String serialize(String data, Context context) {
4040
contextJson.addProperty("timestamp", context.timestamp());
4141
contextJson.addProperty("eventType", context.eventType());
4242

43-
JsonElement resource = gson.fromJson(context.resource(), JsonElement.class);
44-
contextJson.add("resource", resource);
43+
if (context.resource().startsWith("{")) {
44+
JsonElement resource = gson.fromJson(context.resource(), JsonElement.class);
45+
contextJson.add("resource", resource);
46+
} else {
47+
contextJson.addProperty("resource", context.resource());
48+
}
4549

4650
JsonObject dataJson = gson.fromJson(data, JsonObject.class);
4751

invoker/conformance/src/main/java/com/google/cloud/functions/conformance/CloudEventsConformanceFunction.java

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@
1717
import static java.nio.charset.StandardCharsets.UTF_8;
1818

1919
import com.google.cloud.functions.CloudEventsFunction;
20-
import com.google.gson.Gson;
21-
import com.google.gson.GsonBuilder;
22-
import com.google.gson.JsonObject;
2320
import io.cloudevents.CloudEvent;
21+
import io.cloudevents.core.format.EventFormat;
22+
import io.cloudevents.core.provider.EventFormatProvider;
23+
import io.cloudevents.jackson.JsonFormat;
2424
import java.io.BufferedWriter;
2525
import java.io.FileWriter;
26-
import java.time.format.DateTimeFormatter;
2726

2827
/**
2928
* This class is used by the Functions Framework Conformance Tools to validate the framework's Cloud
@@ -40,33 +39,11 @@
4039
*/
4140
public class CloudEventsConformanceFunction implements CloudEventsFunction {
4241

43-
private static final Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().create();
44-
4542
@Override
4643
public void accept(CloudEvent event) throws Exception {
4744
try (BufferedWriter writer = new BufferedWriter(new FileWriter("function_output.json"))) {
48-
writer.write(serialize(event));
45+
EventFormat format = EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE);
46+
writer.write(new String(format.serialize(event), UTF_8));
4947
}
5048
}
51-
52-
/** Create a structured JSON representation of a cloud event */
53-
private String serialize(CloudEvent event) {
54-
JsonObject jsonEvent = new JsonObject();
55-
56-
jsonEvent.addProperty("id", event.getId());
57-
jsonEvent.addProperty("source", event.getSource().toString());
58-
jsonEvent.addProperty("type", event.getType());
59-
jsonEvent.addProperty("datacontenttype", event.getDataContentType());
60-
jsonEvent.addProperty("subject", event.getSubject());
61-
jsonEvent.addProperty("specversion", event.getSpecVersion().toString());
62-
63-
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX");
64-
jsonEvent.addProperty("time", event.getTime().format(formatter));
65-
66-
String payloadJson = new String(event.getData().toBytes(), UTF_8);
67-
JsonObject jsonObject = new Gson().fromJson(payloadJson, JsonObject.class);
68-
jsonEvent.add("data", jsonObject);
69-
70-
return gson.toJson(jsonEvent);
71-
}
7249
}

invoker/core/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@
130130
<version>4.13.1</version>
131131
<scope>test</scope>
132132
</dependency>
133+
<dependency>
134+
<groupId>com.google.re2j</groupId>
135+
<artifactId>re2j</artifactId>
136+
<version>1.6</version>
137+
</dependency>
133138
<dependency>
134139
<groupId>com.google.truth</groupId>
135140
<artifactId>truth</artifactId>

invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
package com.google.cloud.functions.invoker;
1616

17-
import static java.nio.charset.StandardCharsets.UTF_8;
1817
import static java.util.stream.Collectors.toList;
1918
import static java.util.stream.Collectors.toMap;
2019

@@ -263,10 +262,7 @@ void serviceLegacyEvent(Event legacyEvent) throws Exception {
263262

264263
@Override
265264
void serviceCloudEvent(CloudEvent cloudEvent) throws Exception {
266-
Context context = contextFromCloudEvent(cloudEvent);
267-
String jsonData =
268-
(cloudEvent.getData() == null) ? "{}" : new String(cloudEvent.getData().toBytes(), UTF_8);
269-
function.accept(jsonData, context);
265+
serviceLegacyEvent(CloudEvents.convertToLegacyEvent(cloudEvent));
270266
}
271267
}
272268

@@ -295,10 +291,7 @@ void serviceLegacyEvent(Event legacyEvent) throws Exception {
295291
@Override
296292
void serviceCloudEvent(CloudEvent cloudEvent) throws Exception {
297293
if (cloudEvent.getData() != null) {
298-
String data = new String(cloudEvent.getData().toBytes(), UTF_8);
299-
T payload = new Gson().fromJson(data, type);
300-
Context context = contextFromCloudEvent(cloudEvent);
301-
function.accept(payload, context);
294+
serviceLegacyEvent(CloudEvents.convertToLegacyEvent(cloudEvent));
302295
} else {
303296
throw new IllegalStateException("Event has no \"data\" component");
304297
}

0 commit comments

Comments
 (0)