|
1 | | -# Fn Java Functions Developer Kit (FDK) |
2 | 1 | [](https://circleci.com/gh/fnproject/fdk-java) |
3 | 2 |
|
4 | | -This project adds support for writing functions in Java on the [Fn |
5 | | -platform](https://github.com/fnproject/fn), with full support for Java 11 |
6 | | -as the default out of the box. |
| 3 | +# Java Function Development Kit (FDK) |
7 | 4 |
|
8 | | -# FAQ |
9 | | -Some common questions are answered in [our FAQ](docs/FAQ.md). |
| 5 | +The Java Function Development Kit (FDK) makes it easy to build and deploy Java functions to Fn with full support for Java 11+ as the default out of the box. |
10 | 6 |
|
11 | | -# Quick Start Tutorial |
| 7 | +Some of the Java FDK's features include: |
12 | 8 |
|
13 | | -By following this step-by-step guide you will learn to create, run and deploy |
14 | | -a simple app written in Java on Fn. |
| 9 | +- Parsing input and writing output |
| 10 | +- Flexible data binding to Java objects |
| 11 | +- Function testing using JUnit rules |
| 12 | +- And more! |
15 | 13 |
|
16 | | -## Pre-requisites |
| 14 | +## Learn about the Fn Project |
17 | 15 |
|
18 | | -Before you get started you will need the following things: |
| 16 | +New to Fn Project? If you want to learn more about using the Fn Project to power your next project, start with the [official documentation](https://github.com/fnproject/docs). |
19 | 17 |
|
20 | | -* The [Fn CLI](https://github.com/fnproject/cli) tool |
21 | | -* [Docker-ce 17.06+ installed locally](https://docs.docker.com/engine/installation/) |
| 18 | +## Using the Java FDK |
22 | 19 |
|
23 | | -### Install the Fn CLI tool |
| 20 | +For detailed instructions on using the Java FDK to build and deploy Java functions to Fn, please see the official Java FDK developer guide in our docs repo here: https://github.com/fnproject/docs/blob/master/fdks/fdk-java/README.md. |
24 | 21 |
|
25 | | -To install the Fn CLI tool, just run the following: |
| 22 | +## Contributing to the Java FDK |
26 | 23 |
|
27 | | -``` |
28 | | -curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | sh |
29 | | -``` |
30 | | - |
31 | | -This will download a shell script and execute it. If the script asks for |
32 | | -a password, that is because it invokes sudo. |
33 | | - |
34 | | -## Your first Function |
35 | | - |
36 | | -### 1. Create your first Java Function: |
37 | | - |
38 | | -```bash |
39 | | -$ mkdir hello-java-function && cd hello-java-function |
40 | | -$ fn init --runtime=java --name your_dockerhub_account/hello |
41 | | -Runtime: java |
42 | | -function boilerplate generated. |
43 | | -func.yaml created |
44 | | -``` |
45 | | - |
46 | | -This creates the boilerplate for a new Java Function based on Maven and Oracle |
47 | | -Java 11. The `pom.xml` includes a dependency on the latest version of the Fn |
48 | | -Java FDK that is useful for developing your Java functions. |
49 | | - |
50 | | -You can now import this project into your favourite IDE as normal. |
51 | | - |
52 | | -### 2. Deep dive into your first Java Function: |
53 | | -We'll now take a look at what makes up our new Java Function. First, lets take |
54 | | -a look at the `func.yaml`: |
55 | | - |
56 | | -```bash |
57 | | -$ cat func.yaml |
58 | | -name: your_dockerhub_account/hello |
59 | | -version: 0.0.1 |
60 | | -runtime: java |
61 | | -cmd: com.example.fn.HelloFunction::handleRequest |
62 | | -``` |
63 | | - |
64 | | -The `cmd` field determines which method is called when your function is |
65 | | -invoked. In the generated Function, the `func.yaml` references |
66 | | -`com.example.fn.HelloFunction::handleRequest`. Your functions will likely live |
67 | | -in different classes, and this field should always point to the method to |
68 | | -execute, with the following syntax: |
69 | | - |
70 | | -```text |
71 | | -cmd: <fully qualified class name>::<method name> |
72 | | -``` |
73 | | - |
74 | | -For more information about the fields in `func.yaml`, refer to the [Fn platform |
75 | | -documentation](https://github.com/fnproject/fn/blob/master/docs/function-file.md) |
76 | | -about it. |
77 | | - |
78 | | -Let's also have a brief look at the source: |
79 | | -`src/main/java/com/example/fn/HelloFunction.java`: |
80 | | - |
81 | | -```java |
82 | | -package com.example.fn; |
83 | | - |
84 | | -public class HelloFunction { |
85 | | - |
86 | | - public String handleRequest(String input) { |
87 | | - String name = (input == null || input.isEmpty()) ? "world" : input; |
88 | | - |
89 | | - return "Hello, " + name + "!"; |
90 | | - } |
91 | | - |
92 | | -} |
93 | | -``` |
94 | | - |
95 | | -The function takes some optional input and returns a greeting dependent on it. |
96 | | - |
97 | | -### 3. Run your first Java Function: |
98 | | -You are now ready to run your Function locally using the Fn CLI tool. |
99 | | - |
100 | | -```bash |
101 | | -$ fn build |
102 | | -Building image your_dockerhub_account/hello:0.0.1 |
103 | | -Sending build context to Docker daemon 14.34kB |
104 | | -Step 1/11 : FROM fnproject/fn-java-fdk-build:jdk11-latest as build-stage |
105 | | - ---> 5435658a63ac |
106 | | -Step 2/11 : WORKDIR /function |
107 | | - ---> 37340c5aa451 |
108 | | - |
109 | | -... |
110 | | - |
111 | | -Step 5/11 : RUN mvn package dependency:copy-dependencies -DincludeScope=runtime -DskipTests=true -Dmdep.prependGroupId=true -DoutputDirectory=target --fail-never |
112 | | ----> Running in 58b3b1397ba2 |
113 | | -[INFO] Scanning for projects... |
114 | | -Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-compiler-plugin/3.3/maven-compiler-plugin-3.3.pom |
115 | | -Downloaded: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-compiler-plugin/3.3/maven-compiler-plugin-3.3.pom (11 kB at 21 kB/s) |
116 | | - |
117 | | -... |
118 | | - |
119 | | -[INFO] ------------------------------------------------------------------------ |
120 | | -[INFO] BUILD SUCCESS |
121 | | -[INFO] ------------------------------------------------------------------------ |
122 | | -[INFO] Total time: 2.228 s |
123 | | -[INFO] Finished at: 2017-06-27T12:06:59Z |
124 | | -[INFO] Final Memory: 18M/143M |
125 | | -[INFO] ------------------------------------------------------------------------ |
126 | | - |
127 | | -... |
128 | | - |
129 | | -Function your_dockerhub_account/hello:0.0.1 built successfully. |
130 | | - |
131 | | -$ fn run |
132 | | -Hello, world! |
133 | | -``` |
134 | | - |
135 | | -The next time you run this, it will execute much quicker as your dependencies |
136 | | -are cached. Try passing in some input this time: |
137 | | - |
138 | | -```bash |
139 | | -$ echo -n "Universe" | fn run |
140 | | -... |
141 | | -Hello, Universe! |
142 | | -``` |
143 | | - |
144 | | -### 4. Testing your function |
145 | | -The Fn Java FDK includes a testing library providing useful [JUnit |
146 | | -4](http://junit.org/junit4/) rules to test functions. Look at the test in |
147 | | -`src/test/java/com/example/fn/HelloFunctionTest.java`: |
148 | | - |
149 | | -```java |
150 | | -package com.example.fn; |
151 | | - |
152 | | -import com.fnproject.fn.testing.*; |
153 | | -import org.junit.*; |
154 | | - |
155 | | -import static org.junit.Assert.*; |
156 | | - |
157 | | -public class HelloFunctionTest { |
158 | | - |
159 | | - @Rule |
160 | | - public final FnTestingRule testing = FnTestingRule.createDefault(); |
161 | | - |
162 | | - @Test |
163 | | - public void shouldReturnGreeting() { |
164 | | - testing.givenEvent().enqueue(); |
165 | | - testing.thenRun(HelloFunction.class, "handleRequest"); |
166 | | - |
167 | | - FnResult result = testing.getOnlyResult(); |
168 | | - assertEquals("Hello, world!", result.getBodyAsString()); |
169 | | - } |
170 | | - |
171 | | -} |
172 | | -``` |
173 | | - |
174 | | -This test is very simple: it just enqueues an event with empty input and then |
175 | | -runs the function, checking its output. Under the hood, the `FnTestingRule` is |
176 | | -actually instantiating the same runtime wrapping function invocations, so that |
177 | | -during the test your function will be invoked in exactly the same way that it |
178 | | -would when deployed. |
179 | | - |
180 | | -There is much more functionality to construct tests in the testing library. |
181 | | -Testing functions is covered in more detail in [Testing |
182 | | -Functions](docs/TestingFunctions.md). |
183 | | - |
184 | | -### 5. Run using HTTP and the local Fn server |
185 | | -The previous example used `fn run` to run a function directly via docker, you |
186 | | -can also use the Fn server locally to test the deployment of your function and |
187 | | -the HTTP calls to your functions. |
188 | | - |
189 | | -Open another terminal and start the Fn server: |
190 | | - |
191 | | -```bash |
192 | | -$ fn start |
193 | | -``` |
194 | | - |
195 | | -Then in your original terminal create an app: |
196 | | - |
197 | | -```bash |
198 | | -$ fn create app java-app |
199 | | -Successfully created app: java-app |
200 | | -``` |
201 | | - |
202 | | -Now deploy your Function using the `fn deploy` command. This will bump the |
203 | | -function's version up, rebuild it, and push the image to the Docker registry, |
204 | | -ready to be used in the function deployment. Finally it will create a route on |
205 | | -the local Fn server, corresponding to your function. |
206 | | - |
207 | | -We are using the `--local` flag to tell fn to skip pushing the image anywhere |
208 | | -as we are just going to run this on our local fn server that we started with |
209 | | -`fn start` above. |
210 | | - |
211 | | -```bash |
212 | | -$ fn deploy --app java-app --local |
213 | | -... |
214 | | -Bumped to version 0.0.2 |
215 | | -Building image hello:0.0.2 |
216 | | -Sending build context to Docker daemon 14.34kB |
217 | | - |
218 | | -... |
219 | | - |
220 | | -Successfully built bf2b7fa55520 |
221 | | -Successfully tagged your_dockerhub_account/hello:0.0.2 |
222 | | -Updating route /hello-java-function using image your_dockerhub_account/hello:0.0.2... |
223 | | -``` |
224 | | - |
225 | | -Call the Function via the Fn CLI: |
226 | | - |
227 | | -```bash |
228 | | -$ fn call java-app /hello-java-function |
229 | | -Hello, world! |
230 | | -``` |
231 | | - |
232 | | -You can also call the Function via curl: |
233 | | - |
234 | | -```bash |
235 | | -$ curl http://localhost:8080/r/java-app/hello-java-function |
236 | | -Hello, world! |
237 | | -``` |
238 | | - |
239 | | -### 6. Something more interesting |
240 | | -The Fn Java FDK supports [flexible data binding](docs/DataBinding.md) to make |
241 | | -it easier for you to map function input and output data to Java objects. |
242 | | - |
243 | | -Below is an example to of a Function that returns a POJO which will be |
244 | | -serialized to JSON using Jackson: |
245 | | - |
246 | | -```java |
247 | | -package com.example.fn; |
248 | | - |
249 | | -public class PojoFunction { |
250 | | - |
251 | | - public static class Greeting { |
252 | | - public final String name; |
253 | | - public final String salutation; |
254 | | - |
255 | | - public Greeting(String salutation, String name) { |
256 | | - this.salutation = salutation; |
257 | | - this.name = name; |
258 | | - } |
259 | | - } |
260 | | - |
261 | | - public Greeting greet(String name) { |
262 | | - if (name == null || name.isEmpty()) |
263 | | - name = "World"; |
264 | | - |
265 | | - return new Greeting("Hello", name); |
266 | | - } |
267 | | - |
268 | | -} |
269 | | -``` |
270 | | - |
271 | | -Update your `func.yaml` to reference the new method: |
272 | | - |
273 | | -```yaml |
274 | | -cmd: com.example.fn.PojoFunction::greet |
275 | | -``` |
276 | | -
|
277 | | -Now run your new function: |
278 | | -
|
279 | | -```bash |
280 | | -$ fn run |
281 | | -... |
282 | | -{"name":"World","salutation":"Hello"} |
283 | | - |
284 | | -$ echo -n Michael | fn run |
285 | | -... |
286 | | -{"name":"Michael","salutation":"Hello"} |
287 | | -``` |
288 | | - |
289 | | -## 7. Where do I go from here? |
290 | | - |
291 | | -Learn more about the Fn Java FDK by reading the next tutorials in the series. |
292 | | -Also check out the examples in the [`examples` directory](examples) for some |
293 | | -functions demonstrating different features of the Fn Java FDK. |
294 | | - |
295 | | -### Configuring your function |
296 | | - |
297 | | -If you want to set up the state of your function object before the function is |
298 | | -invoked, and to use external configuration variables that you can set up with |
299 | | -the Fn tool, have a look at the [Function |
300 | | -Configuration](docs/FunctionConfiguration.md) tutorial. |
301 | | - |
302 | | -### Handling HTTP requests |
303 | | - |
304 | | -If your function serves an HTTP trigger you may want to access HTTP details such as request or response headers or the HTTP status , check out [Accessing HTTP Information From Functions](docs/HTTPGatewayFunctions.md). |
305 | | - |
306 | | -### Input and output bindings |
307 | | - |
308 | | -You have the option of taking more control of how serialization and |
309 | | -deserialization is performed by defining your own bindings. |
310 | | - |
311 | | -See the [Data Binding](docs/DataBinding.md) tutorial for other out-of-the-box |
312 | | -options and the [Extending Data Binding](docs/ExtendingDataBinding.md) tutorial |
313 | | -for how to define and use your own bindings. |
314 | | - |
315 | | -### Asynchronous workflows |
316 | | - |
317 | | -Suppose you want to call out to some other function from yours - perhaps |
318 | | -a function written in a different language, or even one maintained by |
319 | | -a different team. Maybe you then want to do some processing on the result. Or |
320 | | -even have your function interact asynchronously with a completely different |
321 | | -system. Perhaps you also need to maintain some state for the duration of your |
322 | | -function, but you don't want to pay for execution time while you're waiting for |
323 | | -someone else to do their work. |
324 | | - |
325 | | -If this sounds like you, then have a look at the [Fn Flow |
326 | | -quickstart](docs/FnFlowsUserGuide.md). |
| 24 | +Please see [CONTRIBUTING.md](CONTRIBUTING.md). |
327 | 25 |
|
328 | | -# Get help |
329 | 26 |
|
330 | | - * Come over and chat to us on the [fnproject Slack](https://join.slack.com/t/fnproject/shared_invite/enQtMjIwNzc5MTE4ODg3LTdlYjE2YzU1MjAxODNhNGUzOGNhMmU2OTNhZmEwOTcxZDQxNGJiZmFiMzNiMTk0NjU2NTIxZGEyNjI0YmY4NTA). |
331 | | - * Raise an issue in [our github](https://github.com/fnproject/fn-java-fdk/). |
332 | 27 |
|
333 | | -# Contributing |
334 | 28 |
|
335 | | -Please see [CONTRIBUTING.md](CONTRIBUTING.md). |
0 commit comments