-
Notifications
You must be signed in to change notification settings - Fork 2.9k
WIP: Add GCF samples #1506
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Add GCF samples #1506
Conversation
Note: these have only been tested with Java 8, as the Java 11 runtime itself isn't ready. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are existing samples under functions/snippets
- these should be moved into that package and updated to match.
functions/src/main/java/com/example/functions/HelloPubSubSample.java
Outdated
Show resolved
Hide resolved
// [START functions_helloworld_gcs_event] | ||
package com.example.functions; | ||
|
||
public class GcsEvent { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to use getters (and setters).
What is the point of this class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a struct
that incoming GCS events are marshalled into.
(It's meant to be fairly read-only, so IMHO getters/setters would be overkill here.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Java doesn't have have the concept of structs
. It's idiomatic to use a constructor, private attributes, and getters to make it read-only.
public class HelloGcsSample { | ||
private static Logger logger = Logger.getLogger(HelloGcsSample.class.getName()); | ||
|
||
public void helloGcs(GcsEvent event) throws Exception { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't match the servlet signature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes - AFAIK, GCF itself will marshal incoming GCS notifications into this format.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My concern here is that Java has a very strict typing on classes, so I'm concerned that GCF isn't actually going to use a com.example.functions.GcsEvent
class and this sample won't work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We plan to have the Java GSON parser to unmarshall the GcsEvent Pojo defined along with the user function. This experience aligns with the experience we currently provide users for Go. We also plan to open source the Java functions framework at Beta, so at that point an open source event type could be considered. However, I don't think this would be something we would consider as a blocker for Beta and GA.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the class going to be derived from the parameter for the function then?
Presumably if so, it would be safe to move GcsEvent
as a static class inside the class with the function. This would allow us to keep the goal of having the sample copy/pastable.
Status please? |
This is on hold for now, due to product-side issues. |
FYI: this PR is back on my radar. I'll go through and adjust these samples to conform with the new (Java 11) GCF function signatures. |
@kurtisvg LMK if you want me to apply your comments RE structs |
|
||
# Google Cloud Functions Java Samples | ||
|
||
[Cloud Functions][functions_docs] is a lightweight, event-based, asynchronous |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do the docs have the instructions on how to run/deploy these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not yet - I think @labtopia (TW for GCF) is working on adding them, though.
@@ -0,0 +1 @@ | |||
src/test/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this file auto-generate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No - but I didn't want the test code getting deployed to GCF when I use gcloud functions deploy
. (Otherwise, it does unless you specifically exclude that directory in the deployment command.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you expand on why you've chosen to do include this?
My understanding is that the Functions deployment deploys a jar? Are they compiled locally or after the code is deployed?
If it's compiled locally, I'm not sure this has any effect, and it's done remotely I'm not sure if it's a pattern we should push. As a user, if I've written tests, I want those tests to run on compile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With GCF, you can deploy either a (self-sufficient) jar or a source hierarchy with pom.xml
at the root. We expect users to deploy from source; the jar business is there to support build systems other than Maven. If you include the test source then your tests will be run remotely as part of your deployment. Whether you want that probably depends whether running them locally is enough, and on how long they take to run.
I think we should probably talk about this more in the GCF Java docs. We could also have a comment here saying what this does and why you might or might not want it. #
comments are supported in .gcloudignore
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this doesn't appear to be the obvious default choice, I feel like it make the most sense to remove this for now. It seems like this this makes more sense to include in the GCF docs so the additional context makes clear it isn't required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kurtisvg any objection to adding a comment instead? Without this, gcloud functions deploy
in the repo itself will deploy the tests by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that's the behavior most people will want though right? There might be some folks that don't want to run their tests on deploy, but I don't think it should be the default action.
From my perspective as a user, I would prefer to run gcloud functions deploy
and have it run the tests + deploy rather than have to run mvn verify
then run gcloud functions deploy
.
|
||
private LoggingClient client; | ||
|
||
// Retrieve the latest Cloud Function log entries | ||
public void retrieveLogs(HttpServletRequest request, HttpServletResponse response) | ||
@Override | ||
public void service(HttpRequest request, HttpResponse response) | ||
throws IOException { | ||
// Get the LoggingClient for the function. | ||
client = getClient(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kurtisvg is this idiomatic?
Tests are failing |
functions/snippets/src/test/java/HelloBackgroundSampleTest.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please split into smaller PRs. There is too much here to easily review in a single pass.
functions/snippets/src/test/java/HelloBackgroundSampleTest.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI I think it would be great if we could arrange that some of these snippets were also used as the snippets that appear when you create a function in the Cloud Console. I've done some of the work for that to be possible and would be keen to do the rest. But it means that we'd probably want very skeletal snippets, and trying to make the same snippets do duty as both illustrative examples and starting points might not be the best approach.
@@ -0,0 +1,26 @@ | |||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the FF should have Google-specific classes like this. However there's a good case to be made for providing another artifact that defines them, rather than having everyone reinvent them.
I think we decided that the consensus was to use |
I'm not sure if this is connected, but I believe at one point we only supported functions in the default package (no |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would make sense to submit this. It might not be perfect, but we can always fix details later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other outstanding issues:
- Java 11 tests are currently failing
- @averikitsch 's comment about using the correct package isn't resolved - you are still using the default package
- Headers still need to be updated to 2020 for new files (tried to suggest all the ones I noticed but I may have missed some - please verify)
@@ -0,0 +1 @@ | |||
src/test/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you expand on why you've chosen to do include this?
My understanding is that the Functions deployment deploys a jar? Are they compiled locally or after the code is deployed?
If it's compiled locally, I'm not sure this has any effect, and it's done remotely I'm not sure if it's a pattern we should push. As a user, if I've written tests, I want those tests to run on compile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think my remaining primary concerns:
-
It looks like the classes are still in the default package (under
src/main/java
). We should really move them into a proper package to avoid any unintended weirdness. -
How to handle serialized events. I'm still not convinced there is a good reason to forgo best practices and skip getters and setters.
Other then those two things, I had one or two small nits.
@@ -0,0 +1 @@ | |||
src/test/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this doesn't appear to be the obvious default choice, I feel like it make the most sense to remove this for now. It seems like this this makes more sense to include in the GCF docs so the additional context makes clear it isn't required.
|
||
private EnvironmentVariables environmentVariables; | ||
|
||
private static final TestLogHandler logHandler = new TestLogHandler(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Constant variables should be in all caps:
private static final TestLogHandler logHandler = new TestLogHandler(); | |
private static final TestLogHandler LOG_HANDLER = new TestLogHandler(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done throughout - marking these comments as resolved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually (while we are nitting), Google Style does not say that all static final
fields should be spelled with CONSTANT_CASE
. Only truly immutable values should be, which TestLogHandler
and Logger
are not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah interesting. I didn't know the Google Style Guide specified that - I've always just followed the traditional Java conventions where anything final
is considered a constant since the reference is immutable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM once we reach a decision on the .gcloudignore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM once we reach a decision on the .gcloudignore
FYI: I'm merging this for now, since all local tests are passing. b/150242638 is blocking me from testing it on GCF, so I'm prepared to make changes later if issues come up. |
DO NOT MERGE until these have been tested on Cloud Functions proper