From e7dea60fd829e5ce08ee8066fcc4f96b03f7dcf0 Mon Sep 17 00:00:00 2001 From: Michael Traver Date: Tue, 6 Apr 2021 13:37:36 -0700 Subject: [PATCH 001/239] Upgrade conformance test version to v0.3.9 (#87) --- .github/workflows/conformance.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index cd9452cc..63621adb 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -16,25 +16,25 @@ jobs: ] steps: - uses: actions/checkout@v2 - + - name: Set up JDK ${{ matrix.java }} uses: actions/setup-java@v1 with: java-version: ${{ matrix.java }} - + - name: Setup Go uses: actions/setup-go@v2 with: go-version: '1.15' - + - name: Build API with Maven run: (cd functions-framework-api/ && mvn install) - name: Build invoker with Maven run: (cd invoker/ && mvn install) - + - name: Run HTTP conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@v0.3.8 + uses: GoogleCloudPlatform/functions-framework-conformance/action@v0.3.9 with: functionType: 'http' useBuildpacks: false @@ -43,9 +43,9 @@ jobs: startDelay: 10 - name: Run cloudevent conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@v0.3.8 + uses: GoogleCloudPlatform/functions-framework-conformance/action@v0.3.9 with: functionType: 'cloudevent' useBuildpacks: false cmd: "'mvn -f invoker/conformance/pom.xml function:run -Drun.functionTarget=com.google.cloud.functions.conformance.CloudEventsConformanceFunction'" - startDelay: 10 \ No newline at end of file + startDelay: 10 From f70a30794a9541e608cfbfe9b97a5a716a22369a Mon Sep 17 00:00:00 2001 From: Tobi Date: Thu, 10 Jun 2021 09:38:26 +0200 Subject: [PATCH 002/239] Fix-Gradle-Example-Parameters (#93) --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 74010b53..1f6264f2 100644 --- a/README.md +++ b/README.md @@ -215,8 +215,8 @@ tasks.register("runFunction", JavaExec) { classpath(configurations.invoker) inputs.files(configurations.runtimeClasspath, sourceSets.main.output) args( - '--target', project.findProperty('runFunction.target'), - '--port', project.findProperty('runFunction.port') ?: 8080 + '--target', project.findProperty('run.functionTarget'), + '--port', project.findProperty('run.port') ?: 8080 ) doFirst { args('--classpath', files(configurations.runtimeClasspath, sourceSets.main.output).asPath) @@ -227,15 +227,15 @@ tasks.register("runFunction", JavaExec) { Then in your terminal or IDE, you will be able to run the function locally with: ```sh -gradle runFunction -PrunFunction.target=com.example.HelloWorld \ - -PrunFunction.port=8080 +gradle runFunction -Prun.functionTarget=com.example.HelloWorld \ + -Prun.port=8080 ``` Or if you use the Gradle wrapper provided by your Gradle project build: ```sh -./gradlew runFunction -PrunFunction.target=com.example.HelloWorld \ - -PrunFunction.port=8080 +./gradlew runFunction -Prun.functionTarget=com.example.HelloWorld \ + -Prun.port=8080 ``` ## Functions Framework configuration From e96a3d9fa8ffeb3db63588a733c93300db8741a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89amonn=20McManus?= Date: Thu, 10 Jun 2021 00:43:07 -0700 Subject: [PATCH 003/239] Update version numbers in README.md. (#92) --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 1f6264f2..43dbac5b 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ that supports Maven to create the Maven project. Add this dependency in the com.google.cloud.functions functions-framework-api - 1.0.1 + 1.0.4 provided ``` @@ -42,7 +42,7 @@ Framework dependency in your `build.gradle` project file as follows: ```groovy dependencies { - implementation 'com.google.cloud.functions:functions-framework-api:1.0.1' + implementation 'com.google.cloud.functions:functions-framework-api:1.0.4' } ``` @@ -150,7 +150,7 @@ You can configure the plugin in `pom.xml`: com.google.cloud.functions function-maven-plugin - 0.9.2 + 0.9.7 com.example.function.Echo @@ -168,7 +168,7 @@ mvn function:run You can alternatively configure the plugin with properties on the command line: ```sh - mvn com.google.cloud.functions:function-maven-plugin:0.9.2:run \ + mvn com.google.cloud.functions:function-maven-plugin:0.9.7:run \ -Drun.functionTarget=com.example.function.Echo ``` @@ -179,7 +179,7 @@ Copy the Functions Framework jar to a local location like this: ```sh mvn dependency:copy \ - -Dartifact='com.google.cloud.functions.invoker:java-function-invoker:1.0.0-alpha-2-rc5' \ + -Dartifact='com.google.cloud.functions.invoker:java-function-invoker:1.0.2' \ -DoutputDirectory=. ``` @@ -187,7 +187,7 @@ In this example we use the current directory `.` but you can specify any other directory to copy to. Then run your function: ```sh -java -jar java-function-invoker-1.0.0-alpha-2-rc5.jar \ +java -jar java-function-invoker-1.0.2 \ --classpath myfunction.jar \ --target com.example.HelloWorld ``` @@ -206,8 +206,8 @@ configurations { } dependencies { - implementation 'com.google.cloud.functions:functions-framework-api:1.0.1' - invoker 'com.google.cloud.functions.invoker:java-function-invoker:1.0.0-alpha-2-rc5' + implementation 'com.google.cloud.functions:functions-framework-api:1.0.4' + invoker 'com.google.cloud.functions.invoker:java-function-invoker:1.0.2' } tasks.register("runFunction", JavaExec) { @@ -280,7 +280,7 @@ Framework directly, you must use `--classpath` to indicate how to find the code and its dependencies. For example: ``` -java -jar java-function-invoker-1.0.0-alpha-2-rc5.jar \ +java -jar java-function-invoker-1.0.2 \ --classpath 'myfunction.jar:/some/directory:/some/library/*' \ --target com.example.HelloWorld ``` From 382bd1078bdcac1ed4f2ee8397d32910584a54d7 Mon Sep 17 00:00:00 2001 From: Matthew Robertson Date: Tue, 29 Jun 2021 00:07:32 -0700 Subject: [PATCH 004/239] Add conformance tests for background events (#97) Previously we had been running conformance tests for background function signature types. This enables these tests in the conformance github action. Running the tests uncovered one bug in which JSON fiels with null values were being dropped from the data param passed to RawBackgroundFunctions. Fixing this is a non-breaking change so I bumped the minor verison of the maven package. --- .github/workflows/conformance.yaml | 15 ++++- .../BackgroundEventConformanceFunction.java | 59 +++++++++++++++++++ .../invoker/BackgroundFunctionExecutor.java | 3 +- 3 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 invoker/conformance/src/main/java/com/google/cloud/functions/conformance/BackgroundEventConformanceFunction.java diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index 63621adb..01a1f997 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -34,18 +34,27 @@ jobs: run: (cd invoker/ && mvn install) - name: Run HTTP conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@v0.3.9 + uses: GoogleCloudPlatform/functions-framework-conformance/action@v0.3.12 with: functionType: 'http' useBuildpacks: false - validateMapping: false cmd: "'mvn -f invoker/conformance/pom.xml function:run -Drun.functionTarget=com.google.cloud.functions.conformance.HttpConformanceFunction'" startDelay: 10 + - name: Run background event conformance tests + uses: GoogleCloudPlatform/functions-framework-conformance/action@v0.3.12 + with: + functionType: 'legacyevent' + useBuildpacks: false + validateMapping: false + cmd: "'mvn -f invoker/conformance/pom.xml function:run -Drun.functionTarget=com.google.cloud.functions.conformance.BackgroundEventConformanceFunction'" + startDelay: 10 + - name: Run cloudevent conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@v0.3.9 + uses: GoogleCloudPlatform/functions-framework-conformance/action@v0.3.12 with: functionType: 'cloudevent' useBuildpacks: false + validateMapping: false cmd: "'mvn -f invoker/conformance/pom.xml function:run -Drun.functionTarget=com.google.cloud.functions.conformance.CloudEventsConformanceFunction'" startDelay: 10 diff --git a/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/BackgroundEventConformanceFunction.java b/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/BackgroundEventConformanceFunction.java new file mode 100644 index 00000000..8672e6d8 --- /dev/null +++ b/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/BackgroundEventConformanceFunction.java @@ -0,0 +1,59 @@ +package com.google.cloud.functions.conformance; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.cloud.functions.Context; +import com.google.cloud.functions.RawBackgroundFunction; +import java.io.BufferedWriter; +import java.io.FileWriter; + +/** + * This class is used by the Functions Framework Conformance Tools to validate + * the framework's Background Event API. It can be run with the following + * command: + * + *
+ * {@code
+ * $ functions-framework-conformance-client \
+ *   -cmd="mvn function:run -Drun.functionTarget=com.google.cloud.functions.conformance.BackgroundEventConformanceFunction" \
+ *   -type=legacyevent \
+ *   -buildpacks=false \
+ *   -validate-mapping=false \
+ *   -start-delay=10
+ * }
+ * 
+ */ +public class BackgroundEventConformanceFunction implements RawBackgroundFunction { + + private static final Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().create(); + + @Override + public void accept(String data, Context context) throws Exception { + try (BufferedWriter writer = new BufferedWriter(new FileWriter("function_output.json"))) { + writer.write(serialize(data, context)); + } + } + + /** + * Create a structured JSON representation of the request context and data + */ + private String serialize(String data, Context context) { + JsonObject contextJson = new JsonObject(); + contextJson.addProperty("eventId", context.eventId()); + contextJson.addProperty("timestamp", context.timestamp()); + contextJson.addProperty("eventType", context.eventType()); + + JsonElement resource = gson.fromJson(context.resource(), JsonElement.class); + contextJson.add("resource", resource); + + JsonObject dataJson = gson.fromJson(data, JsonObject.class); + + JsonObject json = new JsonObject(); + json.add("data", dataJson); + json.add("context", contextJson); + return gson.toJson(json); + } + +} diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java index 3aad340b..2238e5d3 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java @@ -241,6 +241,7 @@ final ClassLoader functionClassLoader() { } private static class RawFunctionExecutor extends FunctionExecutor> { + private static Gson gson = new GsonBuilder().serializeNulls().create(); private final RawBackgroundFunction function; RawFunctionExecutor(RawBackgroundFunction function) { @@ -250,7 +251,7 @@ private static class RawFunctionExecutor extends FunctionExecutor> { @Override void serviceLegacyEvent(Event legacyEvent) throws Exception { - function.accept(new Gson().toJson(legacyEvent.getData()), legacyEvent.getContext()); + function.accept(gson.toJson(legacyEvent.getData()), legacyEvent.getContext()); } @Override From 7b6246b8a9137ffeeda4f0450d7edec257c7f035 Mon Sep 17 00:00:00 2001 From: Matthew Robertson Date: Fri, 2 Jul 2021 15:05:28 -0700 Subject: [PATCH 005/239] Update CloudEvent upcasting logic (#99) --- .github/workflows/conformance.yaml | 2 +- .../invoker/CloudFunctionsContext.java | 4 ++ .../cloud/functions/invoker/GcfEvents.java | 52 ++++++++++++++++--- .../functions/invoker/GcfEventsTest.java | 10 +++- .../core/src/test/resources/firebase-db1.json | 1 + .../core/src/test/resources/firebase-db2.json | 21 ++++++++ 6 files changed, 79 insertions(+), 11 deletions(-) create mode 100644 invoker/core/src/test/resources/firebase-db2.json diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index 01a1f997..7d41292b 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -55,6 +55,6 @@ jobs: with: functionType: 'cloudevent' useBuildpacks: false - validateMapping: false + validateMapping: true cmd: "'mvn -f invoker/conformance/pom.xml function:run -Drun.functionTarget=com.google.cloud.functions.conformance.CloudEventsConformanceFunction'" startDelay: 10 diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/CloudFunctionsContext.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/CloudFunctionsContext.java index c9fc06d9..081928ad 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/CloudFunctionsContext.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/CloudFunctionsContext.java @@ -50,6 +50,9 @@ abstract class CloudFunctionsContext implements Context { // TODO: expose this in the Context interface (as a default method). abstract Map params(); + @Nullable + abstract String domain(); + @Override public abstract Map attributes(); @@ -71,6 +74,7 @@ abstract static class Builder { abstract Builder setResource(String x); abstract Builder setParams(Map x); abstract Builder setAttributes(Map value); + abstract Builder setDomain(String x); abstract CloudFunctionsContext build(); } diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/GcfEvents.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/GcfEvents.java index 582f58e0..fc7713bc 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/GcfEvents.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/GcfEvents.java @@ -82,17 +82,13 @@ class GcfEvents { new FirestoreFirebaseEventAdapter("google.firebase.analytics.log.v1.written", FIREBASE_SERVICE)), entry("providers/google.firebase.database/eventTypes/ref.create", - new FirestoreFirebaseEventAdapter("google.firebase.database.document.v1.created", - FIREBASE_DB_SERVICE)), + new FirebaseDatabaseEventAdapter("google.firebase.database.document.v1.created")), entry("providers/google.firebase.database/eventTypes/ref.write", - new FirestoreFirebaseEventAdapter("google.firebase.database.document.v1.written", - FIREBASE_DB_SERVICE)), + new FirebaseDatabaseEventAdapter("google.firebase.database.document.v1.written")), entry("providers/google.firebase.database/eventTypes/ref.update", - new FirestoreFirebaseEventAdapter("google.firebase.database.document.v1.updated", - FIREBASE_DB_SERVICE)), + new FirebaseDatabaseEventAdapter("google.firebase.database.document.v1.updated")), entry("providers/google.firebase.database/eventTypes/ref.delete", - new FirestoreFirebaseEventAdapter("google.firebase.database.document.v1.deleted", - FIREBASE_DB_SERVICE)), + new FirebaseDatabaseEventAdapter("google.firebase.database.document.v1.deleted")), entry("providers/cloud.pubsub/eventTypes/topic.publish", new PubSubEventAdapter(PUB_SUB_MESSAGE_PUBLISHED)), @@ -172,6 +168,8 @@ private static class PubSubEventAdapter extends EventAdapter { @Override String maybeReshapeData(Event legacyEvent, String jsonData) { JsonObject jsonObject = GSON.fromJson(jsonData, JsonObject.class); + jsonObject.addProperty("messageId", legacyEvent.getContext().eventId()); + jsonObject.addProperty("publishTime", legacyEvent.getContext().timestamp()); JsonObject wrapped = new JsonObject(); wrapped.add("message", jsonObject); return GSON.toJson(wrapped); @@ -232,6 +230,44 @@ String maybeReshapeData(Event legacyEvent, String jsonData) { } } + private static class FirebaseDatabaseEventAdapter extends EventAdapter { + private static final Pattern FIREBASE_DB_RESOURCE_PATTERN = + Pattern.compile("^projects/_/(instances/[^/]+)/((documents|refs)/.+)$"); + + FirebaseDatabaseEventAdapter(String cloudEventType) { + super(cloudEventType, FIREBASE_DB_SERVICE); + } + + @Override + SourceAndSubject convertResourceToSourceAndSubject(String resourceName, Event legacyEvent) { + Matcher matcher = FIREBASE_DB_RESOURCE_PATTERN.matcher(resourceName); + String location = parseLocation(legacyEvent); + if (matcher.matches() && location != null) { + String resource = String.format("projects/_/locations/%s/%s", location, matcher.group(1)); + String subject = matcher.group(2); + return SourceAndSubject.of(resource, subject); + } + return super.convertResourceToSourceAndSubject(resourceName, legacyEvent); + } + + private String parseLocation(Event legacyEvent) { + String domain = legacyEvent.getContext().domain(); + if (domain == null) { + return null; + } + // The default location for firebaseio.com is us-central1 + if ("firebaseio.com".equals(domain)) { + return "us-central1"; + } + // Otherwise the location can be inferred from the first subdomain + String[] subdomains = domain.split("\\."); + if (subdomains.length > 1) { + return subdomains[0]; + } + return null; + } + } + private static class FirebaseAuthEventAdapter extends EventAdapter { FirebaseAuthEventAdapter(String cloudEventType) { super(cloudEventType, FIREBASE_AUTH_SERVICE); diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/GcfEventsTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/GcfEventsTest.java index f4861b1c..f4e43e06 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/GcfEventsTest.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/GcfEventsTest.java @@ -52,7 +52,11 @@ public class GcfEventsTest { {"legacy_pubsub.json", "google.cloud.pubsub.topic.v1.messagePublished", "//pubsub.googleapis.com/projects/sample-project/topics/gcf-test", null}, {"firebase-db1.json", "google.firebase.database.document.v1.written", - "//firebasedatabase.googleapis.com/projects/_/instances/my-project-id", "refs/gcf-test/xyz"}, + "//firebasedatabase.googleapis.com/projects/_/locations/us-central1/instances/my-project-id", + "refs/gcf-test/xyz"}, + {"firebase-db2.json", "google.firebase.database.document.v1.written", + "//firebasedatabase.googleapis.com/projects/_/locations/europe-west1/instances/my-project-id", + "refs/gcf-test/xyz"}, {"firebase-auth1.json", "google.firebase.auth.user.v1.created", "//firebaseauth.googleapis.com/projects/my-project-id", "users/UUpby3s4spZre6kHsgVSPetzQ8l2"}, {"firebase-auth2.json", "google.firebase.auth.user.v1.deleted", @@ -211,7 +215,9 @@ public void pubSubWrapping() throws IOException { assertThat(new String(cloudEvent.getData().toBytes(), UTF_8)) .isEqualTo("{\"message\":{\"@type\":\"type.googleapis.com/google.pubsub.v1.PubsubMessage\"," + "\"attributes\":{\"attribute1\":\"value1\"}," - + "\"data\":\"VGhpcyBpcyBhIHNhbXBsZSBtZXNzYWdl\"}}"); + + "\"data\":\"VGhpcyBpcyBhIHNhbXBsZSBtZXNzYWdl\"," + + "\"messageId\":\"1215011316659232\"," + + "\"publishTime\":\"2020-05-18T12:13:19.209Z\"}}"); } // Checks that a Firestore event correctly gets an extra "wildcards" property in its CloudEvent data diff --git a/invoker/core/src/test/resources/firebase-db1.json b/invoker/core/src/test/resources/firebase-db1.json index b7321a06..d6d6a015 100644 --- a/invoker/core/src/test/resources/firebase-db1.json +++ b/invoker/core/src/test/resources/firebase-db1.json @@ -6,6 +6,7 @@ "auth": { "admin": true }, + "domain": "firebaseio.com", "data": { "data": null, "delta": { diff --git a/invoker/core/src/test/resources/firebase-db2.json b/invoker/core/src/test/resources/firebase-db2.json new file mode 100644 index 00000000..371ea00e --- /dev/null +++ b/invoker/core/src/test/resources/firebase-db2.json @@ -0,0 +1,21 @@ +{ + "eventType": "providers/google.firebase.database/eventTypes/ref.write", + "params": { + "child": "xyz" + }, + "auth": { + "admin": true + }, + "domain":"europe-west1.firebasedatabase.app", + "data": { + "data": { + "grandchild": "other" + }, + "delta": { + "grandchild": "other changed" + } + }, + "resource": "projects/_/instances/my-project-id/refs/gcf-test/xyz", + "timestamp": "2020-09-29T11:32:00.000Z", + "eventId": "aaaaaa-1111-bbbb-2222-cccccccccccc" +} \ No newline at end of file From 85612eed6b7b5f24dd1699fcbd8c499711d2b0e8 Mon Sep 17 00:00:00 2001 From: Matthew Robertson Date: Tue, 6 Jul 2021 19:05:46 -0700 Subject: [PATCH 006/239] fix local development with the Pub/Sub emulator (#98) * unblock local development with the pubsub emulator Currently, the functions frameworks are dependent on some private dataplane event marshalling logic in order to correctly pass PubSub events to background functions. This commit implements the same marshalling logic in the FF in order to enable local development using the PubSub emulator. We have already made this change in other languages: https://github.com/GoogleCloudPlatform/functions-framework-nodejs/pull/272 https://github.com/GoogleCloudPlatform/functions-framework-ruby/pull/100 https://github.com/GoogleCloudPlatform/functions-framework-python/pull/121 https://github.com/GoogleCloudPlatform/functions-framework-go/pull/70 * fix code style issues --- .../google/cloud/functions/invoker/Event.java | 38 +++++++++++++ .../BackgroundFunctionExecutorTest.java | 54 +++++++++++++++++-- .../src/test/resources/pubsub_background.json | 19 +++++++ .../src/test/resources/pubsub_emulator.json | 10 ++++ 4 files changed, 117 insertions(+), 4 deletions(-) create mode 100644 invoker/core/src/test/resources/pubsub_background.json create mode 100644 invoker/core/src/test/resources/pubsub_emulator.json diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/Event.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/Event.java index 6f52f20b..ed12efe2 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/Event.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/Event.java @@ -21,6 +21,8 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import java.lang.reflect.Type; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; /** * Represents an event that should be handled by a background function. This is an internal format @@ -53,6 +55,34 @@ public Event deserialize( context = jsonDeserializationContext.deserialize( adjustContextResource(contextCopy), CloudFunctionsContext.class); + } else if (isPubSubEmulatorPayload(root)) { + JsonObject message = root.getAsJsonObject("message"); + + String timestampString = + message.has("publishTime") + ? message.get("publishTime").getAsString() + : DateTimeFormatter.ISO_INSTANT.format(OffsetDateTime.now()); + + context = + CloudFunctionsContext.builder() + .setEventType("google.pubsub.topic.publish") + .setTimestamp(timestampString) + .setEventId(message.get("messageId").getAsString()) + .setResource( + "{" + + "\"name\":null," + + "\"service\":\"pubsub.googleapis.com\"," + + "\"type\":\"type.googleapis.com/google.pubsub.v1.PubsubMessage\"" + + "}") + .build(); + + JsonObject marshalledData = new JsonObject(); + marshalledData.addProperty("@type", "type.googleapis.com/google.pubsub.v1.PubsubMessage"); + marshalledData.add("data", message.get("data")); + if (message.has("attributes")) { + marshalledData.add("attributes", message.get("attributes")); + } + data = marshalledData; } else { JsonObject rootCopy = root.deepCopy(); rootCopy.remove("data"); @@ -63,6 +93,14 @@ public Event deserialize( return Event.of(data, context); } + private boolean isPubSubEmulatorPayload(JsonObject root) { + if (root.has("subscription") && root.has("message") && root.get("message").isJsonObject()) { + JsonObject message = root.getAsJsonObject("message"); + return message.has("data") && message.has("messageId"); + } + return false; + } + /** * Replaces 'resource' member from context JSON with its string equivalent. The original * 'resource' member can be a JSON object itself while {@link CloudFunctionsContext} requires it diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutorTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutorTest.java index 02c5d630..d00b0b4f 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutorTest.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutorTest.java @@ -1,10 +1,15 @@ package com.google.cloud.functions.invoker; import static com.google.cloud.functions.invoker.BackgroundFunctionExecutor.backgroundFunctionTypeArgument; +import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth8.assertThat; import com.google.cloud.functions.BackgroundFunction; import com.google.cloud.functions.Context; +import com.google.gson.JsonObject; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; import java.util.Map; import org.junit.Test; import org.junit.runner.RunWith; @@ -20,7 +25,8 @@ private static class PubSubMessage { } private static class PubSubFunction implements BackgroundFunction { - @Override public void accept(PubSubMessage payload, Context context) {} + @Override + public void accept(PubSubMessage payload, Context context) {} } @Test @@ -31,7 +37,8 @@ public void backgroundFunctionTypeArgument_simple() { private abstract static class Parent implements BackgroundFunction {} private static class Child extends Parent { - @Override public void accept(PubSubMessage payload, Context context) {} + @Override + public void accept(PubSubMessage payload, Context context) {} } @Test @@ -42,7 +49,8 @@ public void backgroundFunctionTypeArgument_superclass() { private interface GenericParent extends BackgroundFunction {} private static class GenericChild implements GenericParent { - @Override public void accept(PubSubMessage payload, Context context) {} + @Override + public void accept(PubSubMessage payload, Context context) {} } @Test @@ -52,7 +60,8 @@ public void backgroundFunctionTypeArgument_genericInterface() { @SuppressWarnings("rawtypes") private static class ForgotTypeParameter implements BackgroundFunction { - @Override public void accept(Object payload, Context context) {} + @Override + public void accept(Object payload, Context context) {} } @Test @@ -62,4 +71,41 @@ public void backgroundFunctionTypeArgument_raw() { (Class>) (Class) ForgotTypeParameter.class; assertThat(backgroundFunctionTypeArgument(c)).isEmpty(); } + + @Test + public void parseLegacyEventPubSub() throws IOException { + try (Reader reader = + new InputStreamReader(getClass().getResourceAsStream("/pubsub_background.json"))) { + Event event = BackgroundFunctionExecutor.parseLegacyEvent(reader); + + Context context = event.getContext(); + assertThat(context.eventType()).isEqualTo("google.pubsub.topic.publish"); + assertThat(context.eventId()).isEqualTo("1"); + assertThat(context.timestamp()).isEqualTo("2021-06-28T05:46:32.390Z"); + + JsonObject data = event.getData().getAsJsonObject(); + assertThat(data.get("data").getAsString()).isEqualTo("eyJmb28iOiJiYXIifQ=="); + String attr = data.get("attributes").getAsJsonObject().get("test").getAsString(); + assertThat(attr).isEqualTo("123"); + } + } + + @Test + public void parseLegacyEventPubSubEmulator() throws IOException { + try (Reader reader = + new InputStreamReader(getClass().getResourceAsStream("/pubsub_emulator.json"))) { + Event event = BackgroundFunctionExecutor.parseLegacyEvent(reader); + + Context context = event.getContext(); + assertThat(context.eventType()).isEqualTo("google.pubsub.topic.publish"); + assertThat(context.eventId()).isEqualTo("1"); + assertThat(context.timestamp()).isNotNull(); + ; + + JsonObject data = event.getData().getAsJsonObject(); + assertThat(data.get("data").getAsString()).isEqualTo("eyJmb28iOiJiYXIifQ=="); + String attr = data.get("attributes").getAsJsonObject().get("test").getAsString(); + assertThat(attr).isEqualTo("123"); + } + } } diff --git a/invoker/core/src/test/resources/pubsub_background.json b/invoker/core/src/test/resources/pubsub_background.json new file mode 100644 index 00000000..5f9927cb --- /dev/null +++ b/invoker/core/src/test/resources/pubsub_background.json @@ -0,0 +1,19 @@ +{ + "data": { + "@type": "type.googleapis.com/google.pubsub.v1.PubsubMessage", + "data": "eyJmb28iOiJiYXIifQ==", + "attributes": { + "test": "123" + } + }, + "context": { + "eventId": "1", + "eventType": "google.pubsub.topic.publish", + "resource": { + "name": "projects/FOO/topics/BAR_TOPIC", + "service": "pubsub.googleapis.com", + "type": "type.googleapis.com/google.pubsub.v1.PubsubMessage" + }, + "timestamp": "2021-06-28T05:46:32.390Z" + } +} \ No newline at end of file diff --git a/invoker/core/src/test/resources/pubsub_emulator.json b/invoker/core/src/test/resources/pubsub_emulator.json new file mode 100644 index 00000000..cdfe340a --- /dev/null +++ b/invoker/core/src/test/resources/pubsub_emulator.json @@ -0,0 +1,10 @@ +{ + "subscription": "projects/FOO/subscriptions/BAR_SUB", + "message": { + "data": "eyJmb28iOiJiYXIifQ==", + "messageId": "1", + "attributes": { + "test": "123" + } + } +} \ No newline at end of file From 9a576debc60777356c4287debd72cbcba7cbaea8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Aug 2021 15:53:25 -0700 Subject: [PATCH 007/239] Bump guava from 28.1-jre to 29.0-jre in /invoker/testfunction (#86) Bumps [guava](https://github.com/google/guava) from 28.1-jre to 29.0-jre. - [Release notes](https://github.com/google/guava/releases) - [Commits](https://github.com/google/guava/commits) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- invoker/testfunction/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index 1b42c15c..3fada351 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -30,7 +30,7 @@ com.google.guava guava - 28.1-jre + 29.0-jre com.google.code.gson From 72852d0f23cdaed48569245440dcd1533c8c7563 Mon Sep 17 00:00:00 2001 From: Matthew Robertson Date: Tue, 14 Sep 2021 10:29:46 -0700 Subject: [PATCH 008/239] fix: update conformance tests (#108) Update the conformance tests action to 1.0.0 and fix firebasedb event conversion bug. --- .github/workflows/conformance.yaml | 6 +++--- .../com/google/cloud/functions/invoker/GcfEvents.java | 8 ++++---- .../com/google/cloud/functions/invoker/GcfEventsTest.java | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index 7d41292b..02686a9d 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -34,7 +34,7 @@ jobs: run: (cd invoker/ && mvn install) - name: Run HTTP conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@v0.3.12 + uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.0.0 with: functionType: 'http' useBuildpacks: false @@ -42,7 +42,7 @@ jobs: startDelay: 10 - name: Run background event conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@v0.3.12 + uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.0.0 with: functionType: 'legacyevent' useBuildpacks: false @@ -51,7 +51,7 @@ jobs: startDelay: 10 - name: Run cloudevent conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@v0.3.12 + uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.0.0 with: functionType: 'cloudevent' useBuildpacks: false diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/GcfEvents.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/GcfEvents.java index fc7713bc..83eca6ce 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/GcfEvents.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/GcfEvents.java @@ -82,13 +82,13 @@ class GcfEvents { new FirestoreFirebaseEventAdapter("google.firebase.analytics.log.v1.written", FIREBASE_SERVICE)), entry("providers/google.firebase.database/eventTypes/ref.create", - new FirebaseDatabaseEventAdapter("google.firebase.database.document.v1.created")), + new FirebaseDatabaseEventAdapter("google.firebase.database.ref.v1.created")), entry("providers/google.firebase.database/eventTypes/ref.write", - new FirebaseDatabaseEventAdapter("google.firebase.database.document.v1.written")), + new FirebaseDatabaseEventAdapter("google.firebase.database.ref.v1.written")), entry("providers/google.firebase.database/eventTypes/ref.update", - new FirebaseDatabaseEventAdapter("google.firebase.database.document.v1.updated")), + new FirebaseDatabaseEventAdapter("google.firebase.database.ref.v1.updated")), entry("providers/google.firebase.database/eventTypes/ref.delete", - new FirebaseDatabaseEventAdapter("google.firebase.database.document.v1.deleted")), + new FirebaseDatabaseEventAdapter("google.firebase.database.ref.v1.deleted")), entry("providers/cloud.pubsub/eventTypes/topic.publish", new PubSubEventAdapter(PUB_SUB_MESSAGE_PUBLISHED)), diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/GcfEventsTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/GcfEventsTest.java index f4e43e06..21e7016c 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/GcfEventsTest.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/GcfEventsTest.java @@ -51,10 +51,10 @@ public class GcfEventsTest { "//pubsub.googleapis.com/projects/sample-project/topics/gcf-test", null}, {"legacy_pubsub.json", "google.cloud.pubsub.topic.v1.messagePublished", "//pubsub.googleapis.com/projects/sample-project/topics/gcf-test", null}, - {"firebase-db1.json", "google.firebase.database.document.v1.written", + {"firebase-db1.json", "google.firebase.database.ref.v1.written", "//firebasedatabase.googleapis.com/projects/_/locations/us-central1/instances/my-project-id", "refs/gcf-test/xyz"}, - {"firebase-db2.json", "google.firebase.database.document.v1.written", + {"firebase-db2.json", "google.firebase.database.ref.v1.written", "//firebasedatabase.googleapis.com/projects/_/locations/europe-west1/instances/my-project-id", "refs/gcf-test/xyz"}, {"firebase-auth1.json", "google.firebase.auth.user.v1.created", From 05755f98b49ae2c4a428db4782484e092ae3987d Mon Sep 17 00:00:00 2001 From: Steren Date: Tue, 14 Sep 2021 10:57:54 -0700 Subject: [PATCH 009/239] docs: Cloud Run on GKE -> Cloud Run for Anthos (#106) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 43dbac5b..ad2ae922 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ different environments, including: * [Google Cloud Functions](https://cloud.google.com/functions/) * Your local development machine -* [Cloud Run and Cloud Run on GKE](https://cloud.google.com/run/) +* [Cloud Run](https://cloud.google.com/run/) and [Cloud Run for Anthos](https://cloud.google.com/anthos/run/) * [Knative](https://github.com/knative/)-based environments ## Installation From b3399424972e1d3534b0bd1e43cce04fbcc4afa8 Mon Sep 17 00:00:00 2001 From: Tianzi Cai Date: Tue, 14 Sep 2021 14:29:57 -0400 Subject: [PATCH 010/239] docs: update pubsub example (#107) --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index ad2ae922..628655c6 100644 --- a/README.md +++ b/README.md @@ -112,26 +112,26 @@ contents: ```java package com.example; -import com.example.PubSubBackground.PubSubMessage; import com.google.cloud.functions.BackgroundFunction; import com.google.cloud.functions.Context; import java.util.Map; import java.util.logging.Logger; +// This is the Pub/Sub message format from the Pub/Sub emulator. +class PubSubMessage { + String data; + Map attributes; + String messageId; + String publishTime; +} + public class PubSubBackground implements BackgroundFunction { private static final Logger logger = Logger.getLogger(PubSubBackground.class.getName()); @Override public void accept(PubSubMessage pubSubMessage, Context context) { - logger.info("Received message with id " + pubSubMessage.messageId); - } - - public static class PubSubMessage { - public String data; - public Map attributes; - public String messageId; - public String publishTime; + logger.info("Received message with id " + context.eventId()); } } ``` From 4a87830b2e46e5305fea884e4d2a11509f465972 Mon Sep 17 00:00:00 2001 From: Grant Timmerman <744973+grant@users.noreply.github.com> Date: Tue, 21 Sep 2021 16:18:08 -0700 Subject: [PATCH 011/239] docs: add badges for Maven Central and CI (#112) Adds detailed badges/links to main packages and CI. [![Maven Central](https://img.shields.io/maven-central/v/com.google.cloud.functions/functions-framework-api.svg?label=functions-framework-api)](https://search.maven.org/artifact/com.google.cloud.functions/functions-framework-api) [![Maven Central](https://img.shields.io/maven-central/v/com.google.cloud.functions.invoker/java-function-invoker.svg?label=java-function-invoker)](https://search.maven.org/artifact/com.google.cloud.functions.invoker/java-function-invoker) [![Java Unit CI](https://github.com/GoogleCloudPlatform/functions-framework-java/actions/workflows/unit.yaml/badge.svg)](https://github.com/GoogleCloudPlatform/functions-framework-java/actions/workflows/unit.yaml) [![Java Lint CI](https://github.com/GoogleCloudPlatform/functions-framework-java/actions/workflows/lint.yaml/badge.svg)](https://github.com/GoogleCloudPlatform/functions-framework-java/actions/workflows/lint.yaml) [![Java Conformance CI](https://github.com/GoogleCloudPlatform/functions-framework-java/actions/workflows/conformance.yaml/badge.svg)](https://github.com/GoogleCloudPlatform/functions-framework-java/actions/workflows/conformance.yaml) --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 628655c6..a53cfeac 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,11 @@ -# Functions Framework for Java [![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2FGoogleCloudPlatform%2Ffunctions-framework-java%2Fbadge&style=flat)](https://actions-badge.atrox.dev/GoogleCloudPlatform/functions-framework-java/goto) [![Maven Central](https://img.shields.io/maven-central/v/com.google.cloud.functions/functions-framework-api.svg)](https://search.maven.org/artifact/com.google.cloud.functions/functions-framework-api) +# Functions Framework for Java + +[![Maven Central](https://img.shields.io/maven-central/v/com.google.cloud.functions/functions-framework-api.svg?label=functions-framework-api)](https://search.maven.org/artifact/com.google.cloud.functions/functions-framework-api) +[![Maven Central](https://img.shields.io/maven-central/v/com.google.cloud.functions.invoker/java-function-invoker.svg?label=java-function-invoker)](https://search.maven.org/artifact/com.google.cloud.functions.invoker/java-function-invoker) + +[![Java Unit CI](https://github.com/GoogleCloudPlatform/functions-framework-java/actions/workflows/unit.yaml/badge.svg)](https://github.com/GoogleCloudPlatform/functions-framework-java/actions/workflows/unit.yaml) +[![Java Lint CI](https://github.com/GoogleCloudPlatform/functions-framework-java/actions/workflows/lint.yaml/badge.svg)](https://github.com/GoogleCloudPlatform/functions-framework-java/actions/workflows/lint.yaml) +[![Java Conformance CI](https://github.com/GoogleCloudPlatform/functions-framework-java/actions/workflows/conformance.yaml/badge.svg)](https://github.com/GoogleCloudPlatform/functions-framework-java/actions/workflows/conformance.yaml) An open source FaaS (Function as a service) framework for writing portable Java functions -- brought to you by the Google Cloud Functions team. From 1684c0ef55dc33f2c4c7f7514d99b0e7af75c44f Mon Sep 17 00:00:00 2001 From: Annie Fu <16651409+anniefu@users.noreply.github.com> Date: Wed, 22 Sep 2021 20:49:45 -0700 Subject: [PATCH 012/239] fix: make user function exceptions log level SEVERE (#113) The FF is inconsistent in how it logs errors in the user function between HTTP functions and Event-driven functions. This change makes it so that all functions log the same error with the same severity if the user function throws an exception. Log level SEVERE is required to be consistent with the Cloud Functions & Error Reporting [docs](https://cloud.google.com/error-reporting/docs/setup/nodejs#cloud_functions). --- .../invoker/BackgroundFunctionExecutor.java | 2 +- .../invoker/HttpFunctionExecutor.java | 6 +-- .../functions/invoker/IntegrationTest.java | 42 +++++++++++++++++++ .../testfunctions/ExceptionBackground.java | 11 +++++ .../invoker/testfunctions/ExceptionHttp.java | 12 ++++++ 5 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/ExceptionBackground.java create mode 100644 invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/ExceptionHttp.java diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java index 2238e5d3..754db8cf 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java @@ -333,7 +333,7 @@ public void service(HttpServletRequest req, HttpServletResponse res) throws IOEx res.setStatus(HttpServletResponse.SC_OK); } catch (Throwable t) { res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - logger.log(Level.WARNING, "Failed to execute " + functionExecutor.functionName(), t); + logger.log(Level.SEVERE, "Failed to execute " + functionExecutor.functionName(), t); } } diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java index d2a46afd..47bd5a55 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java @@ -66,11 +66,7 @@ public void service(HttpServletRequest req, HttpServletResponse res) { Thread.currentThread().setContextClassLoader(function.getClass().getClassLoader()); function.service(reqImpl, respImpl); } catch (Throwable t) { - // TODO(b/146510646): this should be logged properly as an exception, but that currently - // causes integration tests to fail. - // logger.log(Level.WARNING, "Failed to execute " + function.getClass().getName(), t); - logger.log(Level.WARNING, "Failed to execute {0}", function.getClass().getName()); - t.printStackTrace(); + logger.log(Level.SEVERE, "Failed to execute " + function.getClass().getName(), t); res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } finally { Thread.currentThread().setContextClassLoader(oldContextLoader); diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java index 8efe1abf..c6052339 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java @@ -248,6 +248,48 @@ public void helloWorld() throws Exception { ROBOTS_TXT_TEST_CASE)); } + @Test + public void exceptionHttp() throws Exception { + String exceptionExpectedOutput = + "\"severity\": \"ERROR\", \"logging.googleapis.com/sourceLocation\": {\"file\":" + + " \"com/google/cloud/functions/invoker/HttpFunctionExecutor.java\", \"method\":" + + " \"service\"}, \"message\": \"Failed to execute" + + " com.google.cloud.functions.invoker.testfunctions.ExceptionHttp\\n" + + "java.lang.RuntimeException: exception thrown for test"; + testHttpFunction( + fullTarget("ExceptionHttp"), + ImmutableList.of( + TestCase.builder() + .setExpectedResponseCode(500) + .setExpectedOutput(exceptionExpectedOutput) + .build())); + } + + + @Test + public void exceptionBackground() throws Exception { + String exceptionExpectedOutput = + "\"severity\": \"ERROR\", \"logging.googleapis.com/sourceLocation\": {\"file\":" + + " \"com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java\", \"method\":" + + " \"service\"}, \"message\": \"Failed to execute" + + " com.google.cloud.functions.invoker.testfunctions.ExceptionBackground\\n" + + "java.lang.RuntimeException: exception thrown for test"; + + File snoopFile = snoopFile(); + String gcfRequestText = sampleLegacyEvent(snoopFile); + + testFunction( + SignatureType.BACKGROUND, + fullTarget("ExceptionBackground"), + ImmutableList.of(), + ImmutableList.of( + TestCase.builder() + .setRequestText(gcfRequestText) + .setExpectedResponseCode(500) + .setExpectedOutput(exceptionExpectedOutput) + .build())); + } + @Test public void echo() throws Exception { String testText = "hello\nworld\n"; diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/ExceptionBackground.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/ExceptionBackground.java new file mode 100644 index 00000000..d087b395 --- /dev/null +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/ExceptionBackground.java @@ -0,0 +1,11 @@ +package com.google.cloud.functions.invoker.testfunctions; + +import com.google.cloud.functions.Context; +import com.google.cloud.functions.RawBackgroundFunction; + +public class ExceptionBackground implements RawBackgroundFunction { + @Override + public void accept(String json, Context context) { + throw new RuntimeException("exception thrown for test"); + } +} diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/ExceptionHttp.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/ExceptionHttp.java new file mode 100644 index 00000000..b6dee04d --- /dev/null +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/ExceptionHttp.java @@ -0,0 +1,12 @@ +package com.google.cloud.functions.invoker.testfunctions; + +import com.google.cloud.functions.HttpFunction; +import com.google.cloud.functions.HttpRequest; +import com.google.cloud.functions.HttpResponse; + +public class ExceptionHttp implements HttpFunction { + @Override + public void service(HttpRequest request, HttpResponse response) throws Exception { + throw new RuntimeException("exception thrown for test"); + } +} From 0f34cc808d7f487eb6c7288ff7f5756f3d78623d Mon Sep 17 00:00:00 2001 From: Grant Timmerman <744973+grant@users.noreply.github.com> Date: Tue, 28 Sep 2021 13:00:12 -0700 Subject: [PATCH 013/239] docs: add all mvn badges (#115) Add badges to all published packages from this repo. [![Maven Central](https://img.shields.io/maven-central/v/com.google.cloud.functions/functions-framework-api.svg?label=functions-framework-api)](https://search.maven.org/artifact/com.google.cloud.functions/functions-framework-api) [![Maven Central](https://img.shields.io/maven-central/v/com.google.cloud.functions.invoker/java-function-invoker.svg?label=java-function-invoker)](https://search.maven.org/artifact/com.google.cloud.functions.invoker/java-function-invoker) [![Maven Central](https://img.shields.io/maven-central/v/com.google.cloud.functions/function-maven-plugin.svg?label=function-maven-plugin)](https://search.maven.org/artifact/com.google.cloud.functions/function-maven-plugin) --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a53cfeac..1941d269 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # Functions Framework for Java -[![Maven Central](https://img.shields.io/maven-central/v/com.google.cloud.functions/functions-framework-api.svg?label=functions-framework-api)](https://search.maven.org/artifact/com.google.cloud.functions/functions-framework-api) -[![Maven Central](https://img.shields.io/maven-central/v/com.google.cloud.functions.invoker/java-function-invoker.svg?label=java-function-invoker)](https://search.maven.org/artifact/com.google.cloud.functions.invoker/java-function-invoker) +[![Maven Central (functions-framework-api)](https://img.shields.io/maven-central/v/com.google.cloud.functions/functions-framework-api.svg?label=functions-framework-api)](https://search.maven.org/artifact/com.google.cloud.functions/functions-framework-api) +[![Maven Central (java-function-invoker)](https://img.shields.io/maven-central/v/com.google.cloud.functions.invoker/java-function-invoker.svg?label=java-function-invoker)](https://search.maven.org/artifact/com.google.cloud.functions.invoker/java-function-invoker) +[![Maven Central (function-maven-plugin)](https://img.shields.io/maven-central/v/com.google.cloud.functions/function-maven-plugin.svg?label=function-maven-plugin)](https://search.maven.org/artifact/com.google.cloud.functions/function-maven-plugin) [![Java Unit CI](https://github.com/GoogleCloudPlatform/functions-framework-java/actions/workflows/unit.yaml/badge.svg)](https://github.com/GoogleCloudPlatform/functions-framework-java/actions/workflows/unit.yaml) [![Java Lint CI](https://github.com/GoogleCloudPlatform/functions-framework-java/actions/workflows/lint.yaml/badge.svg)](https://github.com/GoogleCloudPlatform/functions-framework-java/actions/workflows/lint.yaml) From c24366849dad24a661139fe5f7adc845fd638ab2 Mon Sep 17 00:00:00 2001 From: Grant Timmerman <744973+grant@users.noreply.github.com> Date: Thu, 30 Sep 2021 10:58:10 -0700 Subject: [PATCH 014/239] ci: Use setup Java v2 (needed for jdk17) (#114) Use `actions/setup-java@v2` (needed for jdk17). See https://github.com/actions/setup-java `jdk17` enabled for now, but there are some test failures we've temporarily disabled for that runtime: - `background(com.google.cloud.functions.invoker.IntegrationTest): 2 expectations failed:(..)` - `typedBackground(com.google.cloud.functions.invoker.IntegrationTest): 2 expectations failed:(..)` --- .github/workflows/unit.yaml | 8 +++---- .../functions/invoker/IntegrationTest.java | 22 +++++++++++++++++-- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index f93c38fb..b7446355 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -6,16 +6,16 @@ jobs: strategy: matrix: java: [ - 11.x - # 12.x, - # 13.x + 11.x, + 17.x ] steps: - uses: actions/checkout@v2 - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@v1 + uses: actions/setup-java@v2 with: java-version: ${{ matrix.java }} + distribution: temurin - name: Build with Maven run: (cd functions-framework-api/ && mvn install) - name: Test diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java index c6052339..051358f8 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java @@ -353,14 +353,32 @@ public void stackDriverLogging() throws Exception { fullTarget("Log"), ImmutableList.of(simpleTestCase, quotingTestCase, exceptionTestCase)); } + private static int getJavaVersion() { + String version = System.getProperty("java.version"); + if (version.startsWith("1.")) { + version = version.substring(2, 3); + } else { + int dot = version.indexOf("."); + if (dot != -1) { + version = version.substring(0, dot); + } + } return Integer.parseInt(version); + } + @Test public void background() throws Exception { - backgroundTest("BackgroundSnoop"); + // TODO: Only enable background tests for < 17 + if (getJavaVersion() < 17) { + backgroundTest("BackgroundSnoop"); + } } @Test public void typedBackground() throws Exception { - backgroundTest("TypedBackgroundSnoop"); + // TODO: Only enable background tests for < 17 + if (getJavaVersion() < 17) { + backgroundTest("TypedBackgroundSnoop"); + } } private void backgroundTest(String target) throws Exception { From f0d19d8012c28fb97dbf4603268acefddac48ead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89amonn=20McManus?= Date: Thu, 30 Sep 2021 11:29:13 -0700 Subject: [PATCH 015/239] [maven-release-plugin] prepare release java-function-invoker-parent-1.0.3 --- invoker/conformance/pom.xml | 6 +++--- invoker/core/pom.xml | 6 +++--- invoker/function-maven-plugin/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 932718e5..753929c1 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.0.3-SNAPSHOT + 1.0.3 com.google.cloud.functions.invoker conformance - 1.0-SNAPSHOT + 1.0 GCF Confromance Tests @@ -42,7 +42,7 @@ com.google.cloud.functions function-maven-plugin - 0.9.8-SNAPSHOT + 0.9.8 diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 29d2def4..816a63a7 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.0.3-SNAPSHOT + 1.0.3 com.google.cloud.functions.invoker java-function-invoker - 1.0.3-SNAPSHOT + 1.0.3 GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -114,7 +114,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.0.3-SNAPSHOT + 1.0.3 test-jar test diff --git a/invoker/function-maven-plugin/pom.xml b/invoker/function-maven-plugin/pom.xml index 0314da97..870b690d 100644 --- a/invoker/function-maven-plugin/pom.xml +++ b/invoker/function-maven-plugin/pom.xml @@ -4,13 +4,13 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.0.3-SNAPSHOT + 1.0.3 com.google.cloud.functions function-maven-plugin maven-plugin - 0.9.8-SNAPSHOT + 0.9.8 Functions Framework Plugin A Maven plugin that allows functions to be deployed, and to be run locally using the Java Functions Framework. @@ -44,7 +44,7 @@ com.google.cloud.functions.invoker java-function-invoker - 1.0.3-SNAPSHOT + 1.0.3 diff --git a/invoker/pom.xml b/invoker/pom.xml index 7f179f46..c15591fb 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -8,7 +8,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.0.3-SNAPSHOT + 1.0.3 pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index 3fada351..157b62ad 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.0.3-SNAPSHOT + 1.0.3 com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.0.3-SNAPSHOT + 1.0.3 Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From 5fd42a74d16ea087987fc2cb517ef861778fd1b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89amonn=20McManus?= Date: Thu, 30 Sep 2021 11:29:15 -0700 Subject: [PATCH 016/239] [maven-release-plugin] prepare for next development iteration --- invoker/conformance/pom.xml | 6 +++--- invoker/core/pom.xml | 6 +++--- invoker/function-maven-plugin/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 753929c1..67ff436e 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.0.3 + 1.0.4-SNAPSHOT com.google.cloud.functions.invoker conformance - 1.0 + 1.0.1-SNAPSHOT GCF Confromance Tests @@ -42,7 +42,7 @@ com.google.cloud.functions function-maven-plugin - 0.9.8 + 0.9.9-SNAPSHOT diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 816a63a7..af524717 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.0.3 + 1.0.4-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker - 1.0.3 + 1.0.4-SNAPSHOT GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -114,7 +114,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.0.3 + 1.0.4-SNAPSHOT test-jar test diff --git a/invoker/function-maven-plugin/pom.xml b/invoker/function-maven-plugin/pom.xml index 870b690d..bf5d8107 100644 --- a/invoker/function-maven-plugin/pom.xml +++ b/invoker/function-maven-plugin/pom.xml @@ -4,13 +4,13 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.0.3 + 1.0.4-SNAPSHOT com.google.cloud.functions function-maven-plugin maven-plugin - 0.9.8 + 0.9.9-SNAPSHOT Functions Framework Plugin A Maven plugin that allows functions to be deployed, and to be run locally using the Java Functions Framework. @@ -44,7 +44,7 @@ com.google.cloud.functions.invoker java-function-invoker - 1.0.3 + 1.0.4-SNAPSHOT diff --git a/invoker/pom.xml b/invoker/pom.xml index c15591fb..989794e6 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -8,7 +8,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.0.3 + 1.0.4-SNAPSHOT pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index 157b62ad..b381e41e 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.0.3 + 1.0.4-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.0.3 + 1.0.4-SNAPSHOT Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From 82401c7bdaa76da798b8ae35f931db0d4236c1e7 Mon Sep 17 00:00:00 2001 From: Annie Fu <16651409+anniefu@users.noreply.github.com> Date: Fri, 1 Oct 2021 18:25:52 -0400 Subject: [PATCH 017/239] docs: update readme with new release version (#116) --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1941d269..04a34659 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,7 @@ You can configure the plugin in `pom.xml`: com.google.cloud.functions function-maven-plugin - 0.9.7 + 0.9.8 com.example.function.Echo @@ -187,7 +187,7 @@ Copy the Functions Framework jar to a local location like this: ```sh mvn dependency:copy \ - -Dartifact='com.google.cloud.functions.invoker:java-function-invoker:1.0.2' \ + -Dartifact='com.google.cloud.functions.invoker:java-function-invoker:1.0.3' \ -DoutputDirectory=. ``` @@ -195,7 +195,7 @@ In this example we use the current directory `.` but you can specify any other directory to copy to. Then run your function: ```sh -java -jar java-function-invoker-1.0.2 \ +java -jar java-function-invoker-1.0.3 \ --classpath myfunction.jar \ --target com.example.HelloWorld ``` @@ -288,7 +288,7 @@ Framework directly, you must use `--classpath` to indicate how to find the code and its dependencies. For example: ``` -java -jar java-function-invoker-1.0.2 \ +java -jar java-function-invoker-1.0.3 \ --classpath 'myfunction.jar:/some/directory:/some/library/*' \ --target com.example.HelloWorld ``` From 5df7444ab1f0ce37028b48477650861a8d745442 Mon Sep 17 00:00:00 2001 From: Grant Timmerman <744973+grant@users.noreply.github.com> Date: Tue, 12 Oct 2021 11:57:17 -0700 Subject: [PATCH 018/239] docs: add instructions for running tests (#118) * docs: add instructions for running tests Signed-off-by: Grant Timmerman * docs: update contributing Signed-off-by: Grant Timmerman --- CONTRIBUTING.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 939e5341..2e34dae2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,3 +26,44 @@ information on using pull requests. This project follows [Google's Open Source Community Guidelines](https://opensource.google.com/conduct/). + +## Developing + +This project is divided into multiple packages, primarily: + +- [`functions-framework-api`](./functions-framework-api) + - `core` + - `testfunction` + - `function-maven-plugin` + - `conformance` +- [`java-function-invoker`](./invoker) + +### Setup JDK 11 / 17 + +Install JDK 11 and 17. One way to install these is through [SDK man](https://sdkman.io/). + +```sh +sdk install java 11.0.2-open +sdk install java 17 +sdk use java 17 +sdk use java 11.0.2-open +``` + +Verify Java version with: + +```sh +java --version +``` + +### Setup Apache Maven + +Install `mvn`: + +https://maven.apache.org/install.html + +## Install and Run Invoker Tests Locally + +``` +cd invoker; +mvn test; +``` From 565f07e3f947162870867d4c3b4e61302c32e62b Mon Sep 17 00:00:00 2001 From: Annie Fu <16651409+anniefu@users.noreply.github.com> Date: Wed, 20 Oct 2021 18:08:04 -0700 Subject: [PATCH 019/239] ci: add formatting CI (#122) * ci: add formatting CI Use Google formatting guidelines to format existing code. * Merge with lint workflow and add formatting instructions to CONTRIBUTING.md --- .github/workflows/lint.yaml | 19 +- .github/workflows/unit.yaml | 6 +- CONTRIBUTING.md | 5 + .../cloud/functions/BackgroundFunction.java | 16 +- .../cloud/functions/CloudEventsFunction.java | 9 +- .../com/google/cloud/functions/Context.java | 24 +- .../google/cloud/functions/HttpFunction.java | 4 +- .../google/cloud/functions/HttpMessage.java | 31 +- .../google/cloud/functions/HttpRequest.java | 40 +- .../google/cloud/functions/HttpResponse.java | 46 ++- .../functions/RawBackgroundFunction.java | 16 +- .../BackgroundEventConformanceFunction.java | 22 +- .../CloudEventsConformanceFunction.java | 13 +- .../conformance/HttpConformanceFunction.java | 9 +- .../invoker/BackgroundFunctionExecutor.java | 78 ++-- .../invoker/CloudFunctionsContext.java | 17 +- .../cloud/functions/invoker/GcfEvents.java | 125 +++--- .../invoker/HttpFunctionExecutor.java | 8 +- .../functions/invoker/gcf/JsonLogHandler.java | 8 +- .../functions/invoker/runner/Invoker.java | 128 +++--- .../functions/invoker/GcfEventsTest.java | 217 +++++++---- .../functions/invoker/IntegrationTest.java | 194 ++++++---- .../functions/invoker/http/HttpTest.java | 365 +++++++++--------- .../functions/invoker/runner/InvokerTest.java | 11 +- .../testfunctions/CloudEventSnoop.java | 3 +- .../invoker/testfunctions/Multipart.java | 7 +- .../testfunctions/TypedBackgroundSnoop.java | 3 +- .../cloud/functions/plugin/RunFunction.java | 35 +- .../com/example/functionjar/Background.java | 4 +- .../java/com/example/functionjar/Checker.java | 3 +- 30 files changed, 798 insertions(+), 668 deletions(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index cc31b736..82a20cfe 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -4,6 +4,7 @@ on: branches: - master pull_request: + workflow_dispatch: jobs: lint: runs-on: ubuntu-latest @@ -20,4 +21,20 @@ jobs: - name: Build Invoker with Maven run: (cd functions-framework-api/ && mvn install) - name: Lint Invoker - run: (cd invoker/ && mvn clean verify -DskipTests -P lint) \ No newline at end of file + run: (cd invoker/ && mvn clean verify -DskipTests -P lint) + formatting: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 # v2 minimum required + - name: Run formatter + id: formatter + uses: axel-op/googlejavaformat-action@v3 + with: + args: "--dry-run --set-exit-if-changed" + continue-on-error: true + - name: Check for failure + if: steps.formatter.outcome != 'success' + run: | + echo "Java format check failed, see 'Run formatter' step for more information." + echo "See https://github.com/google/google-java-format for options on running the formatter locally." + exit 1 \ No newline at end of file diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index b7446355..1938fc01 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -1,5 +1,9 @@ name: Java Unit CI -on: [push, pull_request] +on: + push: + branches: + - master + pull_request: jobs: build: runs-on: ubuntu-latest diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2e34dae2..7e7cc4ed 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -61,6 +61,11 @@ Install `mvn`: https://maven.apache.org/install.html +### Formatting +This repo follows the Google Java Style guide for formatting. You can setup the +formatting tool locally using one of the options provided at +[google/google-java-format](https://github.com/google/google-java-format#google-java-format). + ## Install and Run Invoker Tests Locally ``` diff --git a/functions-framework-api/src/main/java/com/google/cloud/functions/BackgroundFunction.java b/functions-framework-api/src/main/java/com/google/cloud/functions/BackgroundFunction.java index 890a5ade..5052b7b6 100644 --- a/functions-framework-api/src/main/java/com/google/cloud/functions/BackgroundFunction.java +++ b/functions-framework-api/src/main/java/com/google/cloud/functions/BackgroundFunction.java @@ -17,14 +17,14 @@ /** * Represents a Cloud Function that is activated by an event and parsed into a user-supplied class. * The payload of the event is a JSON object, which is deserialized into a user-defined class as - * described for - * Gson. - * - *

Here is an example of an implementation that accesses the {@code messageId} property from - * a payload that matches a user-defined {@code PubSubMessage} class: + * described for Gson. * + *

Here is an example of an implementation that accesses the {@code messageId} property from a + * payload that matches a user-defined {@code PubSubMessage} class: * + * *

  * public class Example implements{@code BackgroundFunction} {
  *   private static final Logger logger = Logger.getLogger(Example.class.getName());
@@ -49,9 +49,9 @@
 @FunctionalInterface
 public interface BackgroundFunction {
   /**
-   * Called to service an incoming event. This interface is implemented by user code to
-   * provide the action for a given background function. If this method throws any exception
-   * (including any {@link Error}) then the HTTP response will have a 500 status code.
+   * Called to service an incoming event. This interface is implemented by user code to provide the
+   * action for a given background function. If this method throws any exception (including any
+   * {@link Error}) then the HTTP response will have a 500 status code.
    *
    * @param payload the payload of the event, deserialized from the original JSON string.
    * @param context the context of the event. This is a set of values that every event has,
diff --git a/functions-framework-api/src/main/java/com/google/cloud/functions/CloudEventsFunction.java b/functions-framework-api/src/main/java/com/google/cloud/functions/CloudEventsFunction.java
index 05a092a7..7e34ae68 100644
--- a/functions-framework-api/src/main/java/com/google/cloud/functions/CloudEventsFunction.java
+++ b/functions-framework-api/src/main/java/com/google/cloud/functions/CloudEventsFunction.java
@@ -3,14 +3,15 @@
 import io.cloudevents.CloudEvent;
 
 /**
- * Represents a Cloud Function that is activated by an event and parsed into a {@link CloudEvent} object.
+ * Represents a Cloud Function that is activated by an event and parsed into a {@link CloudEvent}
+ * object.
  */
 @FunctionalInterface
 public interface CloudEventsFunction {
   /**
-   * Called to service an incoming event. This interface is implemented by user code to
-   * provide the action for a given background function. If this method throws any exception
-   * (including any {@link Error}) then the HTTP response will have a 500 status code.
+   * Called to service an incoming event. This interface is implemented by user code to provide the
+   * action for a given background function. If this method throws any exception (including any
+   * {@link Error}) then the HTTP response will have a 500 status code.
    *
    * @param event the event.
    * @throws Exception to produce a 500 status code in the HTTP response.
diff --git a/functions-framework-api/src/main/java/com/google/cloud/functions/Context.java b/functions-framework-api/src/main/java/com/google/cloud/functions/Context.java
index 36e857b5..5100451e 100644
--- a/functions-framework-api/src/main/java/com/google/cloud/functions/Context.java
+++ b/functions-framework-api/src/main/java/com/google/cloud/functions/Context.java
@@ -21,44 +21,44 @@
 public interface Context {
   /**
    * Returns event ID.
-   * 
+   *
    * @return event ID
    */
   String eventId();
 
   /**
    * Returns event timestamp.
-   * 
+   *
    * @return event timestamp
    */
   String timestamp();
 
   /**
    * Returns event type.
-   * 
+   *
    * @return event type
    */
   String eventType();
 
   /**
    * Returns event resource.
-   * 
+   *
    * @return event resource
    */
   String resource();
 
   /**
    * Returns additional attributes from this event. For CloudEvents, the entries in this map will
-   * include the
-   * required
-   * attributes and may include
-   * optional
-   * attributes and
-   * 
+   * include the required
+   * attributes and may include optional
+   * attributes and 
    * extension attributes.
    *
-   * 

The map returned by this method may be empty but is never null.

- * + *

The map returned by this method may be empty but is never null. + * * @return additional attributes form this event. */ default Map attributes() { diff --git a/functions-framework-api/src/main/java/com/google/cloud/functions/HttpFunction.java b/functions-framework-api/src/main/java/com/google/cloud/functions/HttpFunction.java index 59065ef6..6357724d 100644 --- a/functions-framework-api/src/main/java/com/google/cloud/functions/HttpFunction.java +++ b/functions-framework-api/src/main/java/com/google/cloud/functions/HttpFunction.java @@ -14,9 +14,7 @@ package com.google.cloud.functions; -/** - * Represents a Cloud Function that is activated by an HTTP request. - */ +/** Represents a Cloud Function that is activated by an HTTP request. */ @FunctionalInterface public interface HttpFunction { /** diff --git a/functions-framework-api/src/main/java/com/google/cloud/functions/HttpMessage.java b/functions-framework-api/src/main/java/com/google/cloud/functions/HttpMessage.java index 43b56da3..24a70c9b 100644 --- a/functions-framework-api/src/main/java/com/google/cloud/functions/HttpMessage.java +++ b/functions-framework-api/src/main/java/com/google/cloud/functions/HttpMessage.java @@ -21,9 +21,7 @@ import java.util.Map; import java.util.Optional; -/** - * Represents an HTTP message, either an HTTP request or a part of a multipart HTTP request. - */ +/** Represents an HTTP message, either an HTTP request or a part of a multipart HTTP request. */ public interface HttpMessage { /** * Returns the value of the {@code Content-Type} header, if any. @@ -40,19 +38,19 @@ public interface HttpMessage { long getContentLength(); /** - * Returns the character encoding specified in the {@code Content-Type} header, - * or {@code Optional.empty()} if there is no {@code Content-Type} header or it does not have the - * {@code charset} parameter. + * Returns the character encoding specified in the {@code Content-Type} header, or {@code + * Optional.empty()} if there is no {@code Content-Type} header or it does not have the {@code + * charset} parameter. * * @return the character encoding for the content type, if one is specified. */ Optional getCharacterEncoding(); /** - * Returns an {@link InputStream} that can be used to read the body of this HTTP request. - * Every call to this method on the same {@link HttpMessage} will return the same object. - * This method is typically used to read binary data. If the body is text, the - * {@link #getReader()} method is more appropriate. + * Returns an {@link InputStream} that can be used to read the body of this HTTP request. Every + * call to this method on the same {@link HttpMessage} will return the same object. This method is + * typically used to read binary data. If the body is text, the {@link #getReader()} method is + * more appropriate. * * @return an {@link InputStream} that can be used to read the body of this HTTP request. * @throws IOException if a valid {@link InputStream} cannot be returned for some reason. @@ -72,8 +70,8 @@ public interface HttpMessage { BufferedReader getReader() throws IOException; /** - * Returns a map describing the headers of this HTTP request, or this part of a multipart - * request. If the headers look like this... + * Returns a map describing the headers of this HTTP request, or this part of a multipart request. + * If the headers look like this... * *

    *   Content-Type: text/plain
@@ -82,11 +80,11 @@ public interface HttpMessage {
    * 
* * ...then the returned value will map {@code "Content-Type"} to a one-element list containing - * {@code "text/plain"}, and {@code "Some-Header"} to a two-element list containing - * {@code "some value"} and {@code "another value"}. + * {@code "text/plain"}, and {@code "Some-Header"} to a two-element list containing {@code "some + * value"} and {@code "another value"}. * - * @return a map where each key is an HTTP header and the corresponding {@code List} value has - * one element for each occurrence of that header. + * @return a map where each key is an HTTP header and the corresponding {@code List} value has one + * element for each occurrence of that header. */ Map> getHeaders(); @@ -104,7 +102,6 @@ public interface HttpMessage { * and {@code getFirstHeader("Another-Header")} will return {@code Optional.empty()}. * * @param name an HTTP header name. - * * @return the first value of the given header, if present. */ default Optional getFirstHeader(String name) { diff --git a/functions-framework-api/src/main/java/com/google/cloud/functions/HttpRequest.java b/functions-framework-api/src/main/java/com/google/cloud/functions/HttpRequest.java index fb1999cf..d50f1cf7 100644 --- a/functions-framework-api/src/main/java/com/google/cloud/functions/HttpRequest.java +++ b/functions-framework-api/src/main/java/com/google/cloud/functions/HttpRequest.java @@ -18,9 +18,7 @@ import java.util.Map; import java.util.Optional; -/** - * Represents the contents of an HTTP request that is being serviced by a Cloud Function. - */ +/** Represents the contents of an HTTP request that is being serviced by a Cloud Function. */ public interface HttpRequest extends HttpMessage { /** * The HTTP method of this request, such as {@code "POST"} or {@code "GET"}. @@ -37,39 +35,39 @@ public interface HttpRequest extends HttpMessage { String getUri(); /** - * The path part of the URI for this request, without any query. If the full URI is - * {@code http://foo.com/bar/baz?this=that}, then this method will return {@code /bar/baz}. + * The path part of the URI for this request, without any query. If the full URI is {@code + * http://foo.com/bar/baz?this=that}, then this method will return {@code /bar/baz}. * * @return the path part of the URI for this request. */ String getPath(); /** - * The query part of the URI for this request. If the full URI is - * {@code http://foo.com/bar/baz?this=that}, then this method will return {@code this=that}. - * If there is no query part, the returned {@code Optional} is empty. + * The query part of the URI for this request. If the full URI is {@code + * http://foo.com/bar/baz?this=that}, then this method will return {@code this=that}. If there is + * no query part, the returned {@code Optional} is empty. * * @return the query part of the URI, if any. */ Optional getQuery(); /** - * The query parameters of this request. If the full URI is - * {@code http://foo.com/bar?thing=thing1&thing=thing2&cat=hat}, then the returned map will map - * {@code thing} to the list {@code ["thing1", "thing2"]} and {@code cat} to the list with the - * single element {@code "hat"}. + * The query parameters of this request. If the full URI is {@code + * http://foo.com/bar?thing=thing1&thing=thing2&cat=hat}, then the returned map will map {@code + * thing} to the list {@code ["thing1", "thing2"]} and {@code cat} to the list with the single + * element {@code "hat"}. * - * @return a map where each key is the name of a query parameter and the corresponding - * {@code List} value indicates every value that was associated with that name. + * @return a map where each key is the name of a query parameter and the corresponding {@code + * List} value indicates every value that was associated with that name. */ Map> getQueryParameters(); /** - * The first query parameter with the given name, if any. If the full URI is - * {@code http://foo.com/bar?thing=thing1&thing=thing2&cat=hat}, then - * {@code getFirstQueryParameter("thing")} will return {@code Optional.of("thing1")} and - * {@code getFirstQueryParameter("something")} will return {@code Optional.empty()}. This is a - * more convenient alternative to {@link #getQueryParameters}. + * The first query parameter with the given name, if any. If the full URI is {@code + * http://foo.com/bar?thing=thing1&thing=thing2&cat=hat}, then {@code + * getFirstQueryParameter("thing")} will return {@code Optional.of("thing1")} and {@code + * getFirstQueryParameter("something")} will return {@code Optional.empty()}. This is a more + * convenient alternative to {@link #getQueryParameters}. * * @param name a query parameter name. * @return the first query parameter value with the given name, if any. @@ -102,8 +100,8 @@ interface HttpPart extends HttpMessage { * value. * * @return a map from part names to part contents. - * @throws IllegalStateException if the {@link #getContentType() content type} is not - * {@code multipart/form-data}. + * @throws IllegalStateException if the {@link #getContentType() content type} is not {@code + * multipart/form-data}. */ Map getParts(); } diff --git a/functions-framework-api/src/main/java/com/google/cloud/functions/HttpResponse.java b/functions-framework-api/src/main/java/com/google/cloud/functions/HttpResponse.java index 9098315d..c3f87ea2 100644 --- a/functions-framework-api/src/main/java/com/google/cloud/functions/HttpResponse.java +++ b/functions-framework-api/src/main/java/com/google/cloud/functions/HttpResponse.java @@ -22,30 +22,29 @@ import java.util.Optional; /** - * Represents the contents of an HTTP response that is being sent by a Cloud Function in response - * to an HTTP request. + * Represents the contents of an HTTP response that is being sent by a Cloud Function in response to + * an HTTP request. */ public interface HttpResponse { /** - * Sets the numeric HTTP - * status - * code to use in the response. Most often this will be 200, which is the OK status. The - * named constants in {@link java.net.HttpURLConnection}, such as - * {@link java.net.HttpURLConnection#HTTP_OK HTTP_OK}, can be used as an alternative to writing - * numbers in your source code. + * Sets the numeric HTTP status + * code to use in the response. Most often this will be 200, which is the OK status. The named + * constants in {@link java.net.HttpURLConnection}, such as {@link + * java.net.HttpURLConnection#HTTP_OK HTTP_OK}, can be used as an alternative to writing numbers + * in your source code. * * @param code the status code. */ void setStatusCode(int code); /** - * Sets the numeric HTTP - * status + * Sets the numeric HTTP status * code and reason message to use in the response. For example
- * {@code setStatusCode(400, "Something went wrong")}. The - * named constants in {@link java.net.HttpURLConnection}, such as - * {@link java.net.HttpURLConnection#HTTP_BAD_REQUEST HTTP_BAD_REQUEST}, can be used as an - * alternative to writing numbers in your source code. + * {@code setStatusCode(400, "Something went wrong")}. The named constants in {@link + * java.net.HttpURLConnection}, such as {@link java.net.HttpURLConnection#HTTP_BAD_REQUEST + * HTTP_BAD_REQUEST}, can be used as an alternative to writing numbers in your source code. * * @param code the status code. * @param message the status message. @@ -53,8 +52,8 @@ public interface HttpResponse { void setStatusCode(int code, String message); /** - * Sets the value to use for the {@code Content-Type} header in the response. This may include - * a character encoding, for example {@code setContentType("text/plain; charset=utf-8")}. + * Sets the value to use for the {@code Content-Type} header in the response. This may include a + * character encoding, for example {@code setContentType("text/plain; charset=utf-8")}. * * @param contentType the content type. */ @@ -90,9 +89,9 @@ public interface HttpResponse { Map> getHeaders(); /** - * Returns an {@link OutputStream} that can be used to write the body of the response. - * This method is typically used to write binary data. If the body is text, the - * {@link #getWriter()} method is more appropriate. + * Returns an {@link OutputStream} that can be used to write the body of the response. This method + * is typically used to write binary data. If the body is text, the {@link #getWriter()} method is + * more appropriate. * * @return the output stream. * @throws IOException if a valid {@link OutputStream} cannot be returned for some reason. @@ -101,11 +100,10 @@ public interface HttpResponse { OutputStream getOutputStream() throws IOException; /** - * Returns a {@link BufferedWriter} that can be used to write the text body of the response. - * If the written text will not be US-ASCII, you should specify a character encoding by calling - * {@link #setContentType setContentType("text/foo; charset=bar")} or - * {@link #appendHeader appendHeader("Content-Type", "text/foo; charset=bar")} - * before calling this method. + * Returns a {@link BufferedWriter} that can be used to write the text body of the response. If + * the written text will not be US-ASCII, you should specify a character encoding by calling + * {@link #setContentType setContentType("text/foo; charset=bar")} or {@link #appendHeader + * appendHeader("Content-Type", "text/foo; charset=bar")} before calling this method. * * @return the writer. * @throws IOException if a valid {@link BufferedWriter} cannot be returned for some reason. diff --git a/functions-framework-api/src/main/java/com/google/cloud/functions/RawBackgroundFunction.java b/functions-framework-api/src/main/java/com/google/cloud/functions/RawBackgroundFunction.java index 6eff26d2..e27624ed 100644 --- a/functions-framework-api/src/main/java/com/google/cloud/functions/RawBackgroundFunction.java +++ b/functions-framework-api/src/main/java/com/google/cloud/functions/RawBackgroundFunction.java @@ -16,14 +16,14 @@ /** * Represents a Cloud Function that is activated by an event. The payload of the event is a JSON - * object, which can be parsed using a JSON package such as - * GSON. + * object, which can be parsed using a JSON package such as GSON. * *

Here is an example of an implementation that parses the JSON payload using Gson, to access its * {@code messageId} property: - * * + * *

  * public class Example implements RawBackgroundFunction {
  *   private static final Logger logger = Logger.getLogger(Example.class.getName());
@@ -38,8 +38,8 @@
  * }
  * 
* - *

Here is an example of an implementation that deserializes the JSON payload into a Java - * object for simpler access, again using Gson: + *

Here is an example of an implementation that deserializes the JSON payload into a Java object + * for simpler access, again using Gson: * *

  * public class Example implements RawBackgroundFunction {
@@ -64,9 +64,9 @@
 @FunctionalInterface
 public interface RawBackgroundFunction {
   /**
-   * Called to service an incoming event. This interface is implemented by user code to
-   * provide the action for a given background function. If this method throws any exception
-   * (including any {@link Error}) then the HTTP response will have a 500 status code.
+   * Called to service an incoming event. This interface is implemented by user code to provide the
+   * action for a given background function. If this method throws any exception (including any
+   * {@link Error}) then the HTTP response will have a 500 status code.
    *
    * @param json the payload of the event, as a JSON string.
    * @param context the context of the event. This is a set of values that every event has,
diff --git a/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/BackgroundEventConformanceFunction.java b/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/BackgroundEventConformanceFunction.java
index 8672e6d8..8193abbd 100644
--- a/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/BackgroundEventConformanceFunction.java
+++ b/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/BackgroundEventConformanceFunction.java
@@ -1,29 +1,26 @@
 package com.google.cloud.functions.conformance;
 
+import com.google.cloud.functions.Context;
+import com.google.cloud.functions.RawBackgroundFunction;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
-import com.google.cloud.functions.Context;
-import com.google.cloud.functions.RawBackgroundFunction;
 import java.io.BufferedWriter;
 import java.io.FileWriter;
 
 /**
- * This class is used by the Functions Framework Conformance Tools to validate
- * the framework's Background Event API. It can be run with the following
- * command:
+ * This class is used by the Functions Framework Conformance Tools to validate the framework's
+ * Background Event API. It can be run with the following command:
  *
- * 
- * {@code
+ * 
{@code
  * $ functions-framework-conformance-client \
  *   -cmd="mvn function:run -Drun.functionTarget=com.google.cloud.functions.conformance.BackgroundEventConformanceFunction" \
  *   -type=legacyevent \
  *   -buildpacks=false \
  *   -validate-mapping=false \
  *   -start-delay=10
- * }
- * 
+ * }
*/ public class BackgroundEventConformanceFunction implements RawBackgroundFunction { @@ -36,15 +33,13 @@ public void accept(String data, Context context) throws Exception { } } - /** - * Create a structured JSON representation of the request context and data - */ + /** Create a structured JSON representation of the request context and data */ private String serialize(String data, Context context) { JsonObject contextJson = new JsonObject(); contextJson.addProperty("eventId", context.eventId()); contextJson.addProperty("timestamp", context.timestamp()); contextJson.addProperty("eventType", context.eventType()); - + JsonElement resource = gson.fromJson(context.resource(), JsonElement.class); contextJson.add("resource", resource); @@ -55,5 +50,4 @@ private String serialize(String data, Context context) { json.add("context", contextJson); return gson.toJson(json); } - } diff --git a/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/CloudEventsConformanceFunction.java b/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/CloudEventsConformanceFunction.java index da810047..04371952 100644 --- a/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/CloudEventsConformanceFunction.java +++ b/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/CloudEventsConformanceFunction.java @@ -26,8 +26,8 @@ import java.time.format.DateTimeFormatter; /** - * This class is used by the Functions Framework Conformance Tools to validate - * the framework's Cloud Events API. It can be run with the following command: + * This class is used by the Functions Framework Conformance Tools to validate the framework's Cloud + * Events API. It can be run with the following command: * *
{@code
  * $ functions-framework-conformance-client \
@@ -40,10 +40,7 @@
  */
 public class CloudEventsConformanceFunction implements CloudEventsFunction {
 
-  private static final Gson gson = new GsonBuilder()
-      .serializeNulls()
-      .setPrettyPrinting()
-      .create();
+  private static final Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().create();
 
   @Override
   public void accept(CloudEvent event) throws Exception {
@@ -52,9 +49,7 @@ public void accept(CloudEvent event) throws Exception {
     }
   }
 
-  /**
-   * Create a structured JSON representation of a cloud event
-   */
+  /** Create a structured JSON representation of a cloud event */
   private String serialize(CloudEvent event) {
     JsonObject jsonEvent = new JsonObject();
 
diff --git a/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/HttpConformanceFunction.java b/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/HttpConformanceFunction.java
index 0bdd843b..46eafd09 100644
--- a/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/HttpConformanceFunction.java
+++ b/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/HttpConformanceFunction.java
@@ -23,8 +23,8 @@
 import java.io.IOException;
 
 /**
- * This class is used by the Functions Framework Conformance Tools to validate
- * the framework's HTTP API. It can be run with the following command:
+ * This class is used by the Functions Framework Conformance Tools to validate the framework's HTTP
+ * API. It can be run with the following command:
  *
  * 
{@code
  * $ functions-framework-conformance-client \
@@ -38,8 +38,7 @@
 public class HttpConformanceFunction implements HttpFunction {
 
   @Override
-  public void service(HttpRequest request, HttpResponse response)
-      throws IOException {
+  public void service(HttpRequest request, HttpResponse response) throws IOException {
     try (BufferedReader reader = request.getReader();
         BufferedWriter writer = new BufferedWriter(new FileWriter("function_output.json"))) {
       int c;
@@ -48,4 +47,4 @@ public void service(HttpRequest request, HttpResponse response)
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java
index 754db8cf..6f320438 100644
--- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java
+++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java
@@ -72,18 +72,20 @@ private enum FunctionKind {
 
     /** Returns the {@link FunctionKind} that the given class implements, if any. */
     static Optional forClass(Class functionClass) {
-      return VALUES.stream().filter(v -> v.functionClass.isAssignableFrom(functionClass)).findFirst();
+      return VALUES.stream()
+          .filter(v -> v.functionClass.isAssignableFrom(functionClass))
+          .findFirst();
     }
   }
 
   /**
    * Optionally makes a {@link BackgroundFunctionExecutor} for the given class, if it implements one
-   * of {@link BackgroundFunction}, {@link RawBackgroundFunction}, or
-   * {@link CloudEventsFunction}. Otherwise returns {@link Optional#empty()}.
+   * of {@link BackgroundFunction}, {@link RawBackgroundFunction}, or {@link CloudEventsFunction}.
+   * Otherwise returns {@link Optional#empty()}.
    *
    * @param functionClass the class of a possible background function implementation.
-   * @throws RuntimeException if the given class does implement one of the required interfaces, but we are
-   *     unable to construct an instance using its no-arg constructor.
+   * @throws RuntimeException if the given class does implement one of the required interfaces, but
+   *     we are unable to construct an instance using its no-arg constructor.
    */
   public static Optional maybeForClass(Class functionClass) {
     Optional maybeFunctionKind = FunctionKind.forClass(functionClass);
@@ -96,10 +98,9 @@ public static Optional maybeForClass(Class functi
   /**
    * Makes a {@link BackgroundFunctionExecutor} for the given class.
    *
-   * @throws RuntimeException if either the class does not implement one of
-   *    {@link BackgroundFunction}, {@link RawBackgroundFunction}, or
-   *    {@link CloudEventsFunction}; or we are unable to construct an instance using its no-arg
-   *     constructor.
+   * @throws RuntimeException if either the class does not implement one of {@link
+   *     BackgroundFunction}, {@link RawBackgroundFunction}, or {@link CloudEventsFunction}; or we
+   *     are unable to construct an instance using its no-arg constructor.
    */
   public static BackgroundFunctionExecutor forClass(Class functionClass) {
     Optional maybeFunctionKind = FunctionKind.forClass(functionClass);
@@ -107,13 +108,16 @@ public static BackgroundFunctionExecutor forClass(Class functionClass) {
       List classNames =
           FunctionKind.VALUES.stream().map(v -> v.functionClass.getName()).collect(toList());
       throw new RuntimeException(
-          "Class " + functionClass.getName() + " must implement one of these interfaces: "
+          "Class "
+              + functionClass.getName()
+              + " must implement one of these interfaces: "
               + String.join(", ", classNames));
     }
     return forClass(functionClass, maybeFunctionKind.get());
   }
 
-  private static BackgroundFunctionExecutor forClass(Class functionClass, FunctionKind functionKind) {
+  private static BackgroundFunctionExecutor forClass(
+      Class functionClass, FunctionKind functionKind) {
     Object instance;
     try {
       instance = functionClass.getConstructor().newInstance();
@@ -152,9 +156,8 @@ private static BackgroundFunctionExecutor forClass(Class functionClass, Funct
   }
 
   /**
-   * Returns the {@code T} of a concrete class that implements
-   * {@link BackgroundFunction BackgroundFunction}. Returns an empty {@link Optional} if
-   * {@code T} can't be determined.
+   * Returns the {@code T} of a concrete class that implements {@link BackgroundFunction
+   * BackgroundFunction}. Returns an empty {@link Optional} if {@code T} can't be determined.
    */
   static Optional backgroundFunctionTypeArgument(
       Class> functionClass) {
@@ -163,9 +166,12 @@ static Optional backgroundFunctionTypeArgument(
     // We must be careful because the compiler will also have added a synthetic method
     // accept(Object, Context).
     return Arrays.stream(functionClass.getMethods())
-        .filter(m -> m.getName().equals("accept") && m.getParameterCount() == 2
-            && m.getParameterTypes()[1] == Context.class
-            && m.getParameterTypes()[0] != Object.class)
+        .filter(
+            m ->
+                m.getName().equals("accept")
+                    && m.getParameterCount() == 2
+                    && m.getParameterTypes()[1] == Context.class
+                    && m.getParameterTypes()[0] != Object.class)
         .map(m -> m.getGenericParameterTypes()[0])
         .findFirst();
   }
@@ -175,21 +181,22 @@ private static Event parseLegacyEvent(HttpServletRequest req) throws IOException
       return parseLegacyEvent(bodyReader);
     }
   }
-  
+
   static Event parseLegacyEvent(Reader reader) throws IOException {
     // A Type Adapter is required to set the type of the JsonObject because CloudFunctionsContext
     // is abstract and Gson default behavior instantiates the type provided.
-    TypeAdapter typeAdapter =
-        CloudFunctionsContext.typeAdapter(new Gson());
-    Gson gson = new GsonBuilder()
-        .registerTypeAdapter(CloudFunctionsContext.class, typeAdapter)
-        .registerTypeAdapter(Event.class, new Event.EventDeserializer())
-        .create();
+    TypeAdapter typeAdapter = CloudFunctionsContext.typeAdapter(new Gson());
+    Gson gson =
+        new GsonBuilder()
+            .registerTypeAdapter(CloudFunctionsContext.class, typeAdapter)
+            .registerTypeAdapter(Event.class, new Event.EventDeserializer())
+            .create();
     return gson.fromJson(reader, Event.class);
   }
 
   private static Context contextFromCloudEvent(CloudEvent cloudEvent) {
-    OffsetDateTime timestamp = Optional.ofNullable(cloudEvent.getTime()).orElse(OffsetDateTime.now());
+    OffsetDateTime timestamp =
+        Optional.ofNullable(cloudEvent.getTime()).orElse(OffsetDateTime.now());
     String timestampString = DateTimeFormatter.ISO_INSTANT.format(timestamp);
     // We don't have an obvious replacement for the Context.resource field, which with legacy events
     // corresponded to a value present for some proprietary Google event types.
@@ -214,8 +221,8 @@ private static Context contextFromCloudEvent(CloudEvent cloudEvent) {
    *
    * 

In addition to these two flavours, events can be either "legacy events" or "CloudEvents". * Legacy events are the only kind that GCF originally supported, and use proprietary encodings - * for the various triggers. CloudEvents are ones that follow the standards defined by - * cloudevents.io. + * for the various triggers. CloudEvents are ones that follow the standards defined by cloudevents.io. * * @param the type to be used in the {@link Unmarshallers} call when * unmarshalling this event, if it is a CloudEvent. @@ -257,9 +264,8 @@ void serviceLegacyEvent(Event legacyEvent) throws Exception { @Override void serviceCloudEvent(CloudEvent cloudEvent) throws Exception { Context context = contextFromCloudEvent(cloudEvent); - String jsonData = (cloudEvent.getData() == null) - ? "{}" - : new String(cloudEvent.getData().toBytes(), UTF_8); + String jsonData = + (cloudEvent.getData() == null) ? "{}" : new String(cloudEvent.getData().toBytes(), UTF_8); function.accept(jsonData, context); } } @@ -337,13 +343,16 @@ public void service(HttpServletRequest req, HttpServletResponse res) throws IOEx } } - private enum CloudEventKind {BINARY, STRUCTURED} + private enum CloudEventKind { + BINARY, + STRUCTURED + } /** * Service a CloudEvent. * - * @param a fake type parameter, which corresponds to the type parameter of - * {@link FunctionExecutor}. + * @param a fake type parameter, which corresponds to the type parameter of {@link + * FunctionExecutor}. */ private void serviceCloudEvent(HttpServletRequest req) throws Exception { @SuppressWarnings("unchecked") @@ -353,7 +362,8 @@ private void serviceCloudEvent(HttpServletRequest req) throws Exce // It's important not to set the context ClassLoader earlier, because MessageUtils will use // ServiceLoader.load(EventFormat.class) to find a handler to deserialize a binary CloudEvent // and if it finds something from the function ClassLoader then that something will implement - // the EventFormat interface as defined by that ClassLoader rather than ours. Then ServiceLoader.load + // the EventFormat interface as defined by that ClassLoader rather than ours. Then + // ServiceLoader.load // will throw ServiceConfigurationError. At this point we're still running with the default // context ClassLoader, which is the system ClassLoader that has loaded the code here. runWithContextClassLoader(() -> executor.serviceCloudEvent(reader.toEvent(data -> data))); diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/CloudFunctionsContext.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/CloudFunctionsContext.java index 081928ad..4efc045d 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/CloudFunctionsContext.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/CloudFunctionsContext.java @@ -69,25 +69,33 @@ static Builder builder() { @AutoValue.Builder abstract static class Builder { abstract Builder setEventId(String x); + abstract Builder setTimestamp(String x); + abstract Builder setEventType(String x); + abstract Builder setResource(String x); + abstract Builder setParams(Map x); + abstract Builder setAttributes(Map value); + abstract Builder setDomain(String x); abstract CloudFunctionsContext build(); } /** - * Depending on the event type, the {@link Context#resource()} field is either a JSON string (complete - * with encosing quotes) or a JSON object. This class allows us to redeserialize that JSON representation - * into its components. + * Depending on the event type, the {@link Context#resource()} field is either a JSON string + * (complete with encosing quotes) or a JSON object. This class allows us to redeserialize that + * JSON representation into its components. */ @AutoValue abstract static class Resource { abstract @Nullable String service(); + abstract String name(); + abstract @Nullable String type(); static TypeAdapter typeAdapter(Gson gson) { @@ -115,8 +123,11 @@ static Builder builder() { @AutoValue.Builder abstract static class Builder { abstract Builder setService(String x); + abstract Builder setName(String x); + abstract Builder setType(String x); + abstract Resource build(); } } diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/GcfEvents.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/GcfEvents.java index 83eca6ce..d78365dc 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/GcfEvents.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/GcfEvents.java @@ -28,16 +28,12 @@ import java.net.URI; import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; -import java.util.Arrays; -import java.util.List; import java.util.Map; import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; -/** - * Conversions from GCF events to CloudEvents. - */ +/** Conversions from GCF events to CloudEvents. */ class GcfEvents { private static final String FIREBASE_SERVICE = "firebase.googleapis.com"; private static final String FIREBASE_AUTH_SERVICE = "firebaseauth.googleapis.com"; @@ -46,56 +42,68 @@ class GcfEvents { private static final String PUB_SUB_SERVICE = "pubsub.googleapis.com"; private static final String STORAGE_SERVICE = "storage.googleapis.com"; - private static final String PUB_SUB_MESSAGE_PUBLISHED = "google.cloud.pubsub.topic.v1.messagePublished"; - - private static final Map EVENT_TYPE_MAPPING = Map.ofEntries( - entry("google.pubsub.topic.publish", new PubSubEventAdapter(PUB_SUB_MESSAGE_PUBLISHED)), - - entry("google.storage.object.finalize", - new StorageEventAdapter("google.cloud.storage.object.v1.finalized")), - entry("google.storage.object.delete", - new StorageEventAdapter("google.cloud.storage.object.v1.deleted")), - entry("google.storage.object.archive", - new StorageEventAdapter("google.cloud.storage.object.v1.archived")), - entry("google.storage.object.metadataUpdate", - new StorageEventAdapter("google.cloud.storage.object.v1.metadataUpdated")), - - entry("providers/cloud.firestore/eventTypes/document.write", - new FirestoreFirebaseEventAdapter("google.cloud.firestore.document.v1.written", - FIRESTORE_SERVICE)), - entry("providers/cloud.firestore/eventTypes/document.create", - new FirestoreFirebaseEventAdapter("google.cloud.firestore.document.v1.created", - FIRESTORE_SERVICE)), - entry("providers/cloud.firestore/eventTypes/document.update", - new FirestoreFirebaseEventAdapter("google.cloud.firestore.document.v1.updated", - FIRESTORE_SERVICE)), - entry("providers/cloud.firestore/eventTypes/document.delete", - new FirestoreFirebaseEventAdapter("google.cloud.firestore.document.v1.deleted", - FIRESTORE_SERVICE)), - - entry("providers/firebase.auth/eventTypes/user.create", - new FirebaseAuthEventAdapter("google.firebase.auth.user.v1.created")), - entry("providers/firebase.auth/eventTypes/user.delete", - new FirebaseAuthEventAdapter("google.firebase.auth.user.v1.deleted")), - - entry("providers/google.firebase.analytics/eventTypes/event.log", - new FirestoreFirebaseEventAdapter("google.firebase.analytics.log.v1.written", FIREBASE_SERVICE)), - - entry("providers/google.firebase.database/eventTypes/ref.create", - new FirebaseDatabaseEventAdapter("google.firebase.database.ref.v1.created")), - entry("providers/google.firebase.database/eventTypes/ref.write", - new FirebaseDatabaseEventAdapter("google.firebase.database.ref.v1.written")), - entry("providers/google.firebase.database/eventTypes/ref.update", - new FirebaseDatabaseEventAdapter("google.firebase.database.ref.v1.updated")), - entry("providers/google.firebase.database/eventTypes/ref.delete", - new FirebaseDatabaseEventAdapter("google.firebase.database.ref.v1.deleted")), - - entry("providers/cloud.pubsub/eventTypes/topic.publish", - new PubSubEventAdapter(PUB_SUB_MESSAGE_PUBLISHED)), - - entry("providers/cloud.storage/eventTypes/object.change", - new StorageEventAdapter("google.cloud.storage.object.v1.changed")) - ); + private static final String PUB_SUB_MESSAGE_PUBLISHED = + "google.cloud.pubsub.topic.v1.messagePublished"; + + private static final Map EVENT_TYPE_MAPPING = + Map.ofEntries( + entry("google.pubsub.topic.publish", new PubSubEventAdapter(PUB_SUB_MESSAGE_PUBLISHED)), + entry( + "google.storage.object.finalize", + new StorageEventAdapter("google.cloud.storage.object.v1.finalized")), + entry( + "google.storage.object.delete", + new StorageEventAdapter("google.cloud.storage.object.v1.deleted")), + entry( + "google.storage.object.archive", + new StorageEventAdapter("google.cloud.storage.object.v1.archived")), + entry( + "google.storage.object.metadataUpdate", + new StorageEventAdapter("google.cloud.storage.object.v1.metadataUpdated")), + entry( + "providers/cloud.firestore/eventTypes/document.write", + new FirestoreFirebaseEventAdapter( + "google.cloud.firestore.document.v1.written", FIRESTORE_SERVICE)), + entry( + "providers/cloud.firestore/eventTypes/document.create", + new FirestoreFirebaseEventAdapter( + "google.cloud.firestore.document.v1.created", FIRESTORE_SERVICE)), + entry( + "providers/cloud.firestore/eventTypes/document.update", + new FirestoreFirebaseEventAdapter( + "google.cloud.firestore.document.v1.updated", FIRESTORE_SERVICE)), + entry( + "providers/cloud.firestore/eventTypes/document.delete", + new FirestoreFirebaseEventAdapter( + "google.cloud.firestore.document.v1.deleted", FIRESTORE_SERVICE)), + entry( + "providers/firebase.auth/eventTypes/user.create", + new FirebaseAuthEventAdapter("google.firebase.auth.user.v1.created")), + entry( + "providers/firebase.auth/eventTypes/user.delete", + new FirebaseAuthEventAdapter("google.firebase.auth.user.v1.deleted")), + entry( + "providers/google.firebase.analytics/eventTypes/event.log", + new FirestoreFirebaseEventAdapter( + "google.firebase.analytics.log.v1.written", FIREBASE_SERVICE)), + entry( + "providers/google.firebase.database/eventTypes/ref.create", + new FirebaseDatabaseEventAdapter("google.firebase.database.ref.v1.created")), + entry( + "providers/google.firebase.database/eventTypes/ref.write", + new FirebaseDatabaseEventAdapter("google.firebase.database.ref.v1.written")), + entry( + "providers/google.firebase.database/eventTypes/ref.update", + new FirebaseDatabaseEventAdapter("google.firebase.database.ref.v1.updated")), + entry( + "providers/google.firebase.database/eventTypes/ref.delete", + new FirebaseDatabaseEventAdapter("google.firebase.database.ref.v1.deleted")), + entry( + "providers/cloud.pubsub/eventTypes/topic.publish", + new PubSubEventAdapter(PUB_SUB_MESSAGE_PUBLISHED)), + entry( + "providers/cloud.storage/eventTypes/object.change", + new StorageEventAdapter("google.cloud.storage.object.v1.changed"))); private static final Gson GSON = new GsonBuilder().serializeNulls().create(); @@ -112,6 +120,7 @@ static CloudEvent convertToCloudEvent(Event legacyEvent) { abstract static class SourceAndSubject { /** The source URI, without the initial {@code ///}. */ abstract String source(); + abstract @Nullable String subject(); static SourceAndSubject of(String source, String subject) { @@ -134,7 +143,8 @@ final CloudEvent convertToCloudEvent(Event legacyEvent) { Resource resource = Resource.from(legacyEvent.getContext().resource()); String service = Optional.ofNullable(resource.service()).orElse(defaultService); String resourceName = resource.name(); - SourceAndSubject sourceAndSubject = convertResourceToSourceAndSubject(resourceName, legacyEvent); + SourceAndSubject sourceAndSubject = + convertResourceToSourceAndSubject(resourceName, legacyEvent); URI source = URI.create("//" + service + "/" + sourceAndSubject.source()); OffsetDateTime timestamp = Optional.ofNullable(legacyEvent.getContext().timestamp()) @@ -217,7 +227,8 @@ SourceAndSubject convertResourceToSourceAndSubject(String resourceName, Event le @Override String maybeReshapeData(Event legacyEvent, String jsonData) { - // The reshaping code is disabled for now, because the specification for how the legacy "params" + // The reshaping code is disabled for now, because the specification for how the legacy + // "params" // field should be represented in a CloudEvent is in flux. if (true || legacyEvent.getContext().params().isEmpty()) { return jsonData; diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java index 47bd5a55..7a66fefd 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java @@ -37,13 +37,15 @@ private HttpFunctionExecutor(HttpFunction function) { /** * Makes a {@link HttpFunctionExecutor} for the given class. * - * @throws RuntimeException if either the given class does not implement {@link HttpFunction} - * or we are unable to construct an instance using its no-arg constructor. + * @throws RuntimeException if either the given class does not implement {@link HttpFunction} or + * we are unable to construct an instance using its no-arg constructor. */ public static HttpFunctionExecutor forClass(Class functionClass) { if (!HttpFunction.class.isAssignableFrom(functionClass)) { throw new RuntimeException( - "Class " + functionClass.getName() + " does not implement " + "Class " + + functionClass.getName() + + " does not implement " + HttpFunction.class.getName()); } Class httpFunctionClass = functionClass.asSubclass(HttpFunction.class); diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/gcf/JsonLogHandler.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/gcf/JsonLogHandler.java index 181354c1..9c94b92a 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/gcf/JsonLogHandler.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/gcf/JsonLogHandler.java @@ -10,9 +10,8 @@ import java.util.logging.LogRecord; /** - * A log handler that publishes log messages in a json format. This is StackDriver's - * "structured - * logging" format. + * A log handler that publishes log messages in a json format. This is StackDriver's "structured logging" format. */ public final class JsonLogHandler extends Handler { private static final String SOURCE_LOCATION_KEY = "\"logging.googleapis.com/sourceLocation\": "; @@ -50,8 +49,7 @@ private static void appendMessage(StringBuilder json, LogRecord record) { // unforgiving about commas and you can't have one just before }. json.append("\"message\": \"").append(escapeString(record.getMessage())); if (record.getThrown() != null) { - json.append("\\n") - .append(escapeString(getStackTraceAsString(record.getThrown()))); + json.append("\\n").append(escapeString(getStackTraceAsString(record.getThrown()))); } json.append("\""); } diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java index c87b376b..3256e989 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java @@ -89,35 +89,29 @@ public class Invoker { } private static class Options { - @Parameter( - description = "Port on which to listen for HTTP requests.", - names = "--port" - ) + @Parameter(description = "Port on which to listen for HTTP requests.", names = "--port") private String port = System.getenv().getOrDefault("PORT", "8080"); @Parameter( description = "Name of function class to execute when servicing incoming requests.", - names = "--target" - ) + names = "--target") private String target = System.getenv().getOrDefault("FUNCTION_TARGET", "Function"); @Parameter( - description = "List of files or directories where the compiled Java classes making up" - + " the function will be found. This functions like the -classpath option to the" - + " java command. It is a list of filenames separated by '${path.separator}'." - + " If an entry in the list names a directory then the class foo.bar.Baz will be looked" - + " for in foo${file.separator}bar${file.separator}Baz.class under that" - + " directory. If an entry in the list names a file and that file is a jar file then" - + " class foo.bar.Baz will be looked for in an entry foo/bar/Baz.class in that jar" - + " file. If an entry is a directory followed by '${file.separator}*' then every file" - + " in the directory whose name ends with '.jar' will be searched for classes.", - names = "--classpath" - ) + description = + "List of files or directories where the compiled Java classes making up the function" + + " will be found. This functions like the -classpath option to the java command." + + " It is a list of filenames separated by '${path.separator}'. If an entry in the" + + " list names a directory then the class foo.bar.Baz will be looked for in" + + " foo${file.separator}bar${file.separator}Baz.class under that directory. If an" + + " entry in the list names a file and that file is a jar file then class" + + " foo.bar.Baz will be looked for in an entry foo/bar/Baz.class in that jar file." + + " If an entry is a directory followed by '${file.separator}*' then every file in" + + " the directory whose name ends with '.jar' will be searched for classes.", + names = "--classpath") private String classPath = null; - @Parameter( - names = "--help", help = true - ) + @Parameter(names = "--help", help = true) private boolean help = false; } @@ -134,9 +128,7 @@ static Optional makeInvoker(String... args) { static Optional makeInvoker(Map environment, String... args) { Options options = new Options(); - JCommander jCommander = JCommander.newBuilder() - .addObject(options) - .build(); + JCommander jCommander = JCommander.newBuilder().addObject(options).build(); try { jCommander.parse(args); } catch (ParameterException e) { @@ -161,28 +153,27 @@ static Optional makeInvoker(Map environment, String... Path standardFunctionJarPath = Paths.get("function/function.jar"); Optional functionClasspath = Arrays.asList( - options.classPath, - environment.get("FUNCTION_CLASSPATH"), - Files.exists(standardFunctionJarPath) ? standardFunctionJarPath.toString() : null) + options.classPath, + environment.get("FUNCTION_CLASSPATH"), + Files.exists(standardFunctionJarPath) ? standardFunctionJarPath.toString() : null) .stream() .filter(Objects::nonNull) .findFirst(); ClassLoader functionClassLoader = makeClassLoader(functionClasspath); Invoker invoker = new Invoker( - port, - functionTarget, - environment.get("FUNCTION_SIGNATURE_TYPE"), - functionClassLoader); + port, functionTarget, environment.get("FUNCTION_SIGNATURE_TYPE"), functionClassLoader); return Optional.of(invoker); } private static void usage(JCommander jCommander) { StringBuilder usageBuilder = new StringBuilder(); jCommander.getUsageFormatter().usage(usageBuilder); - String usage = usageBuilder.toString() - .replace("${file.separator}", File.separator) - .replace("${path.separator}", File.pathSeparator); + String usage = + usageBuilder + .toString() + .replace("${file.separator}", File.separator) + .replace("${path.separator}", File.pathSeparator); jCommander.getConsole().println(usage); } @@ -256,10 +247,11 @@ public void startServer() throws Exception { servlet = BackgroundFunctionExecutor.forClass(functionClass); break; default: - String error = String.format( - "Function signature type %s is unknown; should be \"http\", \"event\"," - + " or \"cloudevent\"", - functionSignatureType); + String error = + String.format( + "Function signature type %s is unknown; should be \"http\", \"event\"," + + " or \"cloudevent\"", + functionSignatureType); throw new RuntimeException(error); } } @@ -303,12 +295,13 @@ private HttpServlet servletForDeducedSignatureType(Class functionClass) { if (maybeExecutor.isPresent()) { return maybeExecutor.get(); } - String error = String.format( - "Could not determine function signature type from target %s. Either this should be" - + " a class implementing one of the interfaces in com.google.cloud.functions, or the" - + " environment variable FUNCTION_SIGNATURE_TYPE should be set to \"http\" or" - + " \"event\".", - functionTarget); + String error = + String.format( + "Could not determine function signature type from target %s. Either this should be a" + + " class implementing one of the interfaces in com.google.cloud.functions, or the" + + " environment variable FUNCTION_SIGNATURE_TYPE should be set to \"http\" or" + + " \"event\".", + functionTarget); throw new RuntimeException(error); } @@ -343,13 +336,14 @@ private static List jarsIn(String dir) { } return stream .filter(p -> p.getFileName().toString().endsWith(".jar")) - .map(p -> { - try { - return p.toUri().toURL(); - } catch (MalformedURLException e) { - throw new UncheckedIOException(e); - } - }) + .map( + p -> { + try { + return p.toUri().toURL(); + } catch (MalformedURLException e) { + throw new UncheckedIOException(e); + } + }) .collect(toList()); } @@ -369,9 +363,9 @@ private static boolean isGcf() { /** * Wrapper that intercepts requests for {@code /favicon.ico} and {@code /robots.txt} and causes - * them to produce a 404 status. Otherwise they would be sent to the function code, like any - * other URL, meaning that someone testing their function by using a browser as an HTTP client - * can see two requests, one for {@code /favicon.ico} and one for {@code /} (or whatever). + * them to produce a 404 status. Otherwise they would be sent to the function code, like any other + * URL, meaning that someone testing their function by using a browser as an HTTP client can see + * two requests, one for {@code /favicon.ico} and one for {@code /} (or whatever). */ private static class NotFoundHandler extends HandlerWrapper { static NotFoundHandler forServlet(ServletContextHandler servletHandler) { @@ -384,8 +378,12 @@ static NotFoundHandler forServlet(ServletContextHandler servletHandler) { new HashSet<>(Arrays.asList("/favicon.ico", "/robots.txt")); @Override - public void handle(String target, Request baseRequest, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException { + public void handle( + String target, + Request baseRequest, + HttpServletRequest request, + HttpServletResponse response) + throws IOException, ServletException { if (NOT_FOUND_PATHS.contains(request.getRequestURI())) { response.sendError(HttpStatus.NOT_FOUND_404, "Not Found"); } @@ -394,17 +392,17 @@ public void handle(String target, Request baseRequest, HttpServletRequest reques } /** - * A loader that only loads GCF API classes. Those are classes whose package is exactly - * {@code com.google.cloud.functions}. The package can't be a subpackage, such as - * {@code com.google.cloud.functions.invoker}. + * A loader that only loads GCF API classes. Those are classes whose package is exactly {@code + * com.google.cloud.functions}. The package can't be a subpackage, such as {@code + * com.google.cloud.functions.invoker}. * - *

This loader allows us to load the classes from a user function, without making the - * runtime classes visible to them. We will make this loader the parent of the - * {@link URLClassLoader} that loads the user code in order to filter out those runtime classes. + *

This loader allows us to load the classes from a user function, without making the runtime + * classes visible to them. We will make this loader the parent of the {@link URLClassLoader} that + * loads the user code in order to filter out those runtime classes. * *

The reason we do need to share the API classes between the runtime and the user function is - * so that the runtime can instantiate the function class and cast it to - * {@link com.google.cloud.functions.HttpFunction} or whatever. + * so that the runtime can instantiate the function class and cast it to {@link + * com.google.cloud.functions.HttpFunction} or whatever. */ private static class OnlyApiClassLoader extends ClassLoader { private final ClassLoader runtimeClassLoader; @@ -418,8 +416,8 @@ private static class OnlyApiClassLoader extends ClassLoader { protected Class findClass(String name) throws ClassNotFoundException { String prefix = "com.google.cloud.functions."; if ((name.startsWith(prefix) && Character.isUpperCase(name.charAt(prefix.length()))) - || name.startsWith("javax.servlet.") - || isCloudEventsApiClass(name)) { + || name.startsWith("javax.servlet.") + || isCloudEventsApiClass(name)) { return runtimeClassLoader.loadClass(name); } return super.findClass(name); // should throw ClassNotFoundException diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/GcfEventsTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/GcfEventsTest.java index 21e7016c..24939fff 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/GcfEventsTest.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/GcfEventsTest.java @@ -40,27 +40,60 @@ public class GcfEventsTest { @Rule public Expect expect = Expect.create(); private static final String[][] EVENT_DATA = { - {"storage.json", "google.cloud.storage.object.v1.finalized", - "//storage.googleapis.com/projects/_/buckets/some-bucket", "objects/folder/Test.cs"}, - {"legacy_storage_change.json", "google.cloud.storage.object.v1.changed", - "//storage.googleapis.com/projects/_/buckets/sample-bucket", "objects/MyFile"}, - {"firestore_simple.json", "google.cloud.firestore.document.v1.written", + { + "storage.json", + "google.cloud.storage.object.v1.finalized", + "//storage.googleapis.com/projects/_/buckets/some-bucket", + "objects/folder/Test.cs" + }, + { + "legacy_storage_change.json", + "google.cloud.storage.object.v1.changed", + "//storage.googleapis.com/projects/_/buckets/sample-bucket", + "objects/MyFile" + }, + { + "firestore_simple.json", + "google.cloud.firestore.document.v1.written", "//firestore.googleapis.com/projects/project-id/databases/(default)", - "documents/gcf-test/2Vm2mI1d0wIaK2Waj5to"}, - {"pubsub_text.json", "google.cloud.pubsub.topic.v1.messagePublished", - "//pubsub.googleapis.com/projects/sample-project/topics/gcf-test", null}, - {"legacy_pubsub.json", "google.cloud.pubsub.topic.v1.messagePublished", - "//pubsub.googleapis.com/projects/sample-project/topics/gcf-test", null}, - {"firebase-db1.json", "google.firebase.database.ref.v1.written", + "documents/gcf-test/2Vm2mI1d0wIaK2Waj5to" + }, + { + "pubsub_text.json", + "google.cloud.pubsub.topic.v1.messagePublished", + "//pubsub.googleapis.com/projects/sample-project/topics/gcf-test", + null + }, + { + "legacy_pubsub.json", + "google.cloud.pubsub.topic.v1.messagePublished", + "//pubsub.googleapis.com/projects/sample-project/topics/gcf-test", + null + }, + { + "firebase-db1.json", + "google.firebase.database.ref.v1.written", "//firebasedatabase.googleapis.com/projects/_/locations/us-central1/instances/my-project-id", - "refs/gcf-test/xyz"}, - {"firebase-db2.json", "google.firebase.database.ref.v1.written", + "refs/gcf-test/xyz" + }, + { + "firebase-db2.json", + "google.firebase.database.ref.v1.written", "//firebasedatabase.googleapis.com/projects/_/locations/europe-west1/instances/my-project-id", - "refs/gcf-test/xyz"}, - {"firebase-auth1.json", "google.firebase.auth.user.v1.created", - "//firebaseauth.googleapis.com/projects/my-project-id", "users/UUpby3s4spZre6kHsgVSPetzQ8l2"}, - {"firebase-auth2.json", "google.firebase.auth.user.v1.deleted", - "//firebaseauth.googleapis.com/projects/my-project-id", "users/UUpby3s4spZre6kHsgVSPetzQ8l2"}, + "refs/gcf-test/xyz" + }, + { + "firebase-auth1.json", + "google.firebase.auth.user.v1.created", + "//firebaseauth.googleapis.com/projects/my-project-id", + "users/UUpby3s4spZre6kHsgVSPetzQ8l2" + }, + { + "firebase-auth2.json", + "google.firebase.auth.user.v1.deleted", + "//firebaseauth.googleapis.com/projects/my-project-id", + "users/UUpby3s4spZre6kHsgVSPetzQ8l2" + }, }; @Test @@ -71,7 +104,8 @@ public void convertGcfEvent() throws IOException { } } - private void convertGcfEvent(Event legacyEvent, String expectedType, String expectedSource, String expectedSubject) { + private void convertGcfEvent( + Event legacyEvent, String expectedType, String expectedSource, String expectedSubject) { CloudEvent cloudEvent = GcfEvents.convertToCloudEvent(legacyEvent); expect.that(cloudEvent.getType()).isEqualTo(expectedType); expect.that(cloudEvent.getSource().toString()).isEqualTo(expectedSource); @@ -95,11 +129,15 @@ public void checkAllProperties() throws IOException { assertThat(cloudEvent.getDataSchema()).isNull(); } - // The next set of tests checks the result of using Gson to deserialize the JSON "data" field of the - // CloudEvent that we get from converting a legacy event. For the most part we're not testing much here, - // since the "data" field is essentially copied from the input legacy event. In some cases we adjust it, + // The next set of tests checks the result of using Gson to deserialize the JSON "data" field of + // the + // CloudEvent that we get from converting a legacy event. For the most part we're not testing much + // here, + // since the "data" field is essentially copied from the input legacy event. In some cases we + // adjust it, // though. - // Later, when we have support for handling these types properly in Java, we can change the tests to use + // Later, when we have support for handling these types properly in Java, we can change the tests + // to use // that. See https://github.com/googleapis/google-cloudevents-java @Test @@ -107,12 +145,13 @@ public void storageData() throws IOException { Event legacyEvent = legacyEventForResource("storage.json"); CloudEvent cloudEvent = GcfEvents.convertToCloudEvent(legacyEvent); Map data = cloudEventDataJson(cloudEvent); - assertThat(data).containsAtLeast( - "bucket", "some-bucket", - "timeCreated", "2020-04-23T07:38:57.230Z", - "generation", "1587627537231057", - "metageneration", "1", - "size", "352"); + assertThat(data) + .containsAtLeast( + "bucket", "some-bucket", + "timeCreated", "2020-04-23T07:38:57.230Z", + "generation", "1587627537231057", + "metageneration", "1", + "size", "352"); } @Test @@ -120,26 +159,33 @@ public void firestoreSimpleData() throws IOException { Event legacyEvent = legacyEventForResource("firestore_simple.json"); CloudEvent cloudEvent = GcfEvents.convertToCloudEvent(legacyEvent); Map data = cloudEventDataJson(cloudEvent); - Map expectedValue = Map.of( - "name", "projects/project-id/databases/(default)/documents/gcf-test/2Vm2mI1d0wIaK2Waj5to", - "createTime", "2020-04-23T09:58:53.211035Z", - "updateTime", "2020-04-23T12:00:27.247187Z", - "fields", Map.of( - "another test", Map.of("stringValue", "asd"), - "count", Map.of("integerValue", "4"), - "foo", Map.of("stringValue", "bar"))); - Map expectedOldValue = Map.of( - "name", "projects/project-id/databases/(default)/documents/gcf-test/2Vm2mI1d0wIaK2Waj5to", - "createTime", "2020-04-23T09:58:53.211035Z", - "updateTime", "2020-04-23T12:00:27.247187Z", - "fields", Map.of( - "another test", Map.of("stringValue", "asd"), - "count", Map.of("integerValue", "3"), - "foo", Map.of("stringValue", "bar"))); - assertThat(data).containsAtLeast( - "value", expectedValue, - "oldValue", expectedOldValue, - "updateMask", Map.of("fieldPaths", List.of("count"))); + Map expectedValue = + Map.of( + "name", + "projects/project-id/databases/(default)/documents/gcf-test/2Vm2mI1d0wIaK2Waj5to", + "createTime", "2020-04-23T09:58:53.211035Z", + "updateTime", "2020-04-23T12:00:27.247187Z", + "fields", + Map.of( + "another test", Map.of("stringValue", "asd"), + "count", Map.of("integerValue", "4"), + "foo", Map.of("stringValue", "bar"))); + Map expectedOldValue = + Map.of( + "name", + "projects/project-id/databases/(default)/documents/gcf-test/2Vm2mI1d0wIaK2Waj5to", + "createTime", "2020-04-23T09:58:53.211035Z", + "updateTime", "2020-04-23T12:00:27.247187Z", + "fields", + Map.of( + "another test", Map.of("stringValue", "asd"), + "count", Map.of("integerValue", "3"), + "foo", Map.of("stringValue", "bar"))); + assertThat(data) + .containsAtLeast( + "value", expectedValue, + "oldValue", expectedOldValue, + "updateMask", Map.of("fieldPaths", List.of("count"))); } @Test @@ -149,26 +195,42 @@ public void firestoreComplexData() throws IOException { Map data = cloudEventDataJson(cloudEvent); Map value = (Map) data.get("value"); Map fields = (Map) value.get("fields"); - Map expectedFields = Map.of( - "arrayValue", Map.of("arrayValue", - Map.of("values", - List.of(Map.of("integerValue", "1"), Map.of("integerValue", "2")))), - "booleanValue", Map.of("booleanValue", true), - "geoPointValue", Map.of("geoPointValue", Map.of("latitude", 51.4543, "longitude", -0.9781)), - "intValue", Map.of("integerValue", "50"), - "doubleValue", Map.of("doubleValue", 5.5), - "nullValue", Collections.singletonMap("nullValue", null), - "referenceValue", Map.of("referenceValue", - "projects/project-id/databases/(default)/documents/foo/bar/baz/qux"), - "stringValue", Map.of("stringValue", "text"), - "timestampValue", Map.of("timestampValue", "2020-04-23T14:23:53.241Z"), - "mapValue", Map.of("mapValue", - Map.of("fields", - Map.of("field1", Map.of("stringValue", "x"), - "field2", Map.of("arrayValue", - Map.of("values", - List.of(Map.of("stringValue", "x"), Map.of("integerValue", "1"))))))) - ); + Map expectedFields = + Map.of( + "arrayValue", + Map.of( + "arrayValue", + Map.of( + "values", + List.of(Map.of("integerValue", "1"), Map.of("integerValue", "2")))), + "booleanValue", Map.of("booleanValue", true), + "geoPointValue", + Map.of("geoPointValue", Map.of("latitude", 51.4543, "longitude", -0.9781)), + "intValue", Map.of("integerValue", "50"), + "doubleValue", Map.of("doubleValue", 5.5), + "nullValue", Collections.singletonMap("nullValue", null), + "referenceValue", + Map.of( + "referenceValue", + "projects/project-id/databases/(default)/documents/foo/bar/baz/qux"), + "stringValue", Map.of("stringValue", "text"), + "timestampValue", Map.of("timestampValue", "2020-04-23T14:23:53.241Z"), + "mapValue", + Map.of( + "mapValue", + Map.of( + "fields", + Map.of( + "field1", + Map.of("stringValue", "x"), + "field2", + Map.of( + "arrayValue", + Map.of( + "values", + List.of( + Map.of("stringValue", "x"), + Map.of("integerValue", "1")))))))); assertThat(fields).containsExactlyEntriesIn(expectedFields); } @@ -213,16 +275,19 @@ public void pubSubWrapping() throws IOException { Event legacyEvent = legacyEventForResource("legacy_pubsub.json"); CloudEvent cloudEvent = GcfEvents.convertToCloudEvent(legacyEvent); assertThat(new String(cloudEvent.getData().toBytes(), UTF_8)) - .isEqualTo("{\"message\":{\"@type\":\"type.googleapis.com/google.pubsub.v1.PubsubMessage\"," - + "\"attributes\":{\"attribute1\":\"value1\"}," - + "\"data\":\"VGhpcyBpcyBhIHNhbXBsZSBtZXNzYWdl\"," - + "\"messageId\":\"1215011316659232\"," - + "\"publishTime\":\"2020-05-18T12:13:19.209Z\"}}"); + .isEqualTo( + "{\"message\":{\"@type\":\"type.googleapis.com/google.pubsub.v1.PubsubMessage\"," + + "\"attributes\":{\"attribute1\":\"value1\"}," + + "\"data\":\"VGhpcyBpcyBhIHNhbXBsZSBtZXNzYWdl\"," + + "\"messageId\":\"1215011316659232\"," + + "\"publishTime\":\"2020-05-18T12:13:19.209Z\"}}"); } - // Checks that a Firestore event correctly gets an extra "wildcards" property in its CloudEvent data + // Checks that a Firestore event correctly gets an extra "wildcards" property in its CloudEvent + // data // reflecting the "params" field in the legacy event. - // This test is currently ignored because the final representation of the "params" field is in flux. + // This test is currently ignored because the final representation of the "params" field is in + // flux. @Test @Ignore public void firestoreWildcards() throws IOException { diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java index 051358f8..7a2bee14 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java @@ -96,7 +96,9 @@ private static String sampleLegacyEvent(File snoopFile) { + " \"data\": {\n" + " \"a\": 2,\n" + " \"b\": 3,\n" - + " \"targetFile\": \"" + snoopFile + "\"" + + " \"targetFile\": \"" + + snoopFile + + "\"" + " },\n" + " \"context\": {\n" + " \"eventId\": \"B234-1234-1234\",\n" @@ -241,7 +243,8 @@ private static String fullTarget(String nameWithoutPackage) { @Test public void helloWorld() throws Exception { - testHttpFunction(fullTarget("HelloWorld"), + testHttpFunction( + fullTarget("HelloWorld"), ImmutableList.of( TestCase.builder().setExpectedResponseText("hello\n").build(), FAVICON_TEST_CASE, @@ -265,7 +268,6 @@ public void exceptionHttp() throws Exception { .build())); } - @Test public void exceptionBackground() throws Exception { String exceptionExpectedOutput = @@ -312,9 +314,10 @@ public void echo() throws Exception { @Test public void echoUrl() throws Exception { String[] testUrls = {"/", "/foo/bar", "/?foo=bar&baz=buh", "/foo?bar=baz"}; - List testCases = Arrays.stream(testUrls) - .map(url -> TestCase.builder().setUrl(url).setExpectedResponseText(url + "\n").build()) - .collect(toList()); + List testCases = + Arrays.stream(testUrls) + .map(url -> TestCase.builder().setUrl(url).setExpectedResponseText(url + "\n").build()) + .collect(toList()); testHttpFunction(fullTarget("EchoUrl"), testCases); } @@ -327,10 +330,7 @@ public void stackDriverLogging() throws Exception { + " \"method\": \"service\"}," + " \"message\": \"blim\"}"; TestCase simpleTestCase = - TestCase.builder() - .setUrl("/?message=blim") - .setExpectedOutput(simpleExpectedOutput) - .build(); + TestCase.builder().setUrl("/?message=blim").setExpectedOutput(simpleExpectedOutput).build(); String quotingExpectedOutput = "\"message\": \"foo\\nbar\\\""; TestCase quotingTestCase = TestCase.builder() @@ -362,7 +362,8 @@ private static int getJavaVersion() { if (dot != -1) { version = version.substring(0, dot); } - } return Integer.parseInt(version); + } + return Integer.parseInt(version); } @Test @@ -387,27 +388,31 @@ private void backgroundTest(String target) throws Exception { JsonObject expectedJson = new Gson().fromJson(gcfRequestText, JsonObject.class); // We don't currently put anything in the attributes() map for legacy events. expectedJson.add("attributes", new JsonObject()); - TestCase gcfTestCase = TestCase.builder() - .setRequestText(gcfRequestText) - .setSnoopFile(snoopFile) - .setExpectedJson(expectedJson) - .build(); + TestCase gcfTestCase = + TestCase.builder() + .setRequestText(gcfRequestText) + .setSnoopFile(snoopFile) + .setExpectedJson(expectedJson) + .build(); // A CloudEvent using the "structured content mode", where both the metadata and the payload // are in the body of the HTTP request. - EventFormat jsonFormat = EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE); - String cloudEventRequestText = new String(jsonFormat.serialize(sampleCloudEvent(snoopFile)), UTF_8); + EventFormat jsonFormat = + EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE); + String cloudEventRequestText = + new String(jsonFormat.serialize(sampleCloudEvent(snoopFile)), UTF_8); // For CloudEvents, we don't currently populate Context#getResource with anything interesting, // so we excise that from the expected text we would have with legacy events. JsonObject cloudEventExpectedJson = new Gson().fromJson(gcfRequestText, JsonObject.class); cloudEventExpectedJson.getAsJsonObject("context").add("resource", new JsonObject()); cloudEventExpectedJson.add("attributes", expectedCloudEventAttributes()); - TestCase cloudEventsStructuredTestCase = TestCase.builder() - .setSnoopFile(snoopFile) - .setRequestText(cloudEventRequestText) - .setHttpContentType("application/cloudevents+json; charset=utf-8") - .setExpectedJson(cloudEventExpectedJson) - .build(); + TestCase cloudEventsStructuredTestCase = + TestCase.builder() + .setSnoopFile(snoopFile) + .setRequestText(cloudEventRequestText) + .setHttpContentType("application/cloudevents+json; charset=utf-8") + .setExpectedJson(cloudEventExpectedJson) + .build(); // A CloudEvent using the "binary content mode", where the metadata is in HTTP headers and the // payload is the body of the HTTP request. @@ -415,13 +420,14 @@ private void backgroundTest(String target) throws Exception { AtomicReference bodyRef = new AtomicReference<>(); HttpMessageFactory.createWriter(headers::put, bodyRef::set) .writeBinary(sampleCloudEvent(snoopFile)); - TestCase cloudEventsBinaryTestCase = TestCase.builder() - .setSnoopFile(snoopFile) - .setRequestText(new String(bodyRef.get(), UTF_8)) - .setHttpContentType(headers.get("Content-Type")) - .setHttpHeaders(ImmutableMap.copyOf(headers)) - .setExpectedJson(cloudEventExpectedJson) - .build(); + TestCase cloudEventsBinaryTestCase = + TestCase.builder() + .setSnoopFile(snoopFile) + .setRequestText(new String(bodyRef.get(), UTF_8)) + .setHttpContentType(headers.get("Content-Type")) + .setHttpHeaders(ImmutableMap.copyOf(headers)) + .setExpectedJson(cloudEventExpectedJson) + .build(); backgroundTest( SignatureType.BACKGROUND, @@ -429,23 +435,27 @@ private void backgroundTest(String target) throws Exception { ImmutableList.of(gcfTestCase, cloudEventsStructuredTestCase, cloudEventsBinaryTestCase)); } - /** Tests a CloudEvent being handled by a CloudEvent handler (no translation to or from legacy). */ + /** + * Tests a CloudEvent being handled by a CloudEvent handler (no translation to or from legacy). + */ @Test public void nativeCloudEvent() throws Exception { File snoopFile = snoopFile(); CloudEvent cloudEvent = sampleCloudEvent(snoopFile); - EventFormat jsonFormat = EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE); + EventFormat jsonFormat = + EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE); String cloudEventJson = new String(jsonFormat.serialize(cloudEvent), UTF_8); // A CloudEvent using the "structured content mode", where both the metadata and the payload // are in the body of the HTTP request. JsonObject cloudEventJsonObject = new Gson().fromJson(cloudEventJson, JsonObject.class); - TestCase cloudEventsStructuredTestCase = TestCase.builder() - .setSnoopFile(snoopFile) - .setRequestText(cloudEventJson) - .setHttpContentType("application/cloudevents+json; charset=utf-8") - .setExpectedJson(cloudEventJsonObject) - .build(); + TestCase cloudEventsStructuredTestCase = + TestCase.builder() + .setSnoopFile(snoopFile) + .setRequestText(cloudEventJson) + .setHttpContentType("application/cloudevents+json; charset=utf-8") + .setExpectedJson(cloudEventJsonObject) + .build(); // A CloudEvent using the "binary content mode", where the metadata is in HTTP headers and the // payload is the body of the HTTP request. @@ -453,13 +463,14 @@ public void nativeCloudEvent() throws Exception { AtomicReference bodyRef = new AtomicReference<>(); HttpMessageFactory.createWriter(headers::put, bodyRef::set) .writeBinary(sampleCloudEvent(snoopFile)); - TestCase cloudEventsBinaryTestCase = TestCase.builder() - .setSnoopFile(snoopFile) - .setRequestText(new String(bodyRef.get(), UTF_8)) - .setHttpContentType(headers.get("Content-Type")) - .setHttpHeaders(ImmutableMap.copyOf(headers)) - .setExpectedJson(cloudEventJsonObject) - .build(); + TestCase cloudEventsBinaryTestCase = + TestCase.builder() + .setSnoopFile(snoopFile) + .setRequestText(new String(bodyRef.get(), UTF_8)) + .setHttpContentType(headers.get("Content-Type")) + .setHttpHeaders(ImmutableMap.copyOf(headers)) + .setExpectedJson(cloudEventJsonObject) + .build(); backgroundTest( SignatureType.CLOUD_EVENT, @@ -478,7 +489,8 @@ public void nested() throws Exception { @Test public void packageless() throws Exception { - testHttpFunction("PackagelessHelloWorld", + testHttpFunction( + "PackagelessHelloWorld", ImmutableList.of(TestCase.builder().setExpectedResponseText("hello, world\n").build())); } @@ -489,8 +501,9 @@ public void multipart() throws Exception { multiPartProvider.addFieldPart("bytes", new BytesContentProvider(bytes), new HttpFields()); String string = "1234567890"; multiPartProvider.addFieldPart("string", new StringContentProvider(string), new HttpFields()); - String expectedResponse = "part bytes type application/octet-stream length 17\n" - + "part string type text/plain;charset=UTF-8 length 10\n"; + String expectedResponse = + "part bytes type application/octet-stream length 17\n" + + "part string type text/plain;charset=UTF-8 length 10\n"; testHttpFunction( fullTarget("Multipart"), ImmutableList.of( @@ -512,13 +525,15 @@ private String functionJarString() throws IOException { Path functionJarTargetDir = Paths.get("../testfunction/target"); Pattern functionJarPattern = Pattern.compile("java-function-invoker-testfunction-.*-tests\\.jar"); - List functionJars = Files.list(functionJarTargetDir) - .map(path -> path.getFileName().toString()) - .filter(s -> functionJarPattern.matcher(s).matches()) - .map(s -> functionJarTargetDir.resolve(s)) - .collect(toList()); + List functionJars = + Files.list(functionJarTargetDir) + .map(path -> path.getFileName().toString()) + .filter(s -> functionJarPattern.matcher(s).matches()) + .map(s -> functionJarTargetDir.resolve(s)) + .collect(toList()); assertWithMessage("Number of jars in %s matching %s", functionJarTargetDir, functionJarPattern) - .that(functionJars).hasSize(1); + .that(functionJars) + .hasSize(1); return Iterables.getOnlyElement(functionJars).toString(); } @@ -530,10 +545,11 @@ private String functionJarString() throws IOException { */ @Test public void classpathOptionHttp() throws Exception { - TestCase testCase = TestCase.builder() - .setUrl("/?class=" + INTERNAL_CLASS.getName()) - .setExpectedResponseText("OK") - .build(); + TestCase testCase = + TestCase.builder() + .setUrl("/?class=" + INTERNAL_CLASS.getName()) + .setExpectedResponseText("OK") + .build(); testFunction( SignatureType.HTTP, "com.example.functionjar.Foreground", @@ -574,9 +590,12 @@ private void backgroundTest( Gson gson = new Gson(); JsonObject snoopedJson = gson.fromJson(snooped, JsonObject.class); JsonObject expectedJson = testCase.expectedJson().get(); - expect.withMessage( - "Testing %s with %s\nGOT %s\nNOT %s", functionTarget, testCase, snoopedJson, expectedJson) - .that(snoopedJson).isEqualTo(expectedJson); + expect + .withMessage( + "Testing %s with %s\nGOT %s\nNOT %s", + functionTarget, testCase, snoopedJson, expectedJson) + .that(snoopedJson) + .isEqualTo(expectedJson); } } @@ -597,7 +616,8 @@ private void testFunction( SignatureType signatureType, String target, ImmutableList extraArgs, - List testCases) throws Exception { + List testCases) + throws Exception { ServerProcess serverProcess = startServer(signatureType, target, extraArgs); try { HttpClient httpClient = new HttpClient(); @@ -606,17 +626,21 @@ private void testFunction( testCase.snoopFile().ifPresent(File::delete); String uri = "http://localhost:" + serverPort + testCase.url(); Request request = httpClient.POST(uri); - testCase.httpContentType().ifPresent( - contentType -> request.header(HttpHeader.CONTENT_TYPE, contentType)); + testCase + .httpContentType() + .ifPresent(contentType -> request.header(HttpHeader.CONTENT_TYPE, contentType)); testCase.httpHeaders().forEach((header, value) -> request.header(header, value)); request.content(testCase.requestContent()); ContentResponse response = request.send(); expect .withMessage("Response to %s is %s %s", uri, response.getStatus(), response.getReason()) - .that(response.getStatus()).isEqualTo(testCase.expectedResponseCode()); - testCase.expectedResponseText() + .that(response.getStatus()) + .isEqualTo(testCase.expectedResponseCode()); + testCase + .expectedResponseText() .ifPresent(text -> expect.that(response.getContentAsString()).isEqualTo(text)); - testCase.expectedContentType() + testCase + .expectedContentType() .ifPresent(type -> expect.that(response.getMediaType()).isEqualTo(type)); if (testCase.snoopFile().isPresent()) { checkSnoopFile(testCase); @@ -626,7 +650,8 @@ private void testFunction( serverProcess.close(); } for (TestCase testCase : testCases) { - testCase.expectedOutput() + testCase + .expectedOutput() .ifPresent(output -> expect.that(serverProcess.output()).contains(output)); } // Wait for the output monitor task to terminate. If it threw an exception, we will get an @@ -697,23 +722,28 @@ private ServerProcess startServer( assertThat(javaCommand.exists()).isTrue(); String myClassPath = System.getProperty("java.class.path"); assertThat(myClassPath).isNotNull(); - ImmutableList command = ImmutableList.builder() - .add(javaCommand.toString(), "-classpath", myClassPath, Invoker.class.getName()) - .addAll(extraArgs) - .build(); - ProcessBuilder processBuilder = new ProcessBuilder() - .command(command) - .redirectErrorStream(true); - Map environment = ImmutableMap.of("PORT", String.valueOf(serverPort), - "K_SERVICE", "test-function", - "FUNCTION_SIGNATURE_TYPE", signatureType.toString(), - "FUNCTION_TARGET", target); + ImmutableList command = + ImmutableList.builder() + .add(javaCommand.toString(), "-classpath", myClassPath, Invoker.class.getName()) + .addAll(extraArgs) + .build(); + ProcessBuilder processBuilder = new ProcessBuilder().command(command).redirectErrorStream(true); + Map environment = + ImmutableMap.of( + "PORT", + String.valueOf(serverPort), + "K_SERVICE", + "test-function", + "FUNCTION_SIGNATURE_TYPE", + signatureType.toString(), + "FUNCTION_TARGET", + target); processBuilder.environment().putAll(environment); Process serverProcess = processBuilder.start(); CountDownLatch ready = new CountDownLatch(1); StringBuilder output = new StringBuilder(); - Future outputMonitorResult = EXECUTOR.submit( - () -> monitorOutput(serverProcess.getInputStream(), ready, output)); + Future outputMonitorResult = + EXECUTOR.submit(() -> monitorOutput(serverProcess.getInputStream(), ready, output)); boolean serverReady = ready.await(5, TimeUnit.SECONDS); if (!serverReady) { serverProcess.destroy(); diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/http/HttpTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/http/HttpTest.java index 12d98090..9ef51b2a 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/http/HttpTest.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/http/HttpTest.java @@ -63,6 +63,7 @@ public class HttpTest { + "To marry two wives at a time.\n"; private static final byte[] RANDOM_BYTES = new byte[1024]; + static { new Random().nextBytes(RANDOM_BYTES); } @@ -111,10 +112,10 @@ private interface HttpRequestTest { } /** - * Tests methods on the {@link HttpRequest} object while the request is being serviced. We are - * not guaranteed that the underlying {@link HttpServletRequest} object will still be valid when - * the request completes, and in fact in Jetty it isn't. So we perform the checks in the context - * of the servlet, and report any exception back to the test method. + * Tests methods on the {@link HttpRequest} object while the request is being serviced. We are not + * guaranteed that the underlying {@link HttpServletRequest} object will still be valid when the + * request completes, and in fact in Jetty it isn't. So we perform the checks in the context of + * the servlet, and report any exception back to the test method. */ @Test public void httpRequestMethods() throws Exception { @@ -133,66 +134,70 @@ private void httpRequestMethods( httpClient.start(); String uri = "http://localhost:" + serverPort + "/foo/bar?baz=buh&baz=xxx&blim=blam&baz=what"; HttpRequestTest[] tests = { - request -> assertThat(request.getMethod()).isEqualTo("POST"), - request -> assertThat(request.getMethod()).isEqualTo("POST"), - request -> assertThat(request.getUri()).isEqualTo(uri), - request -> assertThat(request.getPath()).isEqualTo("/foo/bar"), - request -> assertThat(request.getQuery()).hasValue("baz=buh&baz=xxx&blim=blam&baz=what"), - request -> { - Map> expectedQueryParameters = new TreeMap<>(); - expectedQueryParameters.put("baz", Arrays.asList("buh", "xxx", "what")); - expectedQueryParameters.put("blim", Arrays.asList("blam")); - assertThat(request.getQueryParameters()).isEqualTo(expectedQueryParameters); - }, - request -> assertThat(request.getFirstQueryParameter("baz")).hasValue("buh"), - request -> assertThat(request.getFirstQueryParameter("something")).isEmpty(), - request -> assertThat(request.getContentType().get()).ignoringCase() - .isEqualTo("text/plain; charset=utf-8"), - request -> assertThat(request.getContentLength()).isEqualTo(TEST_BODY.length()), - request -> assertThat(request.getCharacterEncoding()).isPresent(), - request -> assertThat(request.getCharacterEncoding().get()).ignoringCase() - .isEqualTo("utf-8"), - request -> { - try (BufferedReader reader = request.getReader()) { - validateReader(reader); - assertThat(request.getReader()).isSameInstanceAs(reader); - } - try { - request.getInputStream(); - fail("Did not get expected exception"); - } catch (IllegalStateException expected) { - } - }, - request -> { - try (InputStream inputStream = request.getInputStream(); - BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { - validateReader(reader); - assertThat(request.getInputStream()).isSameInstanceAs(inputStream); - } - }, - request -> { - Map> expectedHeaders = new TreeMap<>(); - expectedHeaders.put(HttpHeader.CONTENT_LENGTH.asString(), - Arrays.asList(String.valueOf(TEST_BODY.length()))); - expectedHeaders.put("foo", Arrays.asList("bar", "baz")); - assertThat(request.getHeaders()).containsAtLeastEntriesIn(expectedHeaders); - }, - request -> assertThat(request.getFirstHeader("foo")).hasValue("bar"), - request -> { - try { - request.getParts(); - fail("Did not get expected exception"); - } catch (IllegalStateException expected) { - } + request -> assertThat(request.getMethod()).isEqualTo("POST"), + request -> assertThat(request.getMethod()).isEqualTo("POST"), + request -> assertThat(request.getUri()).isEqualTo(uri), + request -> assertThat(request.getPath()).isEqualTo("/foo/bar"), + request -> assertThat(request.getQuery()).hasValue("baz=buh&baz=xxx&blim=blam&baz=what"), + request -> { + Map> expectedQueryParameters = new TreeMap<>(); + expectedQueryParameters.put("baz", Arrays.asList("buh", "xxx", "what")); + expectedQueryParameters.put("blim", Arrays.asList("blam")); + assertThat(request.getQueryParameters()).isEqualTo(expectedQueryParameters); + }, + request -> assertThat(request.getFirstQueryParameter("baz")).hasValue("buh"), + request -> assertThat(request.getFirstQueryParameter("something")).isEmpty(), + request -> + assertThat(request.getContentType().get()) + .ignoringCase() + .isEqualTo("text/plain; charset=utf-8"), + request -> assertThat(request.getContentLength()).isEqualTo(TEST_BODY.length()), + request -> assertThat(request.getCharacterEncoding()).isPresent(), + request -> assertThat(request.getCharacterEncoding().get()).ignoringCase().isEqualTo("utf-8"), + request -> { + try (BufferedReader reader = request.getReader()) { + validateReader(reader); + assertThat(request.getReader()).isSameInstanceAs(reader); + } + try { + request.getInputStream(); + fail("Did not get expected exception"); + } catch (IllegalStateException expected) { } + }, + request -> { + try (InputStream inputStream = request.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { + validateReader(reader); + assertThat(request.getInputStream()).isSameInstanceAs(inputStream); + } + }, + request -> { + Map> expectedHeaders = new TreeMap<>(); + expectedHeaders.put( + HttpHeader.CONTENT_LENGTH.asString(), + Arrays.asList(String.valueOf(TEST_BODY.length()))); + expectedHeaders.put("foo", Arrays.asList("bar", "baz")); + assertThat(request.getHeaders()).containsAtLeastEntriesIn(expectedHeaders); + }, + request -> assertThat(request.getFirstHeader("foo")).hasValue("bar"), + request -> { + try { + request.getParts(); + fail("Did not get expected exception"); + } catch (IllegalStateException expected) { + } + } }; for (HttpRequestTest test : tests) { testReference.set(test); - Request request = httpClient.POST(uri) - .header(HttpHeader.CONTENT_TYPE, "text/plain; charset=utf-8") - .header("foo", "bar") - .header("foo", "baz") - .content(new StringContentProvider(TEST_BODY)); + Request request = + httpClient + .POST(uri) + .header(HttpHeader.CONTENT_TYPE, "text/plain; charset=utf-8") + .header("foo", "bar") + .header("foo", "baz") + .content(new StringContentProvider(TEST_BODY)); ContentResponse response = request.send(); assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200); throwIfNotNull(exceptionReference.get()); @@ -204,14 +209,15 @@ public void emptyRequest() throws Exception { HttpClient httpClient = new HttpClient(); httpClient.start(); String uri = "http://localhost:" + serverPort; - HttpRequestTest test = request -> { - assertThat(request.getUri()).isEqualTo(uri + "/"); - assertThat(request.getPath()).isEqualTo("/"); - assertThat(request.getQuery()).isEmpty(); - assertThat(request.getQueryParameters()).isEmpty(); - assertThat(request.getContentType()).isEmpty(); - assertThat(request.getContentLength()).isEqualTo(0L); - }; + HttpRequestTest test = + request -> { + assertThat(request.getUri()).isEqualTo(uri + "/"); + assertThat(request.getPath()).isEqualTo("/"); + assertThat(request.getQuery()).isEmpty(); + assertThat(request.getQueryParameters()).isEmpty(); + assertThat(request.getContentType()).isEmpty(); + assertThat(request.getContentLength()).isEqualTo(0L); + }; AtomicReference exceptionReference = new AtomicReference<>(); AtomicReference testReference = new AtomicReference<>(test); HttpRequestServlet testServlet = new HttpRequestServlet(testReference, exceptionReference); @@ -245,39 +251,38 @@ public void multiPartRequest() throws Exception { assertThat(bytesHttpFields.getValuesList("foo")).containsExactly("baz", "buh"); multiPart.addFilePart( "binary", "/tmp/binary.x", new BytesContentProvider(RANDOM_BYTES), bytesHttpFields); - HttpRequestTest test = request -> { - // The Content-Type header will also have a boundary=something attribute. - assertThat(request.getContentType().get()).startsWith("multipart/form-data"); - assertThat(request.getParts().keySet()).containsExactly("text", "binary"); - HttpPart textPart = request.getParts().get("text"); - assertThat(textPart.getFileName()).isEmpty(); - assertThat(textPart.getContentLength()).isEqualTo(TEST_BODY.length()); - assertThat(textPart.getContentType().get()).startsWith("text/plain"); - assertThat(textPart.getCharacterEncoding()).isPresent(); - assertThat(textPart.getCharacterEncoding().get()).ignoringCase().isEqualTo("utf-8"); - assertThat(textPart.getHeaders()).containsAtLeast("foo", Arrays.asList("bar")); - assertThat(textPart.getFirstHeader("foo")).hasValue("bar"); - validateReader(textPart.getReader()); - HttpPart bytesPart = request.getParts().get("binary"); - assertThat(bytesPart.getFileName()).hasValue("/tmp/binary.x"); - assertThat(bytesPart.getContentLength()).isEqualTo(RANDOM_BYTES.length); - assertThat(bytesPart.getContentType()).hasValue("application/octet-stream"); - // We only see ["buh"] here, not ["baz", "buh"], apparently due to a Jetty bug. - // Repeated headers on multi-part content are not a big problem anyway. - List foos = bytesPart.getHeaders().get("foo"); - assertThat(foos).contains("buh"); - byte[] bytes = new byte[RANDOM_BYTES.length]; - try (InputStream inputStream = bytesPart.getInputStream()) { - assertThat(inputStream.read(bytes)).isEqualTo(bytes.length); - assertThat(inputStream.read()).isEqualTo(-1); - assertThat(bytes).isEqualTo(RANDOM_BYTES); - } - }; + HttpRequestTest test = + request -> { + // The Content-Type header will also have a boundary=something attribute. + assertThat(request.getContentType().get()).startsWith("multipart/form-data"); + assertThat(request.getParts().keySet()).containsExactly("text", "binary"); + HttpPart textPart = request.getParts().get("text"); + assertThat(textPart.getFileName()).isEmpty(); + assertThat(textPart.getContentLength()).isEqualTo(TEST_BODY.length()); + assertThat(textPart.getContentType().get()).startsWith("text/plain"); + assertThat(textPart.getCharacterEncoding()).isPresent(); + assertThat(textPart.getCharacterEncoding().get()).ignoringCase().isEqualTo("utf-8"); + assertThat(textPart.getHeaders()).containsAtLeast("foo", Arrays.asList("bar")); + assertThat(textPart.getFirstHeader("foo")).hasValue("bar"); + validateReader(textPart.getReader()); + HttpPart bytesPart = request.getParts().get("binary"); + assertThat(bytesPart.getFileName()).hasValue("/tmp/binary.x"); + assertThat(bytesPart.getContentLength()).isEqualTo(RANDOM_BYTES.length); + assertThat(bytesPart.getContentType()).hasValue("application/octet-stream"); + // We only see ["buh"] here, not ["baz", "buh"], apparently due to a Jetty bug. + // Repeated headers on multi-part content are not a big problem anyway. + List foos = bytesPart.getHeaders().get("foo"); + assertThat(foos).contains("buh"); + byte[] bytes = new byte[RANDOM_BYTES.length]; + try (InputStream inputStream = bytesPart.getInputStream()) { + assertThat(inputStream.read(bytes)).isEqualTo(bytes.length); + assertThat(inputStream.read()).isEqualTo(-1); + assertThat(bytes).isEqualTo(RANDOM_BYTES); + } + }; try (SimpleServer server = new SimpleServer(testServlet)) { testReference.set(test); - Request request = httpClient.POST(uri) - .header("foo", "oof") - .content(multiPart); + Request request = httpClient.POST(uri).header("foo", "oof").content(multiPart); ContentResponse response = request.send(); assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200); throwIfNotNull(exceptionReference.get()); @@ -311,9 +316,9 @@ private interface HttpResponseTest { } /** - * Tests interactions with the {@link HttpResponse} object while the request is still ongoing. - * For example, if we append a header then we should see that header in - * {@link HttpResponse#getHeaders()}. + * Tests interactions with the {@link HttpResponse} object while the request is still ongoing. For + * example, if we append a header then we should see that header in {@link + * HttpResponse#getHeaders()}. */ @Test public void httpResponseSetAndGet() throws Exception { @@ -327,31 +332,32 @@ public void httpResponseSetAndGet() throws Exception { private void httpResponseSetAndGet( AtomicReference testReference, - AtomicReference exceptionReference) throws Exception { + AtomicReference exceptionReference) + throws Exception { HttpResponseTest[] tests = { - response -> assertThat(response.getContentType()).isEmpty(), - response -> { - response.setContentType("text/plain; charset=utf-8"); - assertThat(response.getContentType().get()).matches("(?i)text/plain;\\s*charset=utf-8"); - }, - response -> { - response.appendHeader("Content-Type", "application/octet-stream"); - assertThat(response.getContentType()).hasValue("application/octet-stream"); - assertThat(response.getHeaders()) - .containsAtLeast("Content-Type", Arrays.asList("application/octet-stream")); - }, - response -> { - Map> initialHeaders = response.getHeaders(); - // The servlet spec says this should be empty, but actually we get a Date header here. - // So we just check that we can add our own headers. - response.appendHeader("foo", "bar"); - response.appendHeader("wibbly", "wobbly"); - response.appendHeader("foo", "baz"); - Map> updatedHeaders = new TreeMap<>(response.getHeaders()); - updatedHeaders.keySet().removeAll(initialHeaders.keySet()); - assertThat(updatedHeaders).containsExactly( - "foo", Arrays.asList("bar", "baz"), "wibbly", Arrays.asList("wobbly")); - }, + response -> assertThat(response.getContentType()).isEmpty(), + response -> { + response.setContentType("text/plain; charset=utf-8"); + assertThat(response.getContentType().get()).matches("(?i)text/plain;\\s*charset=utf-8"); + }, + response -> { + response.appendHeader("Content-Type", "application/octet-stream"); + assertThat(response.getContentType()).hasValue("application/octet-stream"); + assertThat(response.getHeaders()) + .containsAtLeast("Content-Type", Arrays.asList("application/octet-stream")); + }, + response -> { + Map> initialHeaders = response.getHeaders(); + // The servlet spec says this should be empty, but actually we get a Date header here. + // So we just check that we can add our own headers. + response.appendHeader("foo", "bar"); + response.appendHeader("wibbly", "wobbly"); + response.appendHeader("foo", "baz"); + Map> updatedHeaders = new TreeMap<>(response.getHeaders()); + updatedHeaders.keySet().removeAll(initialHeaders.keySet()); + assertThat(updatedHeaders) + .containsExactly("foo", Arrays.asList("bar", "baz"), "wibbly", Arrays.asList("wobbly")); + }, }; for (HttpResponseTest test : tests) { testReference.set(test); @@ -395,9 +401,7 @@ private static class ResponseTest { final HttpResponseTest responseOperation; final ResponseCheck responseCheck; - private ResponseTest( - HttpResponseTest responseOperation, - ResponseCheck responseCheck) { + private ResponseTest(HttpResponseTest responseOperation, ResponseCheck responseCheck) { this.responseOperation = responseOperation; this.responseCheck = responseCheck; } @@ -426,58 +430,59 @@ public void httpResponseEffects() throws Exception { private void httpResponseEffects( AtomicReference testReference, - AtomicReference exceptionReference) throws Exception { + AtomicReference exceptionReference) + throws Exception { ResponseTest[] tests = { - responseTest( - response -> {}, - response -> assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200)), - responseTest( - response -> response.setStatusCode(HttpStatus.OK_200), - response -> assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200)), - responseTest( - response -> response.setStatusCode(HttpStatus.IM_A_TEAPOT_418), - response -> assertThat(response.getStatus()).isEqualTo(HttpStatus.IM_A_TEAPOT_418)), - responseTest( - response -> response.setStatusCode(HttpStatus.IM_A_TEAPOT_418, "Je suis une théière"), - response -> { - assertThat(response.getStatus()).isEqualTo(HttpStatus.IM_A_TEAPOT_418); - assertThat(response.getReason()).isEqualTo("Je suis une théière"); - }), - responseTest( - response -> response.setContentType("application/noddy"), - response -> assertThat(response.getMediaType()).isEqualTo("application/noddy")), - responseTest( - response -> { - response.appendHeader("foo", "bar"); - response.appendHeader("blim", "blam"); - response.appendHeader("foo", "baz"); - }, - response -> { - assertThat(response.getHeaders().getValuesList("foo")).containsExactly("bar", "baz"); - assertThat(response.getHeaders().getValuesList("blim")).containsExactly("blam"); - }), - responseTest( - response -> { - response.setContentType("text/plain"); - try (BufferedWriter writer = response.getWriter()) { - writer.write(TEST_BODY); - } - }, - response -> { - assertThat(response.getMediaType()).isEqualTo("text/plain"); - assertThat(response.getContentAsString()).isEqualTo(TEST_BODY); - }), - responseTest( - response -> { - response.setContentType("application/octet-stream"); - try (OutputStream outputStream = response.getOutputStream()) { - outputStream.write(RANDOM_BYTES); - } - }, - response -> { - assertThat(response.getMediaType()).isEqualTo("application/octet-stream"); - assertThat(response.getContent()).isEqualTo(RANDOM_BYTES); - }), + responseTest( + response -> {}, + response -> assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200)), + responseTest( + response -> response.setStatusCode(HttpStatus.OK_200), + response -> assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200)), + responseTest( + response -> response.setStatusCode(HttpStatus.IM_A_TEAPOT_418), + response -> assertThat(response.getStatus()).isEqualTo(HttpStatus.IM_A_TEAPOT_418)), + responseTest( + response -> response.setStatusCode(HttpStatus.IM_A_TEAPOT_418, "Je suis une théière"), + response -> { + assertThat(response.getStatus()).isEqualTo(HttpStatus.IM_A_TEAPOT_418); + assertThat(response.getReason()).isEqualTo("Je suis une théière"); + }), + responseTest( + response -> response.setContentType("application/noddy"), + response -> assertThat(response.getMediaType()).isEqualTo("application/noddy")), + responseTest( + response -> { + response.appendHeader("foo", "bar"); + response.appendHeader("blim", "blam"); + response.appendHeader("foo", "baz"); + }, + response -> { + assertThat(response.getHeaders().getValuesList("foo")).containsExactly("bar", "baz"); + assertThat(response.getHeaders().getValuesList("blim")).containsExactly("blam"); + }), + responseTest( + response -> { + response.setContentType("text/plain"); + try (BufferedWriter writer = response.getWriter()) { + writer.write(TEST_BODY); + } + }, + response -> { + assertThat(response.getMediaType()).isEqualTo("text/plain"); + assertThat(response.getContentAsString()).isEqualTo(TEST_BODY); + }), + responseTest( + response -> { + response.setContentType("application/octet-stream"); + try (OutputStream outputStream = response.getOutputStream()) { + outputStream.write(RANDOM_BYTES); + } + }, + response -> { + assertThat(response.getMediaType()).isEqualTo("application/octet-stream"); + assertThat(response.getContent()).isEqualTo(RANDOM_BYTES); + }), }; for (ResponseTest test : tests) { testReference.set(test.responseOperation); diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/runner/InvokerTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/runner/InvokerTest.java index 6c90963d..b3569e4e 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/runner/InvokerTest.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/runner/InvokerTest.java @@ -16,7 +16,6 @@ import java.util.Collections; import java.util.Map; import java.util.Optional; -import java.util.stream.Collectors; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -25,10 +24,12 @@ public class InvokerTest { @Test public void help() throws IOException { - String help = captureOutput(() -> { - Optional invoker = Invoker.makeInvoker("--help"); - assertThat(invoker).isEmpty(); - }); + String help = + captureOutput( + () -> { + Optional invoker = Invoker.makeInvoker("--help"); + assertThat(invoker).isEmpty(); + }); assertThat(help).contains("Usage:"); assertThat(help).contains("--target"); assertThat(help).containsMatch("separated\\s+by\\s+'" + File.pathSeparator + "'"); diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/CloudEventSnoop.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/CloudEventSnoop.java index cd23de0d..439e712d 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/CloudEventSnoop.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/CloudEventSnoop.java @@ -21,7 +21,8 @@ public void accept(CloudEvent event) throws Exception { if (targetFile == null) { throw new IllegalArgumentException("Expected targetFile in JSON payload"); } - EventFormat jsonFormat = EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE); + EventFormat jsonFormat = + EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE); byte[] bytes = jsonFormat.serialize(event); try (FileOutputStream out = new FileOutputStream(targetFile)) { out.write(bytes); diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/Multipart.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/Multipart.java index aa766663..37102bbc 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/Multipart.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/Multipart.java @@ -11,8 +11,8 @@ /** * A simple proof-of-concept function for multipart handling. * - * {@code HttpTest} contains more detailed testing, but this function is part of the - * integration test that shows that we can indeed access the multipart API from a function. + *

{@code HttpTest} contains more detailed testing, but this function is part of the integration + * test that shows that we can indeed access the multipart API from a function. */ public class Multipart implements HttpFunction { @Override @@ -30,7 +30,6 @@ public void service(HttpRequest request, HttpResponse response) throws Exception writer.printf( "part %s type %s length %d\n", name, contents.getContentType().get(), contents.getContentLength()); - } - ); + }); } } diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/TypedBackgroundSnoop.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/TypedBackgroundSnoop.java index 7335f5a3..b1adfbe6 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/TypedBackgroundSnoop.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/TypedBackgroundSnoop.java @@ -16,8 +16,7 @@ * identical to the JSON payload that the Functions Framework received from the client in the test. * This will need to be rewritten when we switch to CloudEvents. */ -public class TypedBackgroundSnoop - implements BackgroundFunction { +public class TypedBackgroundSnoop implements BackgroundFunction { public static class Payload { public int a; public int b; diff --git a/invoker/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/RunFunction.java b/invoker/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/RunFunction.java index c4c9fed4..c79fcd05 100644 --- a/invoker/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/RunFunction.java +++ b/invoker/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/RunFunction.java @@ -14,37 +14,36 @@ import org.apache.maven.plugins.annotations.ResolutionScope; /** - * Runs a function using the Java Functions Framework. Typically this plugin is configured in one - * of two ways. Either in the pom.xml file, like this... + * Runs a function using the Java Functions Framework. Typically this plugin is configured in one of + * two ways. Either in the pom.xml file, like this... * *

{@code
- *  
- *    com.google.cloud.functions
- *    function-maven-plugin
- *    1.0.0-alpha-2-rc3
- *    
- *      com.example.function.Echo
- *    
- *  
+ * 
+ *   com.google.cloud.functions
+ *   function-maven-plugin
+ *   1.0.0-alpha-2-rc3
+ *   
+ *     com.example.function.Echo
+ *   
+ * 
  * }
* * ...and then run using {@code mvn function:run}. Or using properties on the command line, like * this...
* *
{@code
- *   mvn com.google.cloud.functions:function:1.0.0-alpha-2-rc3:run \
- *       -Drun.functionTarget=com.example.function.Echo}
- * 
- * + * mvn com.google.cloud.functions:function:1.0.0-alpha-2-rc3:run \ + * -Drun.functionTarget=com.example.function.Echo + * }
*/ -@Mojo(name = "run", +@Mojo( + name = "run", defaultPhase = LifecyclePhase.GENERATE_RESOURCES, requiresDependencyResolution = ResolutionScope.RUNTIME, requiresDependencyCollection = ResolutionScope.RUNTIME) @Execute(phase = LifecyclePhase.COMPILE) public class RunFunction extends AbstractMojo { - /** * The name of the function to run. This is the name of a class that implements one of the * interfaces in {@code com.google.cloud.functions}. @@ -52,9 +51,7 @@ public class RunFunction extends AbstractMojo { @Parameter(property = "run.functionTarget") private String functionTarget; - /** - * The port on which the HTTP server wrapping the function should listen. - */ + /** The port on which the HTTP server wrapping the function should listen. */ @Parameter(property = "run.port", defaultValue = "8080") private Integer port; diff --git a/invoker/testfunction/src/test/java/com/example/functionjar/Background.java b/invoker/testfunction/src/test/java/com/example/functionjar/Background.java index 6b18b54c..66123a08 100644 --- a/invoker/testfunction/src/test/java/com/example/functionjar/Background.java +++ b/invoker/testfunction/src/test/java/com/example/functionjar/Background.java @@ -20,9 +20,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; -/** - * @author emcmanus@google.com (Éamonn McManus) - */ +/** @author emcmanus@google.com (Éamonn McManus) */ public class Background implements RawBackgroundFunction { @Override public void accept(String json, Context context) { diff --git a/invoker/testfunction/src/test/java/com/example/functionjar/Checker.java b/invoker/testfunction/src/test/java/com/example/functionjar/Checker.java index 19c78cd2..2a4d3920 100644 --- a/invoker/testfunction/src/test/java/com/example/functionjar/Checker.java +++ b/invoker/testfunction/src/test/java/com/example/functionjar/Checker.java @@ -23,8 +23,7 @@ void serviceOrAssert(String runtimeClassName) { throw new AssertionError( String.format( "ClassLoader mismatch: mine %s; context %s", - getClass().getClassLoader(), - Thread.currentThread().getContextClassLoader())); + getClass().getClassLoader(), Thread.currentThread().getContextClassLoader())); } ClassLoader myLoader = getClass().getClassLoader(); From 51d6503177f45efdaae60fc19aade11879e47962 Mon Sep 17 00:00:00 2001 From: Grant Timmerman <744973+grant@users.noreply.github.com> Date: Wed, 27 Oct 2021 12:22:13 -0700 Subject: [PATCH 020/239] ci: add run conformance command (#124) Adds command to run conformance tests. - Adds `run_conformance_tests.sh` - Adds detailed docs about setting up Java and contributing to this repo Very similar to the Go setup, with a few minor modifications.
FULL LOGS

``` ./run_conformance_tests.sh Defaulting to v1.2.0 client. Use './run_conformance_tests vX.X.X' to specify a specific release version. ========== INSTALLING CLIENT@v1.2.0 ========== Note: only works with Go 1.16+ by default, see run_conformance_tests.sh for more information. Done installing client@v1.2.0 ========== HTTP CONFORMANCE TESTS ========== 2021/10/26 17:29:46 Validating for http... 2021/10/26 17:29:46 Framework server started. 2021/10/26 17:29:51 HTTP validation started... 2021/10/26 17:29:51 HTTP validation passed! 2021/10/26 17:29:51 Framework server shut down. Wrote logs to /var/folders/27/9q8h1w651z91hycvdf4qf0h0009rgz/T/serverlog_stdout.txt and /var/folders/27/9q8h1w651z91hycvdf4qf0h0009rgz/T/serverlog_stderr.txt. 2021/10/26 17:29:51 All validation passed! ========== BACKGROUND EVENT CONFORMANCE TESTS ========== 2021/10/26 17:29:51 Validating for legacyevent... 2021/10/26 17:29:51 Framework server started. 2021/10/26 17:29:56 Legacy event validation with legacy event requests... 2021/10/26 17:29:56 Events tried: - firebase-auth (PASSED) - firebase-db1 (PASSED) - firebase-db2 (PASSED) - firebase-db3 (PASSED) - firebase-db4 (PASSED) - firebase-db5 (PASSED) - firebase-db6 (PASSED) - firebase-db7 (PASSED) - firebase-db8 (PASSED) - firebase-dbdelete1 (PASSED) - firebase-dbdelete2 (PASSED) - firestore_complex (PASSED) - firestore_simple (PASSED) - legacy_pubsub (PASSED) - pubsub_binary (PASSED) - pubsub_text (PASSED) - storage (PASSED) 2021/10/26 17:29:56 Legacy event validation passed! 2021/10/26 17:29:56 Framework server shut down. Wrote logs to /var/folders/27/9q8h1w651z91hycvdf4qf0h0009rgz/T/serverlog_stdout.txt and /var/folders/27/9q8h1w651z91hycvdf4qf0h0009rgz/T/serverlog_stderr.txt. 2021/10/26 17:29:56 All validation passed! ========== CLOUDEVENT CONFORMANCE TESTS ========== 2021/10/26 17:29:56 Validating for cloudevent... 2021/10/26 17:29:56 Framework server started. 2021/10/26 17:30:01 CloudEvent validation with CloudEvent requests... 2021/10/26 17:30:01 Events tried: - firebase-auth (PASSED) - firebase-db1 (PASSED) - firebase-db2 (PASSED) - firebase-db3 (PASSED) - firebase-db4 (PASSED) - firebase-db5 (PASSED) - firebase-db6 (PASSED) - firebase-db7 (PASSED) - firebase-db8 (PASSED) - firebase-dbdelete1 (PASSED) - firebase-dbdelete2 (PASSED) - firestore_complex (PASSED) - firestore_simple (PASSED) - legacy_pubsub (PASSED) - pubsub_binary (PASSED) - pubsub_text (PASSED) - storage (PASSED) 2021/10/26 17:30:01 CloudEvent validation passed! 2021/10/26 17:30:01 Framework server shut down. Wrote logs to /var/folders/27/9q8h1w651z91hycvdf4qf0h0009rgz/T/serverlog_stdout.txt and /var/folders/27/9q8h1w651z91hycvdf4qf0h0009rgz/T/serverlog_stderr.txt. 2021/10/26 17:30:01 All validation passed! ```

--- CONTRIBUTING.md | 22 ++++++++++++------ run_conformance_tests.sh | 48 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 7 deletions(-) create mode 100755 run_conformance_tests.sh diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7e7cc4ed..f7e4114c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,12 +31,12 @@ Guidelines](https://opensource.google.com/conduct/). This project is divided into multiple packages, primarily: -- [`functions-framework-api`](./functions-framework-api) - - `core` - - `testfunction` - - `function-maven-plugin` - - `conformance` +- [`functions-framework-api`](./functions-framework-api) – The interfaces for functions. - [`java-function-invoker`](./invoker) + - `core` - The function invoker + - `testfunction` - A set of test functions + - `function-maven-plugin` - The Maven plugin for building functions + - `conformance` - A set of functions used for conformance testing ### Setup JDK 11 / 17 @@ -44,8 +44,8 @@ Install JDK 11 and 17. One way to install these is through [SDK man](https://sdk ```sh sdk install java 11.0.2-open -sdk install java 17 -sdk use java 17 +sdk install java 17-open +sdk use java 17-open sdk use java 11.0.2-open ``` @@ -72,3 +72,11 @@ formatting tool locally using one of the options provided at cd invoker; mvn test; ``` + +### Running Conformance Tests Locally + +First, install Go 1.16+, then run the conformance tests with this script: + +``` +./run_conformance_tests.sh +``` diff --git a/run_conformance_tests.sh b/run_conformance_tests.sh new file mode 100755 index 00000000..6276f158 --- /dev/null +++ b/run_conformance_tests.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# Runs the conformance tests locally from https://github.com/GoogleCloudPlatform/functions-framework-conformance +# +# Servers may fail to shutdown between tests on error, leaving port 8080 bound. +# You can see what's running on port 8080 by running `lsof -i :8080`. You can +# run `kill -9 ` to terminate a process. +# +# USAGE: +# ./run_conformance_tests.sh [client_version] +# +# client_version (optional): +# The version of the conformance tests client to use, formatted as "vX.X.X". +# Defaults to the latest version of the repo, which may be ahead of the +# latest release. + +CLIENT_VERSION=$1 +if [ $CLIENT_VERSION ]; then + CLIENT_VERSION="@$CLIENT_VERSION" +else + echo "Defaulting to v1.2.0 client." + echo "Use './run_conformance_tests vX.X.X' to specify a specific release version." + CLIENT_VERSION="@v1.2.0" +fi + +function print_header() { + echo + echo "========== $1 ==========" +} + +# Fail if any command fails +set -e + +print_header "INSTALLING CLIENT$CLIENT_VERSION" +echo "Note: only works with Go 1.16+ by default, see run_conformance_tests.sh for more information." +# Go install @version only works on go 1.16+, if using a lower Go version +# replace command with: +# go get github.com/GoogleCloudPlatform/functions-framework-conformance/client$CLIENT_VERSION && go install github.com/GoogleCloudPlatform/functions-framework-conformance/client +go install github.com/GoogleCloudPlatform/functions-framework-conformance/client$CLIENT_VERSION +echo "Done installing client$CLIENT_VERSION" + +print_header "HTTP CONFORMANCE TESTS" +client -buildpacks=false -type=http -cmd='mvn -f invoker/conformance/pom.xml function:run -Drun.functionTarget=com.google.cloud.functions.conformance.HttpConformanceFunction' -start-delay 5 + +print_header "BACKGROUND EVENT CONFORMANCE TESTS" +client -buildpacks=false -type=legacyevent -cmd='mvn -f invoker/conformance/pom.xml function:run -Drun.functionTarget=com.google.cloud.functions.conformance.BackgroundEventConformanceFunction' -start-delay 5 -validate-mapping=false + +print_header "CLOUDEVENT CONFORMANCE TESTS" +client -buildpacks=false -type=cloudevent -cmd='mvn -f invoker/conformance/pom.xml function:run -Drun.functionTarget=com.google.cloud.functions.conformance.CloudEventsConformanceFunction' -start-delay 5 -validate-mapping=false From 1c4a01470cc4ee7b3de3c3d7ae4af24e47eb2810 Mon Sep 17 00:00:00 2001 From: Annie Fu <16651409+anniefu@users.noreply.github.com> Date: Wed, 27 Oct 2021 15:40:08 -0700 Subject: [PATCH 021/239] feat: enable converting CloudEvent requests to Background Event requests (#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. --- .github/workflows/conformance.yaml | 11 +- invoker/conformance/pom.xml | 10 + .../BackgroundEventConformanceFunction.java | 8 +- .../CloudEventsConformanceFunction.java | 33 +- invoker/core/pom.xml | 5 + .../invoker/BackgroundFunctionExecutor.java | 11 +- .../cloud/functions/invoker/CloudEvents.java | 296 ++++++++++++++++++ .../invoker/CloudFunctionsContext.java | 9 +- .../google/cloud/functions/invoker/Event.java | 10 +- .../functions/invoker/CloudEventsTest.java | 100 ++++++ .../functions/invoker/IntegrationTest.java | 17 +- .../testfunctions/BackgroundSnoop.java | 1 - .../testfunctions/TypedBackgroundSnoop.java | 1 - .../firebase-auth-cloudevent-input.json | 24 ++ .../firebase-auth-legacy-output.json | 23 ++ .../firebase-db1-cloudevent-input.json | 15 + .../resources/firebase-db1-legacy-output.json | 14 + .../firebase-db2-cloudevent-input.json | 17 + .../resources/firebase-db2-legacy-output.json | 16 + .../firestore_complex-cloudevent-input.json | 80 +++++ .../firestore_complex-legacy-output.json | 79 +++++ .../pubsub_text-cloudevent-input.json | 20 ++ .../resources/pubsub_text-legacy-output.json | 19 ++ .../resources/storage-cloudevent-input.json | 28 ++ .../test/resources/storage-legacy-output.json | 31 ++ 25 files changed, 812 insertions(+), 66 deletions(-) create mode 100644 invoker/core/src/main/java/com/google/cloud/functions/invoker/CloudEvents.java create mode 100644 invoker/core/src/test/java/com/google/cloud/functions/invoker/CloudEventsTest.java create mode 100644 invoker/core/src/test/resources/firebase-auth-cloudevent-input.json create mode 100644 invoker/core/src/test/resources/firebase-auth-legacy-output.json create mode 100644 invoker/core/src/test/resources/firebase-db1-cloudevent-input.json create mode 100644 invoker/core/src/test/resources/firebase-db1-legacy-output.json create mode 100644 invoker/core/src/test/resources/firebase-db2-cloudevent-input.json create mode 100644 invoker/core/src/test/resources/firebase-db2-legacy-output.json create mode 100644 invoker/core/src/test/resources/firestore_complex-cloudevent-input.json create mode 100644 invoker/core/src/test/resources/firestore_complex-legacy-output.json create mode 100644 invoker/core/src/test/resources/pubsub_text-cloudevent-input.json create mode 100644 invoker/core/src/test/resources/pubsub_text-legacy-output.json create mode 100644 invoker/core/src/test/resources/storage-cloudevent-input.json create mode 100644 invoker/core/src/test/resources/storage-legacy-output.json diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index 02686a9d..fbd1ce18 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -34,25 +34,28 @@ jobs: run: (cd invoker/ && mvn install) - name: Run HTTP conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.0.0 + uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.2.1 with: + version: 'v1.2.1' functionType: 'http' useBuildpacks: false cmd: "'mvn -f invoker/conformance/pom.xml function:run -Drun.functionTarget=com.google.cloud.functions.conformance.HttpConformanceFunction'" startDelay: 10 - name: Run background event conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.0.0 + uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.2.1 with: + version: 'v1.2.1' functionType: 'legacyevent' useBuildpacks: false - validateMapping: false + validateMapping: true cmd: "'mvn -f invoker/conformance/pom.xml function:run -Drun.functionTarget=com.google.cloud.functions.conformance.BackgroundEventConformanceFunction'" startDelay: 10 - name: Run cloudevent conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.0.0 + uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.2.1 with: + version: 'v1.2.1' functionType: 'cloudevent' useBuildpacks: false validateMapping: true diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 67ff436e..5a794814 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -34,6 +34,16 @@ gson 2.8.6 + + io.cloudevents + cloudevents-core + 2.2.0 + + + io.cloudevents + cloudevents-json-jackson + 2.2.0 + diff --git a/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/BackgroundEventConformanceFunction.java b/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/BackgroundEventConformanceFunction.java index 8193abbd..b21e68c8 100644 --- a/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/BackgroundEventConformanceFunction.java +++ b/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/BackgroundEventConformanceFunction.java @@ -40,8 +40,12 @@ private String serialize(String data, Context context) { contextJson.addProperty("timestamp", context.timestamp()); contextJson.addProperty("eventType", context.eventType()); - JsonElement resource = gson.fromJson(context.resource(), JsonElement.class); - contextJson.add("resource", resource); + if (context.resource().startsWith("{")) { + JsonElement resource = gson.fromJson(context.resource(), JsonElement.class); + contextJson.add("resource", resource); + } else { + contextJson.addProperty("resource", context.resource()); + } JsonObject dataJson = gson.fromJson(data, JsonObject.class); diff --git a/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/CloudEventsConformanceFunction.java b/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/CloudEventsConformanceFunction.java index 04371952..7faa079c 100644 --- a/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/CloudEventsConformanceFunction.java +++ b/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/CloudEventsConformanceFunction.java @@ -17,13 +17,12 @@ import static java.nio.charset.StandardCharsets.UTF_8; import com.google.cloud.functions.CloudEventsFunction; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonObject; import io.cloudevents.CloudEvent; +import io.cloudevents.core.format.EventFormat; +import io.cloudevents.core.provider.EventFormatProvider; +import io.cloudevents.jackson.JsonFormat; import java.io.BufferedWriter; import java.io.FileWriter; -import java.time.format.DateTimeFormatter; /** * This class is used by the Functions Framework Conformance Tools to validate the framework's Cloud @@ -40,33 +39,11 @@ */ public class CloudEventsConformanceFunction implements CloudEventsFunction { - private static final Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().create(); - @Override public void accept(CloudEvent event) throws Exception { try (BufferedWriter writer = new BufferedWriter(new FileWriter("function_output.json"))) { - writer.write(serialize(event)); + EventFormat format = EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE); + writer.write(new String(format.serialize(event), UTF_8)); } } - - /** Create a structured JSON representation of a cloud event */ - private String serialize(CloudEvent event) { - JsonObject jsonEvent = new JsonObject(); - - jsonEvent.addProperty("id", event.getId()); - jsonEvent.addProperty("source", event.getSource().toString()); - jsonEvent.addProperty("type", event.getType()); - jsonEvent.addProperty("datacontenttype", event.getDataContentType()); - jsonEvent.addProperty("subject", event.getSubject()); - jsonEvent.addProperty("specversion", event.getSpecVersion().toString()); - - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX"); - jsonEvent.addProperty("time", event.getTime().format(formatter)); - - String payloadJson = new String(event.getData().toBytes(), UTF_8); - JsonObject jsonObject = new Gson().fromJson(payloadJson, JsonObject.class); - jsonEvent.add("data", jsonObject); - - return gson.toJson(jsonEvent); - } } diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index af524717..5fd4a9f5 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -130,6 +130,11 @@ 4.13.1 test + + com.google.re2j + re2j + 1.6 + com.google.truth truth diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java index 6f320438..98b9bc8a 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java @@ -14,7 +14,6 @@ package com.google.cloud.functions.invoker; -import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toMap; @@ -263,10 +262,7 @@ void serviceLegacyEvent(Event legacyEvent) throws Exception { @Override void serviceCloudEvent(CloudEvent cloudEvent) throws Exception { - Context context = contextFromCloudEvent(cloudEvent); - String jsonData = - (cloudEvent.getData() == null) ? "{}" : new String(cloudEvent.getData().toBytes(), UTF_8); - function.accept(jsonData, context); + serviceLegacyEvent(CloudEvents.convertToLegacyEvent(cloudEvent)); } } @@ -295,10 +291,7 @@ void serviceLegacyEvent(Event legacyEvent) throws Exception { @Override void serviceCloudEvent(CloudEvent cloudEvent) throws Exception { if (cloudEvent.getData() != null) { - String data = new String(cloudEvent.getData().toBytes(), UTF_8); - T payload = new Gson().fromJson(data, type); - Context context = contextFromCloudEvent(cloudEvent); - function.accept(payload, context); + serviceLegacyEvent(CloudEvents.convertToLegacyEvent(cloudEvent)); } else { throw new IllegalStateException("Event has no \"data\" component"); } diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/CloudEvents.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/CloudEvents.java new file mode 100644 index 00000000..0021d44e --- /dev/null +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/CloudEvents.java @@ -0,0 +1,296 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.cloud.functions.invoker; + +import static java.util.Map.entry; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.re2j.Matcher; +import com.google.re2j.Pattern; +import io.cloudevents.CloudEvent; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Map; +import java.util.Optional; + +/** Conversions from CloudEvents events to GCF Background Events. */ +class CloudEvents { + private static final String PUB_SUB_MESSAGE_TYPE = + "type.googleapis.com/google.pubsub.v1.PubsubMessage"; + + private static final Map EVENT_TYPE_MAPPING = + Map.ofEntries( + entry( + "google.cloud.pubsub.topic.v1.messagePublished", + new PubSubEventAdapter("google.pubsub.topic.publish")), + entry( + "google.cloud.storage.object.v1.finalized", + new StorageEventAdapter("google.storage.object.finalize")), + entry( + "google.cloud.storage.object.v1.deleted", + new StorageEventAdapter("google.storage.object.delete")), + entry( + "google.cloud.storage.object.v1.archived", + new StorageEventAdapter("google.storage.object.archive")), + entry( + "google.cloud.storage.object.v1.metadataUpdated", + new StorageEventAdapter("google.storage.object.metadataUpdate")), + entry( + "google.cloud.firestore.document.v1.written", + new EventAdapter("providers/cloud.firestore/eventTypes/document.write")), + entry( + "google.cloud.firestore.document.v1.created", + new EventAdapter("providers/cloud.firestore/eventTypes/document.create")), + entry( + "google.cloud.firestore.document.v1.updated", + new EventAdapter("providers/cloud.firestore/eventTypes/document.update")), + entry( + "google.cloud.firestore.document.v1.deleted", + new EventAdapter("providers/cloud.firestore/eventTypes/document.delete")), + entry( + "google.firebase.analytics.log.v1.written", + new EventAdapter("providers/google.firebase.analytics/eventTypes/event.log")), + entry( + "google.firebase.auth.user.v1.created", + new FirebaseAuthEventAdapter("providers/firebase.auth/eventTypes/user.create")), + entry( + "google.firebase.auth.user.v1.deleted", + new FirebaseAuthEventAdapter("providers/firebase.auth/eventTypes/user.delete")), + entry( + "google.firebase.database.ref.v1.created", + new FirebaseDatabaseEventAdapter( + "providers/google.firebase.database/eventTypes/ref.create")), + entry( + "google.firebase.database.ref.v1.written", + new FirebaseDatabaseEventAdapter( + "providers/google.firebase.database/eventTypes/ref.write")), + entry( + "google.firebase.database.ref.v1.updated", + new FirebaseDatabaseEventAdapter( + "providers/google.firebase.database/eventTypes/ref.update")), + entry( + "google.firebase.database.ref.v1.deleted", + new FirebaseDatabaseEventAdapter( + "providers/google.firebase.database/eventTypes/ref.delete")), + entry( + "google.cloud.storage.object.v1.changed", + new StorageEventAdapter("providers/cloud.storage/eventTypes/object.change"))); + + private static final Gson GSON = new GsonBuilder().serializeNulls().create(); + + /** + * Converts a CloudEvent to the legacy event format. + * + * @param cloudEvent the CloudEvent to convert + * @return the legacy event representation of the Cloud Event + */ + static Event convertToLegacyEvent(CloudEvent cloudEvent) { + String eventType = cloudEvent.getType(); + EventAdapter eventAdapter = EVENT_TYPE_MAPPING.get(eventType); + if (eventAdapter == null) { + throw new IllegalArgumentException("Unrecognized CloudEvent type \"" + eventType + "\""); + } + return eventAdapter.convertToLegacyEvent(cloudEvent); + } + + private static class EventAdapter { + private final String legacyEventType; + private static Pattern sourcePattern = Pattern.compile("//([^/]+)/(.+)"); + + protected class ParsedCloudEvent { + public final String Resource; + public final String Service; + public final String Name; + + public ParsedCloudEvent(String resource, String service, String name) { + this.Resource = resource; + this.Service = service; + this.Name = name; + } + } + ; + + /** + * Creates an adapter to convert from the CloudEvent to a legacy event. + * + * @param legacyEventType the event type of the legacy event being created + */ + EventAdapter(String legacyEventType) { + this.legacyEventType = legacyEventType; + } + + /** + * Converts a CloudEvent to the legacy event format. + * + * @param cloudEvent the CloudEvent to convert + * @return the legacy event representation of the Cloud Event + */ + final Event convertToLegacyEvent(CloudEvent cloudEvent) { + /* + Ex 1: "//firebaseauth.googleapis.com/projects/my-project-id" + m.group(0): "//firebaseauth.googleapis.com/projects/my-project-id" + m.group(1): "firebaseauth.googleapis.com" + m.group(2): "projects/my-project-id" + + Ex 2: "//pubsub.googleapis.com/projects/sample-project/topics/gcf-test" + m.group(0): "//pubsub.googleapis.com/projects/sample-project/topics/gcf-test" + m.group(1): "pubsub.googleapis.com" + m.group(2): "projects/sample-project/topics/gcf-test" + */ + Matcher m = sourcePattern.matcher(cloudEvent.getSource().toString()); + if (!m.find() || m.groupCount() != 2) { + throw new IllegalArgumentException( + String.format( + "Invalid CloudEvent source '%s', unable to parse into resource service and name", + cloudEvent.getSource().toString())); + } + + String service = m.group(1); + String name = m.group(2); + String resource = String.format("%s/%s", name, cloudEvent.getSubject()); + ParsedCloudEvent parsed = new ParsedCloudEvent(resource, service, name); + + OffsetDateTime timestamp = + Optional.ofNullable(cloudEvent.getTime()).orElse(OffsetDateTime.now()); + + CloudFunctionsContext.Builder ctxBuilder = + CloudFunctionsContext.builder() + .setEventId(cloudEvent.getId()) + .setEventType(this.legacyEventType) + .setResource(resource) + .setTimestamp(DateTimeFormatter.ISO_INSTANT.format(timestamp)); + + JsonObject data = + GSON.fromJson( + new String(cloudEvent.getData().toBytes(), java.nio.charset.StandardCharsets.UTF_8), + JsonObject.class); + return createLegacyEvent(parsed, ctxBuilder, data); + } + + /** + * Provides a hook to furither modify the converted event for specific event adapter subclasses. + * + * @param event convenient information parsed from the original CloudEvent + * @param builder the builder for the converted legacy event's context, pre-populated with + * defaults from the original CloudEvent + * @param data the data for the converted legacy event's data, pre-populated with defaults from + * the original CloudEvent + * @return the fully converted legacy event + */ + Event createLegacyEvent( + ParsedCloudEvent event, CloudFunctionsContext.Builder builder, JsonObject data) { + return Event.of(data, builder.build()); + } + } + + private static class PubSubEventAdapter extends EventAdapter { + PubSubEventAdapter(String legacyEventType) { + super(legacyEventType); + } + + @Override + Event createLegacyEvent( + ParsedCloudEvent event, CloudFunctionsContext.Builder builder, JsonObject data) { + JsonObject resource = new JsonObject(); + resource.addProperty("service", event.Service); + resource.addProperty("name", event.Name); + resource.addProperty("type", PUB_SUB_MESSAGE_TYPE); + builder.setResource(GSON.toJson(resource)); + + // Lift the "message" field into the main "data" field. + if (data.has("message")) { + JsonElement message = data.get("message"); + if (message.isJsonObject()) { + data = message.getAsJsonObject(); + } + } + + data.remove("messageId"); + data.remove("publishTime"); + + return Event.of(data, builder.build()); + } + } + + private static class FirebaseAuthEventAdapter extends EventAdapter { + FirebaseAuthEventAdapter(String legacyEventType) { + super(legacyEventType); + } + + @Override + Event createLegacyEvent( + ParsedCloudEvent event, CloudFunctionsContext.Builder builder, JsonObject data) { + builder.setResource(event.Name); + + if (data.has("metadata")) { + JsonElement meta = data.get("metadata"); + if (meta.isJsonObject()) { + JsonObject metaObj = meta.getAsJsonObject(); + + JsonElement createTime = metaObj.get("createTime"); + if (createTime != null) { + metaObj.add("createdAt", createTime); + metaObj.remove("createTime"); + } + + JsonElement lastSignInTime = metaObj.get("lastSignInTime"); + if (lastSignInTime != null) { + metaObj.add("lastSignedInAt", lastSignInTime); + metaObj.remove("lastSignInTime"); + } + } + } + return Event.of(data, builder.build()); + } + } + + private static class FirebaseDatabaseEventAdapter extends EventAdapter { + private static Pattern resourcePattern = Pattern.compile("/locations/[^/]+"); + + FirebaseDatabaseEventAdapter(String legacyEventType) { + super(legacyEventType); + } + + @Override + Event createLegacyEvent( + ParsedCloudEvent event, CloudFunctionsContext.Builder builder, JsonObject data) { + builder.setResource(resourcePattern.matcher(event.Resource).replaceAll("")); + return Event.of(data, builder.build()); + } + } + + private static class StorageEventAdapter extends EventAdapter { + StorageEventAdapter(String legacyEventType) { + super(legacyEventType); + } + + @Override + Event createLegacyEvent( + ParsedCloudEvent event, CloudFunctionsContext.Builder builder, JsonObject data) { + JsonObject resource = new JsonObject(); + resource.addProperty("service", event.Service); + resource.addProperty("name", event.Resource); + if (data.has("kind")) { + resource.addProperty("type", data.get("kind").getAsString()); + } + + builder.setResource(GSON.toJson(resource)); + return Event.of(data, builder.build()); + } + } +} diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/CloudFunctionsContext.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/CloudFunctionsContext.java index 4efc045d..65df5411 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/CloudFunctionsContext.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/CloudFunctionsContext.java @@ -103,17 +103,12 @@ static TypeAdapter typeAdapter(Gson gson) { } static Resource from(String s) { - Gson baseGson = new Gson(); - if (s.startsWith("\"") && s.endsWith("\"")) { - String name = baseGson.fromJson(s, String.class); - return builder().setName(name).build(); - } if (s.startsWith("{") && (s.endsWith("}") || s.endsWith("}\n"))) { - TypeAdapter typeAdapter = typeAdapter(baseGson); + TypeAdapter typeAdapter = typeAdapter(new Gson()); Gson gson = new GsonBuilder().registerTypeAdapter(Resource.class, typeAdapter).create(); return gson.fromJson(s, Resource.class); } - throw new IllegalArgumentException("Unexpected resource syntax: " + s); + return builder().setName(s).build(); } static Builder builder() { diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/Event.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/Event.java index ed12efe2..642e5118 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/Event.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/Event.java @@ -107,10 +107,12 @@ private boolean isPubSubEmulatorPayload(JsonObject root) { * to be a string. */ private JsonObject adjustContextResource(JsonObject contextObject) { - String resourceValue = - contextObject.has("resource") ? contextObject.get("resource").toString() : ""; - contextObject.remove("resource"); - contextObject.addProperty("resource", resourceValue); + if (contextObject.has("resource")) { + JsonElement resourceElement = contextObject.get("resource"); + if (resourceElement.isJsonObject()) { + contextObject.addProperty("resource", resourceElement.toString()); + } + } return contextObject; } } diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/CloudEventsTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/CloudEventsTest.java new file mode 100644 index 00000000..3e964d7b --- /dev/null +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/CloudEventsTest.java @@ -0,0 +1,100 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.cloud.functions.invoker; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; +import static java.nio.charset.StandardCharsets.UTF_8; + +import io.cloudevents.CloudEvent; +import io.cloudevents.jackson.JsonFormat; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import org.junit.Test; + +public class CloudEventsTest { + @Test + public void firebaseFirestoreTest() throws Exception { + CloudEvent cloudEvent = cloudEventForResource("firestore_complex-cloudevent-input.json"); + Event actualEvent = CloudEvents.convertToLegacyEvent(cloudEvent); + + Event expEvent = legacyEventForResource("firestore_complex-legacy-output.json"); + assertThat(actualEvent).isEqualTo(expEvent); + } + + @Test + public void pubSubTest() throws Exception { + CloudEvent cloudEvent = cloudEventForResource("pubsub_text-cloudevent-input.json"); + Event actualEvent = CloudEvents.convertToLegacyEvent(cloudEvent); + + Event expEvent = legacyEventForResource("pubsub_text-legacy-output.json"); + assertThat(actualEvent).isEqualTo(expEvent); + } + + @Test + public void firebaseAuthTest() throws Exception { + CloudEvent cloudEvent = cloudEventForResource("firebase-auth-cloudevent-input.json"); + Event actualEvent = CloudEvents.convertToLegacyEvent(cloudEvent); + + Event expEvent = legacyEventForResource("firebase-auth-legacy-output.json"); + assertThat(actualEvent).isEqualTo(expEvent); + } + + @Test + public void firebaseDb1Test() throws Exception { + CloudEvent cloudEvent = cloudEventForResource("firebase-db1-cloudevent-input.json"); + Event actualEvent = CloudEvents.convertToLegacyEvent(cloudEvent); + + Event expEvent = legacyEventForResource("firebase-db1-legacy-output.json"); + assertThat(actualEvent).isEqualTo(expEvent); + } + + @Test + public void firebaseDb2Test() throws Exception { + CloudEvent cloudEvent = cloudEventForResource("firebase-db2-cloudevent-input.json"); + Event actualEvent = CloudEvents.convertToLegacyEvent(cloudEvent); + + Event expEvent = legacyEventForResource("firebase-db2-legacy-output.json"); + assertThat(actualEvent).isEqualTo(expEvent); + } + + @Test + public void storageTest() throws Exception { + CloudEvent cloudEvent = cloudEventForResource("storage-cloudevent-input.json"); + Event actualEvent = CloudEvents.convertToLegacyEvent(cloudEvent); + + Event expEvent = legacyEventForResource("storage-legacy-output.json"); + assertThat(actualEvent).isEqualTo(expEvent); + } + + private CloudEvent cloudEventForResource(String resourceName) throws IOException { + try (InputStream in = getClass().getResourceAsStream("/" + resourceName)) { + assertWithMessage("No such resource /%s", resourceName).that(in).isNotNull(); + byte[] req = in.readAllBytes(); + return io.cloudevents.core.provider.EventFormatProvider.getInstance() + .resolveFormat(JsonFormat.CONTENT_TYPE) + .deserialize(req); + } + } + + private Event legacyEventForResource(String resourceName) throws IOException { + try (InputStream in = getClass().getResourceAsStream("/" + resourceName)) { + assertWithMessage("No such resource /%s", resourceName).that(in).isNotNull(); + String legacyEventString = new String(in.readAllBytes(), UTF_8); + return BackgroundFunctionExecutor.parseLegacyEvent(new StringReader(legacyEventString)); + } + } +} diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java index 7a2bee14..335cc7de 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java @@ -103,11 +103,11 @@ private static String sampleLegacyEvent(File snoopFile) { + " \"context\": {\n" + " \"eventId\": \"B234-1234-1234\",\n" + " \"timestamp\": \"2018-04-05T17:31:00Z\",\n" - + " \"eventType\": \"com.example.someevent.new\",\n" + + " \"eventType\": \"google.pubsub.topic.publish\",\n" + " \"resource\": {\n" - + " \"service\":\"test-service\",\n" - + " \"name\":\"test-name\",\n" - + " \"type\":\"test-type\"\n" + + " \"service\":\"pubsub.googleapis.com\",\n" + + " \"name\":\"projects/sample-project/topics/gcf-test\",\n" + + " \"type\":\"type.googleapis.com/google.pubsub.v1.PubsubMessage\"\n" + " }\n" + " }\n" + "}"; @@ -116,8 +116,9 @@ private static String sampleLegacyEvent(File snoopFile) { private static CloudEvent sampleCloudEvent(File snoopFile) { return CloudEventBuilder.v1() .withId("B234-1234-1234") - .withSource(URI.create("/source")) - .withType("com.example.someevent.new") + .withSource(URI.create("//pubsub.googleapis.com/projects/sample-project/topics/gcf-test")) + .withSubject("documents/gcf-test/2Vm2mI1d0wIaK2Waj5to") + .withType("google.cloud.pubsub.topic.v1.messagePublished") .withDataSchema(URI.create("/schema")) .withDataContentType("application/json") .withData(("{\"a\": 2, \"b\": 3, \"targetFile\": \"" + snoopFile + "\"}").getBytes(UTF_8)) @@ -386,8 +387,6 @@ private void backgroundTest(String target) throws Exception { File snoopFile = snoopFile(); String gcfRequestText = sampleLegacyEvent(snoopFile); JsonObject expectedJson = new Gson().fromJson(gcfRequestText, JsonObject.class); - // We don't currently put anything in the attributes() map for legacy events. - expectedJson.add("attributes", new JsonObject()); TestCase gcfTestCase = TestCase.builder() .setRequestText(gcfRequestText) @@ -404,8 +403,6 @@ private void backgroundTest(String target) throws Exception { // For CloudEvents, we don't currently populate Context#getResource with anything interesting, // so we excise that from the expected text we would have with legacy events. JsonObject cloudEventExpectedJson = new Gson().fromJson(gcfRequestText, JsonObject.class); - cloudEventExpectedJson.getAsJsonObject("context").add("resource", new JsonObject()); - cloudEventExpectedJson.add("attributes", expectedCloudEventAttributes()); TestCase cloudEventsStructuredTestCase = TestCase.builder() .setSnoopFile(snoopFile) diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/BackgroundSnoop.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/BackgroundSnoop.java index 825de1f0..0a6dba42 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/BackgroundSnoop.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/BackgroundSnoop.java @@ -34,7 +34,6 @@ public void accept(String json, Context context) { JsonObject contextAndPayloadJson = new JsonObject(); contextAndPayloadJson.add("data", jsonObject); contextAndPayloadJson.add("context", contextJson); - contextAndPayloadJson.add("attributes", gson.toJsonTree(context.attributes())); try (FileWriter fileWriter = new FileWriter(targetFile); PrintWriter writer = new PrintWriter(fileWriter)) { writer.println(contextAndPayloadJson); diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/TypedBackgroundSnoop.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/TypedBackgroundSnoop.java index b1adfbe6..c1e489b4 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/TypedBackgroundSnoop.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/TypedBackgroundSnoop.java @@ -39,7 +39,6 @@ public void accept(Payload payload, Context context) { JsonObject contextAndPayloadJson = new JsonObject(); contextAndPayloadJson.add("data", gson.toJsonTree(payload)); contextAndPayloadJson.add("context", contextJson); - contextAndPayloadJson.add("attributes", gson.toJsonTree(context.attributes())); try (FileWriter fileWriter = new FileWriter(targetFile); PrintWriter writer = new PrintWriter(fileWriter)) { writer.println(contextAndPayloadJson); diff --git a/invoker/core/src/test/resources/firebase-auth-cloudevent-input.json b/invoker/core/src/test/resources/firebase-auth-cloudevent-input.json new file mode 100644 index 00000000..285878e9 --- /dev/null +++ b/invoker/core/src/test/resources/firebase-auth-cloudevent-input.json @@ -0,0 +1,24 @@ +{ + "specversion": "1.0", + "type": "google.firebase.auth.user.v1.created", + "source": "//firebaseauth.googleapis.com/projects/my-project-id", + "subject": "users/UUpby3s4spZre6kHsgVSPetzQ8l2", + "id": "aaaaaa-1111-bbbb-2222-cccccccccccc", + "time": "2020-09-29T11:32:00.123Z", + "datacontenttype": "application/json", + "data": { + "email": "test@nowhere.com", + "metadata": { + "createTime": "2020-05-26T10:42:27Z", + "lastSignInTime": "2020-10-24T11:00:00Z" + }, + "providerData": [ + { + "email": "test@nowhere.com", + "providerId": "password", + "uid": "test@nowhere.com" + } + ], + "uid": "UUpby3s4spZre6kHsgVSPetzQ8l2" + } +} \ No newline at end of file diff --git a/invoker/core/src/test/resources/firebase-auth-legacy-output.json b/invoker/core/src/test/resources/firebase-auth-legacy-output.json new file mode 100644 index 00000000..cf0e572f --- /dev/null +++ b/invoker/core/src/test/resources/firebase-auth-legacy-output.json @@ -0,0 +1,23 @@ +{ + "data": { + "email": "test@nowhere.com", + "metadata": { + "createdAt": "2020-05-26T10:42:27Z", + "lastSignedInAt": "2020-10-24T11:00:00Z" + }, + "providerData": [ + { + "email": "test@nowhere.com", + "providerId": "password", + "uid": "test@nowhere.com" + } + ], + "uid": "UUpby3s4spZre6kHsgVSPetzQ8l2" + }, + "context": { + "eventId": "aaaaaa-1111-bbbb-2222-cccccccccccc", + "eventType": "providers/firebase.auth/eventTypes/user.create", + "resource": "projects/my-project-id", + "timestamp": "2020-09-29T11:32:00.123Z" + } +} \ No newline at end of file diff --git a/invoker/core/src/test/resources/firebase-db1-cloudevent-input.json b/invoker/core/src/test/resources/firebase-db1-cloudevent-input.json new file mode 100644 index 00000000..0d9783c3 --- /dev/null +++ b/invoker/core/src/test/resources/firebase-db1-cloudevent-input.json @@ -0,0 +1,15 @@ +{ + "specversion": "1.0", + "type": "google.firebase.database.ref.v1.written", + "source": "//firebasedatabase.googleapis.com/projects/_/locations/us-central1/instances/my-project-id", + "subject": "refs/gcf-test/xyz", + "id": "aaaaaa-1111-bbbb-2222-cccccccccccc", + "time": "2020-09-29T11:32:00.123Z", + "datacontenttype": "application/json", + "data": { + "data": null, + "delta": { + "grandchild": "other" + } + } +} \ No newline at end of file diff --git a/invoker/core/src/test/resources/firebase-db1-legacy-output.json b/invoker/core/src/test/resources/firebase-db1-legacy-output.json new file mode 100644 index 00000000..50190855 --- /dev/null +++ b/invoker/core/src/test/resources/firebase-db1-legacy-output.json @@ -0,0 +1,14 @@ +{ + "data": { + "data": null, + "delta": { + "grandchild": "other" + } + }, + "context": { + "resource": "projects/_/instances/my-project-id/refs/gcf-test/xyz", + "timestamp": "2020-09-29T11:32:00.123Z", + "eventId": "aaaaaa-1111-bbbb-2222-cccccccccccc", + "eventType": "providers/google.firebase.database/eventTypes/ref.write" + } +} \ No newline at end of file diff --git a/invoker/core/src/test/resources/firebase-db2-cloudevent-input.json b/invoker/core/src/test/resources/firebase-db2-cloudevent-input.json new file mode 100644 index 00000000..71974d42 --- /dev/null +++ b/invoker/core/src/test/resources/firebase-db2-cloudevent-input.json @@ -0,0 +1,17 @@ +{ + "specversion": "1.0", + "type": "google.firebase.database.ref.v1.written", + "source": "//firebasedatabase.googleapis.com/projects/_/locations/europe-west1/instances/my-project-id", + "subject": "refs/gcf-test/xyz", + "id": "aaaaaa-1111-bbbb-2222-cccccccccccc", + "time": "2020-09-29T11:32:00.123Z", + "datacontenttype": "application/json", + "data": { + "data": { + "grandchild": "other" + }, + "delta": { + "grandchild": "other changed" + } + } +} \ No newline at end of file diff --git a/invoker/core/src/test/resources/firebase-db2-legacy-output.json b/invoker/core/src/test/resources/firebase-db2-legacy-output.json new file mode 100644 index 00000000..402868fa --- /dev/null +++ b/invoker/core/src/test/resources/firebase-db2-legacy-output.json @@ -0,0 +1,16 @@ +{ + "data": { + "data": { + "grandchild": "other" + }, + "delta": { + "grandchild": "other changed" + } + }, + "context": { + "resource": "projects/_/instances/my-project-id/refs/gcf-test/xyz", + "timestamp": "2020-09-29T11:32:00.123Z", + "eventType": "providers/google.firebase.database/eventTypes/ref.write", + "eventId": "aaaaaa-1111-bbbb-2222-cccccccccccc" + } +} diff --git a/invoker/core/src/test/resources/firestore_complex-cloudevent-input.json b/invoker/core/src/test/resources/firestore_complex-cloudevent-input.json new file mode 100644 index 00000000..fd5aadfb --- /dev/null +++ b/invoker/core/src/test/resources/firestore_complex-cloudevent-input.json @@ -0,0 +1,80 @@ +{ + "specversion": "1.0", + "type": "google.cloud.firestore.document.v1.written", + "source": "//firestore.googleapis.com/projects/project-id/databases/(default)", + "subject": "documents/gcf-test/IH75dRdeYJKd4uuQiqch", + "id": "aaaaaa-1111-bbbb-2222-cccccccccccc", + "time": "2020-09-29T11:32:00.123Z", + "datacontenttype": "application/json", + "data": { + "oldValue": {}, + "updateMask": {}, + "value": { + "createTime": "2020-04-23T14:25:05.349632Z", + "fields": { + "arrayValue": { + "arrayValue": { + "values": [ + { + "integerValue": "1" + }, + { + "integerValue": "2" + } + ] + } + }, + "booleanValue": { + "booleanValue": true + }, + "doubleValue": { + "doubleValue": 5.5 + }, + "geoPointValue": { + "geoPointValue": { + "latitude": 51.4543, + "longitude": -0.9781 + } + }, + "intValue": { + "integerValue": "50" + }, + "mapValue": { + "mapValue": { + "fields": { + "field1": { + "stringValue": "x" + }, + "field2": { + "arrayValue": { + "values": [ + { + "stringValue": "x" + }, + { + "integerValue": "1" + } + ] + } + } + } + } + }, + "nullValue": { + "nullValue": null + }, + "referenceValue": { + "referenceValue": "projects/project-id/databases/(default)/documents/foo/bar/baz/qux" + }, + "stringValue": { + "stringValue": "text" + }, + "timestampValue": { + "timestampValue": "2020-04-23T14:23:53.241Z" + } + }, + "name": "projects/project-id/databases/(default)/documents/gcf-test/IH75dRdeYJKd4uuQiqch", + "updateTime": "2020-04-23T14:25:05.349632Z" + } + } +} diff --git a/invoker/core/src/test/resources/firestore_complex-legacy-output.json b/invoker/core/src/test/resources/firestore_complex-legacy-output.json new file mode 100644 index 00000000..dc7a26b4 --- /dev/null +++ b/invoker/core/src/test/resources/firestore_complex-legacy-output.json @@ -0,0 +1,79 @@ +{ + "data": { + "oldValue": {}, + "updateMask": {}, + "value": { + "createTime": "2020-04-23T14:25:05.349632Z", + "fields": { + "arrayValue": { + "arrayValue": { + "values": [ + { + "integerValue": "1" + }, + { + "integerValue": "2" + } + ] + } + }, + "booleanValue": { + "booleanValue": true + }, + "doubleValue": { + "doubleValue": 5.5 + }, + "geoPointValue": { + "geoPointValue": { + "latitude": 51.4543, + "longitude": -0.9781 + } + }, + "intValue": { + "integerValue": "50" + }, + "mapValue": { + "mapValue": { + "fields": { + "field1": { + "stringValue": "x" + }, + "field2": { + "arrayValue": { + "values": [ + { + "stringValue": "x" + }, + { + "integerValue": "1" + } + ] + } + } + } + } + }, + "nullValue": { + "nullValue": null + }, + "referenceValue": { + "referenceValue": "projects/project-id/databases/(default)/documents/foo/bar/baz/qux" + }, + "stringValue": { + "stringValue": "text" + }, + "timestampValue": { + "timestampValue": "2020-04-23T14:23:53.241Z" + } + }, + "name": "projects/project-id/databases/(default)/documents/gcf-test/IH75dRdeYJKd4uuQiqch", + "updateTime": "2020-04-23T14:25:05.349632Z" + } + }, + "context": { + "eventId": "aaaaaa-1111-bbbb-2222-cccccccccccc", + "eventType": "providers/cloud.firestore/eventTypes/document.write", + "resource": "projects/project-id/databases/(default)/documents/gcf-test/IH75dRdeYJKd4uuQiqch", + "timestamp": "2020-09-29T11:32:00.123Z" + } +} diff --git a/invoker/core/src/test/resources/pubsub_text-cloudevent-input.json b/invoker/core/src/test/resources/pubsub_text-cloudevent-input.json new file mode 100644 index 00000000..f4994ee8 --- /dev/null +++ b/invoker/core/src/test/resources/pubsub_text-cloudevent-input.json @@ -0,0 +1,20 @@ +{ + "specversion": "1.0", + "type": "google.cloud.pubsub.topic.v1.messagePublished", + "source": "//pubsub.googleapis.com/projects/sample-project/topics/gcf-test", + "id": "aaaaaa-1111-bbbb-2222-cccccccccccc", + "time": "2020-09-29T11:32:00.123Z", + "datacontenttype": "application/json", + "data": { + "subscription": "projects/sample-project/subscriptions/sample-subscription", + "message": { + "@type": "type.googleapis.com/google.pubsub.v1.PubsubMessage", + "messageId": "aaaaaa-1111-bbbb-2222-cccccccccccc", + "publishTime": "2020-09-29T11:32:00.123Z", + "attributes": { + "attr1":"attr1-value" + }, + "data": "dGVzdCBtZXNzYWdlIDM=" + } + } +} diff --git a/invoker/core/src/test/resources/pubsub_text-legacy-output.json b/invoker/core/src/test/resources/pubsub_text-legacy-output.json new file mode 100644 index 00000000..e1b8b8f9 --- /dev/null +++ b/invoker/core/src/test/resources/pubsub_text-legacy-output.json @@ -0,0 +1,19 @@ +{ + "context": { + "eventId":"aaaaaa-1111-bbbb-2222-cccccccccccc", + "timestamp":"2020-09-29T11:32:00.123Z", + "eventType":"google.pubsub.topic.publish", + "resource":{ + "service":"pubsub.googleapis.com", + "name":"projects/sample-project/topics/gcf-test", + "type":"type.googleapis.com/google.pubsub.v1.PubsubMessage" + } + }, + "data": { + "@type": "type.googleapis.com/google.pubsub.v1.PubsubMessage", + "attributes": { + "attr1":"attr1-value" + }, + "data": "dGVzdCBtZXNzYWdlIDM=" + } +} diff --git a/invoker/core/src/test/resources/storage-cloudevent-input.json b/invoker/core/src/test/resources/storage-cloudevent-input.json new file mode 100644 index 00000000..2948b99f --- /dev/null +++ b/invoker/core/src/test/resources/storage-cloudevent-input.json @@ -0,0 +1,28 @@ +{ + "specversion": "1.0", + "type": "google.cloud.storage.object.v1.finalized", + "source": "//storage.googleapis.com/projects/_/buckets/some-bucket", + "subject": "objects/folder/Test.cs", + "id": "aaaaaa-1111-bbbb-2222-cccccccccccc", + "time": "2020-09-29T11:32:00.123Z", + "datacontenttype": "application/json", + "data": { + "bucket": "some-bucket", + "contentType": "text/plain", + "crc32c": "rTVTeQ==", + "etag": "CNHZkbuF/ugCEAE=", + "generation": "1587627537231057", + "id": "some-bucket/folder/Test.cs/1587627537231057", + "kind": "storage#object", + "md5Hash": "kF8MuJ5+CTJxvyhHS1xzRg==", + "mediaLink": "https://www.googleapis.com/download/storage/v1/b/some-bucket/o/folder%2FTest.cs?generation=1587627537231057\u0026alt=media", + "metageneration": "1", + "name": "folder/Test.cs", + "selfLink": "https://www.googleapis.com/storage/v1/b/some-bucket/o/folder/Test.cs", + "size": "352", + "storageClass": "MULTI_REGIONAL", + "timeCreated": "2020-04-23T07:38:57.230Z", + "timeStorageClassUpdated": "2020-04-23T07:38:57.230Z", + "updated": "2020-04-23T07:38:57.230Z" + } +} diff --git a/invoker/core/src/test/resources/storage-legacy-output.json b/invoker/core/src/test/resources/storage-legacy-output.json new file mode 100644 index 00000000..88a9fd57 --- /dev/null +++ b/invoker/core/src/test/resources/storage-legacy-output.json @@ -0,0 +1,31 @@ +{ + "context": { + "eventId": "aaaaaa-1111-bbbb-2222-cccccccccccc", + "timestamp": "2020-09-29T11:32:00.123Z", + "eventType": "google.storage.object.finalize", + "resource": { + "service": "storage.googleapis.com", + "name": "projects/_/buckets/some-bucket/objects/folder/Test.cs", + "type": "storage#object" + } + }, + "data": { + "bucket": "some-bucket", + "contentType": "text/plain", + "crc32c": "rTVTeQ==", + "etag": "CNHZkbuF/ugCEAE=", + "generation": "1587627537231057", + "id": "some-bucket/folder/Test.cs/1587627537231057", + "kind": "storage#object", + "md5Hash": "kF8MuJ5+CTJxvyhHS1xzRg==", + "mediaLink": "https://www.googleapis.com/download/storage/v1/b/some-bucket/o/folder%2FTest.cs?generation=1587627537231057\u0026alt=media", + "metageneration": "1", + "name": "folder/Test.cs", + "selfLink": "https://www.googleapis.com/storage/v1/b/some-bucket/o/folder/Test.cs", + "size": "352", + "storageClass": "MULTI_REGIONAL", + "timeCreated": "2020-04-23T07:38:57.230Z", + "timeStorageClassUpdated": "2020-04-23T07:38:57.230Z", + "updated": "2020-04-23T07:38:57.230Z" + } +} From 3e154e3d28f2676653915b90fa67213a562030b5 Mon Sep 17 00:00:00 2001 From: Annie Fu Date: Mon, 8 Nov 2021 13:44:24 -0800 Subject: [PATCH 022/239] [maven-release-plugin] prepare release java-function-invoker-parent-1.1.0 --- invoker/conformance/pom.xml | 6 +++--- invoker/core/pom.xml | 6 +++--- invoker/function-maven-plugin/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 5a794814..a629a29e 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.0.4-SNAPSHOT + 1.1.0 com.google.cloud.functions.invoker conformance - 1.0.1-SNAPSHOT + 1.1.0 GCF Confromance Tests @@ -52,7 +52,7 @@ com.google.cloud.functions function-maven-plugin - 0.9.9-SNAPSHOT + 0.10.0 diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 5fd4a9f5..cba7638b 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.0.4-SNAPSHOT + 1.1.0 com.google.cloud.functions.invoker java-function-invoker - 1.0.4-SNAPSHOT + 1.1.0 GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -114,7 +114,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.0.4-SNAPSHOT + 1.1.0 test-jar test diff --git a/invoker/function-maven-plugin/pom.xml b/invoker/function-maven-plugin/pom.xml index bf5d8107..5ee799d0 100644 --- a/invoker/function-maven-plugin/pom.xml +++ b/invoker/function-maven-plugin/pom.xml @@ -4,13 +4,13 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.0.4-SNAPSHOT + 1.1.0 com.google.cloud.functions function-maven-plugin maven-plugin - 0.9.9-SNAPSHOT + 0.10.0 Functions Framework Plugin A Maven plugin that allows functions to be deployed, and to be run locally using the Java Functions Framework. @@ -44,7 +44,7 @@ com.google.cloud.functions.invoker java-function-invoker - 1.0.4-SNAPSHOT + 1.1.0 diff --git a/invoker/pom.xml b/invoker/pom.xml index 989794e6..397605e6 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -8,7 +8,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.0.4-SNAPSHOT + 1.1.0 pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index b381e41e..c34fb1d2 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.0.4-SNAPSHOT + 1.1.0 com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.0.4-SNAPSHOT + 1.1.0 Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From 1863d1314d95b57a53003f2cf83f1221f46b2502 Mon Sep 17 00:00:00 2001 From: Annie Fu Date: Mon, 8 Nov 2021 13:44:52 -0800 Subject: [PATCH 023/239] [maven-release-plugin] prepare for next development iteration --- invoker/conformance/pom.xml | 6 +++--- invoker/core/pom.xml | 6 +++--- invoker/function-maven-plugin/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index a629a29e..189f656f 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.1.0 + 1.1.1-SNAPSHOT com.google.cloud.functions.invoker conformance - 1.1.0 + 1.1.1-SNAPSHOT GCF Confromance Tests @@ -52,7 +52,7 @@ com.google.cloud.functions function-maven-plugin - 0.10.0 + 0.10.1-SNAPSHOT diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index cba7638b..be3404bb 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.1.0 + 1.1.1-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker - 1.1.0 + 1.1.1-SNAPSHOT GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -114,7 +114,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.1.0 + 1.1.1-SNAPSHOT test-jar test diff --git a/invoker/function-maven-plugin/pom.xml b/invoker/function-maven-plugin/pom.xml index 5ee799d0..09782cf5 100644 --- a/invoker/function-maven-plugin/pom.xml +++ b/invoker/function-maven-plugin/pom.xml @@ -4,13 +4,13 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.1.0 + 1.1.1-SNAPSHOT com.google.cloud.functions function-maven-plugin maven-plugin - 0.10.0 + 0.10.1-SNAPSHOT Functions Framework Plugin A Maven plugin that allows functions to be deployed, and to be run locally using the Java Functions Framework. @@ -44,7 +44,7 @@ com.google.cloud.functions.invoker java-function-invoker - 1.1.0 + 1.1.1-SNAPSHOT diff --git a/invoker/pom.xml b/invoker/pom.xml index 397605e6..87b43b62 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -8,7 +8,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.1.0 + 1.1.1-SNAPSHOT pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index c34fb1d2..6dada9d4 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.1.0 + 1.1.1-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.1.0 + 1.1.1-SNAPSHOT Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From 6312e648e79d3c0bbc299ea4f64d622e4dbc3b4c Mon Sep 17 00:00:00 2001 From: Annie Fu <16651409+anniefu@users.noreply.github.com> Date: Fri, 12 Nov 2021 13:32:50 -0800 Subject: [PATCH 024/239] docs: update README.md to use newest release (#125) --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 04a34659..ade347b4 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,7 @@ You can configure the plugin in `pom.xml`: com.google.cloud.functions function-maven-plugin - 0.9.8 + 0.10.0 com.example.function.Echo @@ -176,7 +176,7 @@ mvn function:run You can alternatively configure the plugin with properties on the command line: ```sh - mvn com.google.cloud.functions:function-maven-plugin:0.9.7:run \ + mvn com.google.cloud.functions:function-maven-plugin:0.10.0:run \ -Drun.functionTarget=com.example.function.Echo ``` @@ -187,7 +187,7 @@ Copy the Functions Framework jar to a local location like this: ```sh mvn dependency:copy \ - -Dartifact='com.google.cloud.functions.invoker:java-function-invoker:1.0.3' \ + -Dartifact='com.google.cloud.functions.invoker:java-function-invoker:1.1.0' \ -DoutputDirectory=. ``` @@ -195,7 +195,7 @@ In this example we use the current directory `.` but you can specify any other directory to copy to. Then run your function: ```sh -java -jar java-function-invoker-1.0.3 \ +java -jar java-function-invoker-1.1.0 \ --classpath myfunction.jar \ --target com.example.HelloWorld ``` @@ -215,7 +215,7 @@ configurations { dependencies { implementation 'com.google.cloud.functions:functions-framework-api:1.0.4' - invoker 'com.google.cloud.functions.invoker:java-function-invoker:1.0.2' + invoker 'com.google.cloud.functions.invoker:java-function-invoker:1.1.0' } tasks.register("runFunction", JavaExec) { @@ -288,7 +288,7 @@ Framework directly, you must use `--classpath` to indicate how to find the code and its dependencies. For example: ``` -java -jar java-function-invoker-1.0.3 \ +java -jar java-function-invoker-1.1.0 \ --classpath 'myfunction.jar:/some/directory:/some/library/*' \ --target com.example.HelloWorld ``` From 14908caa9e5be824dfb74fff3a3234c4bce688e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mathieu?= Date: Mon, 21 Feb 2022 19:05:36 +0100 Subject: [PATCH 025/239] feat: allow to stop the invoker (#128) --- .../functions/invoker/runner/Invoker.java | 76 ++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java index 3256e989..83ad121f 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java @@ -198,6 +198,8 @@ private static class FunctionClassLoader extends URLClassLoader { private final String functionSignatureType; private final ClassLoader functionClassLoader; + private Server server; + public Invoker( Integer port, String functionTarget, @@ -225,8 +227,58 @@ ClassLoader getFunctionClassLoader() { return functionClassLoader; } + /** + * This will start the server and wait (join) for function calls. + * To start the server inside a unit or integration test, use {@link #startTestServer()} instead. + * + * @see #stopServer() + * @throws Exception + */ public void startServer() throws Exception { - Server server = new Server(port); + startServer(true); + } + + + /** + * This will start the server and return. + * + * This method is designed to be used for unit or integration testing only. + * For other use cases use {@link #startServer()}. + * + * Inside a test a typical usage will be: + *
+   * {@code
+   *         // Create an invoker
+   *         Invoker invoker = new Invoker(
+   *                 8081,
+   *                 "org.example.MyHttpFunction",
+   *                 "http",
+   *                 Thread.currentThread().getContextClassLoader()
+   *         );
+   *
+   *         // Start the test server
+   *         invoker.startTestServer();
+   *
+   *         // Test the function
+   *
+   *         // Stop the test server
+   *         invoker.stopServer();
+   * }
+   * 
+ * + * @see #stopServer() + * @throws Exception + */ + public void startTestServer() throws Exception { + startServer(false); + } + + private void startServer(boolean join) throws Exception { + if (server != null) { + throw new IllegalStateException("Server already started"); + } + + server = new Server(port); ServletContextHandler servletContextHandler = new ServletContextHandler(); servletContextHandler.setContextPath("/"); @@ -261,7 +313,27 @@ public void startServer() throws Exception { server.start(); logServerInfo(); - server.join(); + if (join) { + server.join(); + } + } + + /** + * Stop the server. + * + * @see #startServer() + * @see #startTestServer() + * + * @throws Exception + */ + public void stopServer() throws Exception { + if (server == null) { + throw new IllegalStateException("Server not yet started"); + } + + server.stop(); + // setting the server to null, so it can be started again + server = null; } private Class loadFunctionClass() throws ClassNotFoundException { From aef01901fafcd9fa134a6b0234e7344b1140aaa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89amonn=20McManus?= Date: Mon, 21 Feb 2022 10:15:07 -0800 Subject: [PATCH 026/239] Fix formatting. (#129) * Fix formatting. * Another format fix, due to a change in the formatter. --- .../functions/invoker/runner/Invoker.java | 43 +++++++++---------- .../com/example/functionjar/Background.java | 4 +- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java index 83ad121f..b03b8c63 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java @@ -228,8 +228,8 @@ ClassLoader getFunctionClassLoader() { } /** - * This will start the server and wait (join) for function calls. - * To start the server inside a unit or integration test, use {@link #startTestServer()} instead. + * This will start the server and wait (join) for function calls. To start the server inside a + * unit or integration test, use {@link #startTestServer()} instead. * * @see #stopServer() * @throws Exception @@ -238,33 +238,31 @@ public void startServer() throws Exception { startServer(true); } - /** * This will start the server and return. * - * This method is designed to be used for unit or integration testing only. - * For other use cases use {@link #startServer()}. + *

This method is designed to be used for unit or integration testing only. For other use cases + * use {@link #startServer()}. + * + *

Inside a test a typical usage will be: * - * Inside a test a typical usage will be: - *

-   * {@code
-   *         // Create an invoker
-   *         Invoker invoker = new Invoker(
-   *                 8081,
-   *                 "org.example.MyHttpFunction",
-   *                 "http",
-   *                 Thread.currentThread().getContextClassLoader()
-   *         );
+   * 
{@code
+   * // Create an invoker
+   * Invoker invoker = new Invoker(
+   *         8081,
+   *         "org.example.MyHttpFunction",
+   *         "http",
+   *         Thread.currentThread().getContextClassLoader()
+   * );
    *
-   *         // Start the test server
-   *         invoker.startTestServer();
+   * // Start the test server
+   * invoker.startTestServer();
    *
-   *         // Test the function
+   * // Test the function
    *
-   *         // Stop the test server
-   *         invoker.stopServer();
-   * }
-   * 
+ * // Stop the test server + * invoker.stopServer(); + * }
* * @see #stopServer() * @throws Exception @@ -323,7 +321,6 @@ private void startServer(boolean join) throws Exception { * * @see #startServer() * @see #startTestServer() - * * @throws Exception */ public void stopServer() throws Exception { diff --git a/invoker/testfunction/src/test/java/com/example/functionjar/Background.java b/invoker/testfunction/src/test/java/com/example/functionjar/Background.java index 66123a08..6b18b54c 100644 --- a/invoker/testfunction/src/test/java/com/example/functionjar/Background.java +++ b/invoker/testfunction/src/test/java/com/example/functionjar/Background.java @@ -20,7 +20,9 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; -/** @author emcmanus@google.com (Éamonn McManus) */ +/** + * @author emcmanus@google.com (Éamonn McManus) + */ public class Background implements RawBackgroundFunction { @Override public void accept(String json, Context context) { From 0e052f376231192278061ec79bcf9d710ec310f4 Mon Sep 17 00:00:00 2001 From: Ludovic Champenois Date: Thu, 24 Mar 2022 10:37:35 -0700 Subject: [PATCH 027/239] fix: Add build env vars support for function deployment. (#133) * Add build env vars support for function deployment. * Format. * Format. --- .../functions/plugin/DeployFunction.java | 23 +++++++++++++++++++ .../functions/plugin/DeployFunctionTest.java | 4 ++++ 2 files changed, 27 insertions(+) diff --git a/invoker/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java b/invoker/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java index 74e0b73f..ed1f760a 100644 --- a/invoker/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java +++ b/invoker/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java @@ -200,11 +200,27 @@ public class DeployFunction extends CloudSdkMojo { */ @Parameter(alias = "deploy.envvarsfile", property = "function.deploy.envvarsfile") String envVarsFile; + /** + * List of key-value pairs to set as build environment variables. All existing environment variables + * will be removed first. + */ + @Parameter(alias = "deploy.setbuildenvvars", property = "function.deploy.setbuildenvvars") + Map buildEnvironmentVariables; + /** + * Path to a local YAML file with definitions for all build environment variables. All existing + * environment variables will be removed before the new environment variables are added. + */ + @Parameter(alias = "deploy.buildenvvarsfile", property = "function.deploy.buildenvvarsfile") + String buildEnvVarsFile; boolean hasEnvVariables() { return (this.environmentVariables != null && !this.environmentVariables.isEmpty()); } + boolean hasBuildEnvVariables() { + return (this.buildEnvironmentVariables != null && !this.buildEnvironmentVariables.isEmpty()); + } + // Select a downloaded Cloud SDK or a user defined Cloud SDK version. static Function newManagedSdkFactory() { return version -> { @@ -331,6 +347,13 @@ public List getCommands() { if (envVarsFile != null) { commands.add("--env-vars-file=" + envVarsFile); } + if (hasBuildEnvVariables()) { + Joiner.MapJoiner mapJoiner = Joiner.on(",").withKeyValueSeparator("="); + commands.add("--set-build-env-vars=" + mapJoiner.join(buildEnvironmentVariables)); + } + if (buildEnvVarsFile != null) { + commands.add("--build-env-vars-file=" + buildEnvVarsFile); + } commands.add("--runtime=" + runtime); if (projectId != null) { diff --git a/invoker/function-maven-plugin/src/test/java/com/google/cloud/functions/plugin/DeployFunctionTest.java b/invoker/function-maven-plugin/src/test/java/com/google/cloud/functions/plugin/DeployFunctionTest.java index f1730b96..e5a2913d 100644 --- a/invoker/function-maven-plugin/src/test/java/com/google/cloud/functions/plugin/DeployFunctionTest.java +++ b/invoker/function-maven-plugin/src/test/java/com/google/cloud/functions/plugin/DeployFunctionTest.java @@ -16,6 +16,7 @@ public class DeployFunctionTest { public void testDeployFunctionCommandLine() { DeployFunction mojo = new DeployFunction(); mojo.envVarsFile = "myfile"; + mojo.buildEnvVarsFile = "myfile2"; mojo.functionTarget = "function"; mojo.ignoreFile = "ff"; mojo.maxInstances = new Integer(3); @@ -30,6 +31,7 @@ public void testDeployFunctionCommandLine() { mojo.triggerHttp = true; mojo.allowUnauthenticated = true; mojo.environmentVariables = ImmutableMap.of("env1", "a", "env2", "b"); + mojo.buildEnvironmentVariables = ImmutableMap.of("env1", "a", "env2", "b"); List expected = ImmutableList.of( "functions", @@ -49,6 +51,8 @@ public void testDeployFunctionCommandLine() { "--max-instances=3", "--set-env-vars=env1=a,env2=b", "--env-vars-file=myfile", + "--set-build-env-vars=env1=a,env2=b", + "--build-env-vars-file=myfile2", "--runtime=java11"); assertThat(mojo.getCommands()).isEqualTo(expected); } From faff79d16c6df178d66f0185fb78fba003e60745 Mon Sep 17 00:00:00 2001 From: Ludovic Champenois Date: Thu, 24 Mar 2022 14:56:09 -0700 Subject: [PATCH 028/239] fix: bump dependency versions (#134) * Add build env vars support for function deployment. * Format. * Format. * fix: bump some dependendy versions to latest. --- invoker/core/pom.xml | 6 +++--- invoker/function-maven-plugin/pom.xml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index be3404bb..b751e6a2 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -97,17 +97,17 @@ org.eclipse.jetty jetty-servlet - 9.4.26.v20200117 + 9.4.45.v20220203 org.eclipse.jetty jetty-server - 9.4.26.v20200117 + 9.4.45.v20220203 com.beust jcommander - 1.78 + 1.82 diff --git a/invoker/function-maven-plugin/pom.xml b/invoker/function-maven-plugin/pom.xml index 09782cf5..bb3ee58a 100644 --- a/invoker/function-maven-plugin/pom.xml +++ b/invoker/function-maven-plugin/pom.xml @@ -50,7 +50,7 @@ com.google.cloud.tools appengine-maven-plugin - 2.2.0 + 2.4.1 jar From e9e53e3b52afbe94e1987693ff91f63617ae0241 Mon Sep 17 00:00:00 2001 From: Grant Timmerman <744973+grant@users.noreply.github.com> Date: Sun, 17 Apr 2022 08:27:14 -0700 Subject: [PATCH 029/239] style: fix lint issues (#135) Signed-off-by: Grant Timmerman --- .../com/google/cloud/functions/plugin/DeployFunction.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/invoker/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java b/invoker/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java index ed1f760a..509ccf3e 100644 --- a/invoker/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java +++ b/invoker/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java @@ -201,8 +201,8 @@ public class DeployFunction extends CloudSdkMojo { @Parameter(alias = "deploy.envvarsfile", property = "function.deploy.envvarsfile") String envVarsFile; /** - * List of key-value pairs to set as build environment variables. All existing environment variables - * will be removed first. + * List of key-value pairs to set as build environment variables. All existing environment + * variables will be removed first. */ @Parameter(alias = "deploy.setbuildenvvars", property = "function.deploy.setbuildenvvars") Map buildEnvironmentVariables; @@ -220,7 +220,7 @@ boolean hasEnvVariables() { boolean hasBuildEnvVariables() { return (this.buildEnvironmentVariables != null && !this.buildEnvironmentVariables.isEmpty()); } - + // Select a downloaded Cloud SDK or a user defined Cloud SDK version. static Function newManagedSdkFactory() { return version -> { From 1ef1fdd5c8f29672746deb3e11f81bf809075816 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 May 2022 15:16:41 -0700 Subject: [PATCH 030/239] Bump gson from 2.8.6 to 2.8.9 in /invoker/conformance (#138) Bumps [gson](https://github.com/google/gson) from 2.8.6 to 2.8.9. - [Release notes](https://github.com/google/gson/releases) - [Changelog](https://github.com/google/gson/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/gson/compare/gson-parent-2.8.6...gson-parent-2.8.9) --- updated-dependencies: - dependency-name: com.google.code.gson:gson dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- invoker/conformance/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 189f656f..9ae9fb7f 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -32,7 +32,7 @@ com.google.code.gson gson - 2.8.6 + 2.8.9 io.cloudevents From 5345cca5052f0ed04903169305179a98fa37df6b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 May 2022 15:16:58 -0700 Subject: [PATCH 031/239] Bump gson from 2.8.6 to 2.8.9 in /invoker/testfunction (#137) Bumps [gson](https://github.com/google/gson) from 2.8.6 to 2.8.9. - [Release notes](https://github.com/google/gson/releases) - [Changelog](https://github.com/google/gson/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/gson/compare/gson-parent-2.8.6...gson-parent-2.8.9) --- updated-dependencies: - dependency-name: com.google.code.gson:gson dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- invoker/testfunction/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index 6dada9d4..b361f97d 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -35,7 +35,7 @@ com.google.code.gson gson - 2.8.6 + 2.8.9 From 7afcfbbaa723d34cee7534ee8b3fe9834cd82877 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 May 2022 15:17:15 -0700 Subject: [PATCH 032/239] Bump gson from 2.8.6 to 2.8.9 in /invoker/core (#136) Bumps [gson](https://github.com/google/gson) from 2.8.6 to 2.8.9. - [Release notes](https://github.com/google/gson/releases) - [Changelog](https://github.com/google/gson/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/gson/compare/gson-parent-2.8.6...gson-parent-2.8.9) --- updated-dependencies: - dependency-name: com.google.code.gson:gson dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- invoker/core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index b751e6a2..1475c9e2 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -68,7 +68,7 @@ com.google.code.gson gson - 2.8.6 + 2.8.9 com.ryanharter.auto.value From 4726b572f6feb0e224f2ffeb0790a4916cb93afd Mon Sep 17 00:00:00 2001 From: Pratiksha Kap <107430880+kappratiksha@users.noreply.github.com> Date: Thu, 7 Jul 2022 14:47:05 -0700 Subject: [PATCH 033/239] chore: Add buildpack-integration-test for ff java (#140) * adding buildpack integration for java * add comments * addressing comments * accessing tmpdir * using/tmp * fixing minor errors * fixing comments --- .../workflows/buildpack-integration-test.yml | 30 +++++++++++ invoker/conformance/buildpack_pom.xml | 52 +++++++++++++++++++ invoker/conformance/prerun.sh | 39 ++++++++++++++ 3 files changed, 121 insertions(+) create mode 100644 .github/workflows/buildpack-integration-test.yml create mode 100644 invoker/conformance/buildpack_pom.xml create mode 100755 invoker/conformance/prerun.sh diff --git a/.github/workflows/buildpack-integration-test.yml b/.github/workflows/buildpack-integration-test.yml new file mode 100644 index 00000000..1c4b3a41 --- /dev/null +++ b/.github/workflows/buildpack-integration-test.yml @@ -0,0 +1,30 @@ +# Validates Functions Framework with GCF buildpacks. +name: Buildpack Integration Test +on: + push: + branches: + - master + workflow_dispatch: +jobs: + java11-buildpack-test: + uses: GoogleCloudPlatform/functions-framework-conformance/.github/workflows/buildpack-integration-test.yml@v1.4.1 + with: + http-builder-source: '/tmp/tests/conformance' + http-builder-target: 'com.google.cloud.functions.conformance.HttpConformanceFunction' + cloudevent-builder-source: '/tmp/tests/conformance' + cloudevent-builder-target: 'com.google.cloud.functions.conformance.CloudEventsConformanceFunction' + prerun: 'invoker/conformance/prerun.sh' + builder-runtime: 'java11' + # Latest uploaded tag from us.gcr.io/fn-img/us/buildpacks/java11/builder + builder-tag: 'java11_20220620_11_0_RC00' + java17-buildpack-test: + uses: GoogleCloudPlatform/functions-framework-conformance/.github/workflows/buildpack-integration-test.yml@v1.4.1 + with: + http-builder-source: '/tmp/tests/conformance' + http-builder-target: 'com.google.cloud.functions.conformance.HttpConformanceFunction' + cloudevent-builder-source: '/tmp/tests/conformance' + cloudevent-builder-target: 'com.google.cloud.functions.conformance.CloudEventsConformanceFunction' + prerun: 'invoker/conformance/prerun.sh' + builder-runtime: 'java17' + # Latest uploaded tag from us.gcr.io/fn-img/us/buildpacks/java17/builder + builder-tag: 'java17_20220617_17_0_RC00' \ No newline at end of file diff --git a/invoker/conformance/buildpack_pom.xml b/invoker/conformance/buildpack_pom.xml new file mode 100644 index 00000000..40fa9e78 --- /dev/null +++ b/invoker/conformance/buildpack_pom.xml @@ -0,0 +1,52 @@ + + + 4.0.0 + com.google.cloud.functions.invoker + conformance + 0.0.0-SNAPSHOT + + GCF Conformance Tests + + A GCF project used to validate conformance to the Functions Framework contract + using the Functions Framework Conformance tools. + + https://github.com/GoogleCloudPlatform/functions-framework-conformance + + + UTF-8 + 11 + 11 + + + + conformance + file:./artifacts + + + + com.google.cloud.functions + functions-framework-api + 0.0.0-SNAPSHOT + + + com.google.cloud.functions.invoker + java-function-invoker + 0.0.0-SNAPSHOT + + + com.google.code.gson + gson + 2.8.9 + + + io.cloudevents + cloudevents-core + 2.2.0 + + + io.cloudevents + cloudevents-json-jackson + 2.2.0 + + + \ No newline at end of file diff --git a/invoker/conformance/prerun.sh b/invoker/conformance/prerun.sh new file mode 100755 index 00000000..669d5f49 --- /dev/null +++ b/invoker/conformance/prerun.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# This script is used for buildpack validation. +# Its purpose is to run conformance tests using a buildpack +# with the latest code of functions-framework. +# +# Note: buildpack_pom.xml contains the configuration to use the local versions +# java-function-invoker and functions-framework-api. We will be using this file +# for running our conformance tests with buildpack. +# +# Steps: +# +# - Clear out the temp directory +# - Copy the conformance tests folder into temp +# - Build java-function-invoker with version 0.0.0-SNAPSHOT into artifacts +# folder +# - Build functions-framework-api with version 0.0.0-SNAPSHOT into artifacts +# folder +# - Ensure that we use the buildpack_pom.xml file by renaming it to pom.xml + + +set -e +REPO_ROOT=$(git rev-parse --show-toplevel) + +rm -rf /tmp/tests +mkdir /tmp/tests + +cp -r $REPO_ROOT/invoker/conformance /tmp/tests + +cd $REPO_ROOT/invoker +mvn versions:set -DnewVersion=0.0.0-SNAPSHOT -DprocessAllModules=true +mvn install -Dmaven.repo.local=/tmp/tests/conformance/artifacts + +cd $REPO_ROOT/functions-framework-api +mvn versions:set -DnewVersion=0.0.0-SNAPSHOT -DprocessAllModules=true +mvn install -Dmaven.repo.local=/tmp/tests/conformance/artifacts + +rm /tmp/tests/conformance/pom.xml +mv /tmp/tests/conformance/buildpack_pom.xml /tmp/tests/conformance/pom.xml From 439d0b5d77b2f765e65d84e7d5f31399e547d004 Mon Sep 17 00:00:00 2001 From: Pratiksha Kap <107430880+kappratiksha@users.noreply.github.com> Date: Thu, 11 Aug 2022 10:51:57 -0700 Subject: [PATCH 034/239] feat: Increase maximum concurrent requests for jetty server to 1000. (#144) * Scale java server to support 1000 concurrent requests --- .github/workflows/conformance.yaml | 24 +++++++---- .../ConcurrentHttpConformanceFunction.java | 41 +++++++++++++++++++ .../functions/invoker/runner/Invoker.java | 9 +++- run_conformance_tests.sh | 3 ++ 4 files changed, 69 insertions(+), 8 deletions(-) create mode 100644 invoker/conformance/src/main/java/com/google/cloud/functions/conformance/ConcurrentHttpConformanceFunction.java diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index fbd1ce18..5c56a303 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -25,7 +25,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v2 with: - go-version: '1.15' + go-version: '1.16' - name: Build API with Maven run: (cd functions-framework-api/ && mvn install) @@ -34,18 +34,18 @@ jobs: run: (cd invoker/ && mvn install) - name: Run HTTP conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.2.1 + uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.6.0 with: - version: 'v1.2.1' + version: 'v1.6.0' functionType: 'http' useBuildpacks: false cmd: "'mvn -f invoker/conformance/pom.xml function:run -Drun.functionTarget=com.google.cloud.functions.conformance.HttpConformanceFunction'" startDelay: 10 - name: Run background event conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.2.1 + uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.6.0 with: - version: 'v1.2.1' + version: 'v1.6.0' functionType: 'legacyevent' useBuildpacks: false validateMapping: true @@ -53,11 +53,21 @@ jobs: startDelay: 10 - name: Run cloudevent conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.2.1 + uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.6.0 with: - version: 'v1.2.1' + version: 'v1.6.0' functionType: 'cloudevent' useBuildpacks: false validateMapping: true cmd: "'mvn -f invoker/conformance/pom.xml function:run -Drun.functionTarget=com.google.cloud.functions.conformance.CloudEventsConformanceFunction'" startDelay: 10 + + - name: Run HTTP concurrency conformance tests + uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.6.0 + with: + version: 'v1.6.0' + functionType: 'http' + useBuildpacks: false + validateConcurrency: true + cmd: "'mvn -f invoker/conformance/pom.xml function:run -Drun.functionTarget=com.google.cloud.functions.conformance.ConcurrentHttpConformanceFunction'" + startDelay: 10 \ No newline at end of file diff --git a/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/ConcurrentHttpConformanceFunction.java b/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/ConcurrentHttpConformanceFunction.java new file mode 100644 index 00000000..a342b2ea --- /dev/null +++ b/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/ConcurrentHttpConformanceFunction.java @@ -0,0 +1,41 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.cloud.functions.conformance; + +import com.google.cloud.functions.HttpFunction; +import com.google.cloud.functions.HttpRequest; +import com.google.cloud.functions.HttpResponse; + +/** + * This class is used by the Functions Framework Conformance Tools to validate concurrency for HTTP + * functions. It can be run with the following command: + * + *
{@code
+ * $ functions-framework-conformance-client \
+ *   -cmd="mvn function:run -Drun.functionTarget=com.google.cloud.functions.conformance.ConcurrentHttpConformanceFunction" \
+ *   -type=http \
+ *   -buildpacks=false \
+ *   -validate-mapping=false \
+ *   -start-delay=5 \
+ *   -validate-concurrency=true
+ * }
+ */ +public class ConcurrentHttpConformanceFunction implements HttpFunction { + + @Override + public void service(HttpRequest request, HttpResponse response) throws InterruptedException { + Thread.sleep(1000); + } +} diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java index b03b8c63..d35e21ea 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java @@ -52,11 +52,14 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.HandlerWrapper; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.util.thread.QueuedThreadPool; /** * Java server that runs the user's code (a jar file) on HTTP request and an HTTP response is sent @@ -276,7 +279,11 @@ private void startServer(boolean join) throws Exception { throw new IllegalStateException("Server already started"); } - server = new Server(port); + QueuedThreadPool pool = new QueuedThreadPool(1024); + server = new Server(pool); + ServerConnector connector = new ServerConnector(server); + connector.setPort(port); + server.setConnectors(new Connector[] {connector}); ServletContextHandler servletContextHandler = new ServletContextHandler(); servletContextHandler.setContextPath("/"); diff --git a/run_conformance_tests.sh b/run_conformance_tests.sh index 6276f158..9f344caa 100755 --- a/run_conformance_tests.sh +++ b/run_conformance_tests.sh @@ -46,3 +46,6 @@ client -buildpacks=false -type=legacyevent -cmd='mvn -f invoker/conformance/pom. print_header "CLOUDEVENT CONFORMANCE TESTS" client -buildpacks=false -type=cloudevent -cmd='mvn -f invoker/conformance/pom.xml function:run -Drun.functionTarget=com.google.cloud.functions.conformance.CloudEventsConformanceFunction' -start-delay 5 -validate-mapping=false + +print_header "HTTP CONCURRENCY TESTS" +client -buildpacks=false -type=http -cmd='mvn -f invoker/conformance/pom.xml function:run -Drun.functionTarget=com.google.cloud.functions.conformance.ConcurrentHttpConformanceFunction' -start-delay 5 -validate-concurrency=true From 06fae5bf01d1322b5e12005fc735d1ccd3d1a721 Mon Sep 17 00:00:00 2001 From: Pratiksha Kap <107430880+kappratiksha@users.noreply.github.com> Date: Wed, 17 Aug 2022 13:44:51 -0700 Subject: [PATCH 035/239] chore: Prepare for next development iteration (#145) * [maven-release-plugin] prepare release java-function-invoker-parent-1.1.1 * [maven-release-plugin] prepare for next development iteration --- invoker/conformance/pom.xml | 6 +++--- invoker/core/pom.xml | 6 +++--- invoker/function-maven-plugin/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 9ae9fb7f..0a34c40d 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.1.1-SNAPSHOT + 1.1.2-SNAPSHOT com.google.cloud.functions.invoker conformance - 1.1.1-SNAPSHOT + 1.1.2-SNAPSHOT GCF Confromance Tests @@ -52,7 +52,7 @@ com.google.cloud.functions function-maven-plugin - 0.10.1-SNAPSHOT + 0.10.2-SNAPSHOT diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 1475c9e2..dab8e9ce 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.1.1-SNAPSHOT + 1.1.2-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker - 1.1.1-SNAPSHOT + 1.1.2-SNAPSHOT GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -114,7 +114,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.1.1-SNAPSHOT + 1.1.2-SNAPSHOT test-jar test diff --git a/invoker/function-maven-plugin/pom.xml b/invoker/function-maven-plugin/pom.xml index bb3ee58a..67b34ffd 100644 --- a/invoker/function-maven-plugin/pom.xml +++ b/invoker/function-maven-plugin/pom.xml @@ -4,13 +4,13 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.1.1-SNAPSHOT + 1.1.2-SNAPSHOT com.google.cloud.functions function-maven-plugin maven-plugin - 0.10.1-SNAPSHOT + 0.10.2-SNAPSHOT Functions Framework Plugin A Maven plugin that allows functions to be deployed, and to be run locally using the Java Functions Framework. @@ -44,7 +44,7 @@ com.google.cloud.functions.invoker java-function-invoker - 1.1.1-SNAPSHOT + 1.1.2-SNAPSHOT diff --git a/invoker/pom.xml b/invoker/pom.xml index 87b43b62..80862acf 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -8,7 +8,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.1.1-SNAPSHOT + 1.1.2-SNAPSHOT pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index b361f97d..e62b5f40 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.1.1-SNAPSHOT + 1.1.2-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.1.1-SNAPSHOT + 1.1.2-SNAPSHOT Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From 99908bb573a6fa6652f4ee8246bed2c8675fa0fa Mon Sep 17 00:00:00 2001 From: Pratiksha Kap <107430880+kappratiksha@users.noreply.github.com> Date: Wed, 17 Aug 2022 17:07:20 -0700 Subject: [PATCH 036/239] docs: update README.md to use latest release (#146) --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ade347b4..780a8c34 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,7 @@ You can configure the plugin in `pom.xml`: com.google.cloud.functions function-maven-plugin - 0.10.0 + 0.10.1 com.example.function.Echo @@ -176,7 +176,7 @@ mvn function:run You can alternatively configure the plugin with properties on the command line: ```sh - mvn com.google.cloud.functions:function-maven-plugin:0.10.0:run \ + mvn com.google.cloud.functions:function-maven-plugin:0.10.1:run \ -Drun.functionTarget=com.example.function.Echo ``` @@ -187,7 +187,7 @@ Copy the Functions Framework jar to a local location like this: ```sh mvn dependency:copy \ - -Dartifact='com.google.cloud.functions.invoker:java-function-invoker:1.1.0' \ + -Dartifact='com.google.cloud.functions.invoker:java-function-invoker:1.1.1' \ -DoutputDirectory=. ``` @@ -195,7 +195,7 @@ In this example we use the current directory `.` but you can specify any other directory to copy to. Then run your function: ```sh -java -jar java-function-invoker-1.1.0 \ +java -jar java-function-invoker-1.1.1 \ --classpath myfunction.jar \ --target com.example.HelloWorld ``` @@ -215,7 +215,7 @@ configurations { dependencies { implementation 'com.google.cloud.functions:functions-framework-api:1.0.4' - invoker 'com.google.cloud.functions.invoker:java-function-invoker:1.1.0' + invoker 'com.google.cloud.functions.invoker:java-function-invoker:1.1.1' } tasks.register("runFunction", JavaExec) { @@ -288,7 +288,7 @@ Framework directly, you must use `--classpath` to indicate how to find the code and its dependencies. For example: ``` -java -jar java-function-invoker-1.1.0 \ +java -jar java-function-invoker-1.1.1 \ --classpath 'myfunction.jar:/some/directory:/some/library/*' \ --target com.example.HelloWorld ``` From 925a75cc046626a49cc8d30c4ad99b249909f712 Mon Sep 17 00:00:00 2001 From: Pratiksha Kap <107430880+kappratiksha@users.noreply.github.com> Date: Fri, 2 Sep 2022 09:42:43 -0700 Subject: [PATCH 037/239] chore: Code restructuring. Move maven plugin into top level directory (#147) --- .../pom.xml | 63 ++++++++++++++++--- .../functions/plugin/DeployFunction.java | 0 .../cloud/functions/plugin/RunFunction.java | 0 .../functions/plugin/DeployFunctionTest.java | 0 invoker/conformance/pom.xml | 2 +- invoker/pom.xml | 1 - 6 files changed, 57 insertions(+), 9 deletions(-) rename {invoker/function-maven-plugin => function-maven-plugin}/pom.xml (57%) rename {invoker/function-maven-plugin => function-maven-plugin}/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java (100%) rename {invoker/function-maven-plugin => function-maven-plugin}/src/main/java/com/google/cloud/functions/plugin/RunFunction.java (100%) rename {invoker/function-maven-plugin => function-maven-plugin}/src/test/java/com/google/cloud/functions/plugin/DeployFunctionTest.java (100%) diff --git a/invoker/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml similarity index 57% rename from invoker/function-maven-plugin/pom.xml rename to function-maven-plugin/pom.xml index 67b34ffd..3297047a 100644 --- a/invoker/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -1,12 +1,6 @@ 4.0.0 - - com.google.cloud.functions.invoker - java-function-invoker-parent - 1.1.2-SNAPSHOT - - com.google.cloud.functions function-maven-plugin maven-plugin @@ -16,6 +10,13 @@ using the Java Functions Framework. http://maven.apache.org + + http://github.com/GoogleCloudPlatform/functions-framework-java + scm:git:git://github.com/GoogleCloudPlatform/functions-framework-java.git + scm:git:ssh://git@github.com/GoogleCloudPlatform/functions-framework-java.git + HEAD + + 8 8 @@ -44,7 +45,7 @@ com.google.cloud.functions.invoker java-function-invoker - 1.1.2-SNAPSHOT + 1.1.1 @@ -85,4 +86,52 @@
+ + + sonatype-nexus-snapshots + Sonatype Nexus Snapshots + https://oss.sonatype.org/content/repositories/snapshots/ + + + sonatype-nexus-staging + Nexus Release Repository + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + sonatype-oss-release + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + + + diff --git a/invoker/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java b/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java similarity index 100% rename from invoker/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java rename to function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java diff --git a/invoker/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/RunFunction.java b/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/RunFunction.java similarity index 100% rename from invoker/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/RunFunction.java rename to function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/RunFunction.java diff --git a/invoker/function-maven-plugin/src/test/java/com/google/cloud/functions/plugin/DeployFunctionTest.java b/function-maven-plugin/src/test/java/com/google/cloud/functions/plugin/DeployFunctionTest.java similarity index 100% rename from invoker/function-maven-plugin/src/test/java/com/google/cloud/functions/plugin/DeployFunctionTest.java rename to function-maven-plugin/src/test/java/com/google/cloud/functions/plugin/DeployFunctionTest.java diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 0a34c40d..06b13b59 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -52,7 +52,7 @@ com.google.cloud.functions function-maven-plugin - 0.10.2-SNAPSHOT + 0.10.1 diff --git a/invoker/pom.xml b/invoker/pom.xml index 80862acf..86bcb069 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -27,7 +27,6 @@ core testfunction - function-maven-plugin conformance From 9c88d183bc6bb0e591a2e107e7147eade9be1f7b Mon Sep 17 00:00:00 2001 From: Jihui Nie <56172920+jihuin@users.noreply.github.com> Date: Fri, 9 Sep 2022 13:53:24 -0700 Subject: [PATCH 038/239] chore: Check in initial kokoro build config and build script (#149) --- .kokoro/release.cfg | 14 ++++++++++++++ .kokoro/release.sh | 2 ++ 2 files changed, 16 insertions(+) create mode 100644 .kokoro/release.cfg create mode 100644 .kokoro/release.sh diff --git a/.kokoro/release.cfg b/.kokoro/release.cfg new file mode 100644 index 00000000..6fc853b0 --- /dev/null +++ b/.kokoro/release.cfg @@ -0,0 +1,14 @@ +build_file: "functions-framework-java/.kokoro/release.sh" + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 75669 + keyname: "functions-framework-java-release-bot-gpg-passphrase" + } + keystore_resource { + keystore_config_id: 75669 + keyname: "functions-framework-java-release-bot-sonatype-password" + } + } +} \ No newline at end of file diff --git a/.kokoro/release.sh b/.kokoro/release.sh new file mode 100644 index 00000000..67dd6dab --- /dev/null +++ b/.kokoro/release.sh @@ -0,0 +1,2 @@ +# Make sure `JAVA_HOME` is set. +echo "JAVA_HOME = $JAVA_HOME" \ No newline at end of file From 06d3f4437e75deba1cd3b0062bf508ae827f54ec Mon Sep 17 00:00:00 2001 From: Annie Fu <16651409+anniefu@users.noreply.github.com> Date: Mon, 12 Sep 2022 10:50:12 -0700 Subject: [PATCH 039/239] chore: setup Release Please (#148) * chore: setup Release Please This creates PRs that can be merged to create GitHub Releases for each of the components of Functions Framework Java. --- .github/.release-please-manifest.json | 1 + .github/release-please-config.json | 73 +++++++++++++++++++++++++++ .github/release-please.yml | 5 ++ 3 files changed, 79 insertions(+) create mode 100644 .github/.release-please-manifest.json create mode 100644 .github/release-please-config.json create mode 100644 .github/release-please.yml diff --git a/.github/.release-please-manifest.json b/.github/.release-please-manifest.json new file mode 100644 index 00000000..369e3ece --- /dev/null +++ b/.github/.release-please-manifest.json @@ -0,0 +1 @@ +{"functions-framework-api":"1.0.4","invoker":"1.1.1","function-maven-plugin":"0.10.1"} \ No newline at end of file diff --git a/.github/release-please-config.json b/.github/release-please-config.json new file mode 100644 index 00000000..afc739a2 --- /dev/null +++ b/.github/release-please-config.json @@ -0,0 +1,73 @@ +{ + "separate-pull-requests": true, + "packages": { + "functions-framework-api": { + "release-type": "maven", + "component": "functions-framework-api", + "extra-files": [ + { + "type": "xml", + "path": "pom.xml", + "xpath": "//*[local-name()='artifactId' and text()='functions-framework-api']/parent::*/*[local-name()='version']" + } + ] + }, + "invoker": { + "release-type": "maven", + "component": "java-function-invoker", + "extra-files": [ + { + "type": "xml", + "path": "pom.xml", + "xpath": "//*[local-name()='artifactId' and text()='java-function-invoker-parent']/parent::*/*[local-name()='version']" + }, + { + "type": "xml", + "path": "core/pom.xml", + "xpath": "//*[local-name()='artifactId' and text()='java-function-invoker-parent']/parent::*/*[local-name()='version']" + }, + { + "type": "xml", + "path": "core/pom.xml", + "xpath": "//*[local-name()='artifactId' and text()='java-function-invoker']/parent::*/*[local-name()='version']" + }, + { + "type": "xml", + "path": "core/pom.xml", + "xpath": "//*[local-name()='artifactId' and text()='java-function-invoker-testfunction']/parent::*/*[local-name()='version']" + }, + { + "type": "xml", + "path": "conformance/pom.xml", + "xpath": "//*[local-name()='artifactId' and text()='java-function-invoker-parent']/parent::*/*[local-name()='version']" + }, + { + "type": "xml", + "path": "conformance/pom.xml", + "xpath": "//*[local-name()='artifactId' and text()='conformance']/parent::*/*[local-name()='version']" + }, + { + "type": "xml", + "path": "testfunction/pom.xml", + "xpath": "//*[local-name()='artifactId' and text()='java-function-invoker-parent']/parent::*/*[local-name()='version']" + }, + { + "type": "xml", + "path": "testfunction/pom.xml", + "xpath": "//*[local-name()='artifactId' and text()='java-function-invoker-testfunction']/parent::*/*[local-name()='version']" + } + ] + }, + "function-maven-plugin": { + "release-type": "maven", + "component": "function-maven-plugin", + "extra-files": [ + { + "type": "xml", + "path": "pom.xml", + "xpath": "//*[local-name()='artifactId' and text()='function-maven-plugin']/parent::*/*[local-name()='version']" + } + ] + } + } +} \ No newline at end of file diff --git a/.github/release-please.yml b/.github/release-please.yml new file mode 100644 index 00000000..2e936db0 --- /dev/null +++ b/.github/release-please.yml @@ -0,0 +1,5 @@ +handleGHRelease: true +monorepoTags: true +manifest: true +manifestConfig: '.github/release-please-config.json' +manifestFile: '.github/.release-please-manifest.json' \ No newline at end of file From e82898654bc7735ed38cc3c85d05e8839b18e0a1 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 10:58:26 -0700 Subject: [PATCH 040/239] chore(master): release function-maven-plugin 0.10.2-SNAPSHOT (#152) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> From 919e515019ef638874de807396bb4146e3d230aa Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 11:09:54 -0700 Subject: [PATCH 041/239] chore(master): release java-function-invoker 1.1.2-SNAPSHOT (#151) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> From 72f14378d82816a1c283bd5cdb757cbe75a6d387 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 11:10:12 -0700 Subject: [PATCH 042/239] chore(master): release functions-framework-api 1.0.5-SNAPSHOT (#150) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> From b0c80dd0e0e55b0744ed2bd3cee8cd5cb174bde3 Mon Sep 17 00:00:00 2001 From: Jihui Nie <56172920+jihuin@users.noreply.github.com> Date: Tue, 13 Sep 2022 13:09:58 -0700 Subject: [PATCH 043/239] chore: Print kokoro job name in script (#155) * chore: Check in initial kokoro build config and build script * chore: Print out kokoro job name * remove space in printed out strings --- .kokoro/release.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.kokoro/release.sh b/.kokoro/release.sh index 67dd6dab..ba9d33e3 100644 --- a/.kokoro/release.sh +++ b/.kokoro/release.sh @@ -1,2 +1,6 @@ +#!/bin/bash + # Make sure `JAVA_HOME` is set. -echo "JAVA_HOME = $JAVA_HOME" \ No newline at end of file +echo "JAVA_HOME=$JAVA_HOME" + +echo "KOKORO_JOB_NAME=${KOKORO_JOB_NAME}" From 1845551f13274676b2bed28cc6a279122c33c913 Mon Sep 17 00:00:00 2001 From: Jihui Nie <56172920+jihuin@users.noreply.github.com> Date: Wed, 14 Sep 2022 13:57:28 -0700 Subject: [PATCH 044/239] chore: add nexus-staging-maven-plugin for auto closing the staging repo (#156) --- function-maven-plugin/pom.xml | 29 +++++++++++-- functions-framework-api/pom.xml | 11 +++++ invoker/pom.xml | 73 +++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 3 deletions(-) diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml index 3297047a..43124011 100644 --- a/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -18,9 +18,8 @@ - 8 - 8 - 8 + 11 + 11 @@ -116,6 +115,19 @@ + + org.apache.maven.plugins + maven-javadoc-plugin + 3.1.0 + + + attach-javadocs + + jar + + + + org.apache.maven.plugins maven-gpg-plugin @@ -130,6 +142,17 @@ + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.13 + true + + sonatype-nexus-snapshots + https://oss.sonatype.org/ + false + + diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index 27246b71..4e779dc6 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -186,6 +186,17 @@ + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.13 + true + + sonatype-nexus-snapshots + https://oss.sonatype.org/ + false + + diff --git a/invoker/pom.xml b/invoker/pom.xml index 86bcb069..6d0113ba 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -46,4 +46,77 @@ + + + + sonatype-nexus-snapshots + Sonatype Nexus Snapshots + https://oss.sonatype.org/content/repositories/snapshots/ + + + sonatype-nexus-staging + Nexus Release Repository + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + sonatype-oss-release + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.1.0 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.13 + true + + sonatype-nexus-snapshots + https://oss.sonatype.org/ + false + + + + + + From 58222eedb4db5836261cf6c452bd6c307e25466d Mon Sep 17 00:00:00 2001 From: Jihui Nie <56172920+jihuin@users.noreply.github.com> Date: Thu, 15 Sep 2022 15:15:40 -0700 Subject: [PATCH 045/239] chore: Update kokoro build script to push to Maven (#157) * chore: update build script to push to Maven * print out the current dir * comment on the gpg keybox file * add more mvn flags --- .kokoro/release.cfg | 6 ++++- .kokoro/release.sh | 63 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/.kokoro/release.cfg b/.kokoro/release.cfg index 6fc853b0..109948a0 100644 --- a/.kokoro/release.cfg +++ b/.kokoro/release.cfg @@ -2,6 +2,10 @@ build_file: "functions-framework-java/.kokoro/release.sh" before_action { fetch_keystore { + keystore_resource { + keystore_config_id: 75669 + keyname: "functions-framework-java-release-bot-gpg-pubring" + } keystore_resource { keystore_config_id: 75669 keyname: "functions-framework-java-release-bot-gpg-passphrase" @@ -11,4 +15,4 @@ before_action { keyname: "functions-framework-java-release-bot-sonatype-password" } } -} \ No newline at end of file +} diff --git a/.kokoro/release.sh b/.kokoro/release.sh index ba9d33e3..abd3b431 100644 --- a/.kokoro/release.sh +++ b/.kokoro/release.sh @@ -1,6 +1,65 @@ #!/bin/bash -# Make sure `JAVA_HOME` is set. -echo "JAVA_HOME=$JAVA_HOME" +# Get secrets from keystore and set and environment variables. +setup_environment_secrets() { + export SONATYPE_USERNAME=functions-framework-release-bot + export SONATYPE_PASSWORD=$(cat ${KOKORO_KEYSTORE_DIR}/75669_functions-framework-java-release-bot-sonatype-password) + export GPG_PASSPHRASE=$(cat ${KOKORO_KEYSTORE_DIR}/75669_functions-framework-java-release-bot-gpg-passphrase) + + # Add the keybox file to $GNUPGHOME to verify the GPG credentials. + export GNUPGHOME=/tmp/gpg + mkdir $GNUPGHOME + mv ${KOKORO_KEYSTORE_DIR}/75669_functions-framework-java-release-bot-gpg-pubring $GNUPGHOME/pubring.kbx +} + +create_settings_xml_file() { + echo " + + + + true + + + ${GPG_PASSPHRASE} + + + + + + sonatype-nexus-staging + ${SONATYPE_USERNAME} + ${SONATYPE_PASSWORD} + + + sonatype-nexus-snapshots + ${SONATYPE_USERNAME} + ${SONATYPE_PASSWORD} + + +" > $1 +} +setup_environment_secrets + +# Pick the right package to release based on the Kokoro job name. +cd ${KOKORO_ARTIFACTS_DIR}/github/functions-framework-java +create_settings_xml_file "settings.xml" echo "KOKORO_JOB_NAME=${KOKORO_JOB_NAME}" +if [[ $KOKORO_JOB_NAME == *"function-maven-plugin"* ]]; then + cd function-maven-plugin +elif [[ $KOKORO_JOB_NAME == *"functions-framework-api"* ]]; then + cd functions-framework-api +else + cd invoker +fi +echo "pwd=$(pwd)" + +# Make sure `JAVA_HOME` is set and using jdk11. +sudo update-java-alternatives --set java-1.11.0-openjdk-amd64 +echo "JAVA_HOME=$JAVA_HOME" +mvn clean deploy -B \ + -P sonatype-oss-release \ + --settings=../settings.xml \ + -Dgpg.executable=gpg \ + -Dgpg.passphrase=${GPG_PASSPHRASE} \ + -Dgpg.homedir=${GNUPGHOME} From ffcda6009a5475355e02945878ab37a416ab43ac Mon Sep 17 00:00:00 2001 From: Jihui Nie <56172920+jihuin@users.noreply.github.com> Date: Thu, 15 Sep 2022 17:05:10 -0700 Subject: [PATCH 046/239] chore: explicitly set JAVA_HOME (#158) --- .kokoro/release.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.kokoro/release.sh b/.kokoro/release.sh index abd3b431..5cd5449b 100644 --- a/.kokoro/release.sh +++ b/.kokoro/release.sh @@ -55,7 +55,7 @@ fi echo "pwd=$(pwd)" # Make sure `JAVA_HOME` is set and using jdk11. -sudo update-java-alternatives --set java-1.11.0-openjdk-amd64 +export JAVA_HOME=/usr/lib/jvm/java-1.11.0-openjdk-amd64 echo "JAVA_HOME=$JAVA_HOME" mvn clean deploy -B \ -P sonatype-oss-release \ From a74d17814a9f37dbc9124f84f1c7018eda1083cc Mon Sep 17 00:00:00 2001 From: Jihui Nie <56172920+jihuin@users.noreply.github.com> Date: Thu, 15 Sep 2022 18:28:26 -0700 Subject: [PATCH 047/239] chore: restart gpg agent (#159) --- .kokoro/release.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.kokoro/release.sh b/.kokoro/release.sh index 5cd5449b..b3324f20 100644 --- a/.kokoro/release.sh +++ b/.kokoro/release.sh @@ -10,6 +10,8 @@ setup_environment_secrets() { export GNUPGHOME=/tmp/gpg mkdir $GNUPGHOME mv ${KOKORO_KEYSTORE_DIR}/75669_functions-framework-java-release-bot-gpg-pubring $GNUPGHOME/pubring.kbx + # Restart the gpg-agent to avoid the error of no default secret key. + gpg -k } create_settings_xml_file() { From fea34f64b6c10d95259385ecd0e6733ee4ec898a Mon Sep 17 00:00:00 2001 From: Jihui Nie <56172920+jihuin@users.noreply.github.com> Date: Fri, 16 Sep 2022 14:04:02 -0700 Subject: [PATCH 048/239] chore: use gpg2 to sign the packages (#160) --- .kokoro/release.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.kokoro/release.sh b/.kokoro/release.sh index b3324f20..e08a55e1 100644 --- a/.kokoro/release.sh +++ b/.kokoro/release.sh @@ -1,5 +1,8 @@ #!/bin/bash +# Stop execution when any command fails. +set -e + # Get secrets from keystore and set and environment variables. setup_environment_secrets() { export SONATYPE_USERNAME=functions-framework-release-bot @@ -11,7 +14,7 @@ setup_environment_secrets() { mkdir $GNUPGHOME mv ${KOKORO_KEYSTORE_DIR}/75669_functions-framework-java-release-bot-gpg-pubring $GNUPGHOME/pubring.kbx # Restart the gpg-agent to avoid the error of no default secret key. - gpg -k + gpg2 -k } create_settings_xml_file() { @@ -62,6 +65,6 @@ echo "JAVA_HOME=$JAVA_HOME" mvn clean deploy -B \ -P sonatype-oss-release \ --settings=../settings.xml \ - -Dgpg.executable=gpg \ + -Dgpg.executable=gpg2 \ -Dgpg.passphrase=${GPG_PASSPHRASE} \ -Dgpg.homedir=${GNUPGHOME} From daa3c045d7f08dd3e76c1ed55650e6c629fad2ec Mon Sep 17 00:00:00 2001 From: Jihui Nie <56172920+jihuin@users.noreply.github.com> Date: Fri, 16 Sep 2022 14:43:44 -0700 Subject: [PATCH 049/239] chore: don't list all keys in the gpg keybox (#161) --- .kokoro/release.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/.kokoro/release.sh b/.kokoro/release.sh index e08a55e1..7a946000 100644 --- a/.kokoro/release.sh +++ b/.kokoro/release.sh @@ -13,8 +13,6 @@ setup_environment_secrets() { export GNUPGHOME=/tmp/gpg mkdir $GNUPGHOME mv ${KOKORO_KEYSTORE_DIR}/75669_functions-framework-java-release-bot-gpg-pubring $GNUPGHOME/pubring.kbx - # Restart the gpg-agent to avoid the error of no default secret key. - gpg2 -k } create_settings_xml_file() { From 1e29d09ccfc1db9659d4573999f668df0369d17b Mon Sep 17 00:00:00 2001 From: Jihui Nie <56172920+jihuin@users.noreply.github.com> Date: Mon, 19 Sep 2022 13:40:01 -0700 Subject: [PATCH 050/239] chore: update gpg credentials for signing Maven jars (#162) --- .kokoro/release.cfg | 14 +++++++++----- .kokoro/release.sh | 10 ++++++---- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/.kokoro/release.cfg b/.kokoro/release.cfg index 109948a0..f2ee4665 100644 --- a/.kokoro/release.cfg +++ b/.kokoro/release.cfg @@ -4,15 +4,19 @@ before_action { fetch_keystore { keystore_resource { keystore_config_id: 75669 - keyname: "functions-framework-java-release-bot-gpg-pubring" + keyname: "functions-framework-java-release-bot-sonatype-password" } keystore_resource { - keystore_config_id: 75669 - keyname: "functions-framework-java-release-bot-gpg-passphrase" + keystore_config_id: 70247 + keyname: "maven-gpg-pubkeyring" } keystore_resource { - keystore_config_id: 75669 - keyname: "functions-framework-java-release-bot-sonatype-password" + keystore_config_id: 70247 + keyname: "maven-gpg-keyring" + } + keystore_resource { + keystore_config_id: 70247 + keyname: "maven-gpg-passphrase" } } } diff --git a/.kokoro/release.sh b/.kokoro/release.sh index 7a946000..2e3a96d3 100644 --- a/.kokoro/release.sh +++ b/.kokoro/release.sh @@ -7,12 +7,14 @@ set -e setup_environment_secrets() { export SONATYPE_USERNAME=functions-framework-release-bot export SONATYPE_PASSWORD=$(cat ${KOKORO_KEYSTORE_DIR}/75669_functions-framework-java-release-bot-sonatype-password) - export GPG_PASSPHRASE=$(cat ${KOKORO_KEYSTORE_DIR}/75669_functions-framework-java-release-bot-gpg-passphrase) + export GPG_PASSPHRASE=$(cat ${KOKORO_KEYSTORE_DIR}/70247_maven-gpg-passphrase) - # Add the keybox file to $GNUPGHOME to verify the GPG credentials. + # Add the key ring files to $GNUPGHOME to verify the GPG credentials. export GNUPGHOME=/tmp/gpg mkdir $GNUPGHOME - mv ${KOKORO_KEYSTORE_DIR}/75669_functions-framework-java-release-bot-gpg-pubring $GNUPGHOME/pubring.kbx + mv ${KOKORO_KEYSTORE_DIR}/70247_maven-gpg-pubkeyring $GNUPGHOME/pubring.gpg + mv ${KOKORO_KEYSTORE_DIR}/70247_maven-gpg-keyring $GNUPGHOME/secring.gpg + gpg -k } create_settings_xml_file() { @@ -63,6 +65,6 @@ echo "JAVA_HOME=$JAVA_HOME" mvn clean deploy -B \ -P sonatype-oss-release \ --settings=../settings.xml \ - -Dgpg.executable=gpg2 \ + -Dgpg.executable=gpg \ -Dgpg.passphrase=${GPG_PASSPHRASE} \ -Dgpg.homedir=${GNUPGHOME} From f7f6e6dcf4cd0a0ba0eaf7e5de342215f563b460 Mon Sep 17 00:00:00 2001 From: Jihui Nie <56172920+jihuin@users.noreply.github.com> Date: Mon, 3 Oct 2022 16:24:54 -0700 Subject: [PATCH 051/239] chore: enable release trigger (#163) --- .github/release-trigger.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/release-trigger.yml diff --git a/.github/release-trigger.yml b/.github/release-trigger.yml new file mode 100644 index 00000000..7fe36225 --- /dev/null +++ b/.github/release-trigger.yml @@ -0,0 +1 @@ +enabled: true \ No newline at end of file From f5231a2303aa3565b29d494936e40ee1ec78fdbb Mon Sep 17 00:00:00 2001 From: Jihui Nie <56172920+jihuin@users.noreply.github.com> Date: Wed, 5 Oct 2022 13:44:04 -0700 Subject: [PATCH 052/239] fix: bump jetty version to 9.4.49.v20220914 (#164) --- invoker/core/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index dab8e9ce..80727128 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -97,12 +97,12 @@ org.eclipse.jetty jetty-servlet - 9.4.45.v20220203 + 9.4.49.v20220914 org.eclipse.jetty jetty-server - 9.4.45.v20220203 + 9.4.49.v20220914 com.beust From 4a4e471d05c93a95c5bb84dadd71ab7ae92352f0 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Wed, 5 Oct 2022 14:12:41 -0700 Subject: [PATCH 053/239] chore(master): release java-function-invoker 1.2.0 (#154) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- .github/.release-please-manifest.json | 2 +- invoker/CHANGELOG.md | 19 +++++++++++++++++++ invoker/conformance/pom.xml | 6 +++--- invoker/core/pom.xml | 8 ++++---- invoker/pom.xml | 4 ++-- invoker/testfunction/pom.xml | 6 +++--- 6 files changed, 32 insertions(+), 13 deletions(-) create mode 100644 invoker/CHANGELOG.md diff --git a/.github/.release-please-manifest.json b/.github/.release-please-manifest.json index 369e3ece..485ec31c 100644 --- a/.github/.release-please-manifest.json +++ b/.github/.release-please-manifest.json @@ -1 +1 @@ -{"functions-framework-api":"1.0.4","invoker":"1.1.1","function-maven-plugin":"0.10.1"} \ No newline at end of file +{"functions-framework-api":"1.0.4","invoker":"1.2.0","function-maven-plugin":"0.10.1"} \ No newline at end of file diff --git a/invoker/CHANGELOG.md b/invoker/CHANGELOG.md new file mode 100644 index 00000000..21d264fc --- /dev/null +++ b/invoker/CHANGELOG.md @@ -0,0 +1,19 @@ +# Changelog + +## [1.2.0](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/java-function-invoker-v1.1.1...java-function-invoker-v1.2.0) (2022-10-05) + + +### Features + +* allow to stop the invoker ([#128](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/128)) ([14908ca](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/14908caa9e5be824dfb74fff3a3234c4bce688e7)) +* enable converting CloudEvent requests to Background Event requests ([#123](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/123)) ([1c4a014](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/1c4a01470cc4ee7b3de3c3d7ae4af24e47eb2810)) +* Increase maximum concurrent requests for jetty server to 1000. ([#144](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/144)) ([439d0b5](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/439d0b5d77b2f765e65d84e7d5f31399e547d004)) + + +### Bug Fixes + +* Add build env vars support for function deployment. ([#133](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/133)) ([0e052f3](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/0e052f376231192278061ec79bcf9d710ec310f4)) +* bump dependency versions ([#134](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/134)) ([faff79d](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/faff79d16c6df178d66f0185fb78fba003e60745)) +* bump jetty version to 9.4.49.v20220914 ([#164](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/164)) ([f5231a2](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/f5231a2303aa3565b29d494936e40ee1ec78fdbb)) +* make user function exceptions log level SEVERE ([#113](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/113)) ([1684c0e](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/1684c0ef55dc33f2c4c7f7514d99b0e7af75c44f)) +* update conformance tests ([#108](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/108)) ([72852d0](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/72852d0f23cdaed48569245440dcd1533c8c7563)) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 06b13b59..baa9ec63 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.1.2-SNAPSHOT + 1.2.0 com.google.cloud.functions.invoker conformance - 1.1.2-SNAPSHOT + 1.2.0 GCF Confromance Tests @@ -57,4 +57,4 @@ - + \ No newline at end of file diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 80727128..1139e1ed 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.1.2-SNAPSHOT + 1.2.0 com.google.cloud.functions.invoker java-function-invoker - 1.1.2-SNAPSHOT + 1.2.0 GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -114,7 +114,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.1.2-SNAPSHOT + 1.2.0 test-jar test @@ -183,4 +183,4 @@ - + \ No newline at end of file diff --git a/invoker/pom.xml b/invoker/pom.xml index 6d0113ba..9f363ab5 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -8,7 +8,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.1.2-SNAPSHOT + 1.2.0 pom GCF Java Invoker Parent @@ -119,4 +119,4 @@ - + \ No newline at end of file diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index e62b5f40..ab0b7a00 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.1.2-SNAPSHOT + 1.2.0 com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.1.2-SNAPSHOT + 1.2.0 Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. @@ -92,4 +92,4 @@ - + \ No newline at end of file From 2bd81be88f8b99e2d4a23f0c9c1a9a429f9f1d86 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Thu, 6 Oct 2022 14:47:56 -0700 Subject: [PATCH 054/239] chore(master): release java-function-invoker 1.2.1-SNAPSHOT (#165) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- invoker/conformance/pom.xml | 4 ++-- invoker/core/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index baa9ec63..4531c93c 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.2.0 + 1.2.1-SNAPSHOT com.google.cloud.functions.invoker conformance - 1.2.0 + 1.2.1-SNAPSHOT GCF Confromance Tests diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 1139e1ed..6688f2b9 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.2.0 + 1.2.1-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker - 1.2.0 + 1.2.1-SNAPSHOT GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -114,7 +114,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.2.0 + 1.2.1-SNAPSHOT test-jar test diff --git a/invoker/pom.xml b/invoker/pom.xml index 9f363ab5..d1b0e50f 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -8,7 +8,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.2.0 + 1.2.1-SNAPSHOT pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index ab0b7a00..d89eef20 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.2.0 + 1.2.1-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.2.0 + 1.2.1-SNAPSHOT Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From 6a6662c2a61472f5bfaad806dec370c065ee386f Mon Sep 17 00:00:00 2001 From: Jihui Nie <56172920+jihuin@users.noreply.github.com> Date: Thu, 6 Oct 2022 14:54:47 -0700 Subject: [PATCH 055/239] chore: auto release to Maven after closing staging repo (#166) --- function-maven-plugin/pom.xml | 2 +- functions-framework-api/pom.xml | 2 +- invoker/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml index 43124011..61e69484 100644 --- a/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -150,7 +150,7 @@ sonatype-nexus-snapshots https://oss.sonatype.org/ - false + true diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index 4e779dc6..565aa357 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -194,7 +194,7 @@ sonatype-nexus-snapshots https://oss.sonatype.org/ - false + true diff --git a/invoker/pom.xml b/invoker/pom.xml index d1b0e50f..44640217 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -112,7 +112,7 @@ sonatype-nexus-snapshots https://oss.sonatype.org/ - false + true From 99b162a91c6a1089597c550e76dd28c083a09ce4 Mon Sep 17 00:00:00 2001 From: Annie Fu <16651409+anniefu@users.noreply.github.com> Date: Mon, 7 Nov 2022 15:15:15 -0800 Subject: [PATCH 056/239] chore: update buildpack integration test (#168) --- .github/workflows/buildpack-integration-test.yml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/buildpack-integration-test.yml b/.github/workflows/buildpack-integration-test.yml index 1c4b3a41..6d290f64 100644 --- a/.github/workflows/buildpack-integration-test.yml +++ b/.github/workflows/buildpack-integration-test.yml @@ -7,7 +7,7 @@ on: workflow_dispatch: jobs: java11-buildpack-test: - uses: GoogleCloudPlatform/functions-framework-conformance/.github/workflows/buildpack-integration-test.yml@v1.4.1 + uses: GoogleCloudPlatform/functions-framework-conformance/.github/workflows/buildpack-integration-test.yml@v1.8.0 with: http-builder-source: '/tmp/tests/conformance' http-builder-target: 'com.google.cloud.functions.conformance.HttpConformanceFunction' @@ -15,16 +15,12 @@ jobs: cloudevent-builder-target: 'com.google.cloud.functions.conformance.CloudEventsConformanceFunction' prerun: 'invoker/conformance/prerun.sh' builder-runtime: 'java11' - # Latest uploaded tag from us.gcr.io/fn-img/us/buildpacks/java11/builder - builder-tag: 'java11_20220620_11_0_RC00' java17-buildpack-test: - uses: GoogleCloudPlatform/functions-framework-conformance/.github/workflows/buildpack-integration-test.yml@v1.4.1 + uses: GoogleCloudPlatform/functions-framework-conformance/.github/workflows/buildpack-integration-test.yml@v1.8.0 with: http-builder-source: '/tmp/tests/conformance' http-builder-target: 'com.google.cloud.functions.conformance.HttpConformanceFunction' cloudevent-builder-source: '/tmp/tests/conformance' cloudevent-builder-target: 'com.google.cloud.functions.conformance.CloudEventsConformanceFunction' prerun: 'invoker/conformance/prerun.sh' - builder-runtime: 'java17' - # Latest uploaded tag from us.gcr.io/fn-img/us/buildpacks/java17/builder - builder-tag: 'java17_20220617_17_0_RC00' \ No newline at end of file + builder-runtime: 'java17' \ No newline at end of file From 64ead930064fff55424d6337ea75caf63f9a30e6 Mon Sep 17 00:00:00 2001 From: Andras Kerekes Date: Tue, 29 Nov 2022 10:13:39 -0800 Subject: [PATCH 057/239] Fix type in README.md (#169) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 780a8c34..9edaee1e 100644 --- a/README.md +++ b/README.md @@ -305,7 +305,7 @@ It is a list of entries separated by `:` (`;` on Windows), where each entry is: in that directory (file called `foo.jar`) is treated the same way as if it had been named explicitly. -#### Simplifying the claspath +#### Simplifying the classpath Specifying the right classpath can be tricky. A simpler alternative is to build the function as a "fat jar", where the function code and all its From 3b7b70152ca614e2a3b52f1a7c07d89221095a7d Mon Sep 17 00:00:00 2001 From: Pablo Perich Date: Thu, 1 Dec 2022 19:08:33 -0300 Subject: [PATCH 058/239] feat: Add --gen2 support (#172) --- .../google/cloud/functions/plugin/DeployFunction.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java b/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java index 509ccf3e..821467e0 100644 --- a/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java +++ b/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java @@ -212,7 +212,12 @@ public class DeployFunction extends CloudSdkMojo { */ @Parameter(alias = "deploy.buildenvvarsfile", property = "function.deploy.buildenvvarsfile") String buildEnvVarsFile; - + /** + * If true, deploys the function in the 2nd Generation Environment. + */ + @Parameter(alias = "deploy.gen2", property = "function.deploy.gen2", defaultValue = "false") + boolean gen2; + boolean hasEnvVariables() { return (this.environmentVariables != null && !this.environmentVariables.isEmpty()); } @@ -287,6 +292,9 @@ public List getCommands() { commands.add("functions"); commands.add("deploy"); commands.add(name); + if (gen2) { + commands.add("--gen2"); + } if (region != null) { commands.add("--region=" + region); } From 19fd8ebfe4b5267e858a865c447f279d6f8b5db1 Mon Sep 17 00:00:00 2001 From: Annie Fu <16651409+anniefu@users.noreply.github.com> Date: Thu, 1 Dec 2022 17:22:08 -0800 Subject: [PATCH 059/239] chore: fix formatting and linting action (#174) * chore: fix formatting and linting action * fix formatting in DeployFunction.java --- .github/workflows/lint.yaml | 14 +++++--------- .../cloud/functions/plugin/DeployFunction.java | 6 ++---- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 82a20cfe..a6356989 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -25,16 +25,12 @@ jobs: formatting: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 # v2 minimum required + - uses: actions/checkout@v3 # v2 minimum required - name: Run formatter id: formatter uses: axel-op/googlejavaformat-action@v3 with: - args: "--dry-run --set-exit-if-changed" - continue-on-error: true - - name: Check for failure - if: steps.formatter.outcome != 'success' - run: | - echo "Java format check failed, see 'Run formatter' step for more information." - echo "See https://github.com/google/google-java-format for options on running the formatter locally." - exit 1 \ No newline at end of file + args: "--replace" + skip-commit: true + - name: Print diffs + run: git --no-pager diff --exit-code diff --git a/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java b/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java index 821467e0..f36fa984 100644 --- a/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java +++ b/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java @@ -212,12 +212,10 @@ public class DeployFunction extends CloudSdkMojo { */ @Parameter(alias = "deploy.buildenvvarsfile", property = "function.deploy.buildenvvarsfile") String buildEnvVarsFile; - /** - * If true, deploys the function in the 2nd Generation Environment. - */ + /** If true, deploys the function in the 2nd Generation Environment. */ @Parameter(alias = "deploy.gen2", property = "function.deploy.gen2", defaultValue = "false") boolean gen2; - + boolean hasEnvVariables() { return (this.environmentVariables != null && !this.environmentVariables.isEmpty()); } From adf81d13104a219d2e75c914cc40aaa0ce1df5bb Mon Sep 17 00:00:00 2001 From: Kenneth Rosario Date: Wed, 1 Feb 2023 14:12:36 -0800 Subject: [PATCH 060/239] feat: configure security score card action (#175) --- .github/workflows/scorecard.yml | 47 +++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 .github/workflows/scorecard.yml diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml new file mode 100644 index 00000000..75522f35 --- /dev/null +++ b/.github/workflows/scorecard.yml @@ -0,0 +1,47 @@ +name: Scorecard supply-chain security +on: + # For Branch-Protection check. Only the default branch is supported. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection + branch_protection_rule: + # To guarantee Maintained check is occasionally updated. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained + schedule: + - cron: '0 */12 * * *' + push: + branches: [ "master" ] + +# Declare default permissions as read only. +permissions: read-all + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + permissions: + # Needed to upload the results to code-scanning dashboard. + security-events: write + # Needed to publish results and get a badge (see publish_results below). + id-token: write + + steps: + - name: "Checkout code" + uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0 + with: + persist-credentials: false + + - name: "Run analysis" + uses: ossf/scorecard-action@99c53751e09b9529366343771cc321ec74e9bd3d # v2.0.6 + with: + results_file: results.sarif + results_format: sarif + # Public repositories: + # - Publish results to OpenSSF REST API for easy access by consumers + # - Allows the repository to include the Scorecard badge. + # - See https://github.com/ossf/scorecard-action#publishing-results. + publish_results: true + + # Upload the results to GitHub's code scanning dashboard. + - name: "Upload to code-scanning" + uses: github/codeql-action/upload-sarif@807578363a7869ca324a79039e6db9c843e0e100 # v2.1.27 + with: + sarif_file: results.sarif From 6ac80aae8122fc0dcf332b6c563d243434bd7e1f Mon Sep 17 00:00:00 2001 From: Kenneth Rosario Date: Wed, 8 Feb 2023 12:51:15 -0800 Subject: [PATCH 061/239] chore: configure codeql workflow (#176) --- .github/workflows/codeql.yml | 54 ++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000..199eb9df --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,54 @@ +name: "CodeQL" + +on: + push: + branches: [ "master" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "master" ] + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + # Autobuild each of these seperate maven projects + working-directory: ['invoker', 'functions-framework-api', 'function-maven-plugin'] + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + languages: java + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + with: + working-directory: ${{ matrix.working-directory }} + + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: ${{ matrix.working-directory }} From 3ac1abda2d0d34076d11a93d15bd47ae73ff81fe Mon Sep 17 00:00:00 2001 From: StepSecurity Bot Date: Thu, 23 Feb 2023 08:56:35 -0800 Subject: [PATCH 062/239] chore: [StepSecurity] Harden GitHub Actions (#177) --- .github/workflows/codeql.yml | 16 ++++++++++++---- .github/workflows/conformance.yaml | 19 ++++++++++++------- .github/workflows/lint.yaml | 21 +++++++++++++++++---- .github/workflows/scorecard.yml | 5 +++++ .github/workflows/unit.yaml | 12 ++++++++++-- 5 files changed, 56 insertions(+), 17 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 199eb9df..f41dd57a 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -7,6 +7,9 @@ on: # The branches below must be a subset of the branches above branches: [ "master" ] +permissions: + contents: read + jobs: analyze: name: Analyze @@ -24,12 +27,17 @@ jobs: working-directory: ['invoker', 'functions-framework-api', 'function-maven-plugin'] steps: + - name: Harden Runner + uses: step-security/harden-runner@18bf8ad2ca49c14cbb28b91346d626ccfb00c518 # v2.1.0 + with: + egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs + - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # v2.2.4 with: # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support languages: java @@ -43,12 +51,12 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # v2.2.4 with: working-directory: ${{ matrix.working-directory }} - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # v2.2.4 with: category: ${{ matrix.working-directory }} diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index 5c56a303..5fdeae65 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -15,15 +15,20 @@ jobs: # 13.x ] steps: - - uses: actions/checkout@v2 + - name: Harden Runner + uses: step-security/harden-runner@18bf8ad2ca49c14cbb28b91346d626ccfb00c518 # v2.1.0 + with: + egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs + + - uses: actions/checkout@dc323e67f16fb5f7663d20ff7941f27f5809e9b6 # v2.6.0 - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@v1 + uses: actions/setup-java@d202f5dbf7256730fb690ec59f6381650114feb2 # v1.4.3 with: java-version: ${{ matrix.java }} - name: Setup Go - uses: actions/setup-go@v2 + uses: actions/setup-go@bfdd3570ce990073878bf10f6b2d79082de49492 # v2.2.0 with: go-version: '1.16' @@ -34,7 +39,7 @@ jobs: run: (cd invoker/ && mvn install) - name: Run HTTP conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.6.0 + uses: GoogleCloudPlatform/functions-framework-conformance/action@c52662e612b2685a027b1c3e02224306517722fc # v1.6.0 with: version: 'v1.6.0' functionType: 'http' @@ -43,7 +48,7 @@ jobs: startDelay: 10 - name: Run background event conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.6.0 + uses: GoogleCloudPlatform/functions-framework-conformance/action@c52662e612b2685a027b1c3e02224306517722fc # v1.6.0 with: version: 'v1.6.0' functionType: 'legacyevent' @@ -53,7 +58,7 @@ jobs: startDelay: 10 - name: Run cloudevent conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.6.0 + uses: GoogleCloudPlatform/functions-framework-conformance/action@c52662e612b2685a027b1c3e02224306517722fc # v1.6.0 with: version: 'v1.6.0' functionType: 'cloudevent' @@ -63,7 +68,7 @@ jobs: startDelay: 10 - name: Run HTTP concurrency conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@v1.6.0 + uses: GoogleCloudPlatform/functions-framework-conformance/action@c52662e612b2685a027b1c3e02224306517722fc # v1.6.0 with: version: 'v1.6.0' functionType: 'http' diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index a6356989..78ef3450 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -5,13 +5,21 @@ on: - master pull_request: workflow_dispatch: +permissions: + contents: read + jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - name: Harden Runner + uses: step-security/harden-runner@18bf8ad2ca49c14cbb28b91346d626ccfb00c518 # v2.1.0 + with: + egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs + + - uses: actions/checkout@dc323e67f16fb5f7663d20ff7941f27f5809e9b6 # v2.6.0 - name: Set up JDK - uses: actions/setup-java@v1 + uses: actions/setup-java@d202f5dbf7256730fb690ec59f6381650114feb2 # v1.4.3 with: java-version: 11.x - name: Build API with Maven @@ -25,10 +33,15 @@ jobs: formatting: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 # v2 minimum required + - name: Harden Runner + uses: step-security/harden-runner@18bf8ad2ca49c14cbb28b91346d626ccfb00c518 # v2.1.0 + with: + egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs + + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 # v2 minimum required - name: Run formatter id: formatter - uses: axel-op/googlejavaformat-action@v3 + uses: axel-op/googlejavaformat-action@dbff853fb823671ec5781365233bf86543b13215 # v3 with: args: "--replace" skip-commit: true diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 75522f35..49d3d2ba 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -24,6 +24,11 @@ jobs: id-token: write steps: + - name: Harden Runner + uses: step-security/harden-runner@18bf8ad2ca49c14cbb28b91346d626ccfb00c518 # v2.1.0 + with: + egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs + - name: "Checkout code" uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0 with: diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index 1938fc01..b510fef7 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -4,6 +4,9 @@ on: branches: - master pull_request: +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest @@ -14,9 +17,14 @@ jobs: 17.x ] steps: - - uses: actions/checkout@v2 + - name: Harden Runner + uses: step-security/harden-runner@18bf8ad2ca49c14cbb28b91346d626ccfb00c518 # v2.1.0 + with: + egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs + + - uses: actions/checkout@dc323e67f16fb5f7663d20ff7941f27f5809e9b6 # v2.6.0 - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@v2 + uses: actions/setup-java@f0bb91606209742fe3ea40199be2f3ef195ecabf # v2.5.0 with: java-version: ${{ matrix.java }} distribution: temurin From 44da871e06e967ce132bea06c3b7c5d1b06ddd6b Mon Sep 17 00:00:00 2001 From: Gareth Date: Thu, 2 Mar 2023 10:22:18 -0800 Subject: [PATCH 063/239] fix: retrieving http headers on request object should be case insenstive (#178) * Add test case covering case sensitive header operations * Make HttpRequest.getFirstHeader case insensitive --- .../invoker/http/HttpRequestImpl.java | 9 +++++-- .../invoker/http/HttpResponseImpl.java | 25 +++++++++++++------ .../functions/invoker/http/HttpTest.java | 10 +++++--- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/http/HttpRequestImpl.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/http/HttpRequestImpl.java index db53936e..2119645a 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/http/HttpRequestImpl.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/http/HttpRequestImpl.java @@ -30,6 +30,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.ServletException; @@ -116,8 +117,12 @@ public BufferedReader getReader() throws IOException { @Override public Map> getHeaders() { return Collections.list(request.getHeaderNames()).stream() - .map(name -> new SimpleEntry<>(name, Collections.list(request.getHeaders(name)))) - .collect(toMap(Map.Entry::getKey, Map.Entry::getValue)); + .collect( + toMap( + name -> name, + name -> Collections.list(request.getHeaders(name)), + (a, b) -> b, + () -> new TreeMap<>(String.CASE_INSENSITIVE_ORDER))); } private static class HttpPartImpl implements HttpPart { diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/http/HttpResponseImpl.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/http/HttpResponseImpl.java index 41a96e36..b455eb47 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/http/HttpResponseImpl.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/http/HttpResponseImpl.java @@ -20,12 +20,12 @@ import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStream; -import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.TreeMap; import javax.servlet.http.HttpServletResponse; public class HttpResponseImpl implements HttpResponse { @@ -64,8 +64,12 @@ public void appendHeader(String key, String value) { @Override public Map> getHeaders() { return response.getHeaderNames().stream() - .map(header -> new SimpleEntry<>(header, list(response.getHeaders(header)))) - .collect(toMap(Map.Entry::getKey, Map.Entry::getValue)); + .collect( + toMap( + name -> name, + name -> new ArrayList<>(response.getHeaders(name)), + (a, b) -> b, + () -> new TreeMap<>(String.CASE_INSENSITIVE_ORDER))); } private static List list(Collection collection) { @@ -82,12 +86,17 @@ public OutputStream getOutputStream() throws IOException { @Override public synchronized BufferedWriter getWriter() throws IOException { if (writer == null) { - // Unfortunately this means that we get two intermediate objects between the object we return - // and the underlying Writer that response.getWriter() wraps. We could try accessing the - // PrintWriter.out field via reflection, but that sort of access to non-public fields of - // platform classes is now frowned on and may draw warnings or even fail in subsequent + // Unfortunately this means that we get two intermediate objects between the + // object we return + // and the underlying Writer that response.getWriter() wraps. We could try + // accessing the + // PrintWriter.out field via reflection, but that sort of access to non-public + // fields of + // platform classes is now frowned on and may draw warnings or even fail in + // subsequent // versions. - // We could instead wrap the OutputStream, but that would require us to deduce the appropriate + // We could instead wrap the OutputStream, but that would require us to deduce + // the appropriate // Charset, using logic like this: // https://github.com/eclipse/jetty.project/blob/923ec38adf/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java#L731 // We may end up doing that if performance is an issue. diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/http/HttpTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/http/HttpTest.java index 9ef51b2a..e52ec62a 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/http/HttpTest.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/http/HttpTest.java @@ -181,6 +181,8 @@ private void httpRequestMethods( assertThat(request.getHeaders()).containsAtLeastEntriesIn(expectedHeaders); }, request -> assertThat(request.getFirstHeader("foo")).hasValue("bar"), + request -> assertThat(request.getFirstHeader("CaSe-SeNsItIvE")).hasValue("VaLuE"), + request -> assertThat(request.getFirstHeader("case-sensitive")).hasValue("VaLuE"), request -> { try { request.getParts(); @@ -197,6 +199,7 @@ private void httpRequestMethods( .header(HttpHeader.CONTENT_TYPE, "text/plain; charset=utf-8") .header("foo", "bar") .header("foo", "baz") + .header("CaSe-SeNsItIvE", "VaLuE") .content(new StringContentProvider(TEST_BODY)); ContentResponse response = request.send(); assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200); @@ -352,11 +355,10 @@ private void httpResponseSetAndGet( // So we just check that we can add our own headers. response.appendHeader("foo", "bar"); response.appendHeader("wibbly", "wobbly"); - response.appendHeader("foo", "baz"); - Map> updatedHeaders = new TreeMap<>(response.getHeaders()); - updatedHeaders.keySet().removeAll(initialHeaders.keySet()); + response.appendHeader("FoO", "baz"); + var updatedHeaders = response.getHeaders(); assertThat(updatedHeaders) - .containsExactly("foo", Arrays.asList("bar", "baz"), "wibbly", Arrays.asList("wobbly")); + .containsAtLeast("foo", Arrays.asList("bar", "baz"), "wibbly", Arrays.asList("wobbly")); }, }; for (HttpResponseTest test : tests) { From ed91e93f1be748cea4d28c49740782b5065b89bf Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 24 Mar 2023 14:25:58 -0700 Subject: [PATCH 064/239] chore(master): release java-function-invoker 1.2.1 (#179) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- .github/.release-please-manifest.json | 2 +- invoker/CHANGELOG.md | 7 +++++++ invoker/conformance/pom.xml | 4 ++-- invoker/core/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 6 files changed, 16 insertions(+), 9 deletions(-) diff --git a/.github/.release-please-manifest.json b/.github/.release-please-manifest.json index 485ec31c..0f1a7d79 100644 --- a/.github/.release-please-manifest.json +++ b/.github/.release-please-manifest.json @@ -1 +1 @@ -{"functions-framework-api":"1.0.4","invoker":"1.2.0","function-maven-plugin":"0.10.1"} \ No newline at end of file +{"functions-framework-api":"1.0.4","invoker":"1.2.1","function-maven-plugin":"0.10.1"} \ No newline at end of file diff --git a/invoker/CHANGELOG.md b/invoker/CHANGELOG.md index 21d264fc..f8106cf7 100644 --- a/invoker/CHANGELOG.md +++ b/invoker/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.2.1](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/java-function-invoker-v1.2.0...java-function-invoker-v1.2.1) (2023-03-02) + + +### Bug Fixes + +* retrieving http headers on request object should be case insenstive ([#178](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/178)) ([44da871](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/44da871e06e967ce132bea06c3b7c5d1b06ddd6b)) + ## [1.2.0](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/java-function-invoker-v1.1.1...java-function-invoker-v1.2.0) (2022-10-05) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 4531c93c..c12bf37e 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.2.1-SNAPSHOT + 1.2.1 com.google.cloud.functions.invoker conformance - 1.2.1-SNAPSHOT + 1.2.1 GCF Confromance Tests diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 6688f2b9..6420cf93 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.2.1-SNAPSHOT + 1.2.1 com.google.cloud.functions.invoker java-function-invoker - 1.2.1-SNAPSHOT + 1.2.1 GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -114,7 +114,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.2.1-SNAPSHOT + 1.2.1 test-jar test diff --git a/invoker/pom.xml b/invoker/pom.xml index 44640217..eef187d8 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -8,7 +8,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.2.1-SNAPSHOT + 1.2.1 pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index d89eef20..ce9bdb5d 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.2.1-SNAPSHOT + 1.2.1 com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.2.1-SNAPSHOT + 1.2.1 Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From 89b57bf5a1c7006d9bfd323e93180d255ed77fd4 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 24 Mar 2023 14:31:24 -0700 Subject: [PATCH 065/239] chore(master): release java-function-invoker 1.2.2-SNAPSHOT (#180) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- invoker/conformance/pom.xml | 4 ++-- invoker/core/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index c12bf37e..dc1e3172 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.2.1 + 1.2.2-SNAPSHOT com.google.cloud.functions.invoker conformance - 1.2.1 + 1.2.2-SNAPSHOT GCF Confromance Tests diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 6420cf93..08ade5e3 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.2.1 + 1.2.2-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker - 1.2.1 + 1.2.2-SNAPSHOT GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -114,7 +114,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.2.1 + 1.2.2-SNAPSHOT test-jar test diff --git a/invoker/pom.xml b/invoker/pom.xml index eef187d8..691e4785 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -8,7 +8,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.2.1 + 1.2.2-SNAPSHOT pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index ce9bdb5d..61730b65 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.2.1 + 1.2.2-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.2.1 + 1.2.2-SNAPSHOT Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From 648f4a8b73d211dde7ea3b230cef829076ed6b09 Mon Sep 17 00:00:00 2001 From: Kenneth Rosario Date: Fri, 31 Mar 2023 14:10:04 -0700 Subject: [PATCH 066/239] chore: add missing env variable to fix gpg error (#181) --- .kokoro/release.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.kokoro/release.sh b/.kokoro/release.sh index 2e3a96d3..0a599f31 100644 --- a/.kokoro/release.sh +++ b/.kokoro/release.sh @@ -5,6 +5,7 @@ set -e # Get secrets from keystore and set and environment variables. setup_environment_secrets() { + export GPG_TTY=$(tty) export SONATYPE_USERNAME=functions-framework-release-bot export SONATYPE_PASSWORD=$(cat ${KOKORO_KEYSTORE_DIR}/75669_functions-framework-java-release-bot-sonatype-password) export GPG_PASSPHRASE=$(cat ${KOKORO_KEYSTORE_DIR}/70247_maven-gpg-passphrase) From f435ad04d674a955b9c4216a05916af64d68059a Mon Sep 17 00:00:00 2001 From: Kenneth Rosario Date: Fri, 31 Mar 2023 16:49:09 -0700 Subject: [PATCH 067/239] chore: update gpg maven plugin to make it compatible with gpg v2.1+ (#182) --- function-maven-plugin/pom.xml | 8 +++++--- functions-framework-api/pom.xml | 12 ++++++++---- invoker/pom.xml | 6 ++++-- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml index 61e69484..c1f217c3 100644 --- a/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -1,4 +1,6 @@ - + 4.0.0 com.google.cloud.functions @@ -131,7 +133,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.6 + 3.0.1 sign-artifacts @@ -157,4 +159,4 @@ - + \ No newline at end of file diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index 565aa357..f8375b76 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -13,7 +13,9 @@ See the License for the specific language governing permissions and limitations under the License. --> - + 4.0.0 @@ -122,7 +124,9 @@ attach-docs post-integration-test - jar + + jar + @@ -175,7 +179,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.6 + 3.0.1 sign-artifacts @@ -201,4 +205,4 @@ - + \ No newline at end of file diff --git a/invoker/pom.xml b/invoker/pom.xml index 691e4785..b1017747 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -1,4 +1,6 @@ - + 4.0.0 org.sonatype.oss @@ -93,7 +95,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.6 + 3.0.1 sign-artifacts From 9f209bef86a2e01ce794e42505c64fc2f0be1e10 Mon Sep 17 00:00:00 2001 From: Kenneth Rosario Date: Mon, 3 Apr 2023 14:18:17 -0700 Subject: [PATCH 068/239] Revert "chore(master): release java-function-invoker 1.2.2-SNAPSHOT (#180)" (#184) This reverts commit 89b57bf5a1c7006d9bfd323e93180d255ed77fd4. --- invoker/conformance/pom.xml | 4 ++-- invoker/core/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index dc1e3172..c12bf37e 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.2.2-SNAPSHOT + 1.2.1 com.google.cloud.functions.invoker conformance - 1.2.2-SNAPSHOT + 1.2.1 GCF Confromance Tests diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 08ade5e3..6420cf93 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.2.2-SNAPSHOT + 1.2.1 com.google.cloud.functions.invoker java-function-invoker - 1.2.2-SNAPSHOT + 1.2.1 GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -114,7 +114,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.2.2-SNAPSHOT + 1.2.1 test-jar test diff --git a/invoker/pom.xml b/invoker/pom.xml index b1017747..49815646 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -10,7 +10,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.2.2-SNAPSHOT + 1.2.1 pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index 61730b65..ce9bdb5d 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.2.2-SNAPSHOT + 1.2.1 com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.2.2-SNAPSHOT + 1.2.1 Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From 8db1e85ce7defb9eab32cfa3e23499cdb5d6858f Mon Sep 17 00:00:00 2001 From: Kenneth Rosario Date: Mon, 3 Apr 2023 15:22:15 -0700 Subject: [PATCH 069/239] Revert "Revert "chore(master): release java-function-invoker 1.2.2-SNAPSHOT (#180)" (#184)" (#185) This reverts commit 9f209bef86a2e01ce794e42505c64fc2f0be1e10. --- invoker/conformance/pom.xml | 4 ++-- invoker/core/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index c12bf37e..dc1e3172 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.2.1 + 1.2.2-SNAPSHOT com.google.cloud.functions.invoker conformance - 1.2.1 + 1.2.2-SNAPSHOT GCF Confromance Tests diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 6420cf93..08ade5e3 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.2.1 + 1.2.2-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker - 1.2.1 + 1.2.2-SNAPSHOT GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -114,7 +114,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.2.1 + 1.2.2-SNAPSHOT test-jar test diff --git a/invoker/pom.xml b/invoker/pom.xml index 49815646..b1017747 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -10,7 +10,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.2.1 + 1.2.2-SNAPSHOT pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index ce9bdb5d..61730b65 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.2.1 + 1.2.2-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.2.1 + 1.2.2-SNAPSHOT Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From e4820d96d3fd747767b0df3db592e84f0d114d1a Mon Sep 17 00:00:00 2001 From: Kenneth Rosario Date: Thu, 6 Apr 2023 11:59:30 -0700 Subject: [PATCH 070/239] chore: address some scorecard findings on github actions (#183) --- .github/workflows/buildpack-integration-test.yml | 4 ++++ .github/workflows/conformance.yaml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/.github/workflows/buildpack-integration-test.yml b/.github/workflows/buildpack-integration-test.yml index 6d290f64..35e9b6c7 100644 --- a/.github/workflows/buildpack-integration-test.yml +++ b/.github/workflows/buildpack-integration-test.yml @@ -5,6 +5,10 @@ on: branches: - master workflow_dispatch: + +# Declare default permissions as read only. +permissions: read-all + jobs: java11-buildpack-test: uses: GoogleCloudPlatform/functions-framework-conformance/.github/workflows/buildpack-integration-test.yml@v1.8.0 diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index 5fdeae65..14b5e066 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -4,6 +4,10 @@ on: branches: - master pull_request: + +# Declare default permissions as read only. +permissions: read-all + jobs: build: runs-on: ubuntu-latest From de61196b6211dab6bec023e553f7015c7afe2790 Mon Sep 17 00:00:00 2001 From: Kenneth Rosario Date: Thu, 13 Apr 2023 11:08:10 -0700 Subject: [PATCH 071/239] chore: Configure blunderbuss.yml (#188) --- .github/blunderbuss.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .github/blunderbuss.yml diff --git a/.github/blunderbuss.yml b/.github/blunderbuss.yml new file mode 100644 index 00000000..61347444 --- /dev/null +++ b/.github/blunderbuss.yml @@ -0,0 +1,5 @@ +assign_prs: + - GoogleCloudPlatform/functions-framework-google + +assign_issues: + - GoogleCloudPlatform/functions-framework-google From fdbdfcecaf263ec0b3d8b88553ef764a5762f2e9 Mon Sep 17 00:00:00 2001 From: Kenneth Rosario Date: Thu, 13 Apr 2023 11:16:24 -0700 Subject: [PATCH 072/239] chore: Create renovate bot config (#187) * chore: Create renovate bot config * Update renovate.json --- .github/renovate.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/renovate.json diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 00000000..7287767f --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["group:allNonMajor", "schedule:monthly"], + "packageRules": [ + { + "description": "Create a PR whenever there is a new major version", + "matchUpdateTypes": [ + "major" + ] + } + ] +} From 3e3129eeae86c5fddd5253e9bcf14e5e561bca79 Mon Sep 17 00:00:00 2001 From: Kenneth Rosario Date: Tue, 2 May 2023 11:10:27 -0700 Subject: [PATCH 073/239] chore: Update blunderbuss.yml according to preference (#189) --- .github/blunderbuss.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/blunderbuss.yml b/.github/blunderbuss.yml index 61347444..4234009b 100644 --- a/.github/blunderbuss.yml +++ b/.github/blunderbuss.yml @@ -1,5 +1,9 @@ assign_prs: - - GoogleCloudPlatform/functions-framework-google + - janell-chen + - HKWinterhalter + - garethgeorge assign_issues: - - GoogleCloudPlatform/functions-framework-google + - janell-chen + - HKWinterhalter + - garethgeorge From a3712448c09e59e7cf71de9f19aad8f21bb511a0 Mon Sep 17 00:00:00 2001 From: Kenneth Rosario Date: Tue, 2 May 2023 13:45:33 -0700 Subject: [PATCH 074/239] chore: fix ci lint errors (#195) --- .../com/google/cloud/functions/plugin/DeployFunction.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java b/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java index f36fa984..35dab3f8 100644 --- a/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java +++ b/function-maven-plugin/src/main/java/com/google/cloud/functions/plugin/DeployFunction.java @@ -182,36 +182,42 @@ public class DeployFunction extends CloudSdkMojo { */ @Parameter(alias = "deploy.vpcconnector", property = "function.deploy.vpcconnector") String vpcConnector; + /** * Sets the maximum number of instances for the function. A function execution that would exceed * max-instances times out. */ @Parameter(alias = "deploy.maxinstances", property = "function.deploy.maxinstances") Integer maxInstances; + /** * List of key-value pairs to set as environment variables. All existing environment variables * will be removed first. */ @Parameter(alias = "deploy.setenvvars", property = "function.deploy.setenvvars") Map environmentVariables; + /** * Path to a local YAML file with definitions for all environment variables. All existing * environment variables will be removed before the new environment variables are added. */ @Parameter(alias = "deploy.envvarsfile", property = "function.deploy.envvarsfile") String envVarsFile; + /** * List of key-value pairs to set as build environment variables. All existing environment * variables will be removed first. */ @Parameter(alias = "deploy.setbuildenvvars", property = "function.deploy.setbuildenvvars") Map buildEnvironmentVariables; + /** * Path to a local YAML file with definitions for all build environment variables. All existing * environment variables will be removed before the new environment variables are added. */ @Parameter(alias = "deploy.buildenvvarsfile", property = "function.deploy.buildenvvarsfile") String buildEnvVarsFile; + /** If true, deploys the function in the 2nd Generation Environment. */ @Parameter(alias = "deploy.gen2", property = "function.deploy.gen2", defaultValue = "false") boolean gen2; From aadefa5fc09aa94da937f11f8f5cbfcd708c95bd Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Mon, 15 May 2023 21:22:50 +0200 Subject: [PATCH 075/239] chore(deps): update actions/checkout action to v3 (#192) --- .github/workflows/conformance.yaml | 2 +- .github/workflows/lint.yaml | 2 +- .github/workflows/unit.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index 14b5e066..0ee3236e 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -24,7 +24,7 @@ jobs: with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - - uses: actions/checkout@dc323e67f16fb5f7663d20ff7941f27f5809e9b6 # v2.6.0 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Set up JDK ${{ matrix.java }} uses: actions/setup-java@d202f5dbf7256730fb690ec59f6381650114feb2 # v1.4.3 diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 78ef3450..d559d9f7 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -17,7 +17,7 @@ jobs: with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - - uses: actions/checkout@dc323e67f16fb5f7663d20ff7941f27f5809e9b6 # v2.6.0 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Set up JDK uses: actions/setup-java@d202f5dbf7256730fb690ec59f6381650114feb2 # v1.4.3 with: diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index b510fef7..405a9b57 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -22,7 +22,7 @@ jobs: with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - - uses: actions/checkout@dc323e67f16fb5f7663d20ff7941f27f5809e9b6 # v2.6.0 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Set up JDK ${{ matrix.java }} uses: actions/setup-java@f0bb91606209742fe3ea40199be2f3ef195ecabf # v2.5.0 with: From f3220ce5304add7d198c2a60cf76ae64e9fb0791 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Mon, 15 May 2023 22:16:31 +0200 Subject: [PATCH 076/239] chore(deps): update actions/setup-go action to v4 (#193) --- .github/workflows/conformance.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index 0ee3236e..20a14c9d 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -32,7 +32,7 @@ jobs: java-version: ${{ matrix.java }} - name: Setup Go - uses: actions/setup-go@bfdd3570ce990073878bf10f6b2d79082de49492 # v2.2.0 + uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 with: go-version: '1.16' From 94ed3bfcdcb57d4452aa2e3307acee1e4a48c28f Mon Sep 17 00:00:00 2001 From: Gareth Date: Tue, 16 May 2023 12:06:03 -0700 Subject: [PATCH 077/239] chore(deps): update actions/setup-java to v3 (#196) --- .github/workflows/conformance.yaml | 3 ++- .github/workflows/lint.yaml | 3 ++- .github/workflows/unit.yaml | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index 20a14c9d..8cda2e27 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -27,9 +27,10 @@ jobs: - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@d202f5dbf7256730fb690ec59f6381650114feb2 # v1.4.3 + uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2 # v3.11.0 with: java-version: ${{ matrix.java }} + distribution: temurin - name: Setup Go uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index d559d9f7..291ab619 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -19,9 +19,10 @@ jobs: - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Set up JDK - uses: actions/setup-java@d202f5dbf7256730fb690ec59f6381650114feb2 # v1.4.3 + uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2 # v3.11.0 with: java-version: 11.x + distribution: temurin - name: Build API with Maven run: (cd functions-framework-api/ && mvn install) - name: Lint Functions Framework API diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index 405a9b57..22668053 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -24,7 +24,7 @@ jobs: - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@f0bb91606209742fe3ea40199be2f3ef195ecabf # v2.5.0 + uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2 # v3.11.0 with: java-version: ${{ matrix.java }} distribution: temurin From d6396d10388217993278d35a3c902856dfd89e9c Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Wed, 17 May 2023 19:17:56 +0200 Subject: [PATCH 078/239] chore(deps): update all non-major dependencies (#191) --- .github/workflows/codeql.yml | 10 +++++----- .github/workflows/conformance.yaml | 10 +++++----- .github/workflows/lint.yaml | 6 +++--- .github/workflows/scorecard.yml | 8 ++++---- .github/workflows/unit.yaml | 2 +- function-maven-plugin/pom.xml | 20 ++++++++++---------- functions-framework-api/pom.xml | 8 ++++---- invoker/conformance/pom.xml | 6 +++--- invoker/core/pom.xml | 28 ++++++++++++++-------------- invoker/pom.xml | 4 ++-- invoker/testfunction/pom.xml | 6 +++--- 11 files changed, 54 insertions(+), 54 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index f41dd57a..45f6540c 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -28,16 +28,16 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@18bf8ad2ca49c14cbb28b91346d626ccfb00c518 # v2.1.0 + uses: step-security/harden-runner@128a63446a954579617e875aaab7d2978154e969 # v2.4.0 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - name: Checkout repository - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # v2.2.4 + uses: github/codeql-action/init@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v2.3.3 with: # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support languages: java @@ -51,12 +51,12 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). - name: Autobuild - uses: github/codeql-action/autobuild@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # v2.2.4 + uses: github/codeql-action/autobuild@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v2.3.3 with: working-directory: ${{ matrix.working-directory }} - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # v2.2.4 + uses: github/codeql-action/analyze@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v2.3.3 with: category: ${{ matrix.working-directory }} diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index 8cda2e27..77bf6860 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -20,7 +20,7 @@ jobs: ] steps: - name: Harden Runner - uses: step-security/harden-runner@18bf8ad2ca49c14cbb28b91346d626ccfb00c518 # v2.1.0 + uses: step-security/harden-runner@128a63446a954579617e875aaab7d2978154e969 # v2.4.0 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -44,7 +44,7 @@ jobs: run: (cd invoker/ && mvn install) - name: Run HTTP conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@c52662e612b2685a027b1c3e02224306517722fc # v1.6.0 + uses: GoogleCloudPlatform/functions-framework-conformance/action@1975792fb34ebbfa058d690666186d669d3a5977 # v1.8.0 with: version: 'v1.6.0' functionType: 'http' @@ -53,7 +53,7 @@ jobs: startDelay: 10 - name: Run background event conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@c52662e612b2685a027b1c3e02224306517722fc # v1.6.0 + uses: GoogleCloudPlatform/functions-framework-conformance/action@1975792fb34ebbfa058d690666186d669d3a5977 # v1.8.0 with: version: 'v1.6.0' functionType: 'legacyevent' @@ -63,7 +63,7 @@ jobs: startDelay: 10 - name: Run cloudevent conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@c52662e612b2685a027b1c3e02224306517722fc # v1.6.0 + uses: GoogleCloudPlatform/functions-framework-conformance/action@1975792fb34ebbfa058d690666186d669d3a5977 # v1.8.0 with: version: 'v1.6.0' functionType: 'cloudevent' @@ -73,7 +73,7 @@ jobs: startDelay: 10 - name: Run HTTP concurrency conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@c52662e612b2685a027b1c3e02224306517722fc # v1.6.0 + uses: GoogleCloudPlatform/functions-framework-conformance/action@1975792fb34ebbfa058d690666186d669d3a5977 # v1.8.0 with: version: 'v1.6.0' functionType: 'http' diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 291ab619..8ece5d60 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@18bf8ad2ca49c14cbb28b91346d626ccfb00c518 # v2.1.0 + uses: step-security/harden-runner@128a63446a954579617e875aaab7d2978154e969 # v2.4.0 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -35,11 +35,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@18bf8ad2ca49c14cbb28b91346d626ccfb00c518 # v2.1.0 + uses: step-security/harden-runner@128a63446a954579617e875aaab7d2978154e969 # v2.4.0 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 # v2 minimum required + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 # v2 minimum required - name: Run formatter id: formatter uses: axel-op/googlejavaformat-action@dbff853fb823671ec5781365233bf86543b13215 # v3 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 49d3d2ba..f87e3f7f 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -25,17 +25,17 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@18bf8ad2ca49c14cbb28b91346d626ccfb00c518 # v2.1.0 + uses: step-security/harden-runner@128a63446a954579617e875aaab7d2978154e969 # v2.4.0 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - name: "Checkout code" - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 with: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@99c53751e09b9529366343771cc321ec74e9bd3d # v2.0.6 + uses: ossf/scorecard-action@80e868c13c90f172d68d1f4501dee99e2479f7af # v2.1.3 with: results_file: results.sarif results_format: sarif @@ -47,6 +47,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@807578363a7869ca324a79039e6db9c843e0e100 # v2.1.27 + uses: github/codeql-action/upload-sarif@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v2.3.3 with: sarif_file: results.sarif diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index 22668053..6f4dc3d0 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -18,7 +18,7 @@ jobs: ] steps: - name: Harden Runner - uses: step-security/harden-runner@18bf8ad2ca49c14cbb28b91346d626ccfb00c518 # v2.1.0 + uses: step-security/harden-runner@128a63446a954579617e875aaab7d2978154e969 # v2.4.0 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml index c1f217c3..ca3a98a5 100644 --- a/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -29,43 +29,43 @@ org.apache.maven maven-plugin-api - 3.6.3 + 3.9.2 org.apache.maven maven-core - 3.6.3 + 3.9.2 org.apache.maven.plugin-tools maven-plugin-annotations - 3.6.0 + 3.9.0 provided com.google.cloud.functions.invoker java-function-invoker - 1.1.1 + 1.2.1 com.google.cloud.tools appengine-maven-plugin - 2.4.1 + 2.4.4 jar com.google.truth truth - 1.0.1 + 1.1.3 test junit junit - 4.13.1 + 4.13.2 test @@ -75,7 +75,7 @@ org.apache.maven.plugins maven-plugin-plugin - 3.6.0 + 3.9.0 help-goal @@ -120,7 +120,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.1.0 + 3.5.0 attach-javadocs @@ -133,7 +133,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.0.1 + 3.1.0 sign-artifacts diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index f8375b76..ebc27ba4 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -30,8 +30,8 @@ UTF-8 - 3.8.0 - 3.1.0 + 3.11.0 + 3.5.0 5.3.2 @@ -54,7 +54,7 @@ io.cloudevents cloudevents-api - 2.0.0.RC2 + 2.5.0 @@ -179,7 +179,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.0.1 + 3.1.0 sign-artifacts diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index dc1e3172..553d688e 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -32,17 +32,17 @@ com.google.code.gson gson - 2.8.9 + 2.10.1 io.cloudevents cloudevents-core - 2.2.0 + 2.5.0 io.cloudevents cloudevents-json-jackson - 2.2.0 + 2.5.0 diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 08ade5e3..860c0b4c 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -22,7 +22,7 @@ 5.3.2 11 11 - 2.0.0.RC2 + 2.5.0 @@ -68,12 +68,12 @@ com.google.code.gson gson - 2.8.9 + 2.10.1 com.ryanharter.auto.value auto-value-gson - 1.3.0 + 1.3.1 provided @@ -85,19 +85,19 @@ com.google.auto.value auto-value - 1.7 + 1.10.1 provided com.google.auto.value auto-value-annotations - 1.7 + 1.10.1 provided org.eclipse.jetty jetty-servlet - 9.4.49.v20220914 + 9.4.51.v20230217 org.eclipse.jetty @@ -121,36 +121,36 @@ org.mockito mockito-core - 3.2.4 + 3.12.4 test junit junit - 4.13.1 + 4.13.2 test com.google.re2j re2j - 1.6 + 1.7 com.google.truth truth - 1.0.1 + 1.1.3 test com.google.truth.extensions truth-java8-extension - 1.0.1 + 1.1.3 test org.eclipse.jetty jetty-client - 9.4.26.v20200117 + 9.4.51.v20230217 test @@ -159,7 +159,7 @@ maven-jar-plugin - 3.1.2 + 3.3.0 @@ -171,7 +171,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.1 + 3.4.1 package diff --git a/invoker/pom.xml b/invoker/pom.xml index b1017747..7c2b515e 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -82,7 +82,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.1.0 + 3.5.0 attach-javadocs @@ -95,7 +95,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.0.1 + 3.1.0 sign-artifacts diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index 61730b65..d6571a6d 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -35,7 +35,7 @@ com.google.code.gson gson - 2.8.9 + 2.10.1 @@ -43,7 +43,7 @@ maven-jar-plugin - 3.1.2 + 3.3.0 @@ -85,7 +85,7 @@ org.apache.maven.plugins maven-deploy-plugin - 3.0.0-M1 + 3.1.1 true From 5264e35b2522a789d65f0e0fd9bb5584694529eb Mon Sep 17 00:00:00 2001 From: Gareth Date: Tue, 23 May 2023 12:12:35 -0700 Subject: [PATCH 079/239] feat: Define strongly typed function interface (#186) Introduces a new Typed signature to the functions framework which provides automatic request deserialization and response serialization. --- .github/workflows/codeql.yml | 12 +- function-maven-plugin/pom.xml | 2 +- functions-framework-api/pom.xml | 2 +- .../google/cloud/functions/TypedFunction.java | 59 +++++++ invoker/conformance/pom.xml | 4 +- invoker/core/pom.xml | 7 +- .../invoker/HttpFunctionExecutor.java | 14 +- .../invoker/TypedFunctionExecutor.java | 165 ++++++++++++++++++ .../invoker/http/HttpResponseImpl.java | 34 ++-- .../functions/invoker/runner/Invoker.java | 37 ++-- .../BackgroundFunctionExecutorTest.java | 1 - .../functions/invoker/IntegrationTest.java | 60 ++++++- .../invoker/TypedFunctionExecutorTest.java | 37 ++++ .../invoker/testfunctions/Typed.java | 25 +++ .../testfunctions/TypedCustomFormat.java | 38 ++++ .../invoker/testfunctions/TypedVoid.java | 12 ++ .../resources/typed_nameconcat_request.json | 4 + invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 5 +- .../java/com/example/functionjar/Typed.java | 25 +++ 20 files changed, 488 insertions(+), 57 deletions(-) create mode 100644 functions-framework-api/src/main/java/com/google/cloud/functions/TypedFunction.java create mode 100644 invoker/core/src/main/java/com/google/cloud/functions/invoker/TypedFunctionExecutor.java create mode 100644 invoker/core/src/test/java/com/google/cloud/functions/invoker/TypedFunctionExecutorTest.java create mode 100644 invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/Typed.java create mode 100644 invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/TypedCustomFormat.java create mode 100644 invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/TypedVoid.java create mode 100644 invoker/core/src/test/resources/typed_nameconcat_request.json create mode 100644 invoker/testfunction/src/test/java/com/example/functionjar/Typed.java diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 45f6540c..3d013efd 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -49,12 +49,12 @@ jobs: # queries: security-extended,security-and-quality - # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). - - name: Autobuild - uses: github/codeql-action/autobuild@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v2.3.3 - with: - working-directory: ${{ matrix.working-directory }} - + + - name: Build + run: | + (cd functions-framework-api/ && mvn install) + (cd invoker/ && mvn clean install) + (cd function-maven-plugin && mvn install) - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # v2.3.3 diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml index ca3a98a5..eab73245 100644 --- a/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -46,7 +46,7 @@ com.google.cloud.functions.invoker java-function-invoker - 1.2.1 + 1.2.3-SNAPSHOT diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index ebc27ba4..3bdeffa7 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -26,7 +26,7 @@ com.google.cloud.functions functions-framework-api - 1.0.5-SNAPSHOT + 1.0.6-SNAPSHOT UTF-8 diff --git a/functions-framework-api/src/main/java/com/google/cloud/functions/TypedFunction.java b/functions-framework-api/src/main/java/com/google/cloud/functions/TypedFunction.java new file mode 100644 index 00000000..16baf0b6 --- /dev/null +++ b/functions-framework-api/src/main/java/com/google/cloud/functions/TypedFunction.java @@ -0,0 +1,59 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.cloud.functions; + +import java.lang.reflect.Type; + +/** + * Represents a Cloud Function with a strongly typed interface that is activated by an HTTP request. + */ +@FunctionalInterface +public interface TypedFunction { + /** + * Called to service an incoming HTTP request. This interface is implemented by user code to + * provide the action for a given HTTP function. If this method throws any exception (including + * any {@link Error}) then the HTTP response will have a 500 status code. + * + * @param arg the payload of the event, deserialized from the original JSON string. + * @return invocation result or null to indicate the body of the response should be empty. + * @throws Exception to produce a 500 status code in the HTTP response. + */ + public ResponseT apply(RequestT arg) throws Exception; + + /** + * Called to get the the format object that handles request decoding and response encoding. If + * null is returned a default JSON format is used. + * + * @return the {@link WireFormat} to use for serialization + */ + public default WireFormat getWireFormat() { + return null; + } + + /** + * Describes how to deserialize request object and serialize response objects for an HTTP + * invocation. + */ + public interface WireFormat { + /** Serialize is expected to encode the object to the provided HttpResponse. */ + void serialize(Object object, HttpResponse response) throws Exception; + + /** + * Deserialize is expected to read an object of {@code Type} from the HttpRequest. The Type is + * determined through reflection on the user's function. + */ + Object deserialize(HttpRequest request, Type type) throws Exception; + } +} diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 553d688e..354b3568 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.2.2-SNAPSHOT + 1.2.3-SNAPSHOT com.google.cloud.functions.invoker conformance - 1.2.2-SNAPSHOT + 1.2.3-SNAPSHOT GCF Confromance Tests diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 860c0b4c..dde36f33 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.2.2-SNAPSHOT + 1.2.3-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker - 1.2.2-SNAPSHOT + 1.2.3-SNAPSHOT GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -44,6 +44,7 @@ com.google.cloud.functions functions-framework-api + 1.0.6-SNAPSHOT javax.servlet @@ -114,7 +115,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.2.2-SNAPSHOT + 1.2.3-SNAPSHOT test-jar test diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java index 7a66fefd..21115666 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java @@ -17,7 +17,6 @@ import com.google.cloud.functions.HttpFunction; import com.google.cloud.functions.invoker.http.HttpRequestImpl; import com.google.cloud.functions.invoker.http.HttpResponseImpl; -import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.http.HttpServlet; @@ -72,18 +71,7 @@ public void service(HttpServletRequest req, HttpServletResponse res) { res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } finally { Thread.currentThread().setContextClassLoader(oldContextLoader); - try { - // We can't use HttpServletResponse.flushBuffer() because we wrap the PrintWriter - // returned by HttpServletResponse in our own BufferedWriter to match our API. - // So we have to flush whichever of getWriter() or getOutputStream() works. - try { - respImpl.getOutputStream().flush(); - } catch (IllegalStateException e) { - respImpl.getWriter().flush(); - } - } catch (IOException e) { - // Too bad, can't flush. - } + respImpl.flush(); } } } diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/TypedFunctionExecutor.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/TypedFunctionExecutor.java new file mode 100644 index 00000000..a6edfc32 --- /dev/null +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/TypedFunctionExecutor.java @@ -0,0 +1,165 @@ +package com.google.cloud.functions.invoker; + +import com.google.cloud.functions.HttpRequest; +import com.google.cloud.functions.HttpResponse; +import com.google.cloud.functions.TypedFunction; +import com.google.cloud.functions.TypedFunction.WireFormat; +import com.google.cloud.functions.invoker.http.HttpRequestImpl; +import com.google.cloud.functions.invoker.http.HttpResponseImpl; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class TypedFunctionExecutor extends HttpServlet { + private static final String APPLY_METHOD = "apply"; + private static final Logger logger = Logger.getLogger("com.google.cloud.functions.invoker"); + + private final Type argType; + private final TypedFunction function; + private final WireFormat format; + + private TypedFunctionExecutor( + Type argType, TypedFunction func, WireFormat format) { + this.argType = argType; + this.function = func; + this.format = format; + } + + public static TypedFunctionExecutor forClass(Class functionClass) { + if (!TypedFunction.class.isAssignableFrom(functionClass)) { + throw new RuntimeException( + "Class " + + functionClass.getName() + + " does not implement " + + TypedFunction.class.getName()); + } + @SuppressWarnings("unchecked") + Class> typedFunctionClass = + (Class>) functionClass.asSubclass(TypedFunction.class); + + Optional argType = handlerTypeArgument(typedFunctionClass); + if (argType.isEmpty()) { + throw new RuntimeException( + "Class " + + typedFunctionClass.getName() + + " does not implement " + + TypedFunction.class.getName()); + } + + TypedFunction typedFunction; + try { + typedFunction = typedFunctionClass.getDeclaredConstructor().newInstance(); + } catch (Exception e) { + throw new RuntimeException( + "Class " + + typedFunctionClass.getName() + + " must declare a valid default constructor to be usable as a strongly typed" + + " function. Could not use constructor: " + + e.toString()); + } + + WireFormat format = typedFunction.getWireFormat(); + if (format == null) { + format = LazyDefaultFormatHolder.defaultFormat; + } + + @SuppressWarnings("unchecked") + TypedFunctionExecutor executor = + new TypedFunctionExecutor( + argType.orElseThrow(), (TypedFunction) typedFunction, format); + return executor; + } + + /** + * Returns the {@code ReqT} of a concrete class that implements {@link TypedFunction + * TypedFunction}. Returns an empty {@link Optional} if {@code ReqT} can't be + * determined. + */ + static Optional handlerTypeArgument(Class> functionClass) { + return Arrays.stream(functionClass.getMethods()) + .filter(method -> method.getName().equals(APPLY_METHOD) && method.getParameterCount() == 1) + .map(method -> method.getGenericParameterTypes()[0]) + .filter(type -> type != Object.class) + .findFirst(); + } + + /** Executes the user's method, can handle all HTTP type methods. */ + @Override + public void service(HttpServletRequest req, HttpServletResponse res) { + HttpRequestImpl reqImpl = new HttpRequestImpl(req); + HttpResponseImpl resImpl = new HttpResponseImpl(res); + ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader(); + + try { + Thread.currentThread().setContextClassLoader(function.getClass().getClassLoader()); + handleRequest(reqImpl, resImpl); + } finally { + Thread.currentThread().setContextClassLoader(oldContextClassLoader); + resImpl.flush(); + } + } + + private void handleRequest(HttpRequest req, HttpResponse res) { + Object reqObj; + try { + reqObj = format.deserialize(req, argType); + } catch (Throwable t) { + logger.log(Level.SEVERE, "Failed to parse request for " + function.getClass().getName(), t); + res.setStatusCode(HttpServletResponse.SC_BAD_REQUEST); + return; + } + + Object resObj; + try { + resObj = function.apply(reqObj); + } catch (Throwable t) { + logger.log(Level.SEVERE, "Failed to execute " + function.getClass().getName(), t); + res.setStatusCode(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + return; + } + + try { + format.serialize(resObj, res); + } catch (Throwable t) { + logger.log( + Level.SEVERE, "Failed to serialize response for " + function.getClass().getName(), t); + res.setStatusCode(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + return; + } + } + + private static class LazyDefaultFormatHolder { + static final WireFormat defaultFormat = new GsonWireFormat(); + } + + private static class GsonWireFormat implements TypedFunction.WireFormat { + private final Gson gson = new GsonBuilder().create(); + + @Override + public void serialize(Object object, HttpResponse response) throws Exception { + if (object == null) { + response.setStatusCode(HttpServletResponse.SC_NO_CONTENT); + return; + } + try (BufferedWriter bodyWriter = response.getWriter()) { + gson.toJson(object, bodyWriter); + } + } + + @Override + public Object deserialize(HttpRequest request, Type type) throws Exception { + try (BufferedReader bodyReader = request.getReader()) { + return gson.fromJson(bodyReader, type); + } + } + } +} diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/http/HttpResponseImpl.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/http/HttpResponseImpl.java index b455eb47..c02246f0 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/http/HttpResponseImpl.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/http/HttpResponseImpl.java @@ -86,22 +86,32 @@ public OutputStream getOutputStream() throws IOException { @Override public synchronized BufferedWriter getWriter() throws IOException { if (writer == null) { - // Unfortunately this means that we get two intermediate objects between the - // object we return - // and the underlying Writer that response.getWriter() wraps. We could try - // accessing the - // PrintWriter.out field via reflection, but that sort of access to non-public - // fields of - // platform classes is now frowned on and may draw warnings or even fail in - // subsequent - // versions. - // We could instead wrap the OutputStream, but that would require us to deduce - // the appropriate - // Charset, using logic like this: + // Unfortunately this means that we get two intermediate objects between the object we return + // and the underlying Writer that response.getWriter() wraps. We could try accessing the + // PrintWriter.out field via reflection, but that sort of access to non-public fields of + // platform classes is now frowned on and may draw warnings or even fail in subsequent + // versions. We could instead wrap the OutputStream, but that would require us to deduce the + // appropriate Charset, using logic like this: // https://github.com/eclipse/jetty.project/blob/923ec38adf/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java#L731 // We may end up doing that if performance is an issue. writer = new BufferedWriter(response.getWriter()); } return writer; } + + public void flush() { + try { + // We can't use HttpServletResponse.flushBuffer() because we wrap the + // PrintWriter returned by HttpServletResponse in our own BufferedWriter + // to match our API. So we have to flush whichever of getWriter() or + // getOutputStream() works. + try { + getOutputStream().flush(); + } catch (IllegalStateException e) { + getWriter().flush(); + } + } catch (IOException e) { + // Too bad, can't flush. + } + } } diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java index d35e21ea..4936da4e 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java @@ -20,8 +20,10 @@ import com.beust.jcommander.Parameter; import com.beust.jcommander.ParameterException; import com.google.cloud.functions.HttpFunction; +import com.google.cloud.functions.TypedFunction; import com.google.cloud.functions.invoker.BackgroundFunctionExecutor; import com.google.cloud.functions.invoker.HttpFunctionExecutor; +import com.google.cloud.functions.invoker.TypedFunctionExecutor; import com.google.cloud.functions.invoker.gcf.JsonLogHandler; import java.io.File; import java.io.IOException; @@ -81,9 +83,10 @@ public class Invoker { static { if (isGcf()) { - // If we're running with Google Cloud Functions, we'll get better-looking logs if we arrange - // for them to be formatted using StackDriver's "structured logging" JSON format. Remove the - // JDK's standard logger and replace it with the JSON one. + // If we're running with Google Cloud Functions, we'll get better-looking logs + // if we arrange for them to be formatted using StackDriver's "structured + // logging" JSON format. Remove the JDK's standard logger and replace it with + // the JSON one. for (Handler handler : rootLogger.getHandlers()) { rootLogger.removeHandler(handler); } @@ -252,11 +255,10 @@ public void startServer() throws Exception { *
{@code
    * // Create an invoker
    * Invoker invoker = new Invoker(
-   *         8081,
-   *         "org.example.MyHttpFunction",
-   *         "http",
-   *         Thread.currentThread().getContextClassLoader()
-   * );
+   *     8081,
+   *     "org.example.MyHttpFunction",
+   *     "http",
+   *     Thread.currentThread().getContextClassLoader());
    *
    * // Start the test server
    * invoker.startTestServer();
@@ -303,6 +305,9 @@ private void startServer(boolean join) throws Exception {
         case "cloudevent":
           servlet = BackgroundFunctionExecutor.forClass(functionClass);
           break;
+        case "typed":
+          servlet = TypedFunctionExecutor.forClass(functionClass);
+          break;
         default:
           String error =
               String.format(
@@ -350,9 +355,9 @@ private Class loadFunctionClass() throws ClassNotFoundException {
         if (firstException == null) {
           firstException = e;
         }
-        // This might be a nested class like com.example.Foo.Bar. That will actually appear as
-        // com.example.Foo$Bar as far as Class.forName is concerned. So we try to replace every dot
-        // from the last to the first with a $ in the hope of finding a class we can load.
+        // This might be a nested class like com.example.Foo.Bar. That will actually
+        // appear as com.example.Foo$Bar as far as Class.forName is concerned. So we try to replace
+        // every dot from the last to the first with a $ in the hope of finding a class we can load.
         int lastDot = target.lastIndexOf('.');
         if (lastDot < 0) {
           throw firstException;
@@ -366,6 +371,9 @@ private HttpServlet servletForDeducedSignatureType(Class functionClass) {
     if (HttpFunction.class.isAssignableFrom(functionClass)) {
       return HttpFunctionExecutor.forClass(functionClass);
     }
+    if (TypedFunction.class.isAssignableFrom(functionClass)) {
+      return TypedFunctionExecutor.forClass(functionClass);
+    }
     Optional maybeExecutor =
         BackgroundFunctionExecutor.maybeForClass(functionClass);
     if (maybeExecutor.isPresent()) {
@@ -432,8 +440,8 @@ private void logServerInfo() {
   }
 
   private static boolean isGcf() {
-    // This environment variable is set in the GCF environment but won't be set when invoking
-    // the Functions Framework directly. We don't use its value, just whether it is set.
+    // This environment variable is set in the GCF environment but won't be set when invoking the
+    // Functions Framework directly. We don't use its value, just whether it is set.
     return System.getenv("K_SERVICE") != null;
   }
 
@@ -509,7 +517,8 @@ private static boolean isCloudEventsApiClass(String name) {
 
     private static ClassLoader getSystemOrBootstrapClassLoader() {
       try {
-        // We're still building against the Java 8 API, so we have to use reflection for now.
+        // We're still building against the Java 8 API, so we have to use reflection for
+        // now.
         Method getPlatformClassLoader = ClassLoader.class.getMethod("getPlatformClassLoader");
         return (ClassLoader) getPlatformClassLoader.invoke(null);
       } catch (ReflectiveOperationException e) {
diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutorTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutorTest.java
index d00b0b4f..2b7211c9 100644
--- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutorTest.java
+++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutorTest.java
@@ -100,7 +100,6 @@ public void parseLegacyEventPubSubEmulator() throws IOException {
       assertThat(context.eventType()).isEqualTo("google.pubsub.topic.publish");
       assertThat(context.eventId()).isEqualTo("1");
       assertThat(context.timestamp()).isNotNull();
-      ;
 
       JsonObject data = event.getData().getAsJsonObject();
       assertThat(data.get("data").getAsString()).isEqualTo("eyJmb28iOiJiYXIifQ==");
diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java
index 335cc7de..f84ddbdd 100644
--- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java
+++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java
@@ -383,6 +383,46 @@ public void typedBackground() throws Exception {
     }
   }
 
+  @Test
+  public void typedFunction() throws Exception {
+    URL resourceUrl = getClass().getResource("/typed_nameconcat_request.json");
+    assertThat(resourceUrl).isNotNull();
+    String originalJson = Resources.toString(resourceUrl, StandardCharsets.UTF_8);
+    testFunction(
+        SignatureType.TYPED,
+        fullTarget("Typed"),
+        ImmutableList.of(),
+        ImmutableList.of(
+            TestCase.builder()
+                .setRequestText(originalJson)
+                .setExpectedResponseText("{\"fullName\":\"JohnDoe\"}")
+                .build()));
+  }
+
+  @Test
+  public void typedVoidFunction() throws Exception {
+    testFunction(
+        SignatureType.TYPED,
+        fullTarget("TypedVoid"),
+        ImmutableList.of(),
+        ImmutableList.of(
+            TestCase.builder().setRequestText("{}").setExpectedResponseCode(204).build()));
+  }
+
+  @Test
+  public void typedCustomFormat() throws Exception {
+    testFunction(
+        SignatureType.TYPED,
+        fullTarget("TypedCustomFormat"),
+        ImmutableList.of(),
+        ImmutableList.of(
+            TestCase.builder()
+                .setRequestText("abc\n123\n$#@\n")
+                .setExpectedResponseText("abc123$#@")
+                .setExpectedResponseCode(200)
+                .build()));
+  }
+
   private void backgroundTest(String target) throws Exception {
     File snoopFile = snoopFile();
     String gcfRequestText = sampleLegacyEvent(snoopFile);
@@ -571,6 +611,23 @@ public void classpathOptionBackground() throws Exception {
         ImmutableList.of(TestCase.builder().setRequestText(json.toString()).build()));
   }
 
+  /** Like {@link #classpathOptionHttp} but for typed functions. */
+  @Test
+  public void classpathOptionTyped() throws Exception {
+    URL resourceUrl = getClass().getResource("/typed_nameconcat_request.json");
+    assertThat(resourceUrl).isNotNull();
+    String originalJson = Resources.toString(resourceUrl, StandardCharsets.UTF_8);
+    testFunction(
+        SignatureType.TYPED,
+        "com.example.functionjar.Typed",
+        ImmutableList.of("--classpath", functionJarString()),
+        ImmutableList.of(
+            TestCase.builder()
+                .setRequestText(originalJson)
+                .setExpectedResponseText("{\"fullName\":\"JohnDoe\"}")
+                .build()));
+  }
+
   // In these tests, we test a number of different functions that express the same functionality
   // in different ways. Each function is invoked with a complete HTTP body that looks like a real
   // event. We start with a fixed body and insert into its JSON an extra property that tells the
@@ -659,7 +716,8 @@ private void testFunction(
   private enum SignatureType {
     HTTP("http"),
     BACKGROUND("event"),
-    CLOUD_EVENT("cloudevent");
+    CLOUD_EVENT("cloudevent"),
+    TYPED("typed");
 
     private final String name;
 
diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/TypedFunctionExecutorTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/TypedFunctionExecutorTest.java
new file mode 100644
index 00000000..969d1dcc
--- /dev/null
+++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/TypedFunctionExecutorTest.java
@@ -0,0 +1,37 @@
+package com.google.cloud.functions.invoker;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth8.assertThat;
+
+import com.google.cloud.functions.TypedFunction;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class TypedFunctionExecutorTest {
+  private static class NameConcatRequest {
+    String firstName;
+    String lastName;
+  }
+
+  private static class NameConcatResponse {
+    String fullName;
+  }
+
+  private static class NameConcatFunction
+      implements TypedFunction {
+    @Override
+    public NameConcatResponse apply(NameConcatRequest arg) throws Exception {
+      NameConcatResponse resp = new NameConcatResponse();
+      resp.fullName = arg.firstName + arg.lastName;
+      return resp;
+    }
+  }
+
+  @Test
+  public void canDetermineTypeArgument() {
+    assertThat(TypedFunctionExecutor.handlerTypeArgument(NameConcatFunction.class))
+        .hasValue(NameConcatRequest.class);
+  }
+}
diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/Typed.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/Typed.java
new file mode 100644
index 00000000..af1c9356
--- /dev/null
+++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/Typed.java
@@ -0,0 +1,25 @@
+package com.google.cloud.functions.invoker.testfunctions;
+
+import com.google.cloud.functions.TypedFunction;
+
+public class Typed implements TypedFunction {
+
+  @Override
+  public NameConcatResponse apply(NameConcatRequest arg) throws Exception {
+    return new NameConcatResponse().setFullName(arg.firstName + arg.lastName);
+  }
+}
+
+class NameConcatRequest {
+  String firstName;
+  String lastName;
+}
+
+class NameConcatResponse {
+  String fullName;
+
+  NameConcatResponse setFullName(String fullName) {
+    this.fullName = fullName;
+    return this;
+  }
+}
diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/TypedCustomFormat.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/TypedCustomFormat.java
new file mode 100644
index 00000000..4597f216
--- /dev/null
+++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/TypedCustomFormat.java
@@ -0,0 +1,38 @@
+package com.google.cloud.functions.invoker.testfunctions;
+
+import com.google.cloud.functions.HttpRequest;
+import com.google.cloud.functions.HttpResponse;
+import com.google.cloud.functions.TypedFunction;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+
+public class TypedCustomFormat implements TypedFunction, String> {
+
+  @Override
+  public String apply(List arg) throws Exception {
+    return String.join("", arg);
+  }
+
+  @Override
+  public WireFormat getWireFormat() {
+    return new CustomFormat();
+  }
+}
+
+class CustomFormat implements TypedFunction.WireFormat {
+  @Override
+  public Object deserialize(HttpRequest request, Type type) throws Exception {
+    List req = new ArrayList<>();
+    String line;
+    while ((line = request.getReader().readLine()) != null) {
+      req.add(line);
+    }
+    return req;
+  }
+
+  @Override
+  public void serialize(Object object, HttpResponse response) throws Exception {
+    response.getWriter().write((String) object);
+  }
+}
diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/TypedVoid.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/TypedVoid.java
new file mode 100644
index 00000000..8e0cd00a
--- /dev/null
+++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/TypedVoid.java
@@ -0,0 +1,12 @@
+package com.google.cloud.functions.invoker.testfunctions;
+
+import com.google.cloud.functions.TypedFunction;
+
+public class TypedVoid implements TypedFunction {
+  @Override
+  public Void apply(Request arg) throws Exception {
+    return null;
+  }
+}
+
+class Request {}
diff --git a/invoker/core/src/test/resources/typed_nameconcat_request.json b/invoker/core/src/test/resources/typed_nameconcat_request.json
new file mode 100644
index 00000000..f6b4d425
--- /dev/null
+++ b/invoker/core/src/test/resources/typed_nameconcat_request.json
@@ -0,0 +1,4 @@
+{
+  "firstName": "John",
+  "lastName": "Doe"
+}
\ No newline at end of file
diff --git a/invoker/pom.xml b/invoker/pom.xml
index 7c2b515e..498db704 100644
--- a/invoker/pom.xml
+++ b/invoker/pom.xml
@@ -10,7 +10,7 @@
 
   com.google.cloud.functions.invoker
   java-function-invoker-parent
-  1.2.2-SNAPSHOT
+  1.2.3-SNAPSHOT
   pom
   GCF Java Invoker Parent
   
diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml
index d6571a6d..72a0126a 100644
--- a/invoker/testfunction/pom.xml
+++ b/invoker/testfunction/pom.xml
@@ -4,12 +4,12 @@
   
     com.google.cloud.functions.invoker
     java-function-invoker-parent
-    1.2.2-SNAPSHOT
+    1.2.3-SNAPSHOT
   
 
   com.google.cloud.functions.invoker
   java-function-invoker-testfunction
-  1.2.2-SNAPSHOT
+  1.2.3-SNAPSHOT
   Example GCF Function Jar
   
     An example of a GCF function packaged into a jar. We use this in tests.
@@ -19,6 +19,7 @@
     
       com.google.cloud.functions
       functions-framework-api
+      1.0.6-SNAPSHOT
     
     
       
-
+
   4.0.0
 
   
@@ -26,7 +24,7 @@
 
   com.google.cloud.functions
   functions-framework-api
-  1.0.6-SNAPSHOT
+  1.1.0
 
   
     UTF-8
diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml
index e71bcf20..8cd6254e 100644
--- a/invoker/core/pom.xml
+++ b/invoker/core/pom.xml
@@ -46,7 +46,7 @@
     
       com.google.cloud.functions
       functions-framework-api
-      1.0.6-SNAPSHOT
+      1.1.0
     
     
       javax.servlet
diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml
index 72a0126a..85a0d6a6 100644
--- a/invoker/testfunction/pom.xml
+++ b/invoker/testfunction/pom.xml
@@ -19,7 +19,7 @@
     
       com.google.cloud.functions
       functions-framework-api
-      1.0.6-SNAPSHOT
+      1.1.0
     
     
       
       com.google.escapevelocity
       escapevelocity
-      0.9.1
+      1.1
     
     
       com.google.guava

From e30ace5d45dd598a3865e1b9b72e816b9b1a0fb4 Mon Sep 17 00:00:00 2001
From: janell-chen <122311137+janell-chen@users.noreply.github.com>
Date: Mon, 12 Jun 2023 21:33:32 -0700
Subject: [PATCH 093/239] chore(deps): upgrade maven version to fix integ test
 (#211)

---
 functions-framework-api/pom.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml
index ceb34856..24ac5a35 100644
--- a/functions-framework-api/pom.xml
+++ b/functions-framework-api/pom.xml
@@ -151,7 +151,7 @@
           
             org.apache.maven.plugins
             maven-source-plugin
-            3.3.0
+            3.6.0
             
               
                 attach-sources
@@ -203,4 +203,4 @@
       
     
   
-
\ No newline at end of file
+

From b3045ad380cd23e37f5edec0d758031438bcb568 Mon Sep 17 00:00:00 2001
From: Gareth 
Date: Tue, 27 Jun 2023 11:04:49 -0700
Subject: [PATCH 094/239] fix: typed declaration works correctly with http
 trigger (#212)

* Configure typed function conformance test

* fix: typed function signature should be compatible with 'http' signature type

* apply google-java-format fixes
---
 .github/workflows/conformance.yaml            | 29 ++++++++++++++-----
 invoker/conformance/pom.xml                   |  3 +-
 .../conformance/TypedConformanceFunction.java | 26 +++++++++++++++++
 .../functions/invoker/runner/Invoker.java     |  6 +++-
 4 files changed, 54 insertions(+), 10 deletions(-)
 create mode 100644 invoker/conformance/src/main/java/com/google/cloud/functions/conformance/TypedConformanceFunction.java

diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml
index 446029c3..b9404cfc 100644
--- a/.github/workflows/conformance.yaml
+++ b/.github/workflows/conformance.yaml
@@ -51,19 +51,32 @@ jobs:
     - name: Build invoker with Maven
       run: (cd invoker/ && mvn install)
 
+    - name: Build invoker Maven Plugin
+      run: (cd function-maven-plugin/ && mvn install)
+
     - name: Run HTTP conformance tests
-      uses: GoogleCloudPlatform/functions-framework-conformance/action@1975792fb34ebbfa058d690666186d669d3a5977 # v1.8.0
+      uses: GoogleCloudPlatform/functions-framework-conformance/action@2f5f319c06a3531be7f75dc5acf6bd00417ff76e # v1.8.2
       with:
-        version: 'v1.6.0'
+        version: 'v1.8.2'
         functionType: 'http'
         useBuildpacks: false
         cmd: "'mvn -f invoker/conformance/pom.xml function:run -Drun.functionTarget=com.google.cloud.functions.conformance.HttpConformanceFunction'"
         startDelay: 10
 
+    - name: Run Typed conformance tests
+      uses: GoogleCloudPlatform/functions-framework-conformance/action@2f5f319c06a3531be7f75dc5acf6bd00417ff76e # v1.8.2
+      with:
+        version: 'v1.8.2'
+        functionType: 'http'
+        declarativeType: 'typed'
+        useBuildpacks: false
+        cmd: "'mvn -f invoker/conformance/pom.xml function:run -Drun.functionTarget=com.google.cloud.functions.conformance.TypedConformanceFunction'"
+        startDelay: 10
+
     - name: Run background event conformance tests
-      uses: GoogleCloudPlatform/functions-framework-conformance/action@1975792fb34ebbfa058d690666186d669d3a5977 # v1.8.0
+      uses: GoogleCloudPlatform/functions-framework-conformance/action@2f5f319c06a3531be7f75dc5acf6bd00417ff76e # v1.8.2
       with:
-        version: 'v1.6.0'
+        version: 'v1.8.2'
         functionType: 'legacyevent'
         useBuildpacks: false
         validateMapping: true
@@ -71,9 +84,9 @@ jobs:
         startDelay: 10
 
     - name: Run cloudevent conformance tests
-      uses: GoogleCloudPlatform/functions-framework-conformance/action@1975792fb34ebbfa058d690666186d669d3a5977 # v1.8.0
+      uses: GoogleCloudPlatform/functions-framework-conformance/action@2f5f319c06a3531be7f75dc5acf6bd00417ff76e # v1.8.2
       with:
-        version: 'v1.6.0'
+        version: 'v1.8.2'
         functionType: 'cloudevent'
         useBuildpacks: false
         validateMapping: true
@@ -81,9 +94,9 @@ jobs:
         startDelay: 10
 
     - name: Run HTTP concurrency conformance tests
-      uses: GoogleCloudPlatform/functions-framework-conformance/action@1975792fb34ebbfa058d690666186d669d3a5977 # v1.8.0
+      uses: GoogleCloudPlatform/functions-framework-conformance/action@2f5f319c06a3531be7f75dc5acf6bd00417ff76e # v1.8.2
       with:
-        version: 'v1.6.0'
+        version: 'v1.8.2'
         functionType: 'http'
         useBuildpacks: false
         validateConcurrency: true
diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml
index 1c0d59a8..8296836b 100644
--- a/invoker/conformance/pom.xml
+++ b/invoker/conformance/pom.xml
@@ -28,6 +28,7 @@
     
       com.google.cloud.functions
       functions-framework-api
+      1.1.1-SNAPSHOT
     
     
       com.google.code.gson
@@ -52,7 +53,7 @@
         
           com.google.cloud.functions
           function-maven-plugin
-          0.10.1
+          0.11.1-SNAPSHOT
         
       
     
diff --git a/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/TypedConformanceFunction.java b/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/TypedConformanceFunction.java
new file mode 100644
index 00000000..7b57c6ae
--- /dev/null
+++ b/invoker/conformance/src/main/java/com/google/cloud/functions/conformance/TypedConformanceFunction.java
@@ -0,0 +1,26 @@
+package com.google.cloud.functions.conformance;
+
+import com.google.cloud.functions.TypedFunction;
+import com.google.gson.annotations.SerializedName;
+
+public class TypedConformanceFunction
+    implements TypedFunction {
+  @Override
+  public ConformanceResponse apply(ConformanceRequest req) throws Exception {
+    return new ConformanceResponse(req);
+  }
+}
+
+class ConformanceRequest {
+  @SerializedName("message")
+  public String message;
+}
+
+class ConformanceResponse {
+  @SerializedName("payload")
+  public ConformanceRequest payload = null;
+
+  ConformanceResponse(ConformanceRequest payload) {
+    this.payload = payload;
+  }
+}
diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java
index 4936da4e..ebc70718 100644
--- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java
+++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java
@@ -299,7 +299,11 @@ private void startServer(boolean join) throws Exception {
     } else {
       switch (functionSignatureType) {
         case "http":
-          servlet = HttpFunctionExecutor.forClass(functionClass);
+          if (TypedFunction.class.isAssignableFrom(functionClass)) {
+            servlet = TypedFunctionExecutor.forClass(functionClass);
+          } else {
+            servlet = HttpFunctionExecutor.forClass(functionClass);
+          }
           break;
         case "event":
         case "cloudevent":

From 4e19904e4c4dddda6f4ded8d732e1394a10aee3b Mon Sep 17 00:00:00 2001
From: HKWinterhalter 
Date: Fri, 7 Jul 2023 16:13:57 -0700
Subject: [PATCH 095/239] ci: fix function-maven-plugin release (#217)

Developer and license information was missing from the pom and is required to publish to the Maven
central repo.
---
 function-maven-plugin/pom.xml | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml
index d6b8e5a1..87ac3459 100644
--- a/function-maven-plugin/pom.xml
+++ b/function-maven-plugin/pom.xml
@@ -1,6 +1,12 @@
 
   4.0.0
 
+  
+    org.sonatype.oss
+    oss-parent
+    9
+  
+
   com.google.cloud.functions
   function-maven-plugin
   maven-plugin
@@ -17,6 +23,14 @@
     HEAD
   
 
+  
+    
+      Apache License, Version 2.0
+      http://www.apache.org/licenses/LICENSE-2.0.txt
+      repo
+    
+  
+
   
     11
     11
@@ -157,4 +171,4 @@
       
     
   
-
\ No newline at end of file
+

From 9970a4d35557d8489c33bf6d3600d8e4ad0dcbe4 Mon Sep 17 00:00:00 2001
From: HKWinterhalter 
Date: Mon, 17 Jul 2023 15:40:17 -0700
Subject: [PATCH 096/239] ci: rename master branch to main (#219)

---
 .github/workflows/buildpack-integration-test.yml              | 2 +-
 .github/workflows/codeql.yml                                  | 4 ++--
 .github/workflows/conformance.yaml                            | 2 +-
 .github/workflows/lint.yaml                                   | 2 +-
 .github/workflows/scorecard.yml                               | 2 +-
 .github/workflows/unit.yaml                                   | 2 +-
 .../java/com/google/cloud/functions/BackgroundFunction.java   | 2 +-
 .../com/google/cloud/functions/RawBackgroundFunction.java     | 2 +-
 invoker/pom.xml                                               | 2 +-
 9 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/.github/workflows/buildpack-integration-test.yml b/.github/workflows/buildpack-integration-test.yml
index 35e9b6c7..6a7c3677 100644
--- a/.github/workflows/buildpack-integration-test.yml
+++ b/.github/workflows/buildpack-integration-test.yml
@@ -3,7 +3,7 @@ name: Buildpack Integration Test
 on:
   push:
     branches:
-      - master
+      - main
   workflow_dispatch:
 
 # Declare default permissions as read only.
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index f68b594b..afdbcc5c 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -2,10 +2,10 @@ name: "CodeQL"
 
 on:
   push:
-    branches: [ "master" ]
+    branches: [ "main" ]
   pull_request:
     # The branches below must be a subset of the branches above
-    branches: [ "master" ]
+    branches: [ "main" ]
 
 permissions:
   contents: read
diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml
index b9404cfc..b8d86b87 100644
--- a/.github/workflows/conformance.yaml
+++ b/.github/workflows/conformance.yaml
@@ -2,7 +2,7 @@ name: Java Conformance CI
 on:
   push:
     branches:
-    - master
+    - main
   pull_request:
 
 # Declare default permissions as read only.
diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml
index bfb7350d..7992931a 100644
--- a/.github/workflows/lint.yaml
+++ b/.github/workflows/lint.yaml
@@ -2,7 +2,7 @@ name: Java Lint CI
 on:
   push:
     branches:
-    - master
+    - main
   pull_request:
   workflow_dispatch:
 permissions:
diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
index 3ab2cbec..03f47547 100644
--- a/.github/workflows/scorecard.yml
+++ b/.github/workflows/scorecard.yml
@@ -8,7 +8,7 @@ on:
   schedule:
     - cron: '0 */12 * * *'
   push:
-    branches: [ "master" ]
+    branches: [ "main" ]
   workflow_dispatch:
 
 # Declare default permissions as read only.
diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml
index 763456d0..c4751a83 100644
--- a/.github/workflows/unit.yaml
+++ b/.github/workflows/unit.yaml
@@ -2,7 +2,7 @@ name: Java Unit CI
 on:
   push:
     branches:
-    - master
+    - main
   pull_request:
 permissions:
   contents: read
diff --git a/functions-framework-api/src/main/java/com/google/cloud/functions/BackgroundFunction.java b/functions-framework-api/src/main/java/com/google/cloud/functions/BackgroundFunction.java
index 5052b7b6..5dc0a97e 100644
--- a/functions-framework-api/src/main/java/com/google/cloud/functions/BackgroundFunction.java
+++ b/functions-framework-api/src/main/java/com/google/cloud/functions/BackgroundFunction.java
@@ -18,7 +18,7 @@
  * Represents a Cloud Function that is activated by an event and parsed into a user-supplied class.
  * The payload of the event is a JSON object, which is deserialized into a user-defined class as
  * described for Gson.
+ * href="https://github.com/google/gson/blob/main/UserGuide.md#TOC-Object-Examples">Gson.
  *
  * 

Here is an example of an implementation that accesses the {@code messageId} property from a * payload that matches a user-defined {@code PubSubMessage} class: diff --git a/functions-framework-api/src/main/java/com/google/cloud/functions/RawBackgroundFunction.java b/functions-framework-api/src/main/java/com/google/cloud/functions/RawBackgroundFunction.java index e27624ed..5f9706ba 100644 --- a/functions-framework-api/src/main/java/com/google/cloud/functions/RawBackgroundFunction.java +++ b/functions-framework-api/src/main/java/com/google/cloud/functions/RawBackgroundFunction.java @@ -17,7 +17,7 @@ /** * Represents a Cloud Function that is activated by an event. The payload of the event is a JSON * object, which can be parsed using a JSON package such as GSON. + * href="https://github.com/google/gson/blob/main/UserGuide.md">GSON. * *

Here is an example of an implementation that parses the JSON payload using Gson, to access its * {@code messageId} property: diff --git a/invoker/pom.xml b/invoker/pom.xml index 6009e322..73ba5d34 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -15,7 +15,7 @@ Parent POM for the GCF Java Invoker. The project is structured like this so that we can have modules that build jar files for use in tests. - https://github.com/GoogleCloudPlatform/functions-framework-java/tree/master/invoker + https://github.com/GoogleCloudPlatform/functions-framework-java/tree/main/invoker http://github.com/GoogleCloudPlatform/functions-framework-java From 04f04590492d4240c67cb2a8021fb0be34ee8b59 Mon Sep 17 00:00:00 2001 From: HKWinterhalter Date: Thu, 20 Jul 2023 13:14:16 -0700 Subject: [PATCH 097/239] ci: retarget buildpack integration test to main instead of release version (#222) --- .github/workflows/buildpack-integration-test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/buildpack-integration-test.yml b/.github/workflows/buildpack-integration-test.yml index 6a7c3677..11d53282 100644 --- a/.github/workflows/buildpack-integration-test.yml +++ b/.github/workflows/buildpack-integration-test.yml @@ -11,7 +11,7 @@ permissions: read-all jobs: java11-buildpack-test: - uses: GoogleCloudPlatform/functions-framework-conformance/.github/workflows/buildpack-integration-test.yml@v1.8.0 + uses: GoogleCloudPlatform/functions-framework-conformance/.github/workflows/buildpack-integration-test.yml@main with: http-builder-source: '/tmp/tests/conformance' http-builder-target: 'com.google.cloud.functions.conformance.HttpConformanceFunction' @@ -20,7 +20,7 @@ jobs: prerun: 'invoker/conformance/prerun.sh' builder-runtime: 'java11' java17-buildpack-test: - uses: GoogleCloudPlatform/functions-framework-conformance/.github/workflows/buildpack-integration-test.yml@v1.8.0 + uses: GoogleCloudPlatform/functions-framework-conformance/.github/workflows/buildpack-integration-test.yml@main with: http-builder-source: '/tmp/tests/conformance' http-builder-target: 'com.google.cloud.functions.conformance.HttpConformanceFunction' From 03bc0325b3f232146aee531471885f5cec802230 Mon Sep 17 00:00:00 2001 From: Kenneth Rosario Date: Tue, 25 Jul 2023 11:18:26 -0700 Subject: [PATCH 098/239] chore: run buildpack tests on pull request (#218) --- .github/workflows/buildpack-integration-test.yml | 10 +++++++++- invoker/conformance/prerun.sh | 7 ++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/buildpack-integration-test.yml b/.github/workflows/buildpack-integration-test.yml index 11d53282..728f5a0f 100644 --- a/.github/workflows/buildpack-integration-test.yml +++ b/.github/workflows/buildpack-integration-test.yml @@ -4,7 +4,11 @@ on: push: branches: - main + pull_request: workflow_dispatch: + # Runs every day on 12:00 AM PST + schedule: + - cron: "0 0 * * *" # Declare default permissions as read only. permissions: read-all @@ -19,6 +23,8 @@ jobs: cloudevent-builder-target: 'com.google.cloud.functions.conformance.CloudEventsConformanceFunction' prerun: 'invoker/conformance/prerun.sh' builder-runtime: 'java11' + builder-runtime-version: '11' + builder-url: gcr.io/gae-runtimes/buildpacks/google-gae-22/java/builder:latest java17-buildpack-test: uses: GoogleCloudPlatform/functions-framework-conformance/.github/workflows/buildpack-integration-test.yml@main with: @@ -27,4 +33,6 @@ jobs: cloudevent-builder-source: '/tmp/tests/conformance' cloudevent-builder-target: 'com.google.cloud.functions.conformance.CloudEventsConformanceFunction' prerun: 'invoker/conformance/prerun.sh' - builder-runtime: 'java17' \ No newline at end of file + builder-runtime: 'java17' + builder-runtime-version: '17' + builder-url: gcr.io/gae-runtimes/buildpacks/google-gae-22/java/builder:latest \ No newline at end of file diff --git a/invoker/conformance/prerun.sh b/invoker/conformance/prerun.sh index d5614357..504e3aa8 100755 --- a/invoker/conformance/prerun.sh +++ b/invoker/conformance/prerun.sh @@ -14,11 +14,10 @@ # - Copy the conformance tests folder into temp # - Build java-function-invoker with version 0.0.0-SNAPSHOT into artifacts # folder -# - Build functions-framework-api with version 0.0.0-SNAPSHOT into artifacts +# - Build functions-framework-api with version 0.0.0-SNAPSHOT into artifacts # folder # - Ensure that we use the buildpack_pom.xml file by renaming it to pom.xml - set -e REPO_ROOT=$(git rev-parse --show-toplevel) @@ -36,7 +35,7 @@ function get_mvn_version() { } # Must first install a local version of the API package -cd $REPO_ROOT/functions-framework-api +cd $REPO_ROOT/functions-framework-api mvn install -Dmaven.repo.local=/tmp/tests/conformance/artifacts FRAMEWORK_API_VERSION=$(get_mvn_version) @@ -50,3 +49,5 @@ mv /tmp/tests/conformance/buildpack_pom.xml /tmp/tests/conformance/pom.xml sed -i "s/FRAMEWORK-API-VERSION/${FRAMEWORK_API_VERSION}/g" /tmp/tests/conformance/pom.xml sed -i "s/INVOKER-VERSION/${INVOKER_VERSION}/g" /tmp/tests/conformance/pom.xml + +cat /tmp/tests/conformance/pom.xml From f3fe2ce46fcb1885137cdf504649612e7c31dc4c Mon Sep 17 00:00:00 2001 From: Gareth Date: Tue, 25 Jul 2023 15:39:15 -0700 Subject: [PATCH 099/239] fix(functions): include Implementation-Version key in invoker package manifest (#221) --- invoker/core/pom.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 2308f93b..bdae9e4e 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -165,6 +165,8 @@ com.google.cloud.functions.invoker.runner.Invoker + true + true @@ -184,4 +186,4 @@ - \ No newline at end of file + From 8ff911462bd811fbb10da7f3db25eb1e5b5aaef5 Mon Sep 17 00:00:00 2001 From: Kenneth Rosario Date: Tue, 5 Sep 2023 18:37:49 -0700 Subject: [PATCH 100/239] chore: add missing egress endpoint to codeql ACL (#223) --- .github/workflows/codeql.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index afdbcc5c..6dba3407 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -39,6 +39,7 @@ jobs: proxy.golang.org:443 repo.maven.apache.org:443 storage.googleapis.com:443 + uploads.github.com:443 - name: Checkout repository uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 From 8ae7d850f5e26964b3a8b52b0494be587e946fdc Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 12 Sep 2023 19:50:01 +0200 Subject: [PATCH 101/239] chore(deps): update all non-major dependencies (#228) Co-authored-by: Kenneth Rosario --- .github/workflows/codeql.yml | 8 ++++---- .github/workflows/conformance.yaml | 25 ++++++++++--------------- .github/workflows/lint.yaml | 10 +++++----- .github/workflows/scorecard.yml | 8 ++++---- .github/workflows/unit.yaml | 6 +++--- function-maven-plugin/pom.xml | 6 +++--- invoker/core/pom.xml | 16 ++++++++-------- 7 files changed, 37 insertions(+), 42 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 6dba3407..e9c002ec 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@128a63446a954579617e875aaab7d2978154e969 # v2.4.0 + uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 with: disable-sudo: true egress-policy: block @@ -42,11 +42,11 @@ jobs: uploads.github.com:443 - name: Checkout repository - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@83f0fe6c4988d98a455712a27f0255212bba9bd4 # v2.3.6 + uses: github/codeql-action/init@00e563ead9f72a8461b24876bee2d0c2e8bd2ee8 # v2.21.5 with: # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support languages: java @@ -66,6 +66,6 @@ jobs: (cd function-maven-plugin && mvn install) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@83f0fe6c4988d98a455712a27f0255212bba9bd4 # v2.3.6 + uses: github/codeql-action/analyze@00e563ead9f72a8461b24876bee2d0c2e8bd2ee8 # v2.21.5 with: category: ${{ matrix.working-directory }} diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index b8d86b87..0edd3720 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -20,7 +20,7 @@ jobs: ] steps: - name: Harden Runner - uses: step-security/harden-runner@128a63446a954579617e875aaab7d2978154e969 # v2.4.0 + uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 with: disable-sudo: true egress-policy: block @@ -32,18 +32,18 @@ jobs: repo.maven.apache.org:443 storage.googleapis.com:443 - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2 # v3.11.0 + uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0 with: java-version: ${{ matrix.java }} distribution: temurin - name: Setup Go - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: - go-version: '1.16' + go-version: '1.21' - name: Build API with Maven run: (cd functions-framework-api/ && mvn install) @@ -55,18 +55,16 @@ jobs: run: (cd function-maven-plugin/ && mvn install) - name: Run HTTP conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@2f5f319c06a3531be7f75dc5acf6bd00417ff76e # v1.8.2 + uses: GoogleCloudPlatform/functions-framework-conformance/action@72a4f36b10f1c6435ab1a86a9ea24bda464cc262 # main with: - version: 'v1.8.2' functionType: 'http' useBuildpacks: false cmd: "'mvn -f invoker/conformance/pom.xml function:run -Drun.functionTarget=com.google.cloud.functions.conformance.HttpConformanceFunction'" startDelay: 10 - name: Run Typed conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@2f5f319c06a3531be7f75dc5acf6bd00417ff76e # v1.8.2 + uses: GoogleCloudPlatform/functions-framework-conformance/action@72a4f36b10f1c6435ab1a86a9ea24bda464cc262 # main with: - version: 'v1.8.2' functionType: 'http' declarativeType: 'typed' useBuildpacks: false @@ -74,9 +72,8 @@ jobs: startDelay: 10 - name: Run background event conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@2f5f319c06a3531be7f75dc5acf6bd00417ff76e # v1.8.2 + uses: GoogleCloudPlatform/functions-framework-conformance/action@72a4f36b10f1c6435ab1a86a9ea24bda464cc262 # main with: - version: 'v1.8.2' functionType: 'legacyevent' useBuildpacks: false validateMapping: true @@ -84,9 +81,8 @@ jobs: startDelay: 10 - name: Run cloudevent conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@2f5f319c06a3531be7f75dc5acf6bd00417ff76e # v1.8.2 + uses: GoogleCloudPlatform/functions-framework-conformance/action@72a4f36b10f1c6435ab1a86a9ea24bda464cc262 # main with: - version: 'v1.8.2' functionType: 'cloudevent' useBuildpacks: false validateMapping: true @@ -94,9 +90,8 @@ jobs: startDelay: 10 - name: Run HTTP concurrency conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@2f5f319c06a3531be7f75dc5acf6bd00417ff76e # v1.8.2 + uses: GoogleCloudPlatform/functions-framework-conformance/action@72a4f36b10f1c6435ab1a86a9ea24bda464cc262 # main with: - version: 'v1.8.2' functionType: 'http' useBuildpacks: false validateConcurrency: true diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 7992931a..518c3c3d 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -13,16 +13,16 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@128a63446a954579617e875aaab7d2978154e969 # v2.4.0 + uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 with: disable-sudo: true egress-policy: block allowed-endpoints: > github.com:443 repo.maven.apache.org:443 - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 - name: Set up JDK - uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2 # v3.11.0 + uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0 with: java-version: 11.x distribution: temurin @@ -38,11 +38,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@128a63446a954579617e875aaab7d2978154e969 # v2.4.0 + uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 # v2 minimum required + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 # v2 minimum required - name: Run formatter id: formatter uses: axel-op/googlejavaformat-action@dbff853fb823671ec5781365233bf86543b13215 # v3 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 03f47547..087d9842 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@128a63446a954579617e875aaab7d2978154e969 # v2.4.0 + uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 with: disable-sudo: true egress-policy: block @@ -44,12 +44,12 @@ jobs: rekor.sigstore.dev:443 - name: "Checkout code" - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@80e868c13c90f172d68d1f4501dee99e2479f7af # v2.1.3 + uses: ossf/scorecard-action@08b4669551908b1024bb425080c797723083c031 # v2.2.0 with: results_file: results.sarif results_format: sarif @@ -61,6 +61,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@83f0fe6c4988d98a455712a27f0255212bba9bd4 # v2.3.6 + uses: github/codeql-action/upload-sarif@00e563ead9f72a8461b24876bee2d0c2e8bd2ee8 # v2.21.5 with: sarif_file: results.sarif diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index c4751a83..d88af609 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -18,16 +18,16 @@ jobs: ] steps: - name: Harden Runner - uses: step-security/harden-runner@128a63446a954579617e875aaab7d2978154e969 # v2.4.0 + uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 with: disable-sudo: true egress-policy: block allowed-endpoints: > github.com:443 repo.maven.apache.org:443 - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2 # v3.11.0 + uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0 with: java-version: ${{ matrix.java }} distribution: temurin diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml index 87ac3459..913b9ccf 100644 --- a/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -41,12 +41,12 @@ org.apache.maven maven-plugin-api - 3.9.2 + 3.9.4 org.apache.maven maven-core - 3.9.2 + 3.9.4 org.apache.maven.plugin-tools @@ -71,7 +71,7 @@ com.google.truth truth - 1.1.4 + 1.1.5 test diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index bdae9e4e..837b4cf8 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -86,24 +86,24 @@ com.google.auto.value auto-value - 1.10.1 + 1.10.4 provided com.google.auto.value auto-value-annotations - 1.10.1 + 1.10.4 provided org.eclipse.jetty jetty-servlet - 9.4.51.v20230217 + 9.4.52.v20230823 org.eclipse.jetty jetty-server - 9.4.51.v20230217 + 9.4.52.v20230823 com.beust @@ -139,19 +139,19 @@ com.google.truth truth - 1.1.4 + 1.1.5 test com.google.truth.extensions truth-java8-extension - 1.1.4 + 1.1.5 test org.eclipse.jetty jetty-client - 9.4.51.v20230217 + 9.4.52.v20230823 test @@ -174,7 +174,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.4.1 + 3.5.0 package From 6ece5604faf31a9375710d43d6aa530efd23e0b1 Mon Sep 17 00:00:00 2001 From: Kenneth Rosario Date: Wed, 13 Sep 2023 10:47:58 -0700 Subject: [PATCH 102/239] chore: add egress endpoint to allow list (#233) --- .github/workflows/scorecard.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 087d9842..08480f05 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -42,6 +42,7 @@ jobs: oss-fuzz-build-logs.storage.googleapis.com:443 sigstore-tuf-root.storage.googleapis.com:443 rekor.sigstore.dev:443 + www.bestpractices.dev:443 - name: "Checkout code" uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 From 89b3b92f4d5efeea08256dc56a34d2f4bde57d01 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 16:10:44 -0700 Subject: [PATCH 103/239] chore(main): release java-function-invoker 1.3.1 (#220) * chore(main): release java-function-invoker 1.3.1 * patch maven-plugin package manifest for release --------- Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: Gareth George --- .github/.release-please-manifest.json | 2 +- function-maven-plugin/pom.xml | 2 +- invoker/CHANGELOG.md | 8 ++++++++ invoker/conformance/pom.xml | 4 ++-- invoker/core/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 7 files changed, 18 insertions(+), 10 deletions(-) diff --git a/.github/.release-please-manifest.json b/.github/.release-please-manifest.json index b3d335ae..c2ee81e0 100644 --- a/.github/.release-please-manifest.json +++ b/.github/.release-please-manifest.json @@ -1 +1 @@ -{"functions-framework-api":"1.1.0","invoker":"1.3.0","function-maven-plugin":"0.11.0"} +{"functions-framework-api":"1.1.0","invoker":"1.3.1","function-maven-plugin":"0.11.0"} diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml index 913b9ccf..20cc5882 100644 --- a/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -58,7 +58,7 @@ com.google.cloud.functions.invoker java-function-invoker - 1.3.1-SNAPSHOT + 1.3.1 diff --git a/invoker/CHANGELOG.md b/invoker/CHANGELOG.md index 2646cd1b..2800c114 100644 --- a/invoker/CHANGELOG.md +++ b/invoker/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [1.3.1](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/java-function-invoker-v1.3.0...java-function-invoker-v1.3.1) (2023-09-13) + + +### Bug Fixes + +* **functions:** include Implementation-Version key in invoker package manifest ([#221](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/221)) ([f3fe2ce](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/f3fe2ce46fcb1885137cdf504649612e7c31dc4c)) +* typed declaration works correctly with http trigger ([#212](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/212)) ([b3045ad](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/b3045ad380cd23e37f5edec0d758031438bcb568)) + ## [1.3.0](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/java-function-invoker-v1.2.1...java-function-invoker-v1.3.0) (2023-06-01) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 8296836b..67e36ae0 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.3.1-SNAPSHOT + 1.3.1 com.google.cloud.functions.invoker conformance - 1.3.1-SNAPSHOT + 1.3.1 GCF Confromance Tests diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 837b4cf8..63596639 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.1-SNAPSHOT + 1.3.1 com.google.cloud.functions.invoker java-function-invoker - 1.3.1-SNAPSHOT + 1.3.1 GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -115,7 +115,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.3.1-SNAPSHOT + 1.3.1 test-jar test diff --git a/invoker/pom.xml b/invoker/pom.xml index 73ba5d34..e3159883 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -8,7 +8,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.1-SNAPSHOT + 1.3.1 pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index fa29218b..660e6f05 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.1-SNAPSHOT + 1.3.1 com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.3.1-SNAPSHOT + 1.3.1 Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From 9f7586944034fa63d0f55e6a897d9921b6379049 Mon Sep 17 00:00:00 2001 From: Gareth Date: Fri, 22 Sep 2023 11:54:31 -0700 Subject: [PATCH 104/239] Revert "chore(main): release java-function-invoker 1.3.1 (#220)" (#236) This reverts commit 89b3b92f4d5efeea08256dc56a34d2f4bde57d01. --- .github/.release-please-manifest.json | 2 +- function-maven-plugin/pom.xml | 2 +- invoker/CHANGELOG.md | 8 -------- invoker/conformance/pom.xml | 4 ++-- invoker/core/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 7 files changed, 10 insertions(+), 18 deletions(-) diff --git a/.github/.release-please-manifest.json b/.github/.release-please-manifest.json index c2ee81e0..b3d335ae 100644 --- a/.github/.release-please-manifest.json +++ b/.github/.release-please-manifest.json @@ -1 +1 @@ -{"functions-framework-api":"1.1.0","invoker":"1.3.1","function-maven-plugin":"0.11.0"} +{"functions-framework-api":"1.1.0","invoker":"1.3.0","function-maven-plugin":"0.11.0"} diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml index 20cc5882..913b9ccf 100644 --- a/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -58,7 +58,7 @@ com.google.cloud.functions.invoker java-function-invoker - 1.3.1 + 1.3.1-SNAPSHOT diff --git a/invoker/CHANGELOG.md b/invoker/CHANGELOG.md index 2800c114..2646cd1b 100644 --- a/invoker/CHANGELOG.md +++ b/invoker/CHANGELOG.md @@ -1,13 +1,5 @@ # Changelog -## [1.3.1](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/java-function-invoker-v1.3.0...java-function-invoker-v1.3.1) (2023-09-13) - - -### Bug Fixes - -* **functions:** include Implementation-Version key in invoker package manifest ([#221](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/221)) ([f3fe2ce](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/f3fe2ce46fcb1885137cdf504649612e7c31dc4c)) -* typed declaration works correctly with http trigger ([#212](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/212)) ([b3045ad](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/b3045ad380cd23e37f5edec0d758031438bcb568)) - ## [1.3.0](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/java-function-invoker-v1.2.1...java-function-invoker-v1.3.0) (2023-06-01) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 67e36ae0..8296836b 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.3.1 + 1.3.1-SNAPSHOT com.google.cloud.functions.invoker conformance - 1.3.1 + 1.3.1-SNAPSHOT GCF Confromance Tests diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 63596639..837b4cf8 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.1 + 1.3.1-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker - 1.3.1 + 1.3.1-SNAPSHOT GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -115,7 +115,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.3.1 + 1.3.1-SNAPSHOT test-jar test diff --git a/invoker/pom.xml b/invoker/pom.xml index e3159883..73ba5d34 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -8,7 +8,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.1 + 1.3.1-SNAPSHOT pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index 660e6f05..fa29218b 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.1 + 1.3.1-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.3.1 + 1.3.1-SNAPSHOT Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From bc1ca57738ade76cff8544c3e0dd0bcbd160ae72 Mon Sep 17 00:00:00 2001 From: Kenneth Rosario Date: Mon, 25 Sep 2023 11:38:11 -0700 Subject: [PATCH 105/239] chore: fix scorecard action acls (#238) --- .github/workflows/scorecard.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 08480f05..dc3c7c0b 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -31,18 +31,17 @@ jobs: disable-sudo: true egress-policy: block allowed-endpoints: > - api.github.com:443 api.osv.dev:443 api.securityscorecards.dev:443 auth.docker.io:443 bestpractices.coreinfrastructure.org:443 - fulcio.sigstore.dev:443 github.com:443 index.docker.io:443 oss-fuzz-build-logs.storage.googleapis.com:443 sigstore-tuf-root.storage.googleapis.com:443 - rekor.sigstore.dev:443 www.bestpractices.dev:443 + *.sigstore.dev:443 + *.github.com:443 - name: "Checkout code" uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 From 5795b1261d39845f36142b97cb05360cb202a4df Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Mon, 25 Sep 2023 20:43:51 +0200 Subject: [PATCH 106/239] chore(deps): update dependency javax.servlet:javax.servlet-api to v4 (#229) --- invoker/core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 837b4cf8..9d809a6a 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -49,7 +49,7 @@ javax.servlet javax.servlet-api - 3.1.0 + 4.0.1 io.cloudevents From 7df8be83040252bbeeba0bae09cd8dca4e58eb24 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Mon, 25 Sep 2023 20:47:54 +0200 Subject: [PATCH 107/239] chore(deps): update dependency org.apache.maven.plugins:maven-release-plugin to v3 (#230) --- functions-framework-api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index 24ac5a35..14a940c3 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -86,7 +86,7 @@ org.apache.maven.plugins maven-release-plugin - 2.5.3 + 3.0.1 default From 6dfc3c74d7bbc40fdb02568a7ddf6b352260cd3a Mon Sep 17 00:00:00 2001 From: Gareth Date: Tue, 26 Sep 2023 13:50:43 -0700 Subject: [PATCH 108/239] Reapply "chore(main): release java-function-invoker 1.3.1 (#220)" (#236) (#237) This reverts commit 9f7586944034fa63d0f55e6a897d9921b6379049. --- .github/.release-please-manifest.json | 2 +- function-maven-plugin/pom.xml | 2 +- invoker/CHANGELOG.md | 8 ++++++++ invoker/conformance/pom.xml | 6 +++--- invoker/core/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 7 files changed, 19 insertions(+), 11 deletions(-) diff --git a/.github/.release-please-manifest.json b/.github/.release-please-manifest.json index b3d335ae..c2ee81e0 100644 --- a/.github/.release-please-manifest.json +++ b/.github/.release-please-manifest.json @@ -1 +1 @@ -{"functions-framework-api":"1.1.0","invoker":"1.3.0","function-maven-plugin":"0.11.0"} +{"functions-framework-api":"1.1.0","invoker":"1.3.1","function-maven-plugin":"0.11.0"} diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml index 913b9ccf..20cc5882 100644 --- a/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -58,7 +58,7 @@ com.google.cloud.functions.invoker java-function-invoker - 1.3.1-SNAPSHOT + 1.3.1 diff --git a/invoker/CHANGELOG.md b/invoker/CHANGELOG.md index 2646cd1b..2800c114 100644 --- a/invoker/CHANGELOG.md +++ b/invoker/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [1.3.1](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/java-function-invoker-v1.3.0...java-function-invoker-v1.3.1) (2023-09-13) + + +### Bug Fixes + +* **functions:** include Implementation-Version key in invoker package manifest ([#221](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/221)) ([f3fe2ce](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/f3fe2ce46fcb1885137cdf504649612e7c31dc4c)) +* typed declaration works correctly with http trigger ([#212](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/212)) ([b3045ad](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/b3045ad380cd23e37f5edec0d758031438bcb568)) + ## [1.3.0](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/java-function-invoker-v1.2.1...java-function-invoker-v1.3.0) (2023-06-01) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 8296836b..43894042 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.3.1-SNAPSHOT + 1.3.1 com.google.cloud.functions.invoker conformance - 1.3.1-SNAPSHOT + 1.3.1 GCF Confromance Tests @@ -28,7 +28,7 @@ com.google.cloud.functions functions-framework-api - 1.1.1-SNAPSHOT + 1.1.0 com.google.code.gson diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 9d809a6a..f5f4dced 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.1-SNAPSHOT + 1.3.1 com.google.cloud.functions.invoker java-function-invoker - 1.3.1-SNAPSHOT + 1.3.1 GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -115,7 +115,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.3.1-SNAPSHOT + 1.3.1 test-jar test diff --git a/invoker/pom.xml b/invoker/pom.xml index 73ba5d34..e3159883 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -8,7 +8,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.1-SNAPSHOT + 1.3.1 pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index fa29218b..660e6f05 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.1-SNAPSHOT + 1.3.1 com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.3.1-SNAPSHOT + 1.3.1 Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From 9f7155b77574ec980ecf9e6dffbd2ee0398db8a7 Mon Sep 17 00:00:00 2001 From: Gareth Date: Thu, 28 Sep 2023 10:25:47 -0700 Subject: [PATCH 109/239] fix: set Thread Context ClassLoader correctly when invoking handler constructor (#239) --- .../invoker/HttpFunctionExecutor.java | 4 +++ .../invoker/HttpFunctionExecutorTest.java | 36 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 invoker/core/src/test/java/com/google/cloud/functions/invoker/HttpFunctionExecutorTest.java diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java index 21115666..401e22a2 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java @@ -48,12 +48,16 @@ public static HttpFunctionExecutor forClass(Class functionClass) { + HttpFunction.class.getName()); } Class httpFunctionClass = functionClass.asSubclass(HttpFunction.class); + ClassLoader oldContextLoader = Thread.currentThread().getContextClassLoader(); try { + Thread.currentThread().setContextClassLoader(httpFunctionClass.getClassLoader()); HttpFunction httpFunction = httpFunctionClass.getConstructor().newInstance(); return new HttpFunctionExecutor(httpFunction); } catch (ReflectiveOperationException e) { throw new RuntimeException( "Could not construct an instance of " + functionClass.getName() + ": " + e, e); + } finally { + Thread.currentThread().setContextClassLoader(oldContextLoader); } } diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/HttpFunctionExecutorTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/HttpFunctionExecutorTest.java new file mode 100644 index 00000000..080e3851 --- /dev/null +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/HttpFunctionExecutorTest.java @@ -0,0 +1,36 @@ +package com.google.cloud.functions.invoker; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.cloud.functions.HttpFunction; +import com.google.cloud.functions.HttpRequest; +import com.google.cloud.functions.HttpResponse; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class HttpFunctionExecutorTest { + private static ClassLoader customClassLoader = + new ClassLoader(ClassLoader.getSystemClassLoader()) {}; + + public static class ClassLoaderVerifier implements HttpFunction { + public ClassLoaderVerifier() { + assertThat(Thread.currentThread().getContextClassLoader()) + .isNotSameInstanceAs(customClassLoader); + } + + @Override + public void service(HttpRequest request, HttpResponse response) throws Exception { + throw new UnsupportedOperationException("Not implemented"); + } + } + + @Test + public void usesCorrectClassLoaderOverride() { + ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(customClassLoader); + HttpFunctionExecutor.forClass(ClassLoaderVerifier.class); + Thread.currentThread().setContextClassLoader(oldClassLoader); + } +} From fca867667db593699193da01b69a4cca7ca48fc8 Mon Sep 17 00:00:00 2001 From: Alberto Date: Fri, 29 Sep 2023 00:35:39 +0200 Subject: [PATCH 110/239] fix: avoid executing function when /favicon.ico or /robots.txt is called (#226) --- .../java/com/google/cloud/functions/invoker/runner/Invoker.java | 1 + 1 file changed, 1 insertion(+) diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java index ebc70718..892d6038 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java @@ -474,6 +474,7 @@ public void handle( throws IOException, ServletException { if (NOT_FOUND_PATHS.contains(request.getRequestURI())) { response.sendError(HttpStatus.NOT_FOUND_404, "Not Found"); + return; } super.handle(target, baseRequest, request, response); } From bef9b6de039945aec71ba0999db3367eab20e4ab Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Thu, 28 Sep 2023 15:42:01 -0700 Subject: [PATCH 111/239] chore(main): release java-function-invoker 1.3.2-SNAPSHOT (#234) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- invoker/conformance/pom.xml | 4 ++-- invoker/core/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 43894042..56dfcf68 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.3.1 + 1.3.2-SNAPSHOT com.google.cloud.functions.invoker conformance - 1.3.1 + 1.3.2-SNAPSHOT GCF Confromance Tests diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index f5f4dced..0ffdd993 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.1 + 1.3.2-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker - 1.3.1 + 1.3.2-SNAPSHOT GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -115,7 +115,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.3.1 + 1.3.2-SNAPSHOT test-jar test diff --git a/invoker/pom.xml b/invoker/pom.xml index e3159883..71b2f643 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -8,7 +8,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.1 + 1.3.2-SNAPSHOT pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index 660e6f05..856674a4 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.1 + 1.3.2-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.3.1 + 1.3.2-SNAPSHOT Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From b89ba197384a5790c8b4c9a1af70f808dd382914 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 19 Oct 2023 20:18:12 +0200 Subject: [PATCH 112/239] chore(deps): update all non-major dependencies (#242) --- .github/workflows/codeql.yml | 6 +++--- .github/workflows/conformance.yaml | 4 ++-- .github/workflows/lint.yaml | 6 +++--- .github/workflows/scorecard.yml | 6 +++--- .github/workflows/unit.yaml | 4 ++-- function-maven-plugin/pom.xml | 8 ++++---- functions-framework-api/pom.xml | 2 +- invoker/core/pom.xml | 8 ++++---- invoker/pom.xml | 2 +- 9 files changed, 23 insertions(+), 23 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index e9c002ec..a7a71ab5 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 with: disable-sudo: true egress-policy: block @@ -46,7 +46,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@00e563ead9f72a8461b24876bee2d0c2e8bd2ee8 # v2.21.5 + uses: github/codeql-action/init@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # v2.22.3 with: # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support languages: java @@ -66,6 +66,6 @@ jobs: (cd function-maven-plugin && mvn install) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@00e563ead9f72a8461b24876bee2d0c2e8bd2ee8 # v2.21.5 + uses: github/codeql-action/analyze@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # v2.22.3 with: category: ${{ matrix.working-directory }} diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index 0edd3720..80704601 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -20,7 +20,7 @@ jobs: ] steps: - name: Harden Runner - uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 with: disable-sudo: true egress-policy: block @@ -35,7 +35,7 @@ jobs: - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0 + uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0 with: java-version: ${{ matrix.java }} distribution: temurin diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 518c3c3d..bc964f52 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 with: disable-sudo: true egress-policy: block @@ -22,7 +22,7 @@ jobs: repo.maven.apache.org:443 - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 - name: Set up JDK - uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0 + uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0 with: java-version: 11.x distribution: temurin @@ -38,7 +38,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index dc3c7c0b..ef772cc0 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 with: disable-sudo: true egress-policy: block @@ -49,7 +49,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@08b4669551908b1024bb425080c797723083c031 # v2.2.0 + uses: ossf/scorecard-action@483ef80eb98fb506c348f7d62e28055e49fe2398 # v2.3.0 with: results_file: results.sarif results_format: sarif @@ -61,6 +61,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@00e563ead9f72a8461b24876bee2d0c2e8bd2ee8 # v2.21.5 + uses: github/codeql-action/upload-sarif@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # v2.22.3 with: sarif_file: results.sarif diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index d88af609..987c4e4f 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -18,7 +18,7 @@ jobs: ] steps: - name: Harden Runner - uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 + uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 with: disable-sudo: true egress-policy: block @@ -27,7 +27,7 @@ jobs: repo.maven.apache.org:443 - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@cd89f46ac9d01407894225f350157564c9c7cee2 # v3.12.0 + uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0 with: java-version: ${{ matrix.java }} distribution: temurin diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml index 20cc5882..c4bd7c6c 100644 --- a/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -41,12 +41,12 @@ org.apache.maven maven-plugin-api - 3.9.4 + 3.9.5 org.apache.maven maven-core - 3.9.4 + 3.9.5 org.apache.maven.plugin-tools @@ -64,7 +64,7 @@ com.google.cloud.tools appengine-maven-plugin - 2.4.4 + 2.5.0 jar @@ -132,7 +132,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.5.0 + 3.6.0 attach-javadocs diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index 14a940c3..53dba4d1 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -29,7 +29,7 @@ UTF-8 3.11.0 - 3.5.0 + 3.6.0 5.3.2 diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 0ffdd993..baf0543f 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -98,12 +98,12 @@ org.eclipse.jetty jetty-servlet - 9.4.52.v20230823 + 9.4.53.v20231009 org.eclipse.jetty jetty-server - 9.4.52.v20230823 + 9.4.53.v20231009 com.beust @@ -151,7 +151,7 @@ org.eclipse.jetty jetty-client - 9.4.52.v20230823 + 9.4.53.v20231009 test @@ -174,7 +174,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.5.0 + 3.5.1 package diff --git a/invoker/pom.xml b/invoker/pom.xml index 71b2f643..68a80e46 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -80,7 +80,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.5.0 + 3.6.0 attach-javadocs From e4445930ec3031dc1eff8d2fa872953e553ea517 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 19 Oct 2023 20:19:18 +0200 Subject: [PATCH 113/239] chore(deps): update actions/checkout action to v4 (#243) --- .github/workflows/codeql.yml | 2 +- .github/workflows/conformance.yaml | 2 +- .github/workflows/lint.yaml | 4 ++-- .github/workflows/scorecard.yml | 2 +- .github/workflows/unit.yaml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index a7a71ab5..d5bb2684 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -42,7 +42,7 @@ jobs: uploads.github.com:443 - name: Checkout repository - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index 80704601..b53b1c73 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -32,7 +32,7 @@ jobs: repo.maven.apache.org:443 storage.googleapis.com:443 - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up JDK ${{ matrix.java }} uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0 diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index bc964f52..fd5f6262 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -20,7 +20,7 @@ jobs: allowed-endpoints: > github.com:443 repo.maven.apache.org:443 - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up JDK uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0 with: @@ -42,7 +42,7 @@ jobs: with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 # v2 minimum required + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 # v2 minimum required - name: Run formatter id: formatter uses: axel-op/googlejavaformat-action@dbff853fb823671ec5781365233bf86543b13215 # v3 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index ef772cc0..1fabef33 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -44,7 +44,7 @@ jobs: *.github.com:443 - name: "Checkout code" - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: persist-credentials: false diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index 987c4e4f..7a7f63a6 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -25,7 +25,7 @@ jobs: allowed-endpoints: > github.com:443 repo.maven.apache.org:443 - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up JDK ${{ matrix.java }} uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0 with: From 0f35dea72744f1e60332f2ea18e5cc2535a1b594 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Wed, 1 Nov 2023 07:23:42 +0100 Subject: [PATCH 114/239] chore(deps): update all non-major dependencies (#247) --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 4 ++-- function-maven-plugin/pom.xml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index d5bb2684..d6b2d934 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -46,7 +46,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # v2.22.3 + uses: github/codeql-action/init@74483a38d39275f33fcff5f35b679b5ca4a26a99 # v2.22.5 with: # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support languages: java @@ -66,6 +66,6 @@ jobs: (cd function-maven-plugin && mvn install) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # v2.22.3 + uses: github/codeql-action/analyze@74483a38d39275f33fcff5f35b679b5ca4a26a99 # v2.22.5 with: category: ${{ matrix.working-directory }} diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 1fabef33..c8626a6c 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -49,7 +49,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@483ef80eb98fb506c348f7d62e28055e49fe2398 # v2.3.0 + uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 with: results_file: results.sarif results_format: sarif @@ -61,6 +61,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # v2.22.3 + uses: github/codeql-action/upload-sarif@74483a38d39275f33fcff5f35b679b5ca4a26a99 # v2.22.5 with: sarif_file: results.sarif diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml index c4bd7c6c..fff56345 100644 --- a/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -51,7 +51,7 @@ org.apache.maven.plugin-tools maven-plugin-annotations - 3.9.0 + 3.10.1 provided @@ -87,7 +87,7 @@ org.apache.maven.plugins maven-plugin-plugin - 3.9.0 + 3.10.1 help-goal From 4c454f40aa5d1266821ee9d9d313a41c4225dd69 Mon Sep 17 00:00:00 2001 From: Gareth Date: Tue, 7 Nov 2023 11:48:14 -0800 Subject: [PATCH 115/239] chore: add test coverage for Java 21 (#227) * chore: add test coverage for Java 21 * allowlist api.adoptium.net:443 --------- Co-authored-by: Kenneth Rosario --- .github/workflows/buildpack-integration-test.yml | 2 +- .github/workflows/conformance.yaml | 4 +--- .github/workflows/unit.yaml | 5 ++++- .../com/google/cloud/functions/invoker/IntegrationTest.java | 4 ++++ 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/buildpack-integration-test.yml b/.github/workflows/buildpack-integration-test.yml index 728f5a0f..2c320a6e 100644 --- a/.github/workflows/buildpack-integration-test.yml +++ b/.github/workflows/buildpack-integration-test.yml @@ -35,4 +35,4 @@ jobs: prerun: 'invoker/conformance/prerun.sh' builder-runtime: 'java17' builder-runtime-version: '17' - builder-url: gcr.io/gae-runtimes/buildpacks/google-gae-22/java/builder:latest \ No newline at end of file + builder-url: gcr.io/gae-runtimes/buildpacks/google-gae-22/java/builder:latest diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index b53b1c73..f997ebd9 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -14,9 +14,7 @@ jobs: strategy: matrix: java: [ - 11.x - # 12.x, - # 13.x + 11.x, ] steps: - name: Harden Runner diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index 7a7f63a6..54f15429 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -14,7 +14,8 @@ jobs: matrix: java: [ 11.x, - 17.x + 17.x, + 21-ea ] steps: - name: Harden Runner @@ -25,6 +26,8 @@ jobs: allowed-endpoints: > github.com:443 repo.maven.apache.org:443 + api.adoptium.net:443 + *.githubusercontent.com:443 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up JDK ${{ matrix.java }} uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0 diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java index f84ddbdd..3f3de837 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java @@ -363,6 +363,10 @@ private static int getJavaVersion() { if (dot != -1) { version = version.substring(0, dot); } + int dash = version.indexOf("-"); + if (dash != -1) { + version = version.substring(0, dash); + } } return Integer.parseInt(version); } From 9518d96d44a3eb227080f76696d9335bb0935006 Mon Sep 17 00:00:00 2001 From: Kenneth Rosario Date: Tue, 7 Nov 2023 11:59:43 -0800 Subject: [PATCH 116/239] chore: Update blunderbuss.yml (#252) --- .github/blunderbuss.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/blunderbuss.yml b/.github/blunderbuss.yml index 4234009b..45d57ef1 100644 --- a/.github/blunderbuss.yml +++ b/.github/blunderbuss.yml @@ -1,9 +1,9 @@ assign_prs: - janell-chen - HKWinterhalter - - garethgeorge + - kenneth-rosario assign_issues: - janell-chen - HKWinterhalter - - garethgeorge + - kenneth-rosario From c704548cc693310137ddcc552c25e27f2762eaf3 Mon Sep 17 00:00:00 2001 From: Andras Kerekes Date: Tue, 2 Jan 2024 12:02:06 -0800 Subject: [PATCH 117/239] Update README.md (#257) fix package and class name for examples --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9b117033..e4c543a4 100644 --- a/README.md +++ b/README.md @@ -161,7 +161,7 @@ You can configure the plugin in `pom.xml`: function-maven-plugin 0.10.1 - com.example.function.Echo + com.example.HelloWorld ``` @@ -178,7 +178,7 @@ You can alternatively configure the plugin with properties on the command line: ```sh mvn com.google.cloud.functions:function-maven-plugin:0.10.1:run \ - -Drun.functionTarget=com.example.function.Echo + -Drun.functionTarget=com.example.HelloWorld ``` ### Running the Functions Framework directly From fd73d6dfb6f7aef5e0ce7a667c8623ac0854f0b9 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 9 Jan 2024 16:50:44 +0100 Subject: [PATCH 118/239] chore(deps): update actions/setup-java action to v4 (#256) Co-authored-by: Kenneth Rosario --- .github/workflows/conformance.yaml | 2 +- .github/workflows/lint.yaml | 2 +- .github/workflows/unit.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index f997ebd9..d559b3da 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -33,7 +33,7 @@ jobs: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0 + uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0 with: java-version: ${{ matrix.java }} distribution: temurin diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index fd5f6262..dea46927 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -22,7 +22,7 @@ jobs: repo.maven.apache.org:443 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up JDK - uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0 + uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0 with: java-version: 11.x distribution: temurin diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index 54f15429..19184d88 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -30,7 +30,7 @@ jobs: *.githubusercontent.com:443 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0 + uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0 with: java-version: ${{ matrix.java }} distribution: temurin From 9756755c319ea9b921e1300998caf2173591d147 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Thu, 18 Jan 2024 23:57:32 +0100 Subject: [PATCH 119/239] chore(deps): update dependency com.google.guava:guava to v32 [security] (#253) Co-authored-by: Kenneth Rosario --- invoker/testfunction/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index 856674a4..ade019aa 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -31,7 +31,7 @@ com.google.guava guava - 29.0-jre + 32.0.0-android com.google.code.gson From b8b35b5534a5dbea9e9d61fc8055441861d7696b Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 19 Jan 2024 00:01:43 +0100 Subject: [PATCH 120/239] chore(deps): update all non-major dependencies (#255) --- .github/workflows/codeql.yml | 6 +++--- .github/workflows/conformance.yaml | 2 +- .github/workflows/lint.yaml | 4 ++-- .github/workflows/scorecard.yml | 4 ++-- .github/workflows/unit.yaml | 2 +- function-maven-plugin/pom.xml | 14 +++++++------- functions-framework-api/pom.xml | 4 ++-- invoker/core/pom.xml | 4 ++-- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 2 +- 10 files changed, 22 insertions(+), 22 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index d6b2d934..6476579b 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1 with: disable-sudo: true egress-policy: block @@ -46,7 +46,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@74483a38d39275f33fcff5f35b679b5ca4a26a99 # v2.22.5 + uses: github/codeql-action/init@4759df8df70c5ebe7042c3029bbace20eee13edd # v2.23.1 with: # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support languages: java @@ -66,6 +66,6 @@ jobs: (cd function-maven-plugin && mvn install) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@74483a38d39275f33fcff5f35b679b5ca4a26a99 # v2.22.5 + uses: github/codeql-action/analyze@4759df8df70c5ebe7042c3029bbace20eee13edd # v2.23.1 with: category: ${{ matrix.working-directory }} diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index d559b3da..76965b70 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -18,7 +18,7 @@ jobs: ] steps: - name: Harden Runner - uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1 with: disable-sudo: true egress-policy: block diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index dea46927..448eb910 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1 with: disable-sudo: true egress-policy: block @@ -38,7 +38,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index c8626a6c..f9c7efce 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1 with: disable-sudo: true egress-policy: block @@ -61,6 +61,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@74483a38d39275f33fcff5f35b679b5ca4a26a99 # v2.22.5 + uses: github/codeql-action/upload-sarif@4759df8df70c5ebe7042c3029bbace20eee13edd # v2.23.1 with: sarif_file: results.sarif diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index 19184d88..d8c12f2a 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -19,7 +19,7 @@ jobs: ] steps: - name: Harden Runner - uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 + uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1 with: disable-sudo: true egress-policy: block diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml index fff56345..b37754e6 100644 --- a/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -41,17 +41,17 @@ org.apache.maven maven-plugin-api - 3.9.5 + 3.9.6 org.apache.maven maven-core - 3.9.5 + 3.9.6 org.apache.maven.plugin-tools maven-plugin-annotations - 3.10.1 + 3.11.0 provided @@ -64,14 +64,14 @@ com.google.cloud.tools appengine-maven-plugin - 2.5.0 + 2.6.0 jar com.google.truth truth - 1.1.5 + 1.2.0 test @@ -87,7 +87,7 @@ org.apache.maven.plugins maven-plugin-plugin - 3.10.1 + 3.11.0 help-goal @@ -132,7 +132,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.6.0 + 3.6.3 attach-javadocs diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index 53dba4d1..01e9d22d 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -28,8 +28,8 @@ UTF-8 - 3.11.0 - 3.6.0 + 3.12.1 + 3.6.3 5.3.2 diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index baf0543f..febfd39c 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -139,13 +139,13 @@ com.google.truth truth - 1.1.5 + 1.2.0 test com.google.truth.extensions truth-java8-extension - 1.1.5 + 1.2.0 test diff --git a/invoker/pom.xml b/invoker/pom.xml index 68a80e46..b9b94e60 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -80,7 +80,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.6.0 + 3.6.3 attach-javadocs diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index ade019aa..a19349ce 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -31,7 +31,7 @@ com.google.guava guava - 32.0.0-android + 32.1.3-jre com.google.code.gson From 7757265759327c64c9e8a817c2f668906645991c Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 19 Jan 2024 00:09:15 +0100 Subject: [PATCH 121/239] chore(deps): update actions/setup-go action to v5 (#258) Co-authored-by: HKWinterhalter --- .github/workflows/conformance.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index 76965b70..b946eeeb 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -39,7 +39,7 @@ jobs: distribution: temurin - name: Setup Go - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 + uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: '1.21' From f2d4f89c980a69e3c3bb4005c68ac6acff713702 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 19 Jan 2024 00:16:45 +0100 Subject: [PATCH 122/239] chore(deps): update github/codeql-action action to v3 (#259) Co-authored-by: HKWinterhalter --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 6476579b..d09610e0 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -46,7 +46,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@4759df8df70c5ebe7042c3029bbace20eee13edd # v2.23.1 + uses: github/codeql-action/init@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1 with: # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support languages: java @@ -66,6 +66,6 @@ jobs: (cd function-maven-plugin && mvn install) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4759df8df70c5ebe7042c3029bbace20eee13edd # v2.23.1 + uses: github/codeql-action/analyze@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1 with: category: ${{ matrix.working-directory }} diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index f9c7efce..d0d20ff2 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -61,6 +61,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@4759df8df70c5ebe7042c3029bbace20eee13edd # v2.23.1 + uses: github/codeql-action/upload-sarif@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1 with: sarif_file: results.sarif From a9b2a2c69376e987f7034d32ce8401f923948b12 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 19 Jan 2024 00:21:11 +0100 Subject: [PATCH 123/239] chore(deps): update dependency org.mockito:mockito-core to v5 (#250) Co-authored-by: HKWinterhalter --- invoker/core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index febfd39c..c1501eb6 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -122,7 +122,7 @@ org.mockito mockito-core - 3.12.4 + 5.7.0 test From a290d09a1178cb85d8de0061386ba9bcbf1dc9b5 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Mon, 5 Feb 2024 15:09:48 +0100 Subject: [PATCH 124/239] chore(deps): update all non-major dependencies (#264) --- .github/workflows/codeql.yml | 6 +++--- .github/workflows/conformance.yaml | 2 +- .github/workflows/lint.yaml | 4 ++-- .github/workflows/scorecard.yml | 4 ++-- .github/workflows/unit.yaml | 2 +- function-maven-plugin/pom.xml | 4 ++-- invoker/core/pom.xml | 6 +++--- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index d09610e0..9b2d50ba 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1 + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 with: disable-sudo: true egress-policy: block @@ -46,7 +46,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1 + uses: github/codeql-action/init@e8893c57a1f3a2b659b6b55564fdfdbbd2982911 # v3.24.0 with: # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support languages: java @@ -66,6 +66,6 @@ jobs: (cd function-maven-plugin && mvn install) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1 + uses: github/codeql-action/analyze@e8893c57a1f3a2b659b6b55564fdfdbbd2982911 # v3.24.0 with: category: ${{ matrix.working-directory }} diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index b946eeeb..a38ab081 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -18,7 +18,7 @@ jobs: ] steps: - name: Harden Runner - uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1 + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 with: disable-sudo: true egress-policy: block diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 448eb910..47fdb814 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1 + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 with: disable-sudo: true egress-policy: block @@ -38,7 +38,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1 + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index d0d20ff2..36390246 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1 + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 with: disable-sudo: true egress-policy: block @@ -61,6 +61,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1 + uses: github/codeql-action/upload-sarif@e8893c57a1f3a2b659b6b55564fdfdbbd2982911 # v3.24.0 with: sarif_file: results.sarif diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index d8c12f2a..7e1e91d1 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -19,7 +19,7 @@ jobs: ] steps: - name: Harden Runner - uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1 + uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 with: disable-sudo: true egress-policy: block diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml index b37754e6..e8874a93 100644 --- a/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -64,14 +64,14 @@ com.google.cloud.tools appengine-maven-plugin - 2.6.0 + 2.8.0 jar com.google.truth truth - 1.2.0 + 1.4.0 test diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index c1501eb6..dbf10306 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -122,7 +122,7 @@ org.mockito mockito-core - 5.7.0 + 5.10.0 test @@ -139,13 +139,13 @@ com.google.truth truth - 1.2.0 + 1.4.0 test com.google.truth.extensions truth-java8-extension - 1.2.0 + 1.4.0 test From 6e4fb6881529aa9ebd113329a2e0fd271ffa8167 Mon Sep 17 00:00:00 2001 From: Kenneth Rosario Date: Mon, 1 Apr 2024 22:31:47 -0700 Subject: [PATCH 125/239] chore: Update blunderbuss.yml (#269) --- .github/blunderbuss.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/blunderbuss.yml b/.github/blunderbuss.yml index 45d57ef1..cafaa0ce 100644 --- a/.github/blunderbuss.yml +++ b/.github/blunderbuss.yml @@ -1,9 +1,7 @@ assign_prs: - janell-chen - HKWinterhalter - - kenneth-rosario assign_issues: - janell-chen - HKWinterhalter - - kenneth-rosario From f99decfad7eb050dfbab57a916d9cb57f34b0ad2 Mon Sep 17 00:00:00 2001 From: HKWinterhalter Date: Sun, 2 Jun 2024 23:59:10 -0700 Subject: [PATCH 126/239] chore: Update blunderbuss.yml (#273) * Update blunderbuss.yml * chore: Update blunderbuss.yml * chore: Update blunderbuss.yml Remove assignees - to be replaced with other mechanism * Update blunderbuss.yml --- .github/blunderbuss.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/blunderbuss.yml b/.github/blunderbuss.yml index cafaa0ce..8b137891 100644 --- a/.github/blunderbuss.yml +++ b/.github/blunderbuss.yml @@ -1,7 +1 @@ -assign_prs: - - janell-chen - - HKWinterhalter -assign_issues: - - janell-chen - - HKWinterhalter From 5a66df34ab06a75c277bab874f23042117f59756 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 21 Jun 2024 01:25:01 +0200 Subject: [PATCH 127/239] chore(deps): update dependency io.cloudevents:cloudevents-json-jackson to v3 (#271) Co-authored-by: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> --- invoker/conformance/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 56dfcf68..964f3bf9 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -43,7 +43,7 @@ io.cloudevents cloudevents-json-jackson - 2.5.0 + 3.0.0 From 0415a6b123d0e5f1aa5dadc366c1c222b87bd4bb Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 21 Jun 2024 02:10:24 +0200 Subject: [PATCH 128/239] chore(deps): update dependency io.cloudevents:cloudevents-api to v3 (#268) Co-authored-by: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> --- functions-framework-api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index 01e9d22d..183a6184 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -52,7 +52,7 @@ io.cloudevents cloudevents-api - 2.5.0 + 3.0.0 From a2665683e1ec3df4ae078f60e7fa418ce4d09dd9 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 21 Jun 2024 02:24:13 +0200 Subject: [PATCH 129/239] chore(deps): update dependency com.google.guava:guava to v33 (#266) Co-authored-by: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> --- invoker/testfunction/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index a19349ce..6958ad2d 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -31,7 +31,7 @@ com.google.guava guava - 32.1.3-jre + 33.2.1-jre com.google.code.gson From e095e1d114d0641c8468cf37469be0125387821f Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 21 Jun 2024 02:27:53 +0200 Subject: [PATCH 130/239] chore(deps): update dependency io.cloudevents:cloudevents-core to v3 (#270) Co-authored-by: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> --- invoker/conformance/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 964f3bf9..054af20e 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -38,7 +38,7 @@ io.cloudevents cloudevents-core - 2.5.0 + 3.0.0 io.cloudevents From 3fd0521d4999c17ea45ba6ae47a8cea29d9b6ad8 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 21 Jun 2024 02:38:13 +0200 Subject: [PATCH 131/239] chore(deps): update cloudevents.sdk.version to v3 (#267) Co-authored-by: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> --- invoker/core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index dbf10306..9a879c0c 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -22,7 +22,7 @@ 5.3.2 11 11 - 2.5.0 + 3.0.0 From 8d44947c7524cca045906aa444bc3eb48bbbff85 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 21 Jun 2024 02:58:19 +0200 Subject: [PATCH 132/239] chore(deps): update all non-major dependencies (#265) * chore(deps): update all non-major dependencies * remove all references to truth8 --------- Co-authored-by: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> Co-authored-by: Jeremy Fehr --- .github/workflows/codeql.yml | 8 +++---- .github/workflows/conformance.yaml | 8 +++---- .github/workflows/lint.yaml | 10 ++++----- .github/workflows/scorecard.yml | 8 +++---- .github/workflows/unit.yaml | 6 ++--- function-maven-plugin/pom.xml | 18 +++++++-------- functions-framework-api/pom.xml | 12 +++++----- invoker/conformance/pom.xml | 2 +- invoker/core/pom.xml | 22 +++++++++---------- .../BackgroundFunctionExecutorTest.java | 1 - .../invoker/TypedFunctionExecutorTest.java | 1 - .../functions/invoker/http/HttpTest.java | 1 - .../functions/invoker/runner/InvokerTest.java | 1 - invoker/pom.xml | 8 +++---- invoker/testfunction/pom.xml | 6 ++--- 15 files changed, 54 insertions(+), 58 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 9b2d50ba..a974e193 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 with: disable-sudo: true egress-policy: block @@ -42,11 +42,11 @@ jobs: uploads.github.com:443 - name: Checkout repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@e8893c57a1f3a2b659b6b55564fdfdbbd2982911 # v3.24.0 + uses: github/codeql-action/init@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10 with: # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support languages: java @@ -66,6 +66,6 @@ jobs: (cd function-maven-plugin && mvn install) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e8893c57a1f3a2b659b6b55564fdfdbbd2982911 # v3.24.0 + uses: github/codeql-action/analyze@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10 with: category: ${{ matrix.working-directory }} diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index a38ab081..c914263e 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -18,7 +18,7 @@ jobs: ] steps: - name: Harden Runner - uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 with: disable-sudo: true egress-policy: block @@ -30,16 +30,16 @@ jobs: repo.maven.apache.org:443 storage.googleapis.com:443 - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0 + uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 with: java-version: ${{ matrix.java }} distribution: temurin - name: Setup Go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 with: go-version: '1.21' diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 47fdb814..a712703e 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -13,16 +13,16 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 with: disable-sudo: true egress-policy: block allowed-endpoints: > github.com:443 repo.maven.apache.org:443 - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up JDK - uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0 + uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 with: java-version: 11.x distribution: temurin @@ -38,11 +38,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 # v2 minimum required + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 # v2 minimum required - name: Run formatter id: formatter uses: axel-op/googlejavaformat-action@dbff853fb823671ec5781365233bf86543b13215 # v3 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 36390246..728eb127 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 with: disable-sudo: true egress-policy: block @@ -44,12 +44,12 @@ jobs: *.github.com:443 - name: "Checkout code" - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 with: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 + uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3 with: results_file: results.sarif results_format: sarif @@ -61,6 +61,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@e8893c57a1f3a2b659b6b55564fdfdbbd2982911 # v3.24.0 + uses: github/codeql-action/upload-sarif@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10 with: sarif_file: results.sarif diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index 7e1e91d1..64821a08 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -19,7 +19,7 @@ jobs: ] steps: - name: Harden Runner - uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 with: disable-sudo: true egress-policy: block @@ -28,9 +28,9 @@ jobs: repo.maven.apache.org:443 api.adoptium.net:443 *.githubusercontent.com:443 - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0 + uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 with: java-version: ${{ matrix.java }} distribution: temurin diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml index e8874a93..ac6c3552 100644 --- a/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -41,17 +41,17 @@ org.apache.maven maven-plugin-api - 3.9.6 + 3.9.8 org.apache.maven maven-core - 3.9.6 + 3.9.8 org.apache.maven.plugin-tools maven-plugin-annotations - 3.11.0 + 3.13.1 provided @@ -71,7 +71,7 @@ com.google.truth truth - 1.4.0 + 1.4.2 test @@ -87,7 +87,7 @@ org.apache.maven.plugins maven-plugin-plugin - 3.11.0 + 3.13.1 help-goal @@ -119,7 +119,7 @@ org.apache.maven.plugins maven-source-plugin - 3.3.0 + 3.3.1 attach-sources @@ -132,7 +132,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.6.3 + 3.7.0 attach-javadocs @@ -145,7 +145,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.1.0 + 3.2.4 sign-artifacts @@ -159,7 +159,7 @@ org.sonatype.plugins nexus-staging-maven-plugin - 1.6.13 + 1.7.0 true sonatype-nexus-snapshots diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index 183a6184..b9fec533 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -28,8 +28,8 @@ UTF-8 - 3.12.1 - 3.6.3 + 3.13.0 + 3.7.0 5.3.2 @@ -73,7 +73,7 @@ org.apache.maven.plugins maven-source-plugin - 3.3.0 + 3.3.1 attach-sources @@ -86,7 +86,7 @@ org.apache.maven.plugins maven-release-plugin - 3.0.1 + 3.1.0 default @@ -177,7 +177,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.1.0 + 3.2.4 sign-artifacts @@ -191,7 +191,7 @@ org.sonatype.plugins nexus-staging-maven-plugin - 1.6.13 + 1.7.0 true sonatype-nexus-snapshots diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 054af20e..a4c6820e 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -33,7 +33,7 @@ com.google.code.gson gson - 2.10.1 + 2.11.0 io.cloudevents diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 9a879c0c..7351b402 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -69,7 +69,7 @@ com.google.code.gson gson - 2.10.1 + 2.11.0 com.ryanharter.auto.value @@ -86,24 +86,24 @@ com.google.auto.value auto-value - 1.10.4 + 1.11.0 provided com.google.auto.value auto-value-annotations - 1.10.4 + 1.11.0 provided org.eclipse.jetty jetty-servlet - 9.4.53.v20231009 + 9.4.54.v20240208 org.eclipse.jetty jetty-server - 9.4.53.v20231009 + 9.4.54.v20240208 com.beust @@ -122,7 +122,7 @@ org.mockito mockito-core - 5.10.0 + 5.12.0 test @@ -139,19 +139,19 @@ com.google.truth truth - 1.4.0 + 1.4.2 test com.google.truth.extensions truth-java8-extension - 1.4.0 + 1.4.2 test org.eclipse.jetty jetty-client - 9.4.53.v20231009 + 9.4.54.v20240208 test @@ -160,7 +160,7 @@ maven-jar-plugin - 3.3.0 + 3.4.2 @@ -174,7 +174,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.5.1 + 3.6.0 package diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutorTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutorTest.java index 2b7211c9..87b9bd31 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutorTest.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutorTest.java @@ -2,7 +2,6 @@ import static com.google.cloud.functions.invoker.BackgroundFunctionExecutor.backgroundFunctionTypeArgument; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth8.assertThat; import com.google.cloud.functions.BackgroundFunction; import com.google.cloud.functions.Context; diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/TypedFunctionExecutorTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/TypedFunctionExecutorTest.java index 969d1dcc..668d60c8 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/TypedFunctionExecutorTest.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/TypedFunctionExecutorTest.java @@ -1,7 +1,6 @@ package com.google.cloud.functions.invoker; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth8.assertThat; import com.google.cloud.functions.TypedFunction; import org.junit.Test; diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/http/HttpTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/http/HttpTest.java index e52ec62a..e0ca4675 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/http/HttpTest.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/http/HttpTest.java @@ -15,7 +15,6 @@ package com.google.cloud.functions.invoker.http; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth8.assertThat; import static org.junit.Assert.fail; import com.google.cloud.functions.HttpRequest; diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/runner/InvokerTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/runner/InvokerTest.java index b3569e4e..c1a7ca29 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/runner/InvokerTest.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/runner/InvokerTest.java @@ -2,7 +2,6 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; -import static com.google.common.truth.Truth8.assertThat; import static java.util.stream.Collectors.joining; import java.io.ByteArrayOutputStream; diff --git a/invoker/pom.xml b/invoker/pom.xml index b9b94e60..f23ff693 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -67,7 +67,7 @@ org.apache.maven.plugins maven-source-plugin - 3.3.0 + 3.3.1 attach-sources @@ -80,7 +80,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.6.3 + 3.7.0 attach-javadocs @@ -93,7 +93,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.1.0 + 3.2.4 sign-artifacts @@ -107,7 +107,7 @@ org.sonatype.plugins nexus-staging-maven-plugin - 1.6.13 + 1.7.0 true sonatype-nexus-snapshots diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index 6958ad2d..7160841b 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -36,7 +36,7 @@ com.google.code.gson gson - 2.10.1 + 2.11.0 @@ -44,7 +44,7 @@ maven-jar-plugin - 3.3.0 + 3.4.2 @@ -86,7 +86,7 @@ org.apache.maven.plugins maven-deploy-plugin - 3.1.1 + 3.1.2 true From c3a3161204707e0952e0de9df53044bcf42d893b Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 21 Jun 2024 03:08:21 +0200 Subject: [PATCH 133/239] chore(deps): update googlecloudplatform/functions-framework-conformance digest to 1041a97 (#263) Co-authored-by: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> --- .github/workflows/conformance.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index c914263e..b58ae762 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -53,7 +53,7 @@ jobs: run: (cd function-maven-plugin/ && mvn install) - name: Run HTTP conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@72a4f36b10f1c6435ab1a86a9ea24bda464cc262 # main + uses: GoogleCloudPlatform/functions-framework-conformance/action@1041a97e93a463d9efb17dda821f3ddc0bf0024f # main with: functionType: 'http' useBuildpacks: false @@ -61,7 +61,7 @@ jobs: startDelay: 10 - name: Run Typed conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@72a4f36b10f1c6435ab1a86a9ea24bda464cc262 # main + uses: GoogleCloudPlatform/functions-framework-conformance/action@1041a97e93a463d9efb17dda821f3ddc0bf0024f # main with: functionType: 'http' declarativeType: 'typed' @@ -70,7 +70,7 @@ jobs: startDelay: 10 - name: Run background event conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@72a4f36b10f1c6435ab1a86a9ea24bda464cc262 # main + uses: GoogleCloudPlatform/functions-framework-conformance/action@1041a97e93a463d9efb17dda821f3ddc0bf0024f # main with: functionType: 'legacyevent' useBuildpacks: false @@ -79,7 +79,7 @@ jobs: startDelay: 10 - name: Run cloudevent conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@72a4f36b10f1c6435ab1a86a9ea24bda464cc262 # main + uses: GoogleCloudPlatform/functions-framework-conformance/action@1041a97e93a463d9efb17dda821f3ddc0bf0024f # main with: functionType: 'cloudevent' useBuildpacks: false @@ -88,7 +88,7 @@ jobs: startDelay: 10 - name: Run HTTP concurrency conformance tests - uses: GoogleCloudPlatform/functions-framework-conformance/action@72a4f36b10f1c6435ab1a86a9ea24bda464cc262 # main + uses: GoogleCloudPlatform/functions-framework-conformance/action@1041a97e93a463d9efb17dda821f3ddc0bf0024f # main with: functionType: 'http' useBuildpacks: false From 2e823c62876b3b26b1e9704b47cf852e2e32e2e0 Mon Sep 17 00:00:00 2001 From: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> Date: Thu, 27 Jun 2024 08:49:26 -0700 Subject: [PATCH 134/239] fix: update scorecard.yml (#276) --- .github/workflows/scorecard.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 728eb127..74ce67bb 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -32,6 +32,7 @@ jobs: egress-policy: block allowed-endpoints: > api.osv.dev:443 + api.scorecard.dev:443 api.securityscorecards.dev:443 auth.docker.io:443 bestpractices.coreinfrastructure.org:443 From 7e4ca5d15d5b200787b999f82da6d6cd1cbd4b7e Mon Sep 17 00:00:00 2001 From: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> Date: Thu, 27 Jun 2024 11:02:37 -0700 Subject: [PATCH 135/239] fix: release 1.1.1 (#277) Release-As: 1.1.1 --- functions-framework-api/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/functions-framework-api/CHANGELOG.md b/functions-framework-api/CHANGELOG.md index 1ab28e74..469c198b 100644 --- a/functions-framework-api/CHANGELOG.md +++ b/functions-framework-api/CHANGELOG.md @@ -11,3 +11,4 @@ ### Bug Fixes * remove warnings from mvn install ([#66](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/66)) ([270f4ec](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/270f4ec7936239eff9c00b8d3ff0f09a8615b9c9)) + From cb4d76dd384d076f66c10fa5fdb151e556369cd7 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 11:30:18 -0700 Subject: [PATCH 136/239] chore(main): release functions-framework-api 1.1.1 (#278) * chore(main): release functions-framework-api 1.1.1 * Update CHANGELOG.md --------- Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> --- .github/.release-please-manifest.json | 2 +- functions-framework-api/CHANGELOG.md | 8 +++++++- functions-framework-api/pom.xml | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/.release-please-manifest.json b/.github/.release-please-manifest.json index c2ee81e0..efcd0568 100644 --- a/.github/.release-please-manifest.json +++ b/.github/.release-please-manifest.json @@ -1 +1 @@ -{"functions-framework-api":"1.1.0","invoker":"1.3.1","function-maven-plugin":"0.11.0"} +{"functions-framework-api":"1.1.1","invoker":"1.3.1","function-maven-plugin":"0.11.0"} diff --git a/functions-framework-api/CHANGELOG.md b/functions-framework-api/CHANGELOG.md index 469c198b..e999fd1d 100644 --- a/functions-framework-api/CHANGELOG.md +++ b/functions-framework-api/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.1.1](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/functions-framework-api-v1.1.0...functions-framework-api-v1.1.1) (2024-06-27) + + +### Bug Fixes + +* release 1.1.1; this updates transitive dependencies on jackson ([#277](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/277)) ([7e4ca5d](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/7e4ca5d15d5b200787b999f82da6d6cd1cbd4b7e)) + ## [1.1.0](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/functions-framework-api-v1.0.4...functions-framework-api-v1.1.0) (2023-05-31) @@ -11,4 +18,3 @@ ### Bug Fixes * remove warnings from mvn install ([#66](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/66)) ([270f4ec](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/270f4ec7936239eff9c00b8d3ff0f09a8615b9c9)) - diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index b9fec533..576df30c 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -24,7 +24,7 @@ com.google.cloud.functions functions-framework-api - 1.1.1-SNAPSHOT + 1.1.1 UTF-8 From dc9bc1f03c90a60e8007bc4f61f78ade61d97817 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 13:52:52 -0700 Subject: [PATCH 137/239] chore(main): release functions-framework-api 1.1.2-SNAPSHOT (#279) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- functions-framework-api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index 576df30c..7c08e00f 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -24,7 +24,7 @@ com.google.cloud.functions functions-framework-api - 1.1.1 + 1.1.2-SNAPSHOT UTF-8 From 9e91f57b12d73c655e3d7e226d21d54ccec32b73 Mon Sep 17 00:00:00 2001 From: janell-chen <122311137+janell-chen@users.noreply.github.com> Date: Mon, 8 Jul 2024 11:01:21 -0700 Subject: [PATCH 138/239] fix: server times out when specified by CLOUD_RUN_TIMEOUT_SECONDS (#275) * fix: server times out when specified by CLOUD_RUN_TIMEOUT_SECONDS --- .../functions/invoker/http/TimeoutFilter.java | 71 +++++++++++++++++++ .../functions/invoker/runner/Invoker.java | 17 +++++ .../functions/invoker/IntegrationTest.java | 71 +++++++++++++++---- .../invoker/testfunctions/TimeoutHttp.java | 18 +++++ 4 files changed, 165 insertions(+), 12 deletions(-) create mode 100644 invoker/core/src/main/java/com/google/cloud/functions/invoker/http/TimeoutFilter.java create mode 100644 invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/TimeoutHttp.java diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/http/TimeoutFilter.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/http/TimeoutFilter.java new file mode 100644 index 00000000..e0577f9b --- /dev/null +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/http/TimeoutFilter.java @@ -0,0 +1,71 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.cloud.functions.invoker.http; + +import java.io.IOException; +import java.util.Timer; +import java.util.TimerTask; +import java.util.logging.Logger; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponse; + +public class TimeoutFilter implements Filter { + + private static final Logger logger = Logger.getLogger(TimeoutFilter.class.getName()); + private final int timeoutMs; + + public TimeoutFilter(int timeoutSeconds) { + this.timeoutMs = timeoutSeconds * 1000; // Convert seconds to milliseconds + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + Timer timer = new Timer(true); + TimerTask timeoutTask = + new TimerTask() { + @Override + public void run() { + if (response instanceof HttpServletResponse) { + try { + ((HttpServletResponse) response) + .sendError(HttpServletResponse.SC_REQUEST_TIMEOUT, "Request timed out"); + } catch (IOException e) { + logger.warning("Error while sending HTTP response: " + e.toString()); + } + } else { + try { + response.getWriter().write("Request timed out"); + } catch (IOException e) { + logger.warning("Error while writing response: " + e.toString()); + } + } + } + }; + + timer.schedule(timeoutTask, timeoutMs); + + try { + chain.doFilter(request, response); + timeoutTask.cancel(); + } finally { + timer.purge(); + } + } +} diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java index 892d6038..da5e72ec 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/runner/Invoker.java @@ -25,6 +25,7 @@ import com.google.cloud.functions.invoker.HttpFunctionExecutor; import com.google.cloud.functions.invoker.TypedFunctionExecutor; import com.google.cloud.functions.invoker.gcf.JsonLogHandler; +import com.google.cloud.functions.invoker.http.TimeoutFilter; import java.io.File; import java.io.IOException; import java.io.UncheckedIOException; @@ -38,6 +39,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -48,6 +50,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Stream; +import javax.servlet.DispatcherType; import javax.servlet.MultipartConfigElement; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -59,6 +62,7 @@ import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.HandlerWrapper; +import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.util.thread.QueuedThreadPool; @@ -324,6 +328,7 @@ private void startServer(boolean join) throws Exception { ServletHolder servletHolder = new ServletHolder(servlet); servletHolder.getRegistration().setMultipartConfig(new MultipartConfigElement("")); servletContextHandler.addServlet(servletHolder, "/*"); + servletContextHandler = addTimerFilterForRequestTimeout(servletContextHandler); server.start(); logServerInfo(); @@ -393,6 +398,18 @@ private HttpServlet servletForDeducedSignatureType(Class functionClass) { throw new RuntimeException(error); } + private ServletContextHandler addTimerFilterForRequestTimeout( + ServletContextHandler servletContextHandler) { + String timeoutSeconds = System.getenv("CLOUD_RUN_TIMEOUT_SECONDS"); + if (timeoutSeconds == null) { + return servletContextHandler; + } + int seconds = Integer.parseInt(timeoutSeconds); + FilterHolder holder = new FilterHolder(new TimeoutFilter(seconds)); + servletContextHandler.addFilter(holder, "/*", EnumSet.of(DispatcherType.REQUEST)); + return servletContextHandler; + } + static URL[] classpathToUrls(String classpath) { String[] components = classpath.split(File.pathSeparator); List urls = new ArrayList<>(); diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java index 3f3de837..82197547 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java @@ -51,6 +51,7 @@ import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; @@ -252,6 +253,34 @@ public void helloWorld() throws Exception { ROBOTS_TXT_TEST_CASE)); } + @Test + public void timeoutHttpSuccess() throws Exception { + testFunction( + SignatureType.HTTP, + fullTarget("TimeoutHttp"), + ImmutableList.of(), + ImmutableList.of( + TestCase.builder() + .setExpectedResponseText("finished\n") + .setExpectedResponseText(Optional.empty()) + .build()), + ImmutableMap.of("CLOUD_RUN_TIMEOUT_SECONDS", "3")); + } + + @Test + public void timeoutHttpTimesOut() throws Exception { + testFunction( + SignatureType.HTTP, + fullTarget("TimeoutHttp"), + ImmutableList.of(), + ImmutableList.of( + TestCase.builder() + .setExpectedResponseCode(408) + .setExpectedResponseText(Optional.empty()) + .build()), + ImmutableMap.of("CLOUD_RUN_TIMEOUT_SECONDS", "1")); + } + @Test public void exceptionHttp() throws Exception { String exceptionExpectedOutput = @@ -290,7 +319,8 @@ public void exceptionBackground() throws Exception { .setRequestText(gcfRequestText) .setExpectedResponseCode(500) .setExpectedOutput(exceptionExpectedOutput) - .build())); + .build()), + Collections.emptyMap()); } @Test @@ -400,7 +430,8 @@ public void typedFunction() throws Exception { TestCase.builder() .setRequestText(originalJson) .setExpectedResponseText("{\"fullName\":\"JohnDoe\"}") - .build())); + .build()), + Collections.emptyMap()); } @Test @@ -410,7 +441,8 @@ public void typedVoidFunction() throws Exception { fullTarget("TypedVoid"), ImmutableList.of(), ImmutableList.of( - TestCase.builder().setRequestText("{}").setExpectedResponseCode(204).build())); + TestCase.builder().setRequestText("{}").setExpectedResponseCode(204).build()), + Collections.emptyMap()); } @Test @@ -424,7 +456,8 @@ public void typedCustomFormat() throws Exception { .setRequestText("abc\n123\n$#@\n") .setExpectedResponseText("abc123$#@") .setExpectedResponseCode(200) - .build())); + .build()), + Collections.emptyMap()); } private void backgroundTest(String target) throws Exception { @@ -595,7 +628,8 @@ public void classpathOptionHttp() throws Exception { SignatureType.HTTP, "com.example.functionjar.Foreground", ImmutableList.of("--classpath", functionJarString()), - ImmutableList.of(testCase)); + ImmutableList.of(testCase), + Collections.emptyMap()); } /** Like {@link #classpathOptionHttp} but for background functions. */ @@ -612,7 +646,8 @@ public void classpathOptionBackground() throws Exception { SignatureType.BACKGROUND, "com.example.functionjar.Background", ImmutableList.of("--classpath", functionJarString()), - ImmutableList.of(TestCase.builder().setRequestText(json.toString()).build())); + ImmutableList.of(TestCase.builder().setRequestText(json.toString()).build()), + Collections.emptyMap()); } /** Like {@link #classpathOptionHttp} but for typed functions. */ @@ -629,7 +664,8 @@ public void classpathOptionTyped() throws Exception { TestCase.builder() .setRequestText(originalJson) .setExpectedResponseText("{\"fullName\":\"JohnDoe\"}") - .build())); + .build()), + Collections.emptyMap()); } // In these tests, we test a number of different functions that express the same functionality @@ -643,7 +679,12 @@ private void backgroundTest( for (TestCase testCase : testCases) { File snoopFile = testCase.snoopFile().get(); snoopFile.delete(); - testFunction(signatureType, functionTarget, ImmutableList.of(), ImmutableList.of(testCase)); + testFunction( + signatureType, + functionTarget, + ImmutableList.of(), + ImmutableList.of(testCase), + Collections.emptyMap()); String snooped = new String(Files.readAllBytes(snoopFile.toPath()), StandardCharsets.UTF_8); Gson gson = new Gson(); JsonObject snoopedJson = gson.fromJson(snooped, JsonObject.class); @@ -667,16 +708,18 @@ private void checkSnoopFile(TestCase testCase) throws IOException { } private void testHttpFunction(String target, List testCases) throws Exception { - testFunction(SignatureType.HTTP, target, ImmutableList.of(), testCases); + testFunction(SignatureType.HTTP, target, ImmutableList.of(), testCases, Collections.emptyMap()); } private void testFunction( SignatureType signatureType, String target, ImmutableList extraArgs, - List testCases) + List testCases, + Map environmentVariables) throws Exception { - ServerProcess serverProcess = startServer(signatureType, target, extraArgs); + ServerProcess serverProcess = + startServer(signatureType, target, extraArgs, environmentVariables); try { HttpClient httpClient = new HttpClient(); httpClient.start(); @@ -772,7 +815,10 @@ public void close() { } private ServerProcess startServer( - SignatureType signatureType, String target, ImmutableList extraArgs) + SignatureType signatureType, + String target, + ImmutableList extraArgs, + Map environmentVariables) throws IOException, InterruptedException { File javaHome = new File(System.getProperty("java.home")); assertThat(javaHome.exists()).isTrue(); @@ -798,6 +844,7 @@ private ServerProcess startServer( "FUNCTION_TARGET", target); processBuilder.environment().putAll(environment); + processBuilder.environment().putAll(environmentVariables); Process serverProcess = processBuilder.start(); CountDownLatch ready = new CountDownLatch(1); StringBuilder output = new StringBuilder(); diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/TimeoutHttp.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/TimeoutHttp.java new file mode 100644 index 00000000..c73e52d2 --- /dev/null +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/testfunctions/TimeoutHttp.java @@ -0,0 +1,18 @@ +package com.google.cloud.functions.invoker.testfunctions; + +import com.google.cloud.functions.HttpFunction; +import com.google.cloud.functions.HttpRequest; +import com.google.cloud.functions.HttpResponse; + +public class TimeoutHttp implements HttpFunction { + + @Override + public void service(HttpRequest request, HttpResponse response) throws Exception { + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + response.getWriter().close(); + } + response.getWriter().write("finished\n"); + } +} From b7a5d05f4ee362508a546c906bfa1a3c44d93d7f Mon Sep 17 00:00:00 2001 From: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> Date: Wed, 18 Sep 2024 09:00:38 -0700 Subject: [PATCH 139/239] chore: Update blunderbuss.yml (#286) --- .github/blunderbuss.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/blunderbuss.yml b/.github/blunderbuss.yml index 8b137891..2dfa51ed 100644 --- a/.github/blunderbuss.yml +++ b/.github/blunderbuss.yml @@ -1 +1,10 @@ +assign_prs: + - HKwinterhalter + - dixuswe + - janell-chen +assign_issues: + - HKwinterhalter + - dixuswe + - janell-chen + From 023ceff31315e324a38a1782e5d7fcae6b00131d Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Sat, 28 Sep 2024 01:10:22 +0200 Subject: [PATCH 140/239] chore(deps): update dependency io.cloudevents:cloudevents-json-jackson to v4 (#285) Co-authored-by: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> --- invoker/conformance/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index a4c6820e..4ff8fa05 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -43,7 +43,7 @@ io.cloudevents cloudevents-json-jackson - 3.0.0 + 4.0.1 From fe6da26cd9af4ceb0efab92609fcae5921720525 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Sat, 28 Sep 2024 01:10:32 +0200 Subject: [PATCH 141/239] chore(deps): update cloudevents.sdk.version to v4 (#282) Co-authored-by: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> --- invoker/core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 7351b402..64e2fe24 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -22,7 +22,7 @@ 5.3.2 11 11 - 3.0.0 + 4.0.1 From fd33779cc8633a3d09ecee99ca20a624f0efc676 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Sat, 28 Sep 2024 01:10:42 +0200 Subject: [PATCH 142/239] chore(deps): update dependency io.cloudevents:cloudevents-core to v4 (#284) Co-authored-by: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> --- invoker/conformance/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 4ff8fa05..d94dbf8a 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -38,7 +38,7 @@ io.cloudevents cloudevents-core - 3.0.0 + 4.0.1 io.cloudevents From 744996348029857d7054753b83a62f172e8fa5e5 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Sat, 28 Sep 2024 01:11:10 +0200 Subject: [PATCH 143/239] chore(deps): update all non-major dependencies (#280) --- .github/workflows/codeql.yml | 8 ++++---- .github/workflows/conformance.yaml | 8 ++++---- .github/workflows/lint.yaml | 10 +++++----- .github/workflows/scorecard.yml | 8 ++++---- .github/workflows/unit.yaml | 6 +++--- function-maven-plugin/pom.xml | 16 ++++++++-------- functions-framework-api/pom.xml | 6 +++--- invoker/core/pom.xml | 12 ++++++------ invoker/pom.xml | 4 ++-- invoker/testfunction/pom.xml | 4 ++-- 10 files changed, 41 insertions(+), 41 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index a974e193..518a5853 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: disable-sudo: true egress-policy: block @@ -42,11 +42,11 @@ jobs: uploads.github.com:443 - name: Checkout repository - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10 + uses: github/codeql-action/init@461ef6c76dfe95d5c364de2f431ddbd31a417628 # v3.26.9 with: # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support languages: java @@ -66,6 +66,6 @@ jobs: (cd function-maven-plugin && mvn install) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10 + uses: github/codeql-action/analyze@461ef6c76dfe95d5c364de2f431ddbd31a417628 # v3.26.9 with: category: ${{ matrix.working-directory }} diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index b58ae762..1745c330 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -18,7 +18,7 @@ jobs: ] steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: disable-sudo: true egress-policy: block @@ -30,16 +30,16 @@ jobs: repo.maven.apache.org:443 storage.googleapis.com:443 - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 + uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0 with: java-version: ${{ matrix.java }} distribution: temurin - name: Setup Go - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version: '1.21' diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index a712703e..7b32858c 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -13,16 +13,16 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: disable-sudo: true egress-policy: block allowed-endpoints: > github.com:443 repo.maven.apache.org:443 - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Set up JDK - uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 + uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0 with: java-version: 11.x distribution: temurin @@ -38,11 +38,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 # v2 minimum required + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 # v2 minimum required - name: Run formatter id: formatter uses: axel-op/googlejavaformat-action@dbff853fb823671ec5781365233bf86543b13215 # v3 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 74ce67bb..c90435f2 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: disable-sudo: true egress-policy: block @@ -45,12 +45,12 @@ jobs: *.github.com:443 - name: "Checkout code" - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 with: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3 + uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 with: results_file: results.sarif results_format: sarif @@ -62,6 +62,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10 + uses: github/codeql-action/upload-sarif@461ef6c76dfe95d5c364de2f431ddbd31a417628 # v3.26.9 with: sarif_file: results.sarif diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index 64821a08..c970fd3e 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -19,7 +19,7 @@ jobs: ] steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 with: disable-sudo: true egress-policy: block @@ -28,9 +28,9 @@ jobs: repo.maven.apache.org:443 api.adoptium.net:443 *.githubusercontent.com:443 - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 # v4.2.1 + uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0 with: java-version: ${{ matrix.java }} distribution: temurin diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml index ac6c3552..bab9524c 100644 --- a/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -41,17 +41,17 @@ org.apache.maven maven-plugin-api - 3.9.8 + 3.9.9 org.apache.maven maven-core - 3.9.8 + 3.9.9 org.apache.maven.plugin-tools maven-plugin-annotations - 3.13.1 + 3.15.0 provided @@ -64,14 +64,14 @@ com.google.cloud.tools appengine-maven-plugin - 2.8.0 + 2.8.1 jar com.google.truth truth - 1.4.2 + 1.4.4 test @@ -87,7 +87,7 @@ org.apache.maven.plugins maven-plugin-plugin - 3.13.1 + 3.15.0 help-goal @@ -132,7 +132,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.7.0 + 3.10.0 attach-javadocs @@ -145,7 +145,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.2.4 + 3.2.7 sign-artifacts diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index 7c08e00f..603b7c72 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -29,7 +29,7 @@ UTF-8 3.13.0 - 3.7.0 + 3.10.0 5.3.2 @@ -86,7 +86,7 @@ org.apache.maven.plugins maven-release-plugin - 3.1.0 + 3.1.1 default @@ -177,7 +177,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.2.4 + 3.2.7 sign-artifacts diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 64e2fe24..4202e33c 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -98,12 +98,12 @@ org.eclipse.jetty jetty-servlet - 9.4.54.v20240208 + 9.4.56.v20240826 org.eclipse.jetty jetty-server - 9.4.54.v20240208 + 9.4.56.v20240826 com.beust @@ -122,7 +122,7 @@ org.mockito mockito-core - 5.12.0 + 5.14.0 test @@ -139,19 +139,19 @@ com.google.truth truth - 1.4.2 + 1.4.4 test com.google.truth.extensions truth-java8-extension - 1.4.2 + 1.4.4 test org.eclipse.jetty jetty-client - 9.4.54.v20240208 + 9.4.56.v20240826 test diff --git a/invoker/pom.xml b/invoker/pom.xml index f23ff693..c0432cf8 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -80,7 +80,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.7.0 + 3.10.0 attach-javadocs @@ -93,7 +93,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.2.4 + 3.2.7 sign-artifacts diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index 7160841b..c90f121f 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -31,7 +31,7 @@ com.google.guava guava - 33.2.1-jre + 33.3.1-jre com.google.code.gson @@ -86,7 +86,7 @@ org.apache.maven.plugins maven-deploy-plugin - 3.1.2 + 3.1.3 true From 34b763ef9bc68b962876fc47be4885354a0a5ca1 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Sat, 28 Sep 2024 01:14:22 +0200 Subject: [PATCH 144/239] chore(deps): update dependency io.cloudevents:cloudevents-api to v4 (#283) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [io.cloudevents:cloudevents-api](https://cloudevents.github.io/sdk-java/) ([source](https://redirect.github.com/cloudevents/sdk-java)) | `3.0.0` -> `4.0.1` | [![age](https://developer.mend.io/api/mc/badges/age/maven/io.cloudevents:cloudevents-api/4.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/io.cloudevents:cloudevents-api/4.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/io.cloudevents:cloudevents-api/3.0.0/4.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/io.cloudevents:cloudevents-api/3.0.0/4.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- > [!WARNING] > Some dependencies could not be looked up. Check the warning logs for more information. --- ### Release Notes

cloudevents/sdk-java (io.cloudevents:cloudevents-api) ### [`v4.0.1`](https://redirect.github.com/cloudevents/sdk-java/releases/tag/v4.0.1) [Compare Source](https://redirect.github.com/cloudevents/sdk-java/compare/v4.0.0...v4.0.1) #### What's Changed - \[4.0] Make CloudEventValidatorProvider thread safe ([#​650](https://redirect.github.com/cloudevents/sdk-java/issues/650)) by [@​pierDipi](https://redirect.github.com/pierDipi) in [https://togithub.com/cloudevents/sdk-java/pull/651](https://redirect.github.com/cloudevents/sdk-java/pull/651) **Full Changelog**: https://togithub.com/cloudevents/sdk-java/compare/v4.0.0...v4.0.1 ### [`v4.0.0`](https://redirect.github.com/cloudevents/sdk-java/releases/tag/v4.0.0) [Compare Source](https://redirect.github.com/cloudevents/sdk-java/compare/3.0.0...v4.0.0) #### What's Changed - Support CloudEvents SQL v1 (CE SQL) by [@​Cali0707](https://redirect.github.com/Cali0707) in [https://togithub.com/cloudevents/sdk-java/pull/641](https://redirect.github.com/cloudevents/sdk-java/pull/641) - doc: update & uniformize package version by [@​BoboTiG](https://redirect.github.com/BoboTiG) in [https://togithub.com/cloudevents/sdk-java/pull/640](https://redirect.github.com/cloudevents/sdk-java/pull/640) - fix: invalid automatic module name by [@​Jummartinezro](https://redirect.github.com/Jummartinezro) in [https://togithub.com/cloudevents/sdk-java/pull/639](https://redirect.github.com/cloudevents/sdk-java/pull/639) - Bump io.vertx:vertx-core from 4.3.7 to 4.5.3 in /http/vertx by [@​dependabot](https://redirect.github.com/dependabot) in [https://togithub.com/cloudevents/sdk-java/pull/622](https://redirect.github.com/cloudevents/sdk-java/pull/622) - Bump nokogiri from 1.16.3 to 1.16.5 in /docs by [@​dependabot](https://redirect.github.com/dependabot) in [https://togithub.com/cloudevents/sdk-java/pull/632](https://redirect.github.com/cloudevents/sdk-java/pull/632) - Bump org.xmlunit:xmlunit-core from 2.9.0 to 2.10.0 in /formats/xml by [@​dependabot](https://redirect.github.com/dependabot) in [https://togithub.com/cloudevents/sdk-java/pull/631](https://redirect.github.com/cloudevents/sdk-java/pull/631) #### New Contributors - [@​BoboTiG](https://redirect.github.com/BoboTiG) made their first contribution in [https://togithub.com/cloudevents/sdk-java/pull/640](https://redirect.github.com/cloudevents/sdk-java/pull/640) - [@​Jummartinezro](https://redirect.github.com/Jummartinezro) made their first contribution in [https://togithub.com/cloudevents/sdk-java/pull/639](https://redirect.github.com/cloudevents/sdk-java/pull/639) **Full Changelog**: https://togithub.com/cloudevents/sdk-java/compare/3.0.0...v4.0.0
--- ### Configuration 📅 **Schedule**: Branch creation - "before 4am on the first day of the month" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/GoogleCloudPlatform/functions-framework-java). --- functions-framework-api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index 603b7c72..3b87a18d 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -52,7 +52,7 @@ io.cloudevents cloudevents-api - 3.0.0 + 4.0.1 From f8c1d575660312101532a1f579c0492593248f37 Mon Sep 17 00:00:00 2001 From: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> Date: Fri, 27 Sep 2024 16:18:22 -0700 Subject: [PATCH 145/239] fix: use a version of maven-source-plugin that's available in mavencentral (#288) --- functions-framework-api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index 3b87a18d..31d5c735 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -151,7 +151,7 @@ org.apache.maven.plugins maven-source-plugin - 3.6.0 + 3.3.1 attach-sources From f82b70174513edf3e21752aa4739e3b6636e0604 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 27 Sep 2024 16:31:42 -0700 Subject: [PATCH 146/239] chore(main): release java-function-invoker 1.3.2 (#240) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> --- .github/.release-please-manifest.json | 2 +- invoker/CHANGELOG.md | 9 +++++++++ invoker/conformance/pom.xml | 4 ++-- invoker/core/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 6 files changed, 18 insertions(+), 9 deletions(-) diff --git a/.github/.release-please-manifest.json b/.github/.release-please-manifest.json index efcd0568..3c2d06fd 100644 --- a/.github/.release-please-manifest.json +++ b/.github/.release-please-manifest.json @@ -1 +1 @@ -{"functions-framework-api":"1.1.1","invoker":"1.3.1","function-maven-plugin":"0.11.0"} +{"functions-framework-api":"1.1.1","invoker":"1.3.2","function-maven-plugin":"0.11.0"} diff --git a/invoker/CHANGELOG.md b/invoker/CHANGELOG.md index 2800c114..c9661841 100644 --- a/invoker/CHANGELOG.md +++ b/invoker/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## [1.3.2](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/java-function-invoker-v1.3.1...java-function-invoker-v1.3.2) (2024-09-18) + + +### Bug Fixes + +* avoid executing function when /favicon.ico or /robots.txt is called ([#226](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/226)) ([fca8676](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/fca867667db593699193da01b69a4cca7ca48fc8)) +* server times out when specified by CLOUD_RUN_TIMEOUT_SECONDS ([#275](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/275)) ([9e91f57](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/9e91f57b12d73c655e3d7e226d21d54ccec32b73)) +* set Thread Context ClassLoader correctly when invoking handler constructor ([#239](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/239)) ([9f7155b](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/9f7155b77574ec980ecf9e6dffbd2ee0398db8a7)) + ## [1.3.1](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/java-function-invoker-v1.3.0...java-function-invoker-v1.3.1) (2023-09-13) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index d94dbf8a..d4f41397 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.3.2-SNAPSHOT + 1.3.2 com.google.cloud.functions.invoker conformance - 1.3.2-SNAPSHOT + 1.3.2 GCF Confromance Tests diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 4202e33c..b2de93e5 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.2-SNAPSHOT + 1.3.2 com.google.cloud.functions.invoker java-function-invoker - 1.3.2-SNAPSHOT + 1.3.2 GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -115,7 +115,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.3.2-SNAPSHOT + 1.3.2 test-jar test diff --git a/invoker/pom.xml b/invoker/pom.xml index c0432cf8..6b61101a 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -8,7 +8,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.2-SNAPSHOT + 1.3.2 pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index c90f121f..152d8f94 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.2-SNAPSHOT + 1.3.2 com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.3.2-SNAPSHOT + 1.3.2 Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From ec709f645c92a48a4db887b3b3ccd6d1354c7b4b Mon Sep 17 00:00:00 2001 From: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> Date: Fri, 27 Sep 2024 16:47:44 -0700 Subject: [PATCH 147/239] fix: update readme with newer versions (and release 1.1.2) (#289) --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e4c543a4..4b4da494 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ that supports Maven to create the Maven project. Add this dependency in the com.google.cloud.functions functions-framework-api - 1.0.4 + 1.1.2 provided ``` @@ -51,7 +51,7 @@ Framework dependency in your `build.gradle` project file as follows: ```groovy dependencies { - implementation 'com.google.cloud.functions:functions-framework-api:1.0.4' + implementation 'com.google.cloud.functions:functions-framework-api:1.1.2' } ``` @@ -188,7 +188,7 @@ Copy the Functions Framework jar to a local location like this: ```sh mvn dependency:copy \ - -Dartifact='com.google.cloud.functions.invoker:java-function-invoker:1.1.1' \ + -Dartifact='com.google.cloud.functions.invoker:java-function-invoker:1.3.2' \ -DoutputDirectory=. ``` @@ -196,7 +196,7 @@ In this example we use the current directory `.` but you can specify any other directory to copy to. Then run your function: ```sh -java -jar java-function-invoker-1.1.1 \ +java -jar java-function-invoker-1.3.2 \ --classpath myfunction.jar \ --target com.example.HelloWorld ``` @@ -215,8 +215,8 @@ configurations { } dependencies { - implementation 'com.google.cloud.functions:functions-framework-api:1.0.4' - invoker 'com.google.cloud.functions.invoker:java-function-invoker:1.1.1' + implementation 'com.google.cloud.functions:functions-framework-api:1.1.2' + invoker 'com.google.cloud.functions.invoker:java-function-invoker:1.3.2' } tasks.register("runFunction", JavaExec) { @@ -289,7 +289,7 @@ Framework directly, you must use `--classpath` to indicate how to find the code and its dependencies. For example: ``` -java -jar java-function-invoker-1.1.1 \ +java -jar java-function-invoker-1.3.2 \ --classpath 'myfunction.jar:/some/directory:/some/library/*' \ --target com.example.HelloWorld ``` From 478e5834d93d595f5650bf46909ad86945d20578 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 27 Sep 2024 17:02:26 -0700 Subject: [PATCH 148/239] chore(main): release functions-framework-api 1.1.2 (#290) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- .github/.release-please-manifest.json | 2 +- functions-framework-api/CHANGELOG.md | 7 +++++++ functions-framework-api/pom.xml | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/.release-please-manifest.json b/.github/.release-please-manifest.json index 3c2d06fd..85061204 100644 --- a/.github/.release-please-manifest.json +++ b/.github/.release-please-manifest.json @@ -1 +1 @@ -{"functions-framework-api":"1.1.1","invoker":"1.3.2","function-maven-plugin":"0.11.0"} +{"functions-framework-api":"1.1.2","invoker":"1.3.2","function-maven-plugin":"0.11.0"} diff --git a/functions-framework-api/CHANGELOG.md b/functions-framework-api/CHANGELOG.md index e999fd1d..7b57f5b6 100644 --- a/functions-framework-api/CHANGELOG.md +++ b/functions-framework-api/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.1.2](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/functions-framework-api-v1.1.1...functions-framework-api-v1.1.2) (2024-09-27) + + +### Bug Fixes + +* use a version of maven-source-plugin that's available in mavencentral ([#288](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/288)) ([f8c1d57](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/f8c1d575660312101532a1f579c0492593248f37)) + ## [1.1.1](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/functions-framework-api-v1.1.0...functions-framework-api-v1.1.1) (2024-06-27) diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index 31d5c735..bd040f3f 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -24,7 +24,7 @@ com.google.cloud.functions functions-framework-api - 1.1.2-SNAPSHOT + 1.1.2 UTF-8 From b199dcb587c390ef00ff40be60d4d2f45a88c222 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 27 Sep 2024 17:03:23 -0700 Subject: [PATCH 149/239] chore(main): release java-function-invoker 1.3.3-SNAPSHOT (#291) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- invoker/conformance/pom.xml | 4 ++-- invoker/core/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index d4f41397..f2ffd4ec 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.3.2 + 1.3.3-SNAPSHOT com.google.cloud.functions.invoker conformance - 1.3.2 + 1.3.3-SNAPSHOT GCF Confromance Tests diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index b2de93e5..ab455d4a 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.2 + 1.3.3-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker - 1.3.2 + 1.3.3-SNAPSHOT GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -115,7 +115,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.3.2 + 1.3.3-SNAPSHOT test-jar test diff --git a/invoker/pom.xml b/invoker/pom.xml index 6b61101a..ff2966e1 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -8,7 +8,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.2 + 1.3.3-SNAPSHOT pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index 152d8f94..2713b478 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.2 + 1.3.3-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.3.2 + 1.3.3-SNAPSHOT Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From a39c77318cf59ab1c3b358d07e4e8697594664ec Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 27 Sep 2024 17:09:28 -0700 Subject: [PATCH 150/239] chore(main): release functions-framework-api 1.1.3-SNAPSHOT (#292) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- functions-framework-api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index bd040f3f..a4804766 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -24,7 +24,7 @@ com.google.cloud.functions functions-framework-api - 1.1.2 + 1.1.3-SNAPSHOT UTF-8 From a8a8cad4d9d0a5f7ed71349b2fc36945c3ea0a0a Mon Sep 17 00:00:00 2001 From: dixuswe <152918466+dixuswe@users.noreply.github.com> Date: Fri, 4 Oct 2024 13:20:27 -0700 Subject: [PATCH 151/239] fix: update Maven version on Kokoro cluster to fix release pipeline (#294) * update Maven version on Kokoro cluster to fix release pipeline * fix: update Maven version on Kokoro cluster to fix release pipeline --- .kokoro/release.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.kokoro/release.sh b/.kokoro/release.sh index 0a599f31..6bbb8455 100644 --- a/.kokoro/release.sh +++ b/.kokoro/release.sh @@ -3,6 +3,16 @@ # Stop execution when any command fails. set -e +# update the Maven version to 3.6.3 +pushd /usr/local +wget https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.tar.gz +tar -xvzf apache-maven-3.6.3-bin.tar.gz apache-maven-3.6.3 +rm -f /usr/local/apache-maven +ln -s /usr/local/apache-maven-3.6.3 /usr/local/apache-maven +rm apache-maven-3.6.3-bin.tar.gz +popd + + # Get secrets from keystore and set and environment variables. setup_environment_secrets() { export GPG_TTY=$(tty) From 346714a6162adc72fc0f2ae6a2337198742b2197 Mon Sep 17 00:00:00 2001 From: dixuswe <152918466+dixuswe@users.noreply.github.com> Date: Fri, 4 Oct 2024 15:25:02 -0700 Subject: [PATCH 152/239] fix: update maven-source-plugin version (#295) * update Maven version on Kokoro cluster to fix release pipeline * fix: update Maven version on Kokoro cluster to fix release pipeline * fix: update the dependecy version --- functions-framework-api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index a4804766..f6a0026c 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -151,7 +151,7 @@ org.apache.maven.plugins maven-source-plugin - 3.3.1 + 3.6.0 attach-sources From 8f1fd84ca4cc43b2e93b66fe160f78a868b55ffe Mon Sep 17 00:00:00 2001 From: dixuswe <152918466+dixuswe@users.noreply.github.com> Date: Fri, 4 Oct 2024 17:08:19 -0700 Subject: [PATCH 153/239] fix: revert maven-source-plugin to 3.2.1 (#297) * update Maven version on Kokoro cluster to fix release pipeline * fix: update Maven version on Kokoro cluster to fix release pipeline * fix: update the dependecy version * fix: revert maven-javadoc-plugin to 3.2.1 --- functions-framework-api/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index f6a0026c..b7f60a7c 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -73,7 +73,7 @@ org.apache.maven.plugins maven-source-plugin - 3.3.1 + 3.2.1 attach-sources @@ -151,7 +151,7 @@ org.apache.maven.plugins maven-source-plugin - 3.6.0 + 3.2.1 attach-sources From f909f73652c338493162a92371255f3f8267fa21 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 17:31:52 -0700 Subject: [PATCH 154/239] chore(main): release functions-framework-api 1.1.3 (#296) * chore(main): release functions-framework-api 1.1.3 * Update CHANGELOG.md --------- Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: dixuswe <152918466+dixuswe@users.noreply.github.com> --- .github/.release-please-manifest.json | 2 +- functions-framework-api/CHANGELOG.md | 7 +++++++ functions-framework-api/pom.xml | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/.release-please-manifest.json b/.github/.release-please-manifest.json index 85061204..e6849dfb 100644 --- a/.github/.release-please-manifest.json +++ b/.github/.release-please-manifest.json @@ -1 +1 @@ -{"functions-framework-api":"1.1.2","invoker":"1.3.2","function-maven-plugin":"0.11.0"} +{"functions-framework-api":"1.1.3","invoker":"1.3.2","function-maven-plugin":"0.11.0"} diff --git a/functions-framework-api/CHANGELOG.md b/functions-framework-api/CHANGELOG.md index 7b57f5b6..497626cf 100644 --- a/functions-framework-api/CHANGELOG.md +++ b/functions-framework-api/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.1.3](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/functions-framework-api-v1.1.2...functions-framework-api-v1.1.3) (2024-10-05) + + +### Bug Fixes + +* revert maven-source-plugin to 3.2.1 ([#297](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/297)) ([8f1fd84](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/8f1fd84ca4cc43b2e93b66fe160f78a868b55ffe)) + ## [1.1.2](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/functions-framework-api-v1.1.1...functions-framework-api-v1.1.2) (2024-09-27) diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index b7f60a7c..43b48830 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -24,7 +24,7 @@ com.google.cloud.functions functions-framework-api - 1.1.3-SNAPSHOT + 1.1.3 UTF-8 From 066c29e3030a6ff6efa50d2f288bba44e6366738 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 17:38:23 -0700 Subject: [PATCH 155/239] chore(main): release functions-framework-api 1.1.4-SNAPSHOT (#298) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- functions-framework-api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index 43b48830..dd25d18d 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -24,7 +24,7 @@ com.google.cloud.functions functions-framework-api - 1.1.3 + 1.1.4-SNAPSHOT UTF-8 From c622da956f44be5148cc2aec171a61e4b0f27f1e Mon Sep 17 00:00:00 2001 From: HKWinterhalter Date: Tue, 19 Nov 2024 15:03:50 -0800 Subject: [PATCH 156/239] fix: update builder image url to correct project repository (#299) * fix: update builder image url to correct project repository the gcr.io/gae-runtimes project is no longer supported, which is causing integration tests to fail in this repo. serverless-runtimes should be used instead. --- .github/workflows/buildpack-integration-test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/buildpack-integration-test.yml b/.github/workflows/buildpack-integration-test.yml index 2c320a6e..41182ce3 100644 --- a/.github/workflows/buildpack-integration-test.yml +++ b/.github/workflows/buildpack-integration-test.yml @@ -24,7 +24,7 @@ jobs: prerun: 'invoker/conformance/prerun.sh' builder-runtime: 'java11' builder-runtime-version: '11' - builder-url: gcr.io/gae-runtimes/buildpacks/google-gae-22/java/builder:latest + builder-url: gcr.io/serverless-runtimes/google-22-full/builder/java:latest java17-buildpack-test: uses: GoogleCloudPlatform/functions-framework-conformance/.github/workflows/buildpack-integration-test.yml@main with: @@ -35,4 +35,4 @@ jobs: prerun: 'invoker/conformance/prerun.sh' builder-runtime: 'java17' builder-runtime-version: '17' - builder-url: gcr.io/gae-runtimes/buildpacks/google-gae-22/java/builder:latest + builder-url: gcr.io/serverless-runtimes/google-22-full/builder/java:latest From ab539e82c6394c64f2dfd1e35e2870cc3dbcb67e Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Wed, 20 Nov 2024 00:13:36 +0100 Subject: [PATCH 157/239] chore(deps): update all non-major dependencies (#293) Co-authored-by: HKWinterhalter --- .github/workflows/codeql.yml | 8 ++++---- .github/workflows/conformance.yaml | 8 ++++---- .github/workflows/lint.yaml | 10 +++++----- .github/workflows/scorecard.yml | 6 +++--- .github/workflows/unit.yaml | 6 +++--- function-maven-plugin/pom.xml | 6 +++--- functions-framework-api/pom.xml | 6 +++--- invoker/core/pom.xml | 2 +- invoker/pom.xml | 2 +- 9 files changed, 27 insertions(+), 27 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 518a5853..ec4e95c0 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: disable-sudo: true egress-policy: block @@ -42,11 +42,11 @@ jobs: uploads.github.com:443 - name: Checkout repository - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@461ef6c76dfe95d5c364de2f431ddbd31a417628 # v3.26.9 + uses: github/codeql-action/init@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4 with: # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support languages: java @@ -66,6 +66,6 @@ jobs: (cd function-maven-plugin && mvn install) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@461ef6c76dfe95d5c364de2f431ddbd31a417628 # v3.26.9 + uses: github/codeql-action/analyze@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4 with: category: ${{ matrix.working-directory }} diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index 1745c330..2391a71f 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -18,7 +18,7 @@ jobs: ] steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: disable-sudo: true egress-policy: block @@ -30,16 +30,16 @@ jobs: repo.maven.apache.org:443 storage.googleapis.com:443 - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0 + uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0 with: java-version: ${{ matrix.java }} distribution: temurin - name: Setup Go - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 with: go-version: '1.21' diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 7b32858c..0ed43ead 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -13,16 +13,16 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: disable-sudo: true egress-policy: block allowed-endpoints: > github.com:443 repo.maven.apache.org:443 - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Set up JDK - uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0 + uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0 with: java-version: 11.x distribution: temurin @@ -38,11 +38,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 # v2 minimum required + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 # v2 minimum required - name: Run formatter id: formatter uses: axel-op/googlejavaformat-action@dbff853fb823671ec5781365233bf86543b13215 # v3 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index c90435f2..5d49971e 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: disable-sudo: true egress-policy: block @@ -45,7 +45,7 @@ jobs: *.github.com:443 - name: "Checkout code" - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false @@ -62,6 +62,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@461ef6c76dfe95d5c364de2f431ddbd31a417628 # v3.26.9 + uses: github/codeql-action/upload-sarif@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4 with: sarif_file: results.sarif diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index c970fd3e..1767bb9f 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -19,7 +19,7 @@ jobs: ] steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: disable-sudo: true egress-policy: block @@ -28,9 +28,9 @@ jobs: repo.maven.apache.org:443 api.adoptium.net:443 *.githubusercontent.com:443 - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0 + uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0 with: java-version: ${{ matrix.java }} distribution: temurin diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml index bab9524c..c78f0265 100644 --- a/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -51,7 +51,7 @@ org.apache.maven.plugin-tools maven-plugin-annotations - 3.15.0 + 3.15.1 provided @@ -87,7 +87,7 @@ org.apache.maven.plugins maven-plugin-plugin - 3.15.0 + 3.15.1 help-goal @@ -132,7 +132,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.10.0 + 3.11.1 attach-javadocs diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index dd25d18d..2b937978 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -29,7 +29,7 @@ UTF-8 3.13.0 - 3.10.0 + 3.11.1 5.3.2 @@ -73,7 +73,7 @@ org.apache.maven.plugins maven-source-plugin - 3.2.1 + 3.3.1 attach-sources @@ -151,7 +151,7 @@ org.apache.maven.plugins maven-source-plugin - 3.2.1 + 3.3.1 attach-sources diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index ab455d4a..40837faa 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -122,7 +122,7 @@ org.mockito mockito-core - 5.14.0 + 5.14.2 test diff --git a/invoker/pom.xml b/invoker/pom.xml index ff2966e1..8d3182ae 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -80,7 +80,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.10.0 + 3.11.1 attach-javadocs From d93ccf318b096d093c7095442260b3bfec45f8e0 Mon Sep 17 00:00:00 2001 From: HKWinterhalter Date: Thu, 21 Nov 2024 15:45:59 -0800 Subject: [PATCH 158/239] fix: update lint to use JDK 17 so axel-op/googlejavaformat-action works (#301) * fix: update lint to use JDK 17 so axel-op/googlejavaformat-action works --- .github/workflows/lint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 0ed43ead..d1fb2a4b 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -24,7 +24,7 @@ jobs: - name: Set up JDK uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0 with: - java-version: 11.x + java-version: 17.x distribution: temurin - name: Build API with Maven run: (cd functions-framework-api/ && mvn install) From 09caeca002e74a92dbfce575b4bdd19da6bcab45 Mon Sep 17 00:00:00 2001 From: HKWinterhalter Date: Thu, 21 Nov 2024 16:15:48 -0800 Subject: [PATCH 159/239] =?UTF-8?q?fix:=20update=20lint=20formatting=20to?= =?UTF-8?q?=20use=20JDK=2017=20so=20axel-op/googlejavaformat=E2=80=A6=20(#?= =?UTF-8?q?302)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: update lint formatting to use JDK 17 so axel-op/googlejavaformat-action works --- .github/workflows/lint.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index d1fb2a4b..59372931 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -24,7 +24,7 @@ jobs: - name: Set up JDK uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0 with: - java-version: 17.x + java-version: 11.x distribution: temurin - name: Build API with Maven run: (cd functions-framework-api/ && mvn install) @@ -43,6 +43,11 @@ jobs: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 # v2 minimum required + - name: Set up JDK + uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0 + with: + java-version: 17.x + distribution: temurin - name: Run formatter id: formatter uses: axel-op/googlejavaformat-action@dbff853fb823671ec5781365233bf86543b13215 # v3 From bcce78ed4959e6ec965ee42bc7840a775529b2f0 Mon Sep 17 00:00:00 2001 From: dixuswe <152918466+dixuswe@users.noreply.github.com> Date: Thu, 21 Nov 2024 16:55:16 -0800 Subject: [PATCH 160/239] fix: update release pipeline to use maven token instead of user:password (#300) --- .kokoro/release.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.kokoro/release.sh b/.kokoro/release.sh index 6bbb8455..66ef1e6d 100644 --- a/.kokoro/release.sh +++ b/.kokoro/release.sh @@ -16,8 +16,8 @@ popd # Get secrets from keystore and set and environment variables. setup_environment_secrets() { export GPG_TTY=$(tty) - export SONATYPE_USERNAME=functions-framework-release-bot - export SONATYPE_PASSWORD=$(cat ${KOKORO_KEYSTORE_DIR}/75669_functions-framework-java-release-bot-sonatype-password) + export SONATYPE_USERNAME=$(cat ${KOKORO_KEYSTORE_DIR}/75669_functions-framework-java-release-bot-sonatype-password | cut -f1 -d':') + export SONATYPE_PASSWORD=$(cat ${KOKORO_KEYSTORE_DIR}/75669_functions-framework-java-release-bot-sonatype-password | cut -f2 -d':') export GPG_PASSPHRASE=$(cat ${KOKORO_KEYSTORE_DIR}/70247_maven-gpg-passphrase) # Add the key ring files to $GNUPGHOME to verify the GPG credentials. From 2db9a2bec6ba93e7954e68c2301c5fc2fcc032d8 Mon Sep 17 00:00:00 2001 From: dixuswe <152918466+dixuswe@users.noreply.github.com> Date: Fri, 22 Nov 2024 10:37:21 -0800 Subject: [PATCH 161/239] fix: revert maven-source-plugin to 3.2.1 (#303) * fix: update release pipeline to use maven token instead of user:password * fix:revert maven-source-plugin to 3.2.1 --- function-maven-plugin/pom.xml | 2 +- functions-framework-api/pom.xml | 2 +- invoker/pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml index c78f0265..a48f544c 100644 --- a/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -119,7 +119,7 @@ org.apache.maven.plugins maven-source-plugin - 3.3.1 + 3.2.1 attach-sources diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index 2b937978..51d6a67a 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -151,7 +151,7 @@ org.apache.maven.plugins maven-source-plugin - 3.3.1 + 3.2.1 attach-sources diff --git a/invoker/pom.xml b/invoker/pom.xml index 8d3182ae..28992926 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -67,7 +67,7 @@ org.apache.maven.plugins maven-source-plugin - 3.3.1 + 3.2.1 attach-sources @@ -119,4 +119,4 @@ - \ No newline at end of file + From 54180ada60ef776e1f720ff12cdf7a2978a8952e Mon Sep 17 00:00:00 2001 From: dixuswe <152918466+dixuswe@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:06:26 -0800 Subject: [PATCH 162/239] fix: print username for maven repo publish and revert maven-source-plugin to 3.2.1 (#307) * fix: update release pipeline to use maven token instead of user:password * fix:revert maven-source-plugin to 3.2.1 * fix: print username for maven repo publish and revert maven-source-plugin to 3.2.1 --- .kokoro/release.sh | 1 + functions-framework-api/pom.xml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.kokoro/release.sh b/.kokoro/release.sh index 66ef1e6d..929f8ed1 100644 --- a/.kokoro/release.sh +++ b/.kokoro/release.sh @@ -19,6 +19,7 @@ setup_environment_secrets() { export SONATYPE_USERNAME=$(cat ${KOKORO_KEYSTORE_DIR}/75669_functions-framework-java-release-bot-sonatype-password | cut -f1 -d':') export SONATYPE_PASSWORD=$(cat ${KOKORO_KEYSTORE_DIR}/75669_functions-framework-java-release-bot-sonatype-password | cut -f2 -d':') export GPG_PASSPHRASE=$(cat ${KOKORO_KEYSTORE_DIR}/70247_maven-gpg-passphrase) + echo $SONATYPE_USERNAME # Add the key ring files to $GNUPGHOME to verify the GPG credentials. export GNUPGHOME=/tmp/gpg diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index 51d6a67a..8e792243 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -73,7 +73,7 @@ org.apache.maven.plugins maven-source-plugin - 3.3.1 + 3.2.1 attach-sources From 6d2fc846d78de346bafacbaa38587ba8bfc81e7b Mon Sep 17 00:00:00 2001 From: dixuswe <152918466+dixuswe@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:35:31 -0800 Subject: [PATCH 163/239] fix: remove print maven repo username (#308) * fix: update release pipeline to use maven token instead of user:password * fix:revert maven-source-plugin to 3.2.1 * fix: print username for maven repo publish and revert maven-source-plugin to 3.2.1 * fix: remove print maven repo username --------- Co-authored-by: HKWinterhalter --- .kokoro/release.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/.kokoro/release.sh b/.kokoro/release.sh index 929f8ed1..66ef1e6d 100644 --- a/.kokoro/release.sh +++ b/.kokoro/release.sh @@ -19,7 +19,6 @@ setup_environment_secrets() { export SONATYPE_USERNAME=$(cat ${KOKORO_KEYSTORE_DIR}/75669_functions-framework-java-release-bot-sonatype-password | cut -f1 -d':') export SONATYPE_PASSWORD=$(cat ${KOKORO_KEYSTORE_DIR}/75669_functions-framework-java-release-bot-sonatype-password | cut -f2 -d':') export GPG_PASSPHRASE=$(cat ${KOKORO_KEYSTORE_DIR}/70247_maven-gpg-passphrase) - echo $SONATYPE_USERNAME # Add the key ring files to $GNUPGHOME to verify the GPG credentials. export GNUPGHOME=/tmp/gpg From 150676451da73a9c697af21a3c914a6a32914043 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 15:39:09 -0800 Subject: [PATCH 164/239] chore(main): release functions-framework-api 1.1.4 (#304) * chore(main): release functions-framework-api 1.1.4 * Update CHANGELOG.md --------- Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: dixuswe <152918466+dixuswe@users.noreply.github.com> --- .github/.release-please-manifest.json | 2 +- functions-framework-api/CHANGELOG.md | 7 +++++++ functions-framework-api/pom.xml | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/.release-please-manifest.json b/.github/.release-please-manifest.json index e6849dfb..6f51842e 100644 --- a/.github/.release-please-manifest.json +++ b/.github/.release-please-manifest.json @@ -1 +1 @@ -{"functions-framework-api":"1.1.3","invoker":"1.3.2","function-maven-plugin":"0.11.0"} +{"functions-framework-api":"1.1.4","invoker":"1.3.2","function-maven-plugin":"0.11.0"} diff --git a/functions-framework-api/CHANGELOG.md b/functions-framework-api/CHANGELOG.md index 497626cf..b97246fe 100644 --- a/functions-framework-api/CHANGELOG.md +++ b/functions-framework-api/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.1.4](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/functions-framework-api-v1.1.3...functions-framework-api-v1.1.4) (2024-11-22) + + +### Bug Fixes + +* revert maven-source-plugin to 3.2.1 ([#303](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/303)) ([2db9a2b](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/2db9a2bec6ba93e7954e68c2301c5fc2fcc032d8)) + ## [1.1.3](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/functions-framework-api-v1.1.2...functions-framework-api-v1.1.3) (2024-10-05) diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index 8e792243..7bc776c4 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -24,7 +24,7 @@ com.google.cloud.functions functions-framework-api - 1.1.4-SNAPSHOT + 1.1.4 UTF-8 From 32217a10fca464676c8dcc06f4453770debed8bc Mon Sep 17 00:00:00 2001 From: Tomo Suzuki Date: Wed, 27 Nov 2024 12:44:19 -0500 Subject: [PATCH 165/239] ci: release-trigger.yml to specify multiScmName (#311) This adjusts the release configuration to the recent infrastructure upgrade. --- .github/release-trigger.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/release-trigger.yml b/.github/release-trigger.yml index 7fe36225..a97dad2f 100644 --- a/.github/release-trigger.yml +++ b/.github/release-trigger.yml @@ -1 +1,2 @@ -enabled: true \ No newline at end of file +enabled: true +multiScmName: functions-framework-java From 3fc0251ca1c0c00282f1bfc36ae4db962f481565 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Wed, 27 Nov 2024 10:21:37 -0800 Subject: [PATCH 166/239] chore(main): release java-function-invoker 1.3.3 (#306) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- .github/.release-please-manifest.json | 2 +- invoker/CHANGELOG.md | 7 +++++++ invoker/conformance/pom.xml | 4 ++-- invoker/core/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 6 files changed, 16 insertions(+), 9 deletions(-) diff --git a/.github/.release-please-manifest.json b/.github/.release-please-manifest.json index 6f51842e..421fba65 100644 --- a/.github/.release-please-manifest.json +++ b/.github/.release-please-manifest.json @@ -1 +1 @@ -{"functions-framework-api":"1.1.4","invoker":"1.3.2","function-maven-plugin":"0.11.0"} +{"functions-framework-api":"1.1.4","invoker":"1.3.3","function-maven-plugin":"0.11.0"} diff --git a/invoker/CHANGELOG.md b/invoker/CHANGELOG.md index c9661841..2ac0970a 100644 --- a/invoker/CHANGELOG.md +++ b/invoker/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.3.3](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/java-function-invoker-v1.3.2...java-function-invoker-v1.3.3) (2024-11-27) + + +### Bug Fixes + +* revert maven-source-plugin to 3.2.1 ([#303](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/303)) ([2db9a2b](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/2db9a2bec6ba93e7954e68c2301c5fc2fcc032d8)) + ## [1.3.2](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/java-function-invoker-v1.3.1...java-function-invoker-v1.3.2) (2024-09-18) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index f2ffd4ec..c3c41d4a 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.3.3-SNAPSHOT + 1.3.3 com.google.cloud.functions.invoker conformance - 1.3.3-SNAPSHOT + 1.3.3 GCF Confromance Tests diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 40837faa..3e231706 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.3-SNAPSHOT + 1.3.3 com.google.cloud.functions.invoker java-function-invoker - 1.3.3-SNAPSHOT + 1.3.3 GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -115,7 +115,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.3.3-SNAPSHOT + 1.3.3 test-jar test diff --git a/invoker/pom.xml b/invoker/pom.xml index 28992926..80eebd42 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -8,7 +8,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.3-SNAPSHOT + 1.3.3 pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index 2713b478..17d99019 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.3-SNAPSHOT + 1.3.3 com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.3.3-SNAPSHOT + 1.3.3 Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From 7444fef44b860c416ad0e8f51773c58826a18bec Mon Sep 17 00:00:00 2001 From: HKWinterhalter Date: Wed, 27 Nov 2024 13:56:51 -0800 Subject: [PATCH 167/239] fix: prevent maven-source-plugin from being automatically upgraded (#309) --- .github/renovate.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/renovate.json b/.github/renovate.json index 7287767f..03752847 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -1,6 +1,7 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": ["group:allNonMajor", "schedule:monthly"], + "ignoreDeps": ["org.apache.maven.plugins:maven-source-plugin"] "packageRules": [ { "description": "Create a PR whenever there is a new major version", From f2e3740eaea5c1e1a61d18619adfee429ce949c8 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Wed, 27 Nov 2024 14:20:31 -0800 Subject: [PATCH 168/239] chore(main): release function-maven-plugin 0.11.1 (#305) * chore(main): release function-maven-plugin 0.11.1 * Remove SNAPSHOT from version in conformance pom.xml --------- Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: dixuswe <152918466+dixuswe@users.noreply.github.com> Co-authored-by: HKWinterhalter --- .github/.release-please-manifest.json | 2 +- function-maven-plugin/CHANGELOG.md | 7 +++++++ function-maven-plugin/pom.xml | 2 +- invoker/conformance/pom.xml | 4 ++-- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/.release-please-manifest.json b/.github/.release-please-manifest.json index 421fba65..ee718aed 100644 --- a/.github/.release-please-manifest.json +++ b/.github/.release-please-manifest.json @@ -1 +1 @@ -{"functions-framework-api":"1.1.4","invoker":"1.3.3","function-maven-plugin":"0.11.0"} +{"functions-framework-api":"1.1.4","invoker":"1.3.3","function-maven-plugin":"0.11.1"} diff --git a/function-maven-plugin/CHANGELOG.md b/function-maven-plugin/CHANGELOG.md index fc0c67b1..f1fbe49a 100644 --- a/function-maven-plugin/CHANGELOG.md +++ b/function-maven-plugin/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [0.11.1](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/function-maven-plugin-v0.11.0...function-maven-plugin-v0.11.1) (2024-11-27) + + +### Bug Fixes + +* revert maven-source-plugin to 3.2.1 ([#303](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/303)) ([2db9a2b](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/2db9a2bec6ba93e7954e68c2301c5fc2fcc032d8)) + ## [0.11.0](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/function-maven-plugin-v0.10.1...function-maven-plugin-v0.11.0) (2023-05-31) diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml index a48f544c..aee89999 100644 --- a/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -10,7 +10,7 @@ com.google.cloud.functions function-maven-plugin maven-plugin - 0.11.1-SNAPSHOT + 0.11.1 Functions Framework Plugin A Maven plugin that allows functions to be deployed, and to be run locally using the Java Functions Framework. diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index c3c41d4a..9efbc40a 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -53,9 +53,9 @@ com.google.cloud.functions function-maven-plugin - 0.11.1-SNAPSHOT + 0.11.1 - \ No newline at end of file + From d31b502fc019777a308ad694987c54fd6f6eb0a1 Mon Sep 17 00:00:00 2001 From: HKWinterhalter Date: Mon, 2 Dec 2024 08:54:47 -0800 Subject: [PATCH 169/239] Fix: Update release-please-config to properly version bump functions-maven-plugin for invoker/conformance/pom.xml (#315) * Update release-please-config.json * fix: Update release-please-config to properly version bump functions-maven-plugin for invoker/conformance/pom.xml --- .github/release-please-config.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/release-please-config.json b/.github/release-please-config.json index afc739a2..05f7dc1c 100644 --- a/.github/release-please-config.json +++ b/.github/release-please-config.json @@ -46,6 +46,11 @@ "path": "conformance/pom.xml", "xpath": "//*[local-name()='artifactId' and text()='conformance']/parent::*/*[local-name()='version']" }, + { + "type": "xml", + "path": "conformance/pom.xml", + "xpath": "//*[local-name()='artifactId' and text()='function-maven-plugin']/parent::*/*[local-name()='version']" + }, { "type": "xml", "path": "testfunction/pom.xml", @@ -70,4 +75,4 @@ ] } } -} \ No newline at end of file +} From eaa846b66cffa5e29245090bf45912fdd42cad4a Mon Sep 17 00:00:00 2001 From: James Ma Date: Tue, 3 Dec 2024 09:15:37 -0800 Subject: [PATCH 170/239] Update README.md (#316) --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4b4da494..850b806c 100644 --- a/README.md +++ b/README.md @@ -10,14 +10,13 @@ ![Security Scorecard](https://api.securityscorecards.dev/projects/github.com/GoogleCloudPlatform/functions-framework-java/badge) An open source FaaS (Function as a service) framework for writing portable -Java functions -- brought to you by the Google Cloud Functions team. +Java functions. The Functions Framework lets you write lightweight functions that run in many different environments, including: -* [Google Cloud Functions](https://cloud.google.com/functions/) +* [Google Cloud Run functions](https://cloud.google.com/functions/) * Your local development machine -* [Cloud Run](https://cloud.google.com/run/) and [Cloud Run for Anthos](https://cloud.google.com/anthos/run/) * [Knative](https://github.com/knative/)-based environments ## Installation From bb3d014eef2abef765740029bc31ab2c93c3a86f Mon Sep 17 00:00:00 2001 From: dixuswe <152918466+dixuswe@users.noreply.github.com> Date: Wed, 4 Dec 2024 17:29:49 -0800 Subject: [PATCH 171/239] fix: renovate.json format (#317) --- .github/renovate.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/renovate.json b/.github/renovate.json index 03752847..2e79135d 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -1,7 +1,7 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": ["group:allNonMajor", "schedule:monthly"], - "ignoreDeps": ["org.apache.maven.plugins:maven-source-plugin"] + "ignoreDeps": ["org.apache.maven.plugins:maven-source-plugin"], "packageRules": [ { "description": "Create a PR whenever there is a new major version", From 36a156688de9a272c4467a65c82460b8bd621eca Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:59:45 -0800 Subject: [PATCH 172/239] chore(main): release functions-framework-api 1.1.5-SNAPSHOT (#310) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- functions-framework-api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index 7bc776c4..7fbdce19 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -24,7 +24,7 @@ com.google.cloud.functions functions-framework-api - 1.1.4 + 1.1.5-SNAPSHOT UTF-8 From d6fc4a4155c5c56426334e1112f902edbc39d88f Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Wed, 12 Feb 2025 14:16:33 -0800 Subject: [PATCH 173/239] chore(main): release java-function-invoker 1.3.4-SNAPSHOT (#312) * chore(main): release java-function-invoker 1.3.4-SNAPSHOT * Update pom.xml We should not bump the version for maven plugin --------- Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: Maeve <167252720+maemayve@users.noreply.github.com> --- invoker/conformance/pom.xml | 4 ++-- invoker/core/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 9efbc40a..2f2b8aae 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.3.3 + 1.3.4-SNAPSHOT com.google.cloud.functions.invoker conformance - 1.3.3 + 1.3.4-SNAPSHOT GCF Confromance Tests diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 3e231706..a63cff27 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.3 + 1.3.4-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker - 1.3.3 + 1.3.4-SNAPSHOT GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -115,7 +115,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.3.3 + 1.3.4-SNAPSHOT test-jar test diff --git a/invoker/pom.xml b/invoker/pom.xml index 80eebd42..705aab2d 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -8,7 +8,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.3 + 1.3.4-SNAPSHOT pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index 17d99019..27e6e595 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.3 + 1.3.4-SNAPSHOT com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.3.3 + 1.3.4-SNAPSHOT Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From 5ef53174b6cdbc644336121bc19bab6c4b90892d Mon Sep 17 00:00:00 2001 From: Maeve <167252720+maemayve@users.noreply.github.com> Date: Wed, 12 Feb 2025 14:26:11 -0800 Subject: [PATCH 174/239] feat: Add execution id logging to uniquely identify request logs (#319) Adds an execution id for each http. When the LOG_EXECUTION_ID env var is set, the execution id is added as a new field to the json logs. --- .gitignore | 1 + .../invoker/BackgroundFunctionExecutor.java | 14 ++++- .../invoker/HttpFunctionExecutor.java | 4 ++ .../invoker/gcf/ExecutionIdUtil.java | 63 +++++++++++++++++++ .../functions/invoker/gcf/JsonLogHandler.java | 25 ++++++++ .../functions/invoker/IntegrationTest.java | 49 +++++++++++++-- 6 files changed, 150 insertions(+), 6 deletions(-) create mode 100644 invoker/core/src/main/java/com/google/cloud/functions/invoker/gcf/ExecutionIdUtil.java diff --git a/.gitignore b/.gitignore index cb8a3b7e..4cd4e4f0 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ # Maven target/ +dependency-reduced-pom.xml # Gradle .gradle diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java index 98b9bc8a..a35f2225 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java @@ -21,6 +21,7 @@ import com.google.cloud.functions.CloudEventsFunction; import com.google.cloud.functions.Context; import com.google.cloud.functions.RawBackgroundFunction; +import com.google.cloud.functions.invoker.gcf.ExecutionIdUtil; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.TypeAdapter; @@ -51,6 +52,7 @@ public final class BackgroundFunctionExecutor extends HttpServlet { private static final Logger logger = Logger.getLogger("com.google.cloud.functions.invoker"); private final FunctionExecutor functionExecutor; + private final ExecutionIdUtil executionIdUtil = new ExecutionIdUtil(); private BackgroundFunctionExecutor(FunctionExecutor functionExecutor) { this.functionExecutor = functionExecutor; @@ -323,6 +325,7 @@ void serviceCloudEvent(CloudEvent cloudEvent) throws Exception { public void service(HttpServletRequest req, HttpServletResponse res) throws IOException { String contentType = req.getContentType(); try { + executionIdUtil.storeExecutionId(req); if ((contentType != null && contentType.startsWith("application/cloudevents+json")) || req.getHeader("ce-specversion") != null) { serviceCloudEvent(req); @@ -333,6 +336,8 @@ public void service(HttpServletRequest req, HttpServletResponse res) throws IOEx } catch (Throwable t) { res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); logger.log(Level.SEVERE, "Failed to execute " + functionExecutor.functionName(), t); + } finally { + executionIdUtil.removeExecutionId(); } } @@ -359,7 +364,14 @@ private void serviceCloudEvent(HttpServletRequest req) throws Exce // ServiceLoader.load // will throw ServiceConfigurationError. At this point we're still running with the default // context ClassLoader, which is the system ClassLoader that has loaded the code here. - runWithContextClassLoader(() -> executor.serviceCloudEvent(reader.toEvent(data -> data))); + try { + executionIdUtil.storeExecutionId(req); + runWithContextClassLoader(() -> executor.serviceCloudEvent(reader.toEvent(data -> data))); + } catch (Throwable t) { + logger.log(Level.SEVERE, "Failed to execute " + executor.functionName(), t); + } finally { + executionIdUtil.removeExecutionId(); + } // The data->data is a workaround for a bug fixed since Milestone 4 of the SDK, in // https://github.com/cloudevents/sdk-java/pull/259. } diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java index 401e22a2..01f07e74 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/HttpFunctionExecutor.java @@ -15,6 +15,7 @@ package com.google.cloud.functions.invoker; import com.google.cloud.functions.HttpFunction; +import com.google.cloud.functions.invoker.gcf.ExecutionIdUtil; import com.google.cloud.functions.invoker.http.HttpRequestImpl; import com.google.cloud.functions.invoker.http.HttpResponseImpl; import java.util.logging.Level; @@ -28,6 +29,7 @@ public class HttpFunctionExecutor extends HttpServlet { private static final Logger logger = Logger.getLogger("com.google.cloud.functions.invoker"); private final HttpFunction function; + private final ExecutionIdUtil executionIdUtil = new ExecutionIdUtil(); private HttpFunctionExecutor(HttpFunction function) { this.function = function; @@ -68,6 +70,7 @@ public void service(HttpServletRequest req, HttpServletResponse res) { HttpResponseImpl respImpl = new HttpResponseImpl(res); ClassLoader oldContextLoader = Thread.currentThread().getContextClassLoader(); try { + executionIdUtil.storeExecutionId(req); Thread.currentThread().setContextClassLoader(function.getClass().getClassLoader()); function.service(reqImpl, respImpl); } catch (Throwable t) { @@ -75,6 +78,7 @@ public void service(HttpServletRequest req, HttpServletResponse res) { res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } finally { Thread.currentThread().setContextClassLoader(oldContextLoader); + executionIdUtil.removeExecutionId(); respImpl.flush(); } } diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/gcf/ExecutionIdUtil.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/gcf/ExecutionIdUtil.java new file mode 100644 index 00000000..7987317d --- /dev/null +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/gcf/ExecutionIdUtil.java @@ -0,0 +1,63 @@ +package com.google.cloud.functions.invoker.gcf; + +import java.util.Base64; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; +import java.util.logging.Handler; +import java.util.logging.Logger; +import javax.servlet.http.HttpServletRequest; + +/** + * A helper class that either fetches a unique execution id from request HTTP headers or generates a + * random id. + */ +public final class ExecutionIdUtil { + private static final Logger rootLogger = Logger.getLogger(""); + private static final int EXECUTION_ID_LENGTH = 12; + private static final String EXECUTION_ID_HTTP_HEADER = "HTTP_FUNCTION_EXECUTION_ID"; + private static final String LOG_EXECUTION_ID_ENV_NAME = "LOG_EXECUTION_ID"; + + private final Random random = ThreadLocalRandom.current(); + + /** + * Add mapping to root logger from current thread id to execution id. This mapping will be used to + * append the execution id to log lines. + */ + public void storeExecutionId(HttpServletRequest request) { + if (!executionIdLoggingEnabled()) { + return; + } + for (Handler handler : rootLogger.getHandlers()) { + if (handler instanceof JsonLogHandler) { + String id = getOrGenerateExecutionId(request); + ((JsonLogHandler) handler).addExecutionId(Thread.currentThread().getId(), id); + } + } + } + + /** Remove mapping from curent thread to request execution id */ + public void removeExecutionId() { + if (!executionIdLoggingEnabled()) { + return; + } + for (Handler handler : rootLogger.getHandlers()) { + if (handler instanceof JsonLogHandler) { + ((JsonLogHandler) handler).removeExecutionId(Thread.currentThread().getId()); + } + } + } + + private String getOrGenerateExecutionId(HttpServletRequest request) { + String executionId = request.getHeader(EXECUTION_ID_HTTP_HEADER); + if (executionId == null) { + byte[] array = new byte[EXECUTION_ID_LENGTH]; + random.nextBytes(array); + executionId = Base64.getEncoder().encodeToString(array); + } + return executionId; + } + + private boolean executionIdLoggingEnabled() { + return Boolean.parseBoolean(System.getenv().getOrDefault(LOG_EXECUTION_ID_ENV_NAME, "false")); + } +} diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/gcf/JsonLogHandler.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/gcf/JsonLogHandler.java index 9c94b92a..b21f78a1 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/gcf/JsonLogHandler.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/gcf/JsonLogHandler.java @@ -5,6 +5,8 @@ import java.io.StringWriter; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogRecord; @@ -24,6 +26,14 @@ public final class JsonLogHandler extends Handler { private final PrintStream out; private final boolean closePrintStreamOnClose; + // This map is used to track execution id for currently running Jetty requests. Mapping thread + // id to request works because of an implementation detail of Jetty thread pool handling. + // Jetty worker threads completely handle a request before beginning work on a new request. + // NOTE: Store thread id as a string to avoid comparison failures between int and long. + // + // Jetty Documentation (https://jetty.org/docs/jetty/10/programming-guide/arch/threads.html) + private static final ConcurrentMap executionIdByThreadMap = + new ConcurrentHashMap<>(); public JsonLogHandler(PrintStream out, boolean closePrintStreamOnClose) { this.out = out; @@ -38,6 +48,7 @@ public void publish(LogRecord record) { StringBuilder json = new StringBuilder("{"); appendSeverity(json, record); appendSourceLocation(json, record); + appendExecutionId(json, record); appendMessage(json, record); // must be last, see appendMessage json.append("}"); // We must output the log all at once (should only call println once per call to publish) @@ -96,6 +107,12 @@ private static void appendSourceLocation(StringBuilder json, LogRecord record) { json.append(SOURCE_LOCATION_KEY).append("{").append(String.join(", ", entries)).append("}, "); } + private void appendExecutionId(StringBuilder json, LogRecord record) { + json.append("\"execution_id\": \"") + .append(executionIdByThreadMap.get(Integer.toString(record.getThreadID()))) + .append("\", "); + } + private static String escapeString(String s) { return s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n").replace("\r", "\\r"); } @@ -117,4 +134,12 @@ public void close() throws SecurityException { out.close(); } } + + public void addExecutionId(long threadId, String executionId) { + executionIdByThreadMap.put(Long.toString(threadId), executionId); + } + + public void removeExecutionId(long threadId) { + executionIdByThreadMap.remove(Long.toString(threadId)); + } } diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java index 82197547..37d35ebd 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java @@ -28,6 +28,8 @@ import com.google.common.truth.Expect; import com.google.gson.Gson; import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.stream.JsonReader; import io.cloudevents.CloudEvent; import io.cloudevents.core.builder.CloudEventBuilder; import io.cloudevents.core.format.EventFormat; @@ -39,6 +41,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.StringReader; import java.io.UncheckedIOException; import java.net.ServerSocket; import java.net.URI; @@ -89,6 +92,8 @@ public class IntegrationTest { @Rule public final TestName testName = new TestName(); private static final String SERVER_READY_STRING = "Started ServerConnector"; + private static final String EXECUTION_ID_HTTP_HEADER = "HTTP_FUNCTION_EXECUTION_ID"; + private static final String EXECUTION_ID = "1234abcd"; private static final ExecutorService EXECUTOR = Executors.newCachedThreadPool(); @@ -286,7 +291,10 @@ public void exceptionHttp() throws Exception { String exceptionExpectedOutput = "\"severity\": \"ERROR\", \"logging.googleapis.com/sourceLocation\": {\"file\":" + " \"com/google/cloud/functions/invoker/HttpFunctionExecutor.java\", \"method\":" - + " \"service\"}, \"message\": \"Failed to execute" + + " \"service\"}, \"execution_id\": \"" + + EXECUTION_ID + + "\"," + + " \"message\": \"Failed to execute" + " com.google.cloud.functions.invoker.testfunctions.ExceptionHttp\\n" + "java.lang.RuntimeException: exception thrown for test"; testHttpFunction( @@ -294,6 +302,7 @@ public void exceptionHttp() throws Exception { ImmutableList.of( TestCase.builder() .setExpectedResponseCode(500) + .setHttpHeaders(ImmutableMap.of(EXECUTION_ID_HTTP_HEADER, EXECUTION_ID)) .setExpectedOutput(exceptionExpectedOutput) .build())); } @@ -303,7 +312,10 @@ public void exceptionBackground() throws Exception { String exceptionExpectedOutput = "\"severity\": \"ERROR\", \"logging.googleapis.com/sourceLocation\": {\"file\":" + " \"com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java\", \"method\":" - + " \"service\"}, \"message\": \"Failed to execute" + + " \"service\"}, \"execution_id\": \"" + + EXECUTION_ID + + "\", " + + "\"message\": \"Failed to execute" + " com.google.cloud.functions.invoker.testfunctions.ExceptionBackground\\n" + "java.lang.RuntimeException: exception thrown for test"; @@ -317,6 +329,7 @@ public void exceptionBackground() throws Exception { ImmutableList.of( TestCase.builder() .setRequestText(gcfRequestText) + .setHttpHeaders(ImmutableMap.of(EXECUTION_ID_HTTP_HEADER, EXECUTION_ID)) .setExpectedResponseCode(500) .setExpectedOutput(exceptionExpectedOutput) .build()), @@ -359,13 +372,21 @@ public void stackDriverLogging() throws Exception { + "\"logging.googleapis.com/sourceLocation\": " + "{\"file\": \"com/google/cloud/functions/invoker/testfunctions/Log.java\"," + " \"method\": \"service\"}," + + " \"execution_id\": \"" + + EXECUTION_ID + + "\"," + " \"message\": \"blim\"}"; TestCase simpleTestCase = - TestCase.builder().setUrl("/?message=blim").setExpectedOutput(simpleExpectedOutput).build(); + TestCase.builder() + .setUrl("/?message=blim") + .setHttpHeaders(ImmutableMap.of(EXECUTION_ID_HTTP_HEADER, EXECUTION_ID)) + .setExpectedOutput(simpleExpectedOutput) + .build(); String quotingExpectedOutput = "\"message\": \"foo\\nbar\\\""; TestCase quotingTestCase = TestCase.builder() .setUrl("/?message=" + URLEncoder.encode("foo\nbar\"", "UTF-8")) + .setHttpHeaders(ImmutableMap.of(EXECUTION_ID_HTTP_HEADER, EXECUTION_ID)) .setExpectedOutput(quotingExpectedOutput) .build(); String exceptionExpectedOutput = @@ -373,11 +394,15 @@ public void stackDriverLogging() throws Exception { + "\"logging.googleapis.com/sourceLocation\": " + "{\"file\": \"com/google/cloud/functions/invoker/testfunctions/Log.java\", " + "\"method\": \"service\"}, " + + "\"execution_id\": \"" + + EXECUTION_ID + + "\", " + "\"message\": \"oops\\njava.lang.Exception: disaster\\n" + " at com.google.cloud.functions.invoker.testfunctions.Log.service(Log.java:"; TestCase exceptionTestCase = TestCase.builder() .setUrl("/?message=oops&level=severe&exception=disaster") + .setHttpHeaders(ImmutableMap.of(EXECUTION_ID_HTTP_HEADER, EXECUTION_ID)) .setExpectedOutput(exceptionExpectedOutput) .build(); testHttpFunction( @@ -753,7 +778,11 @@ private void testFunction( for (TestCase testCase : testCases) { testCase .expectedOutput() - .ifPresent(output -> expect.that(serverProcess.output()).contains(output)); + .ifPresent( + (output) -> { + expect.that(serverProcess.output()).contains(output); + parseLogJson(serverProcess.output()); + }); } // Wait for the output monitor task to terminate. If it threw an exception, we will get an // ExecutionException here. @@ -842,7 +871,9 @@ private ServerProcess startServer( "FUNCTION_SIGNATURE_TYPE", signatureType.toString(), "FUNCTION_TARGET", - target); + target, + "LOG_EXECUTION_ID", + "true"); processBuilder.environment().putAll(environment); processBuilder.environment().putAll(environmentVariables); Process serverProcess = processBuilder.start(); @@ -879,4 +910,12 @@ private void monitorOutput( throw new UncheckedIOException(e); } } + + // Attempt to parse Json object, throws on parse failure + private void parseLogJson(String json) throws RuntimeException { + System.out.println("trying to parse the following object "); + System.out.println(json); + JsonReader reader = new JsonReader(new StringReader(json)); + JsonParser.parseReader(reader); + } } From d17cc6305b7232129dec48281cca51588ec9dedf Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Wed, 12 Feb 2025 15:15:56 -0800 Subject: [PATCH 175/239] chore(main): release java-function-invoker 1.4.0 (#320) * chore(main): release java-function-invoker 1.4.0 * Update pom.xml bot incorrectly bumped function-maven-plugin version --------- Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: Maeve <167252720+maemayve@users.noreply.github.com> --- .github/.release-please-manifest.json | 2 +- invoker/CHANGELOG.md | 7 +++++++ invoker/conformance/pom.xml | 4 ++-- invoker/core/pom.xml | 6 +++--- invoker/pom.xml | 2 +- invoker/testfunction/pom.xml | 4 ++-- 6 files changed, 16 insertions(+), 9 deletions(-) diff --git a/.github/.release-please-manifest.json b/.github/.release-please-manifest.json index ee718aed..d17a5bf0 100644 --- a/.github/.release-please-manifest.json +++ b/.github/.release-please-manifest.json @@ -1 +1 @@ -{"functions-framework-api":"1.1.4","invoker":"1.3.3","function-maven-plugin":"0.11.1"} +{"functions-framework-api":"1.1.4","invoker":"1.4.0","function-maven-plugin":"0.11.1"} diff --git a/invoker/CHANGELOG.md b/invoker/CHANGELOG.md index 2ac0970a..628267db 100644 --- a/invoker/CHANGELOG.md +++ b/invoker/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.4.0](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/java-function-invoker-v1.3.3...java-function-invoker-v1.4.0) (2025-02-12) + + +### Features + +* Add execution id logging to uniquely identify request logs ([#319](https://github.com/GoogleCloudPlatform/functions-framework-java/issues/319)) ([5ef5317](https://github.com/GoogleCloudPlatform/functions-framework-java/commit/5ef53174b6cdbc644336121bc19bab6c4b90892d)) + ## [1.3.3](https://github.com/GoogleCloudPlatform/functions-framework-java/compare/java-function-invoker-v1.3.2...java-function-invoker-v1.3.3) (2024-11-27) diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 2f2b8aae..929b9408 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -4,12 +4,12 @@ java-function-invoker-parent com.google.cloud.functions.invoker - 1.3.4-SNAPSHOT + 1.4.0 com.google.cloud.functions.invoker conformance - 1.3.4-SNAPSHOT + 1.4.0 GCF Confromance Tests diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index a63cff27..35ec377e 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.4-SNAPSHOT + 1.4.0 com.google.cloud.functions.invoker java-function-invoker - 1.3.4-SNAPSHOT + 1.4.0 GCF Java Invoker Application that invokes a GCF Java function. This application is a @@ -115,7 +115,7 @@ com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.3.4-SNAPSHOT + 1.4.0 test-jar test diff --git a/invoker/pom.xml b/invoker/pom.xml index 705aab2d..7c5c4484 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -8,7 +8,7 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.4-SNAPSHOT + 1.4.0 pom GCF Java Invoker Parent diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index 27e6e595..e8642676 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -4,12 +4,12 @@ com.google.cloud.functions.invoker java-function-invoker-parent - 1.3.4-SNAPSHOT + 1.4.0 com.google.cloud.functions.invoker java-function-invoker-testfunction - 1.3.4-SNAPSHOT + 1.4.0 Example GCF Function Jar An example of a GCF function packaged into a jar. We use this in tests. From e8a3dd2f4eca2d7f0980607795db4edc6b32d1a8 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Thu, 13 Feb 2025 10:02:26 -0800 Subject: [PATCH 176/239] chore(main): release function-maven-plugin 0.11.2-SNAPSHOT (#314) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- function-maven-plugin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml index aee89999..11d3baae 100644 --- a/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -10,7 +10,7 @@ com.google.cloud.functions function-maven-plugin maven-plugin - 0.11.1 + 0.11.2-SNAPSHOT Functions Framework Plugin A Maven plugin that allows functions to be deployed, and to be run locally using the Java Functions Framework. From 8c7f6d8b8a9587516b68499d6ee2715e6ca0aacd Mon Sep 17 00:00:00 2001 From: Maeve <167252720+maemayve@users.noreply.github.com> Date: Tue, 18 Feb 2025 09:18:28 -0800 Subject: [PATCH 177/239] fix: remove maven-plugin from release-please-config for invoker/conformance/pom.xml (#322) Previous change d31b502 incorrectly added an extra file to the invoker release which is causing automation breakages when the invoker release PRs are created. Move config to the right package. --- .github/release-please-config.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/release-please-config.json b/.github/release-please-config.json index 05f7dc1c..cfe9f42a 100644 --- a/.github/release-please-config.json +++ b/.github/release-please-config.json @@ -46,11 +46,6 @@ "path": "conformance/pom.xml", "xpath": "//*[local-name()='artifactId' and text()='conformance']/parent::*/*[local-name()='version']" }, - { - "type": "xml", - "path": "conformance/pom.xml", - "xpath": "//*[local-name()='artifactId' and text()='function-maven-plugin']/parent::*/*[local-name()='version']" - }, { "type": "xml", "path": "testfunction/pom.xml", From d6f71867195bc674e7814f05132c33a02916148e Mon Sep 17 00:00:00 2001 From: Maeve <167252720+maemayve@users.noreply.github.com> Date: Wed, 19 Feb 2025 16:19:21 -0800 Subject: [PATCH 178/239] chore: Update blunderbuss.yml (#323) Add mayv to issue and pr handling --- .github/blunderbuss.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/blunderbuss.yml b/.github/blunderbuss.yml index 2dfa51ed..dcd61b31 100644 --- a/.github/blunderbuss.yml +++ b/.github/blunderbuss.yml @@ -2,9 +2,11 @@ assign_prs: - HKwinterhalter - dixuswe - janell-chen + - mayv assign_issues: - HKwinterhalter - dixuswe - janell-chen + - mayv From 9899a67a9a8cb6ebb27a92cccb740e7e23d48578 Mon Sep 17 00:00:00 2001 From: Maeve <167252720+maemayve@users.noreply.github.com> Date: Thu, 6 Mar 2025 16:45:04 -0800 Subject: [PATCH 179/239] fix: correct Cloud Event retry functionality (#326) * fix: Correct exception handling for CloudEvents A previous change resulted broke exception handling for cloud events so that an exception from the function would not result in a failure response code. Correct error handling for CloudEvents and add a test to cover this case to avoid future breakages. * fix: Do not add execution_id field if logging is disabled Fix logger to not add field if logging is disabled. --- .../invoker/BackgroundFunctionExecutor.java | 9 +---- .../functions/invoker/gcf/JsonLogHandler.java | 13 +++++-- .../functions/invoker/IntegrationTest.java | 37 +++++++++++++++++++ 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java index a35f2225..331c9586 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java @@ -364,14 +364,7 @@ private void serviceCloudEvent(HttpServletRequest req) throws Exce // ServiceLoader.load // will throw ServiceConfigurationError. At this point we're still running with the default // context ClassLoader, which is the system ClassLoader that has loaded the code here. - try { - executionIdUtil.storeExecutionId(req); - runWithContextClassLoader(() -> executor.serviceCloudEvent(reader.toEvent(data -> data))); - } catch (Throwable t) { - logger.log(Level.SEVERE, "Failed to execute " + executor.functionName(), t); - } finally { - executionIdUtil.removeExecutionId(); - } + runWithContextClassLoader(() -> executor.serviceCloudEvent(reader.toEvent(data -> data))); // The data->data is a workaround for a bug fixed since Milestone 4 of the SDK, in // https://github.com/cloudevents/sdk-java/pull/259. } diff --git a/invoker/core/src/main/java/com/google/cloud/functions/invoker/gcf/JsonLogHandler.java b/invoker/core/src/main/java/com/google/cloud/functions/invoker/gcf/JsonLogHandler.java index b21f78a1..51aad21a 100644 --- a/invoker/core/src/main/java/com/google/cloud/functions/invoker/gcf/JsonLogHandler.java +++ b/invoker/core/src/main/java/com/google/cloud/functions/invoker/gcf/JsonLogHandler.java @@ -17,6 +17,7 @@ */ public final class JsonLogHandler extends Handler { private static final String SOURCE_LOCATION_KEY = "\"logging.googleapis.com/sourceLocation\": "; + private static final String LOG_EXECUTION_ID_ENV_NAME = "LOG_EXECUTION_ID"; private static final String DEBUG = "DEBUG"; private static final String INFO = "INFO"; @@ -108,9 +109,11 @@ private static void appendSourceLocation(StringBuilder json, LogRecord record) { } private void appendExecutionId(StringBuilder json, LogRecord record) { - json.append("\"execution_id\": \"") - .append(executionIdByThreadMap.get(Integer.toString(record.getThreadID()))) - .append("\", "); + if (executionIdLoggingEnabled()) { + json.append("\"execution_id\": \"") + .append(executionIdByThreadMap.get(Integer.toString(record.getThreadID()))) + .append("\", "); + } } private static String escapeString(String s) { @@ -142,4 +145,8 @@ public void addExecutionId(long threadId, String executionId) { public void removeExecutionId(long threadId) { executionIdByThreadMap.remove(Long.toString(threadId)); } + + private boolean executionIdLoggingEnabled() { + return Boolean.parseBoolean(System.getenv().getOrDefault(LOG_EXECUTION_ID_ENV_NAME, "false")); + } } diff --git a/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java b/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java index 37d35ebd..2f1d8bc8 100644 --- a/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java +++ b/invoker/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java @@ -577,6 +577,43 @@ public void nativeCloudEvent() throws Exception { ImmutableList.of(cloudEventsStructuredTestCase, cloudEventsBinaryTestCase)); } + /** Tests a CloudEvent being handled by a CloudEvent handler throws exception */ + @Test + public void nativeCloudEventException() throws Exception { + String exceptionExpectedOutput = + "\"severity\": \"ERROR\", \"logging.googleapis.com/sourceLocation\": {\"file\":" + + " \"com/google/cloud/functions/invoker/BackgroundFunctionExecutor.java\", \"method\":" + + " \"service\"}, \"execution_id\": \"" + + EXECUTION_ID + + "\", " + + "\"message\": \"Failed to execute" + + " com.google.cloud.functions.invoker.testfunctions.ExceptionBackground\\n" + + "java.lang.RuntimeException: exception thrown for test"; + File snoopFile = snoopFile(); + CloudEvent cloudEvent = sampleCloudEvent(snoopFile); + EventFormat jsonFormat = + EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE); + String cloudEventJson = new String(jsonFormat.serialize(cloudEvent), UTF_8); + + // A CloudEvent using the "structured content mode", where both the metadata and the payload + // are in the body of the HTTP request. + TestCase cloudEventsStructuredTestCase = + TestCase.builder() + .setRequestText(cloudEventJson) + .setHttpContentType("application/cloudevents+json; charset=utf-8") + .setHttpHeaders(ImmutableMap.of(EXECUTION_ID_HTTP_HEADER, EXECUTION_ID)) + .setExpectedResponseCode(500) + .setExpectedOutput(exceptionExpectedOutput) + .build(); + + testFunction( + SignatureType.CLOUD_EVENT, + fullTarget("ExceptionBackground"), + ImmutableList.of(), + ImmutableList.of(cloudEventsStructuredTestCase), + Collections.emptyMap()); + } + @Test public void nested() throws Exception { String testText = "sic transit gloria mundi"; From 185d15f77c4a165ec01950ae11960024b0f27151 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 7 Mar 2025 18:00:24 +0100 Subject: [PATCH 180/239] chore(deps): update all non-major dependencies (#318) Co-authored-by: Maeve <167252720+maemayve@users.noreply.github.com> --- .github/workflows/codeql.yml | 6 +++--- .github/workflows/conformance.yaml | 6 +++--- .github/workflows/lint.yaml | 8 ++++---- .github/workflows/scorecard.yml | 6 +++--- .github/workflows/unit.yaml | 4 ++-- function-maven-plugin/pom.xml | 6 +++--- functions-framework-api/pom.xml | 4 ++-- invoker/conformance/pom.xml | 4 ++-- invoker/core/pom.xml | 14 +++++++------- invoker/pom.xml | 4 ++-- invoker/testfunction/pom.xml | 8 ++++---- 11 files changed, 35 insertions(+), 35 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index ec4e95c0..c28404fd 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 + uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0 with: disable-sudo: true egress-policy: block @@ -46,7 +46,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4 + uses: github/codeql-action/init@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 with: # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support languages: java @@ -66,6 +66,6 @@ jobs: (cd function-maven-plugin && mvn install) - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4 + uses: github/codeql-action/analyze@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 with: category: ${{ matrix.working-directory }} diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index 2391a71f..82e50d85 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -18,7 +18,7 @@ jobs: ] steps: - name: Harden Runner - uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 + uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0 with: disable-sudo: true egress-policy: block @@ -33,13 +33,13 @@ jobs: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0 + uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0 with: java-version: ${{ matrix.java }} distribution: temurin - name: Setup Go - uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 with: go-version: '1.21' diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 59372931..ab57ead9 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 + uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0 with: disable-sudo: true egress-policy: block @@ -22,7 +22,7 @@ jobs: repo.maven.apache.org:443 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Set up JDK - uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0 + uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0 with: java-version: 11.x distribution: temurin @@ -38,13 +38,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 + uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 # v2 minimum required - name: Set up JDK - uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0 + uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0 with: java-version: 17.x distribution: temurin diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 5d49971e..752afbf3 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 + uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0 with: disable-sudo: true egress-policy: block @@ -50,7 +50,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 + uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1 with: results_file: results.sarif results_format: sarif @@ -62,6 +62,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4 + uses: github/codeql-action/upload-sarif@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 with: sarif_file: results.sarif diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml index 1767bb9f..01522215 100644 --- a/.github/workflows/unit.yaml +++ b/.github/workflows/unit.yaml @@ -19,7 +19,7 @@ jobs: ] steps: - name: Harden Runner - uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 + uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0 with: disable-sudo: true egress-policy: block @@ -30,7 +30,7 @@ jobs: *.githubusercontent.com:443 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0 + uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0 with: java-version: ${{ matrix.java }} distribution: temurin diff --git a/function-maven-plugin/pom.xml b/function-maven-plugin/pom.xml index 11d3baae..76de071a 100644 --- a/function-maven-plugin/pom.xml +++ b/function-maven-plugin/pom.xml @@ -58,13 +58,13 @@ com.google.cloud.functions.invoker java-function-invoker - 1.3.1 + 1.4.0 com.google.cloud.tools appengine-maven-plugin - 2.8.1 + 2.8.3 jar @@ -132,7 +132,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.11.1 + 3.11.2 attach-javadocs diff --git a/functions-framework-api/pom.xml b/functions-framework-api/pom.xml index 7fbdce19..438f2898 100644 --- a/functions-framework-api/pom.xml +++ b/functions-framework-api/pom.xml @@ -28,8 +28,8 @@ UTF-8 - 3.13.0 - 3.11.1 + 3.14.0 + 3.11.2 5.3.2 diff --git a/invoker/conformance/pom.xml b/invoker/conformance/pom.xml index 929b9408..b7d60325 100644 --- a/invoker/conformance/pom.xml +++ b/invoker/conformance/pom.xml @@ -28,12 +28,12 @@ com.google.cloud.functions functions-framework-api - 1.1.0 + 1.1.4 com.google.code.gson gson - 2.11.0 + 2.12.1 io.cloudevents diff --git a/invoker/core/pom.xml b/invoker/core/pom.xml index 35ec377e..b7f41622 100644 --- a/invoker/core/pom.xml +++ b/invoker/core/pom.xml @@ -44,7 +44,7 @@ com.google.cloud.functions functions-framework-api - 1.1.0 + 1.1.4 javax.servlet @@ -69,7 +69,7 @@ com.google.code.gson gson - 2.11.0 + 2.12.1 com.ryanharter.auto.value @@ -98,12 +98,12 @@ org.eclipse.jetty jetty-servlet - 9.4.56.v20240826 + 9.4.57.v20241219 org.eclipse.jetty jetty-server - 9.4.56.v20240826 + 9.4.57.v20241219 com.beust @@ -122,7 +122,7 @@ org.mockito mockito-core - 5.14.2 + 5.16.0 test @@ -134,7 +134,7 @@ com.google.re2j re2j - 1.7 + 1.8 com.google.truth @@ -151,7 +151,7 @@ org.eclipse.jetty jetty-client - 9.4.56.v20240826 + 9.4.57.v20241219 test diff --git a/invoker/pom.xml b/invoker/pom.xml index 7c5c4484..4151e994 100644 --- a/invoker/pom.xml +++ b/invoker/pom.xml @@ -42,7 +42,7 @@ com.google.cloud.functions functions-framework-api - 1.1.0 + 1.1.4 @@ -80,7 +80,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.11.1 + 3.11.2 attach-javadocs diff --git a/invoker/testfunction/pom.xml b/invoker/testfunction/pom.xml index e8642676..44c4f110 100644 --- a/invoker/testfunction/pom.xml +++ b/invoker/testfunction/pom.xml @@ -19,7 +19,7 @@ com.google.cloud.functions functions-framework-api - 1.1.0 + 1.1.4 + + airlock-mirror + Airlock Maven Central mirror + https://us-maven.pkg.dev/artifact-foundry-prod/maven-3p-trusted + * + + + + + + airlock-mirror + oauth2accesstoken + ${MAVEN_TOKEN} + + + + exit-gate-ar + oauth2accesstoken + ${MAVEN_TOKEN} + + + +EOF + +# ============================================================================== +# 2. Retrieve GPG keys from Secret Manager +# ============================================================================== +GPG_KEYRING="${KOKORO_ARTIFACTS_DIR}/gpg-keyring" +GPG_PASSPHRASE_FILE="${KOKORO_ARTIFACTS_DIR}/gpg-passphrase" + +# Read names from environment variables injected by Louhi +PROJECT_ID="${_LOUHI_SECRET_PROJECT_ID}" +KEYRING_NAME="${_LOUHI_GPG_KEYRING_SECRET_NAME}" +PASSPHRASE_NAME="${_LOUHI_GPG_PASSPHRASE_SECRET_NAME}" + +echo "Fetching secrets from project: ${PROJECT_ID}" +gcloud secrets versions access latest --secret="${KEYRING_NAME}" --project="${PROJECT_ID}" > "${GPG_KEYRING}" +gcloud secrets versions access latest --secret="${PASSPHRASE_NAME}" --project="${PROJECT_ID}" > "${GPG_PASSPHRASE_FILE}" + +export GPG_TTY=$(tty) +export GPG_PASSPHRASE=$(cat "${GPG_PASSPHRASE_FILE}") +export GNUPGHOME=/tmp/gpg +mkdir -p "${GNUPGHOME}" +gpg --batch --import "${GPG_KEYRING}" + +# ============================================================================== +# 3. Build, Sign, and Deploy +# ============================================================================== +# Detect which package to build based on the Louhi trigger tag +if [[ -n "${_LOUHI_REF_NAME:-}" ]]; then + echo "Triggered by Louhi tag: ${_LOUHI_REF_NAME}" + if [[ "${_LOUHI_REF_NAME}" == *functions-framework-api* ]]; then + PACKAGE_DIR="functions-framework-api" + elif [[ "${_LOUHI_REF_NAME}" == *function-maven-plugin* ]]; then + PACKAGE_DIR="function-maven-plugin" + elif [[ "${_LOUHI_REF_NAME}" == *java-function-invoker* ]]; then + PACKAGE_DIR="invoker" + else + echo "Unknown tag format: ${_LOUHI_REF_NAME}. Defaulting to invoker." + PACKAGE_DIR="invoker" + fi +else + # Fallback for manual/non-tag builds (e.g. testing) + echo "No Louhi tag detected. Falling back to KOKORO_JOB_NAME detection." + if [[ $KOKORO_JOB_NAME == *"function-maven-plugin"* ]]; then + PACKAGE_DIR="function-maven-plugin" + elif [[ $KOKORO_JOB_NAME == *"functions-framework-api"* ]]; then + PACKAGE_DIR="functions-framework-api" + else + PACKAGE_DIR="invoker" + fi +fi + +echo "Building package in directory: ${PACKAGE_DIR}" +cd "${PACKAGE_DIR}" + +# Run maven deploy using the temporary settings.xml +# We use altDeploymentRepository to override the deploy target without editing pom.xml +mvn clean deploy -B \ + -P sonatype-oss-release \ + --settings=../settings.xml \ + -DaltDeploymentRepository=exit-gate-ar::https://us-maven.pkg.dev/oss-exit-gate-prod/ff-releases--mavencentral \ + -Dgpg.executable=gpg \ + -Dgpg.passphrase="${GPG_PASSPHRASE}" \ + -Dgpg.homedir="${GNUPGHOME}" + +# ============================================================================== +# 4. Copy artifacts to 'artifacts/' folder for Kokoro Attestation Generation +# ============================================================================== +ARTIFACTS_DIR="${REPO_DIR}/artifacts" +mkdir -p "${ARTIFACTS_DIR}" + +# Copy target jars and poms (excluding test jars) to be captured by build.cfg +find target/ -maxdepth 1 -name "*.jar" -o -name "*.pom" | grep -v "test" | xargs -I {} cp {} "${ARTIFACTS_DIR}/" diff --git a/.kokoro/release.cfg b/.kokoro/release.cfg index 08d0ac9f..c617e165 100644 --- a/.kokoro/release.cfg +++ b/.kokoro/release.cfg @@ -1,30 +1,23 @@ +# -*- protobuffer -*- +# proto-file: google3/devtools/kokoro/config/proto/build.proto +# proto-message: BuildConfig + build_file: "functions-framework-java/.kokoro/release.sh" +container_properties { + docker_image: "us-docker.pkg.dev/artifact-foundry-prod/docker-3p-trusted/ubuntu:22.04" +} -before_action { - fetch_keystore { - keystore_resource { - keystore_config_id: 75669 - keyname: "functions-framework-java-release-bot-sonatype-password" - } - keystore_resource { - keystore_config_id: 75669 - keyname: "functions-framework-release-sonatype-central-portal-username" - } - keystore_resource { - keystore_config_id: 75669 - keyname: "functions-framework-release-sonatype-central-portal-password" - } - keystore_resource { - keystore_config_id: 70247 - keyname: "maven-gpg-pubkeyring" - } - keystore_resource { - keystore_config_id: 70247 - keyname: "maven-gpg-keyring" - } - keystore_resource { - keystore_config_id: 70247 - keyname: "maven-gpg-passphrase" +fileset_artifacts { + name: "manifest" + artifact_globs: "manifest.json" + error_if_missing: true + destinations { + store_attestation: false + gcs { + gcs_root_path: "oss-exit-gate-prod-projects-bucket/ff-releases/mavencentral/manifests" + populate_content_type: true } } + generate_sbom_from_fileset: false + generate_attestation: false } diff --git a/.kokoro/release.sh b/.kokoro/release.sh old mode 100644 new mode 100755 index b85e6003..58b865a6 --- a/.kokoro/release.sh +++ b/.kokoro/release.sh @@ -1,84 +1,10 @@ #!/bin/bash +set -euo pipefail -# Stop execution when any command fails. -set -e +cd "${KOKORO_ARTIFACTS_DIR}" -# update the Maven version to 3.9.11 -pushd /usr/local -wget https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.tar.gz -tar -xvzf apache-maven-3.9.11-bin.tar.gz apache-maven-3.9.11 -rm -f /usr/local/apache-maven -ln -s /usr/local/apache-maven-3.9.11 /usr/local/apache-maven -rm apache-maven-3.9.11-bin.tar.gz -popd - - -# Get secrets from keystore and set and environment variables. -setup_environment_secrets() { - export GPG_TTY=$(tty) - export GPG_PASSPHRASE=$(cat ${KOKORO_KEYSTORE_DIR}/70247_maven-gpg-passphrase) - - # Add the key ring files to $GNUPGHOME to verify the GPG credentials. - export GNUPGHOME=/tmp/gpg - mkdir $GNUPGHOME - mv ${KOKORO_KEYSTORE_DIR}/70247_maven-gpg-pubkeyring $GNUPGHOME/pubring.gpg - mv ${KOKORO_KEYSTORE_DIR}/70247_maven-gpg-keyring $GNUPGHOME/secring.gpg - gpg -k -} - -create_settings_xml_file() { - echo " - - - - true - - - ${GPG_PASSPHRASE} - - - - - - sonatype-central-portal - $(cat "${KOKORO_KEYSTORE_DIR}/75669_functions-framework-release-sonatype-central-portal-username") - $(cat "${KOKORO_KEYSTORE_DIR}/75669_functions-framework-release-sonatype-central-portal-password") - - -" > $1 +cat > manifest.json <<'EOF' +{ + "publish_all": true } - -setup_environment_secrets - -# Pick the right package to release based on the Kokoro job name. -cd ${KOKORO_ARTIFACTS_DIR}/github/functions-framework-java -create_settings_xml_file "settings.xml" -echo "KOKORO_JOB_NAME=${KOKORO_JOB_NAME}" -if [[ $KOKORO_JOB_NAME == *"function-maven-plugin"* ]]; then - cd function-maven-plugin -elif [[ $KOKORO_JOB_NAME == *"functions-framework-api"* ]]; then - cd functions-framework-api -else - cd invoker -fi -echo "pwd=$(pwd)" - -# Make sure `JAVA_HOME` is set and using jdk17. -JDK_VERSION=17 -apt-get update -# Install new JDK version -apt-get install -y openjdk-"${JDK_VERSION}"-jdk -export JAVA_HOME="$(update-java-alternatives -l | grep "1.${JDK_VERSION}" | head -n 1 | tr -s " " | cut -d " " -f 3)" -echo "JAVA_HOME=$JAVA_HOME" - -SUPPRESS_LOGS='-q' -if [[ -n "${ENABLE_LOGS}" ]]; then - SUPPRESS_LOGS='' -fi - -mvn clean deploy -B ${SUPPRESS_LOGS} \ - -P sonatype-oss-release \ - --settings=../settings.xml \ - -Dgpg.executable=gpg \ - -Dgpg.passphrase=${GPG_PASSPHRASE} \ - -Dgpg.homedir=${GNUPGHOME} +EOF