{"id":189,"date":"2018-10-16T02:42:44","date_gmt":"2018-10-16T02:42:44","guid":{"rendered":"http:\/\/www.appservgrid.com\/paw93\/index.php\/2018\/10\/16\/java-comes-to-the-official-openfaas-templates\/"},"modified":"2018-10-16T02:42:44","modified_gmt":"2018-10-16T02:42:44","slug":"java-comes-to-the-official-openfaas-templates","status":"publish","type":"post","link":"https:\/\/www.appservgrid.com\/paw93\/index.php\/2018\/10\/16\/java-comes-to-the-official-openfaas-templates\/","title":{"rendered":"Java comes to the official OpenFaaS templates"},"content":{"rendered":"<p>At the core of OpenFaaS is a community which is trying to Make Serverless Functions Simple for Docker and Kubernetes. In this blog post I want to show you the new Java template released today which brings Serverless functions to Java developers.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/github.com\/openfaas\/media\/raw\/master\/OpenFaaS_Magnet_3_1_png.png\" width=\"80%\" \/><\/p>\n<p>If you&#8217;re not familiar with the OpenFaaS CLI, it is used to generate new files with everything you need to start building functions in your favourite programming language.<\/p>\n<p>The new template made available today provides Java 9 using the OpenJDK, Alpine Linux and <a href=\"https:\/\/gradle.org\/\">gradle<\/a> as a build system. The serverless runtimes for OpenFaaS uses the new accelerated watchdog built out in the <a href=\"https:\/\/github.com\/openfaas-incubator\/\">OpenFaaS Incubator organisation on GitHub<\/a>.<\/p>\n<h2>Quickstart<\/h2>\n<p>First of all, set up OpenFaaS on your laptop or the cloud with Kubernetes or Docker Swarm. Follow <a href=\"https:\/\/docs.openfaas.com\/deployment\/\">the quickstart here<\/a><\/p>\n<p>Checklist:<\/p>\n<ul>\n<li>I have my API Gateway URL<\/li>\n<li>I&#8217;ve installed the faas-cli<\/li>\n<li>I have Docker installed<\/li>\n<li>I have a Docker Hub account or similar local Docker registry available<\/li>\n<\/ul>\n<p>I recommend using <a href=\"https:\/\/code.visualstudio.com\/\">Visual Studio Code<\/a> to edit your Java functions. You can also install the <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=vscjava.vscode-java-pack\">Java Extension Pack<\/a> from Microsoft.<\/p>\n<h3>Generate a Java function<\/h3>\n<p>You can pull templates from any supported GitHub repository, this means that teams can build their own templates for golden Linux images needed for compliance in the enterprise.<\/p>\n<p>$ faas-cli template pull<\/p>\n<p>You can list all the templates you&#8217;ve downloaded like this:<\/p>\n<p>$ faas-cli new &#8211;list<\/p>\n<p>&#8230;<br \/>\njava8<br \/>\n&#8230;<\/p>\n<blockquote>\n<p>Tip: Before we get started, sign up for a <a href=\"https:\/\/hub.docker.com\/\">Docker Hub accout<\/a>, or log into your own local Docker registry.<\/p>\n<\/blockquote>\n<p>Below update username=alexellis2 to your Docker Hub user name or private registry address. Now generate a new Java function using the faas-cli which you should have installed.<\/p>\n<p>export username=alexellis2<\/p>\n<p>mkdir -p blog<br \/>\ncd blog<\/p>\n<p>faas-cli new &#8211;lang java8 hello-java &#8211;prefix=$username<\/p>\n<p>This generates several files:<\/p>\n<ul>\n<li>build.gradle &#8211; specify any other JAR files or code repositories needed<\/li>\n<li>settings.gradle &#8211; specify any other build settings needed<\/li>\n<\/ul>\n<p>You then get a function Handler.java and HandlerTest.java file in the .\/src folder.<\/p>\n<p>package com.openfaas.function;<\/p>\n<p>import com.openfaas.model.IHandler;<br \/>\nimport com.openfaas.model.IResponse;<br \/>\nimport com.openfaas.model.IRequest;<br \/>\nimport com.openfaas.model.Response;<\/p>\n<p>public class Handler implements com.openfaas.model.IHandler {<\/p>\n<p> public IResponse Handle(IRequest req) {<br \/>\n Response res = new Response();<br \/>\n res.setBody(&#8220;Hello, world!&#8221;);<\/p>\n<p> return res;<br \/>\n }<br \/>\n}<\/p>\n<p>Contents of <em>.\/hello-java\/src\/main\/java\/com\/openfaas\/function\/Handler.java<\/em><\/p>\n<h3>Build and deploy the function<\/h3>\n<p>Now use the faas-cli to build the function, you will see gradle kick in and start downloading the dependencies it needs:<\/p>\n<p>faas-cli build -f hello-java.yml<\/p>\n<p>If you are running on Kubernetes, then you may need to pass the &#8211;gateway flag with the URL you used for the OpenFaaS portal. You can also set this in the OPENFAAS_URL environmental-variable.<\/p>\n<p>faas-cli deploy -f hello-java.yml &#8211;gateway 127.0.0.1:31112<\/p>\n<h3>Test the function<\/h3>\n<p>You can now test the function via the OpenFaaS UI portal, using Postman, the CLI or even curl.<\/p>\n<p>export OPENFAAS_URL=http:\/\/127.0.0.1:31112\/<\/p>\n<p>echo -n &#8220;&#8221; | faas-cli invoke hello-java<\/p>\n<h2>Add a third-party dependency<\/h2>\n<p>You can now add a third-party dependency such as okhttp which is a popular and easy to use HTTP client. We will create a very rudimentary HTTP proxy which simply fetches the text of any URL passed in via the request.<\/p>\n<ul>\n<li>Scaffold a new template<\/li>\n<\/ul>\n<p>$ faas-cli new &#8211;lang java8 web-proxy<\/p>\n<ul>\n<li>Edit build.gradle<\/li>\n<\/ul>\n<p>At the end of the dependencies { add the following:<\/p>\n<p> implementation &#8216;com.squareup.okhttp3:okhttp:3.10.0&#8217;<br \/>\n implementation &#8216;com.squareup.okio:okio:1.14.1&#8217;<\/p>\n<ul>\n<li>Edit Handler.java<\/li>\n<\/ul>\n<p>Paste the following into your Handler.java file, this imports the OKHttpClient into scope.<\/p>\n<p>package com.openfaas.function;<\/p>\n<p>import com.openfaas.model.IHandler;<br \/>\nimport com.openfaas.model.IResponse;<br \/>\nimport com.openfaas.model.IRequest;<br \/>\nimport com.openfaas.model.Response;<\/p>\n<p>import java.io.IOException;<\/p>\n<p>import okhttp3.OkHttpClient;<\/p>\n<p>public class Handler implements IHandler {<\/p>\n<p> public IResponse Handle(IRequest req) {<br \/>\n IResponse res = new Response();<\/p>\n<p> try {<br \/>\n OkHttpClient client = new OkHttpClient();<\/p>\n<p> okhttp3.Request request = new okhttp3.Request.Builder()<br \/>\n .url(req.getBody())<br \/>\n .build();<\/p>\n<p> okhttp3.Response response = client.newCall(request).execute();<br \/>\n String ret = response.body().string();<br \/>\n res.setBody(ret);<\/p>\n<p> } catch(Exception e) {<br \/>\n e.printStackTrace();<br \/>\n res.setBody(e.toString());<br \/>\n }<\/p>\n<p> return res;<br \/>\n }<br \/>\n}<\/p>\n<ul>\n<li>Package, deploy and test<\/li>\n<\/ul>\n<p>faas-cli build -f web-proxy.yml<br \/>\nfaas-cli push -f web-proxy.yml<br \/>\nfaas-cli deploy -f web-proxy.yml<\/p>\n<p>Now test it out with a JSON endpoint returning the position of the <a href=\"http:\/\/open-notify.org\/Open-Notify-API\/ISS-Location-Now\/\">International Space Station<\/a>.<\/p>\n<p>$ echo -n &#8220;http:\/\/api.open-notify.org\/iss-now.json&#8221; | faas-cli invoke web-proxy<\/p>\n<h2>Parse a JSON request<\/h2>\n<p>You can use your preferred JSON library to parse a request in JSON format. This example uses Google&#8217;s GSON library and loads a JSON request into a Java POJO.<\/p>\n<ul>\n<li>Create a function<\/li>\n<\/ul>\n<p>faas-cli new &#8211;lang java8 buildinfo<\/p>\n<ul>\n<li>Edit build.gradle<\/li>\n<\/ul>\n<p>Within dependencies add:<\/p>\n<p> implementation &#8216;com.google.code.gson:gson:2.8.5&#8217;<\/p>\n<ul>\n<li>Edit Handler.java<\/li>\n<\/ul>\n<p>package com.openfaas.function;<\/p>\n<p>import com.openfaas.model.IHandler;<br \/>\nimport com.openfaas.model.IResponse;<br \/>\nimport com.openfaas.model.IRequest;<br \/>\nimport com.openfaas.model.Response;<\/p>\n<p>import com.google.gson.*;<\/p>\n<p>public class Handler implements com.openfaas.model.IHandler {<\/p>\n<p> public IResponse Handle(IRequest req) {<br \/>\n Response res = new Response();<\/p>\n<p> Gson gson = new Gson();<br \/>\n BuildInfo buildInfo = gson.fromJson(req.getBody(), BuildInfo.class);<\/p>\n<p> res.setBody(&#8220;The status of the build is: &#8221; + buildInfo.getStatus());<\/p>\n<p> return res;<br \/>\n }<br \/>\n}<\/p>\n<p>class BuildInfo {<br \/>\n private String status = &#8220;&#8221;;<br \/>\n public String getStatus() { return this.status; }<br \/>\n}<\/p>\n<p>Build, push and deploy your function.<\/p>\n<p>Now invoke it via the CLI:<\/p>\n<p>$ echo &#8216;{&#8220;status&#8221;: &#8220;queued&#8221;}&#8217; | faas invoke buildinfo<br \/>\nThe status of the build is: queued<\/p>\n<h2>Donwload and parse JSON from an URL<\/h2>\n<p>In this example I will show you how to fetch the manifest file from the OpenFaaS Function Store, we will then deserialize it into an ArrayList and print out the count.<\/p>\n<ul>\n<li>\n<p>Create a function named deserialize<\/p>\n<\/li>\n<li>\n<p>Edit build.gradle<\/p>\n<\/li>\n<\/ul>\n<p>Within dependencies add:<\/p>\n<p> implementation &#8216;com.google.code.gson:gson:2.8.5&#8217;<br \/>\n implementation &#8216;com.squareup.okhttp3:okhttp:3.10.0&#8217;<br \/>\n implementation &#8216;com.squareup.okio:okio:1.14.1&#8217;<\/p>\n<ul>\n<li>Handler.java<\/li>\n<\/ul>\n<p>package com.openfaas.function;<\/p>\n<p>import com.openfaas.model.IHandler;<br \/>\nimport com.openfaas.model.IResponse;<br \/>\nimport com.openfaas.model.IRequest;<br \/>\nimport com.openfaas.model.Response;<\/p>\n<p>import com.google.gson.*;<br \/>\nimport okhttp3.OkHttpClient;<br \/>\nimport com.google.gson.reflect.TypeToken;<br \/>\nimport java.util.ArrayList;<\/p>\n<p>public class Handler implements com.openfaas.model.IHandler {<\/p>\n<p> public IResponse Handle(IRequest req) {<br \/>\n Response res = new Response();<\/p>\n<p> Gson gson = new Gson();<br \/>\n String url = &#8220;https:\/\/raw.githubusercontent.com\/openfaas\/store\/master\/store.json&#8221;;<br \/>\n ArrayList&lt;Function&gt; functions = (ArrayList&lt;Function&gt;) gson.fromJson(downloadFromURL(url), new TypeToken&lt;ArrayList&lt;Function&gt;&gt;(){}.getType());<\/p>\n<p> int size = functions.size();<br \/>\n String functionCount = Integer.toString(size);<br \/>\n res.setBody(functionCount +&#8221; function(s) in the OpenFaaS Function Store&#8221;);<br \/>\n return res;<br \/>\n }<\/p>\n<p> public String downloadFromURL(String url) {<br \/>\n String ret = &#8220;{}&#8221;;<\/p>\n<p> try {<br \/>\n OkHttpClient client = new OkHttpClient();<br \/>\n okhttp3.Request request = new okhttp3.Request.Builder()<br \/>\n .url(url)<br \/>\n .build();<\/p>\n<p> okhttp3.Response response = client.newCall(request).execute();<br \/>\n ret = response.body().string();<br \/>\n } catch(Exception e) {<br \/>\n e.printStackTrace();<br \/>\n System.out.println(e.toString());<br \/>\n }<br \/>\n return ret;<br \/>\n }<br \/>\n}<\/p>\n<p>class Function {<br \/>\n public String Name = &#8220;&#8221;;<br \/>\n}<\/p>\n<p>Here is the output:<\/p>\n<p>$ echo | faas-cli invoke deserialize ; echo<br \/>\n16 function(s) in the OpenFaaS Function Store<\/p>\n<h2>Wrapping up<\/h2>\n<p>We have now packaged and deployed a Serverless function written in Java. The new OpenFaaS watchdog component keeps your function <em>hot<\/em> and that ensures the JVM is re-used between invocations. This approach enables high-throughput for your code.<\/p>\n<p>Let us know what you think of the new Java template by tweeting to <a href=\"https:\/\/twitter.com\/openfaas\">@openfaas<\/a> or <a href=\"https:\/\/docs.openfaas.com\/community\">join the Slack community<\/a> for one of the special-interest channels like #kubernetes or #templates.<\/p>\n<h2>Take it further<\/h2>\n<p>If you would like to use some other JDK version, a different base-image for the Linux container or even a different build-tool like Maven, you can fork the templates repository and add your own variant.<\/p>\n<p>Contributions are welcome, so if you have an enhancement that will benefit the community, please feel free to suggest it over on GitHub.<\/p>\n<p>The Java 8 + Gradle 4.8.1 template is available here:<\/p>\n<p><a href=\"https:\/\/github.com\/openfaas\/templates\/tree\/master\/template\/java8\">https:\/\/github.com\/openfaas\/templates\/tree\/master\/template\/java8<\/a><\/p>\n<p> <a href=\"https:\/\/blog.alexellis.io\/java-comes-to-openfaas\/\" target=\"_blank\">Source<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>At the core of OpenFaaS is a community which is trying to Make Serverless Functions Simple for Docker and Kubernetes. In this blog post I want to show you the new Java template released today which brings Serverless functions to Java developers. If you&#8217;re not familiar with the OpenFaaS CLI, it is used to generate &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.appservgrid.com\/paw93\/index.php\/2018\/10\/16\/java-comes-to-the-official-openfaas-templates\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Java comes to the official OpenFaaS templates&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-189","post","type-post","status-publish","format-standard","hentry","category-docker"],"_links":{"self":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts\/189","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/comments?post=189"}],"version-history":[{"count":0,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts\/189\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/media?parent=189"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/categories?post=189"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/tags?post=189"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}