|
1 |
| -# Fn Java Functions Developer Kit (FDK) |
| 1 | +# Fn Java Functions Developer Kit - Docs and Examples |
2 | 2 | [](https://circleci.com/gh/fnproject/fdk-java)
|
3 | 3 |
|
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 9 |
6 |
| -as the default out of the box. |
| 4 | +This page provides links to docs and examples on how to use the Java Functions Development Kit (Java FDK) to develop applications. |
7 | 5 |
|
8 |
| -# FAQ |
9 |
| -Some common questions are answered in [our FAQ](../../fn/general/faq.md). |
| 6 | +## Docs |
| 7 | +* [Data Binding for function input and output](DataBinding.md) |
| 8 | +* [Extending the data binding functionality](ExtendingDataBinding.md) |
| 9 | +* [Function initialization and configuration](FunctionConfiguration.md) |
| 10 | +* [Accessing HTTP information From functions](HTTPGatewayFunction.md) |
| 11 | +* [Spring cloud functions with Fn](SpringCloudFunctionSupport.md) |
| 12 | +* [Testing your functions](TestingFunctions.md) |
10 | 13 |
|
11 |
| -# Quick Start Tutorial |
| 14 | +## Examples |
| 15 | +* To be Linked |
12 | 16 |
|
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. |
| 17 | +## Develop the Java FDK |
| 18 | +If wish to contribute to the Java FDK development see our [Contributing to Fn Guide](https://github.com/fnproject/fn/tree/master/docs#for-contributors). |
15 | 19 |
|
16 |
| -## Pre-requisites |
| 20 | +For details on the Java FDK Development see the [Java FDK Repo](https://github.com/fnproject/fdk-java). |
17 | 21 |
|
18 |
| -Before you get started you will need the following things: |
19 |
| - |
20 |
| -* The [Fn CLI](https://github.com/fnproject/cli) tool |
21 |
| -* [Docker-ce 17.06+ installed locally](https://docs.docker.com/engine/installation/) |
22 |
| - |
23 |
| -### Install the Fn CLI tool |
24 |
| - |
25 |
| -To install the Fn CLI tool, just run the following: |
26 |
| - |
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 9. 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 funciton 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](../../fn/develop/func-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:jdk9-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 |
| -### 5. Run using HTTP and the local Fn server |
181 |
| -The previous example used `fn run` to run a function directly via docker, you |
182 |
| -can also use the Fn server locally to test the deployment of your function and |
183 |
| -the HTTP calls to your functions. |
184 |
| - |
185 |
| -Open another terminal and start the Fn server: |
186 |
| - |
187 |
| -```bash |
188 |
| -$ fn start |
189 |
| -``` |
190 |
| - |
191 |
| -Then in your original terminal create an app: |
192 |
| - |
193 |
| -```bash |
194 |
| -$ fn create app java-app |
195 |
| -Successfully created app: java-app |
196 |
| -``` |
197 |
| - |
198 |
| -Now deploy your Function using the `fn deploy` command. This will bump the |
199 |
| -function's version up, rebuild it, and push the image to the Docker registry, |
200 |
| -ready to be used in the function deployment. Finally it will create a route on |
201 |
| -the local Fn server, corresponding to your function. |
202 |
| - |
203 |
| -We are using the `--local` flag to tell fn to skip pushing the image anywhere |
204 |
| -as we are just going to run this on our local fn server that we started with |
205 |
| -`fn start` above. |
206 |
| - |
207 |
| -```bash |
208 |
| -$ fn deploy --app java-app --local |
209 |
| -... |
210 |
| -Bumped to version 0.0.2 |
211 |
| -Building image hello:0.0.2 |
212 |
| -Sending build context to Docker daemon 14.34kB |
213 |
| - |
214 |
| -... |
215 |
| - |
216 |
| -Successfully built bf2b7fa55520 |
217 |
| -Successfully tagged your_dockerhub_account/hello:0.0.2 |
218 |
| -Updating route /hello-java-function using image your_dockerhub_account/hello:0.0.2... |
219 |
| -``` |
220 |
| - |
221 |
| -Call the Function via the Fn CLI: |
222 |
| - |
223 |
| -```bash |
224 |
| -$ fn call java-app /hello-java-function |
225 |
| -Hello, world! |
226 |
| -``` |
227 |
| - |
228 |
| -You can also call the Function via curl: |
229 |
| - |
230 |
| -```bash |
231 |
| -$ curl http://localhost:8080/r/java-app/hello-java-function |
232 |
| -Hello, world! |
233 |
| -``` |
234 |
| - |
235 |
| -### 6. Something more interesting |
236 |
| -The Fn Java FDK supports [flexible data binding](DataBinding.md) to make |
237 |
| -it easier for you to map function input and output data to Java objects. |
238 |
| - |
239 |
| -Below is an example to of a Function that returns a POJO which will be |
240 |
| -serialized to JSON using Jackson: |
241 |
| - |
242 |
| -```java |
243 |
| -package com.example.fn; |
244 |
| - |
245 |
| -public class PojoFunction { |
246 |
| - |
247 |
| - public static class Greeting { |
248 |
| - public final String name; |
249 |
| - public final String salutation; |
250 |
| - |
251 |
| - public Greeting(String salutation, String name) { |
252 |
| - this.salutation = salutation; |
253 |
| - this.name = name; |
254 |
| - } |
255 |
| - } |
256 |
| - |
257 |
| - public Greeting greet(String name) { |
258 |
| - if (name == null || name.isEmpty()) |
259 |
| - name = "World"; |
260 |
| - |
261 |
| - return new Greeting("Hello", name); |
262 |
| - } |
263 |
| - |
264 |
| -} |
265 |
| -``` |
266 |
| - |
267 |
| -Update your `func.yaml` to reference the new method: |
268 |
| - |
269 |
| -```yaml |
270 |
| -cmd: com.example.fn.PojoFunction::greet |
271 |
| -``` |
272 |
| -
|
273 |
| -Now run your new function: |
274 |
| -
|
275 |
| -```bash |
276 |
| -$ fn run |
277 |
| -... |
278 |
| -{"name":"World","salutation":"Hello"} |
279 |
| - |
280 |
| -$ echo -n Michael | fn run |
281 |
| -... |
282 |
| -{"name":"Michael","salutation":"Hello"} |
283 |
| -``` |
284 |
| - |
285 |
| -## 7. Where do I go from here? |
286 |
| - |
287 |
| -Learn more about the Fn Java FDK by reading the next tutorials in the series. |
288 |
| -Also check out the examples in the [`examples` directory](examples) for some |
289 |
| -functions demonstrating different features of the Fn Java FDK. |
290 |
| - |
291 |
| -### Configuring your function |
292 |
| - |
293 |
| -If you want to set up the state of your function object before the function is |
294 |
| -invoked, and to use external configuration variables that you can set up with |
295 |
| -the Fn tool, have a look at the [Function |
296 |
| -Configuration](FunctionConfiguration.md) tutorial. |
297 |
| - |
298 |
| -### Input and output bindings |
299 |
| - |
300 |
| -You have the option of taking more control of how serialization and |
301 |
| -deserialization is performed by defining your own bindings. |
302 |
| - |
303 |
| -See the [Data Binding](DataBinding.md) tutorial for other out-of-the-box |
304 |
| -options and the [Extending Data Binding](ExtendingDataBinding.md) tutorial |
305 |
| -for how to define and use your own bindings. |
306 |
| - |
307 |
| -### Asynchronous workflows |
308 |
| - |
309 |
| -Suppose you want to call out to some other function from yours - perhaps |
310 |
| -a function written in a different language, or even one maintained by |
311 |
| -a different team. Maybe you then want to do some processing on the result. Or |
312 |
| -even have your function interact asynchronously with a completely different |
313 |
| -system. Perhaps you also need to maintain some state for the duration of your |
314 |
| -function, but you don't want to pay for execution time while you're waiting for |
315 |
| -someone else to do their work. |
316 |
| - |
317 |
| -If this sounds like you, then have a look at the [Fn Flow |
318 |
| -quickstart](https://github.com/fnproject/fdk-java/blob/master/docs/FnFlowsUserGuide.md). |
319 |
| - |
320 |
| -# Get help |
321 |
| - |
322 |
| - * Come over and chat to us on the [fnproject Slack](https://join.slack.com/t/fnproject/shared_invite/enQtMjIwNzc5MTE4ODg3LTdlYjE2YzU1MjAxODNhNGUzOGNhMmU2OTNhZmEwOTcxZDQxNGJiZmFiMzNiMTk0NjU2NTIxZGEyNjI0YmY4NTA). |
323 |
| - * Raise an issue in [our github](https://github.com/fnproject/fn-java-fdk/). |
324 |
| - |
325 |
| -# Contributing |
326 |
| - |
327 |
| -Please see "[For Contributers](https://github.com/fnproject/fn/tree/master/docs#for-contributors)". |
0 commit comments