From zero to hero on Cloud Functions Java 11

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
GUILLAUME LAFORGE: Hello, everyone, and welcome to this session about the new Java 11 runtime for Cloud functions. Java is a very important and widely used programming language in the enterprise. And customers have asked for Java support ever since we released the first runtime for Google Cloud Functions. So let's dive into Java 11 for Cloud functions. And that's my pleasure to introduce you to my colleague Eamonn. EAMONN MCMANUS: Hi, I'm Eamonn McManus. I'm the lead developer for GCF Java. GUILLAUME LAFORGE: And I'm Guillaume Laforge. I'm a Developer Advocate for Google Cloud. And I'm focusing on our serverless solutions. I also contributed to the Java API for this runtime. So I'm very excited to share that with you. So let's start with a few words about the serverless concept. More than just a buzzword, serverless is both about an operational and a programming perspective. From an operational standpoint, developers can focus on their code, and don't need to bother about servers to manage, clusters to provision. It's a pay for usage model. So you pay proportionately to the number of times your functions are invoked or the duration. So you really pay only for the underlying infrastructure when it's actually used for your workloads, not when it's idle. For the programming model, developers are encouraged to write more granular services instead of the good old big monolith. And functions react to events, so whether it's an http call or it's some event coming from your Cloud infrastructure. Furthermore, we've been building Cloud Functions with an open approach. So we'll tell you more about this with the Functions framework. And you can easily run your functions elsewhere, not just in the Cloud, but also on your local machine, which improves the developer experience, as well as anywhere else, on premises, or even in other clouds, potentially. So Google Cloud offers three serverless compute solutions. So there's Cloud Functions, which is the topic of the day, where you write event-driven services a small unit of code. There's App Engine for deploying your web application, your services, your backend APIs, like mobile backends. And there's Cloud Run, where you can deploy anything within a container with any language that you want any runtime, any executable you want to use. Now, zooming back on to Cloud Functions, there were so far only three runtimes available. So there's node js, Python, and Go. And today, we're also happy to have Java 11, which is available in beta. Let's now have a look at the types and shape of functions. And I'll let Eamonn tell you all about our Java function API. EAMONN MCMANUS: Thanks, Guillaume. So there's basically two kinds of functions. And this is true for all of the different language runtimes on GCF. There are http functions and background functions. So http functions react to a URL being accessed. So it's a public URL subject to access controls. And whenever there's an http request made to that URL, the function gets executed. And it can specify what the reply to the http request is going to be. And then there's background functions. And those are invoked by the system in response to certain events. And so we see here some of the events that that might be. For example, Pub/Sub events or a file gets created in Cloud storage, and so on. So, Java doesn't really have a notion of functions as such. So the approach that we chose was a familiar one for Java, which is to define an interface that has a single method. And then your function is an implementation of that interface. So it has that method in it. So when we look at http functions, the interface in question is called http function. Typically, you would just type something like, in your IDE class example, implements http function. And then you would ask, basically get the IDE to fill in the details. It knows that that interface has one method so it provides that method for you. You don't have to remember the method signature. And then all you need to do is implement that method. And it's unsurprising. There is a request parameter that allows you to see the details of the incoming http request, like what the URL was, the query parameters, if there's a body and what that was. And then there's a response parameter that allows you to say what the http response is going to look like, status code, the content type, the body of that, and so on. GUILLAUME LAFORGE: Let's have a look at a slightly more complex function, an http function. So I'm defining a new class in a package. I'm importing the key functions framework APIs, the http function interface, the http request and response. And in this example, we're going to check whether a number is prime or not. So we're going to use a [INAUDIBLE] dependency. Here, we're going to use apache commons math, particularly the prime's class, which gives us the ability to know if a number is prime or not. So, let's implement the http function interface and overwrite the service method. The service method takes an http request and an http response. Here you can see on the response object. I can, for example, set the status code 200, set the content type. Here, it's just some plain text. And I can also get the writer to write on the output. On the request, on the request object, I can call get first query parameter to get the query parameters. In this case, that's the number that is passed as a parameter. If there's no number, you don't necessarily know. So this method actually returns an optional. So if there's a number that is present, then I can have some logic. And otherwise, I'm going to say, OK, please provide a number. So if a number is provided, I'm going to look at this number. It's actually a string. It's part of the query string. So I'm going to turn that string into an integer in the end value variable. And then I'm going to say, OK, is this value a prime number? And then I call the dependency from the primes class. Primes is prime with the values. It's going to return a Boolean value, whether it's prime or not. And if there was a parsing error from the query string, I'm going to write, please provide a valid number. And let's have a look at the [INAUDIBLE].. Here I'm building with Maven. So I'm saying, OK, I'm using Java 11. And here, you can see the two dependencies. The dependency on the function's framework API with the provided scope, because the environment on the Cloud Functions runtime provides this API. And I have my user dependency on apache commons math. And now let's have a look at how to run this. So please provide a number. If I don't provide any number. So let's add a number here. ABC. Oh. Please provide valid number. So let's do it again, but with 1, 2, 3, 4. So is this number prime? It's false. So let's say, let's try it with another number. 17. Is 17 prime? Yes, that's true. So here's our first http function. EAMONN MCMANUS: So we saw http functions. What about background functions? The way the background functions work behind the scenes is that you still have incoming http, but you don't have to be concerned with it anymore. So the http has a payload, which is a JSON payload. And we can consider that comes in two parts. There is essentially an envelope, which is the things that are common to all kinds of events. And that says what the event type is, what the timestamp is, and so on. And then there's the content, which is the things that are specific to the particular event that you're receiving. Then there are two ways of handling these. They're quite similar. They just have to do with how the JSON is presented to you. So in both cases, the envelope will be parsed for you. You don't have to see how that's represented in JSON. That's the second parameter to these functions. The first parameter, then, is where they differ. In the background function case, the interface call background function, that parameter will be deserialized into a Java class that you provide using the JSON framework. So that makes it a little more convenient to get out the contents of the JSON. And then in the second form, we just give you a string, which is the incoming JSON as is. And then you can parse that, using whatever framework you like, Jackson or whatever. So we've seen how to write functions. Now, Guillaume will talk about how you build and deploy them. GUILLAUME LAFORGE: So let's see how we can do that. There are a couple of options for building functions. Your functions can be built in the Cloud from sources using Maven or Gradle build tools. Your sources should provide a pom.xml file or build.gradle project file. You can also build a JAR with any build tool that you want. Either a shaded JAR with dependencies within the JAR file. Or JAR archive whose manifest descriptor provides class path attribute pointing at the JAR dependencies in some local subdirectory. With Maven, to build a JAR project containing your functions, your pom.xml project build file must import the function's framework API dependency. This is actually a dependency, which is available on Maven Central or [INAUDIBLE].. It's a JAR that provides various interfaces we've seen representing functions, requests, responses, context, et cetera. If you want to build with Gradle, similarly to Maven, you need to have a build.gradle file with a function's framework API dependency as well. So here, the dependency is played over two lines, but it's really just for readability purpose. And that's all. When you deploy this project on Cloud Functions, the platform will take care of the build for you. You can then deploy your functions from either the Google Cloud console UI, from the G Cloud command line, or with the Maven function plug-in. We provide a dedicated plug-in for that. In the G Cloud command here, notice the Java 11 runtime flag, which proves that we're indeed using this new runtime. Also note the entry point. It corresponds to the fully qualified class name of your Java function. Now that we've seen what functions look like, I'll let Eamonn tell you more about the developer experience. EAMONN MCMANUS: So, in common with all of the other runtimes on GCF, we have a notion of a functions framework. And that is basically that the code that we-- the framework that we use to run your function when you deploy it to GCF is also available as an open source project on GitHub. You can download that and build it, and you can run your function, of course, by deploying it. But you can also run it locally on your machine using this functions framework. So and you can also use that to package the function into a container and deploy that container wherever you like to execute the function wherever you like. So what this looks like in Maven, for example, is that in your pom.xml, we supply you with a plug-in that makes this a little bit easier that is based on top of the function's framework. If you put this extract of code into your pom.xml, then you can just type on the command line, maven function code on run. We already saw this plug-in in action to deploy the function with maven function code and deploy. Here you can use maven function code on run. And then you can interact with your function, which again, is just http. You can interact with it, you know, either from your browser or from the command line using curl or from tests or whatever you like. GUILLAUME LAFORGE: Let's come back to our prime number function, which allowed us to know whether a number was prime or not. I define the build file for Maven, the pom.xml file. And there's a step that I skipped, I didn't explain. That's this part. So this is where we are actually configuring the function maven plug-in, OK? We're defining a parameter for this plug-in. say, the function target. That's the function we want to run with the function maven plug-in. That's this prime number function from my com xfm package. And if I go into the terminal and run MVN function run, it's going to run my function locally on my machine. And it's already running locally. And I can, again, for example, I can do curl request locally. Here, 19 is a prime number. 1, 2, 3, 4 is not a prime number, OK? So it's very simple. Just define the maven function plug-in configuration here in your pom.xml file. And you're able to read your function locally in your terminal on your laptop, on your desktop, without having to deploy in the Cloud. Actually, we've been talking about Java so far. But you're not limited to just the Java language. You can also run and use alternative JVM languages for authoring your functions. For instance, you can use Apache Groovy, Kotlin, [INAUDIBLE] or [INAUDIBLE]. Thanks to Java, thanks to its Java virtual machine, Java is actually a platform where you can run alternative languages as well. And you can do that with Cloud Functions for Java as well. So let's take an example. Here is an http function example using the Apache Groovy programming language. It looks pretty similar to our Java example from earlier. Same approach-- just implement the http function interface and use the http request, the http response parameters, to inspect incoming request and reply back to the calling client. That's also the same approach with background functions. When you implement the background function or the raw background function interfaces. So let's see a concrete example with a demo. Let's have a look at a Groovy function. It's a useful function this time, not a hello world, which is going to parse a file using the Ascii doctor format, the file that is hosted on GitHub, and which lists the official Java champions. So it's a table with different lines and showing the pictures, details, names, et cetera, town, country. This file is using the Ascii doctor format, which is format-- text format-- similar to mark down. Each row for each champion looks something like this. You've got some links. You've got, again, country, year, et cetera. And the goal of my function is to output something that is easier to parse for tools. And I'm going to output JSON list of documents. So I want to transform that into this, basically. So let's have a look at the code. So here's my Groovy function. I'm implementing the http function interface, as usual. I have a service method with a request and a response object. I'm doing things like adding a header for cache control, setting the content type. And then I'm going to output some JSON data. I also have a look at the path, because I can sort my Java champions by year, by country. And what's interesting as well-- look at this and that, same thing below. We're using the Groovy equivalent of Java lambda expressions. That's Groovy closures. So here, we are grouping by date, sorting by key. That's the name, the country, and again, the key here. So this is Groovy notation, basically, right? And what else? Easily, I can fetch the document that I'm going to parse. And then I'm using the Ascii doctor j library to parse the document. And I go through the various blocks of text to create champions, instances of champions, which have a name, Twitter alias, town, country, et cetera. So how do I do that? So let's have a look at my pom.xml file. This time, I add a new plug-in, that's the G Maven plus plug-in, which is used to compile Groovy code. You have to instruct your Maven build to say, OK, you also want to compile some Groovy code along with Java code potentially. So that's the first plug-in. The other plug-in, that's the Google Cloud Functions Maven plug-in. And I'm saying, OK, this is the function to run, if I want to run the function locally. Let's have a look at the dependencies now. Still, the functions framework API, which is a provided dependency. But, since I'm using the Groovy language, I'm adding the Groovy library here. And I also add the Ascii doctor j library for parsing the document. What's interesting with this function is that actually, this is a Groovy function using some Java libraries, but also Ascii doctor j, which is actually a ruby library, which is interpreted with the J ruby alternative JVM language. So you have basically three languages. Java, Groovy, Ruby at the same time running with Cloud Functions for Java. So let's continue on this polyglot journey with another language here. Again, that's the same thing, but this time, we're using the Kotlin programming language. That's pretty similar. You have to implement the http function interface, use the http request and response object. That's pretty much the same thing, except, of course, that the syntax of the language is slightly different. Alternative languages. Check. But you're not locked to the function's framework API. It's also possible to use familiar frameworks like Spring Cloud, Micronaut, Quarkus, using their own programming models to create functions for the Java 11 runtime for Cloud Functions. So let's have a look. Spring Cloud and Spring Boot have a different approach to creating functions. In Spring, a function is a Spring [INAUDIBLE] that returns Java function interface, which is parameterized by an input type and output type. Your Spring functions returns a lambda expression, hence the arrow that you see here, this example. But you don't use the Functions framework API directly. You use Spring's programming model instead. In other framework, this time, Micronaut. For http functions, the Micronaut framework actually uses its own annotation driven programming model. So you can see here, we are defining a controller, a path, path variables, et cetera, reusing the annotations provided by the Micronaut framework. This is really just a plain Micronaut controller. But the Micronaut team provided a specific Cloud Functions integration that wraps the Functions framework interfaces. So Micronaut developers just prefer normal a plain, usual Micronaut controller using their programming model that they are used to, which is pretty poor table. Because this controller can run elsewhere in a container, as a web application, and not just as a Cloud Function. Let's have a look at a concrete example with the Micronaut's framework. So what does a Micronaut function look like? I'm actually going to use a project called Micronaut Launch, which has been created by the Micronaut team to scaffold a new project, a template for your project. So you can select what you want to create, which language you want to use, which build, which kind of testing tool. And you can also add features. So I already added it initially. There's a specific feature for Google Cloud Function. So the Micronaut team created an integration for Cloud Functions Java 11. So you can click the Generate button to generate an archive zip file for your project. But you can also click the little Preview button to see what's generated. A controller. There's even a Docker file if you run that, if you want to run that function, that application, that Micronaut application elsewhere, for example, as a Cloud Run container. That's possible. And there's also a build. But I've already downloaded this. And, so I have a build.gradle file that's been generated using the function's framework API, the invoker-- that's what allows you to run functions locally or invoke your functions anywhere. And what's interesting is that there's a special task that's been added here, Run Function, which does the same job as the Maven function plug in, which is using the invoker to run the function locally. And it's going to call the integration point created by the Micronaut folks, the http function, which is going to delegate the work to the Halo controller. So this controller, it's a standard Micronaut controller, using the Add Controller annotation, looking at the /halo sub path. It's going to output some plaintext. Let's write something. GCF Java 11 rocks. Let's save this. And then let's run that locally. So it's going to build this function locally and run it locally using the functions invoker through the Gradle build. So let's have a look. Yeah. GCF Java 11 rocks. So, unlike Spring Cloud and Micronaut, Quarkus follows the function framework native API approach, just decorating functions with Quarkus specific annotations, like @Named, @ApplicationScoped, or @Inject to do dependency injection for the dependencies that are needed for your function. This is also the same approach for background functions. So taking advantage of Quarkus annotations, but following the Functions framework API using the Functions framework API interfaces instead. So that's about it. I'll let Eamonn conclude. EAMONN MCMANUS: So, we saw a rapid tour of GCF Java. So Java is one of the new runtimes available with GCF now. We saw that there are two kinds of functions, http functions and background functions. Both functions are portable, thanks to the Functions framework. So you can deploy them using the Functions framework in production to GCF. But you can also run them locally. And you can put them in a container and deploy them anywhere you want. We saw all of that it isn't really just a Java runtime. It's the JVM runtime. So you can run any JVM language, such as Kotlin or Groovy. And finally, we saw that it works not only on its own, but also in conjunction with a certain number of other frameworks, so such as Spring Cloud, Quarkus, and Micronaut. So that's GCF Java. And we're excited to see what you build with it.
Info
Channel: Google Cloud Tech
Views: 3,297
Rating: undefined out of 5
Keywords: type: Conference Talk (Full production);, pr_pr: Google Cloud Next, purpose: Educate
Id: uHXdffqy04Q
Channel Id: undefined
Length: 25min 5sec (1505 seconds)
Published: Tue Sep 15 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.