Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/vladimir-dejanovic/java-in-fn-project
Examples for my talk Java in Serverless world with FN Project
https://github.com/vladimir-dejanovic/java-in-fn-project
examples fnproject java
Last synced: 19 days ago
JSON representation
Examples for my talk Java in Serverless world with FN Project
- Host: GitHub
- URL: https://github.com/vladimir-dejanovic/java-in-fn-project
- Owner: vladimir-dejanovic
- License: gpl-3.0
- Created: 2018-10-19T16:15:55.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2018-11-10T23:13:48.000Z (about 6 years ago)
- Last Synced: 2024-10-27T16:23:15.245Z (2 months ago)
- Topics: examples, fnproject, java
- Language: Java
- Size: 34.2 KB
- Stars: 3
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Java in Serverless world with FN Project
This are code examples for my talk *Java in Serverless world with FN Project*
In order to start this examples you need to have FN installed, https://fnproject.io/
All examples are developed by using bellow versions of FN server and client
```
$ fn version
Client version: 0.5.15
Server version: 0.3.595
```## Basic simple example of FN function in java language - branch init-0.1
To create fn function in Java programing language type this
```
$ fn init --runtime java --trigger http
```In my case I will call my function **function1**, so command becomes
```
$ fn init --runtime java --trigger http function1
```Let us exam what is generated for us by FN project
```
$ cd function1
$ find ../src/main/java/com/example/fn/HelloFunction.java
./src/test/java/com/example/fn/HelloFunctionTest.java
./pom.xml
./func.yaml
```If you check pom.xml you will see nothing special about it, it is plain pom.xml with some dependencies for fn-project, however this dependencies are needed only for testing purpose.
If this dependencies are removed, everything will still work without any issues, only unit tests will fail.If you open src/main/java/com/example/fn/HelloFunction.java you will see that it is very simple class
```
package com.example.fn;public class HelloFunction {
public String handleRequest(String input) {
String name = (input == null || input.isEmpty()) ? "world" : input;return "Hello, " + name + "!";
}}
```As you can see there is no real dependency on FN Project nowhere in the code. So you might ask your self how FN magic works.
In order to answer that question open func.yaml file```
$ cat func.yamlschema_version: 20180708
name: function1
version: 0.0.1
runtime: java
build_image: fnproject/fn-java-fdk-build:jdk9-1.0.75
run_image: fnproject/fn-java-fdk:jdk9-1.0.75
cmd: com.example.fn.HelloFunction::handleRequest
format: http-stream
triggers:
- name: function1-trigger
type: http
source: /function1-trigger
```- schema_version - schema version of fn project
- name - name of function
- version - version of function, it will be ramped up by default after every deployment
- runtime - language in which function is written, this is needed in order to know how to create fn function from code
- build_image - docker image used for building fn function
- run_image - docker image used for running fn function
- cmd - what is executed when request come for fn function
- triggers - here are defined triggers which can be used to invoke fn functionBy using this data, FN project can create fn function from our code although there are no dependencies in code it self.
### Starting & deploying FN function
In order to deploy our fn function and start using it, follow this steps.
First start FN Server by running this command
```
$ fn start
```Check that all is good by running this command
```
$ fn version
```
output should be something like this```
Client version: 0.5.15
Server version: 0.3.595```
After this in directory of your function run this command
```
$ fn deploy --app --local
```This will deploy function to FN Server.
Paramater **--local** means that function will be deployed to local instance of fn server, and docker image will not be pushed to Docker Hub. This is useful during development, so that you don't pollute your Docker HUB.Command, for example, should like this
```
$ fn deploy --app myapp1 --local
```Now we can invoke function by calling this command
```
$ fn invoke
```in my case it would be
```
$ fn invoke myapp1 function1```
### Unit Testing in FN Project
If you open src/test/java/com/example/fn/HelloFunctionTest.java, you will see how unit test is done in FN project
```
public class HelloFunctionTest {@Rule
public final FnTestingRule testing = FnTestingRule.createDefault();@Test
public void shouldReturnGreeting() {
testing.givenEvent().enqueue();
testing.thenRun(HelloFunction.class, "handleRequest");FnResult result = testing.getOnlyResult();
assertEquals("Hello, world!", result.getBodyAsString());
}}
```If you are experienced with JUnit tests, this shouldn't need any explanations.
Result is on branch **init-0.1**
## Updated unit test - branch init-0.2
Let us add one more unit test, where we will pass argument Developer.
Code for unit test is very similar to init unit test and it goes like this
```
@Test
public void testWithBody() {
testing.givenEvent().withBody("Developer").enqueue();
testing.thenRun(HelloFunction.class, "handleRequest");FnResult result = testing.getOnlyResult();
assertEquals("Hello, Developer!", result.getBodyAsString());
}
```Important part here is **withBody** which we use to pass parameter to our function.
Result is on branch **init-0.2**
## JSON as input and output - branch init-0.3
Added class Message, which is simple class with single field message of type String.
Lombok annotations are used to generate getter, setter and constructors.```
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Message {private String message;
}
```This class will be used as input and output of function instead of String that was used in previous example. Modification to function is minimal.
```
public Message handleRequest(Message input) {
String name = (input == null || input.getMessage().isEmpty()) ? "world" : input.getMessage();return new Message(message + ", " + name + "!");
}```
After deploying function we can invoke it in this way
```
$ echo "{\"message\":\"It works\"}" | fn invoke --content-type "application/json" myapp1 function1```
to invoke it via curl do this
```
$ curl -d '{"message":"Testing"}' http://localhost:8080/t/myapp1/function1-trigger
```Result is on branch **init-0.3**