Preparing a WebHook in Fn

The Fn Project works best with functions written in Java. When calling a function, the framework would be able to automatically transform the body of the request as a parameter of the entrypoint method. In the following example, the JSON from the request will be converted into a string for the handleRequest method, the entrypoint method of this Fn function:

public Object handleRequest(String body) {
if (body == null || body.isEmpty()) {
body = "{}";
}
Input input;
try {
val mapper = new ObjectMapper();
input = mapper.readValue(body, Input.class);
} catch (IOException e) {
return new Error(e.getMessage());
}
if (input == null) {
return new Error(body);
}
/* process the rest of business logic */
}

Here's the list of data transfer object (DTO) classes to properly encode and decode Parse's WebHook messages inside an Fn function. With help from Project Lombok and Jackson, we can dramatically reduce numbers of lines of code. An Input object is the wrapper for a Java's Transfer object, that contains all columns similar to the Transfer class, which we have defined on the Parse platform.

Please note that we have a Transfer class on both sides of the system, on the Parse platform, and also on the Fn platform.

The Success and Error class are for returning processing results back to Parse:

@Data
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Input {
private Transfer object;
}

@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Transfer {
private String objectId;
private String from;
private String to;
private Double amount;
private Boolean sent;
private Boolean processed;
}

@Data
@AllArgsConstructor
public static class Success {
private Transfer success;
}

@Data
@AllArgsConstructor
public static class Error {
private String error;
}

As it is a Java project, we do not need to build it inside the container. Here's the Gradle build file, which could be built using the gradle installDist command:

plugins {
id 'io.franzbecker.gradle-lombok' version '1.11'
id 'java'
id 'groovy'
id 'application'
}

mainClassName = 'App'

dependencies {
// FN Project
compile 'com.fnproject.fn:api:1.0.56'

// JSON encoding
compile 'com.fasterxml.jackson.core:jackson-annotations:2.9.4'
compile 'com.fasterxml.jackson.core:jackson-databind:2.9.4'

// REST client
compile 'com.squareup.okhttp3:okhttp:3.9.1'

// Simplify Java syntax
compile group: 'org.projectlombok', name: 'lombok-maven',
version: '1.16.20.0', ext: 'pom'

// Ethereum Client
compile 'org.web3j:core:3.2.0'

// Testing
testCompile 'com.fnproject.fn:testing:1.0.56'
testCompile 'junit:junit:4.12'
testCompile 'org.codehaus.groovy:groovy-all:2.4.12'
testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
}

repositories {
mavenCentral()
jcenter()
maven {
url "https://dl.bintray.com/fnproject/fnproject"
}
}

The following is the Dockerfile to build an image for the Fn Project. It needs to inherit from fn-java-fdk. We use jdk9-1.0.56 for the demo in this book. What you do is copy all JAR files from the build directory to the /function/app inside the container image:

FROM fnproject/fn-java-fdk:jdk9-1.0.56

WORKDIR /function

COPY ./build/install/routing_fn/lib/*.jar /function/app/

CMD ["com.example.fn.TransferFunction::handleRequest"]

The following steps are to prepare the Fn server, and then we build our function with the gradle command. Then we build and push its Docker image onto the hub before redefining it as an Fn route.

First, we deploy an Fn Server manually with the following docker run command. Also, we attach Fn to the parse_net. There is a special hack to Fn so that we can make every container started by Fn be in the same network, as specified by FN_NETWORK there:

docker run 
--name fnserver
--detach
-v /var/run/docker.sock:/var/run/docker.sock
-v fn_vol:/app/data
-p 28080:8080
--network=parse_net
--network-alias=fn_gateway
-e FN_LOG_LEVEL=debug
-e FN_NETWORK=parse_net
fnproject/fnserver

Here's the build and push script. Save the following scripts as ./buildAndPush:

./gradlew installDist

VERSION=$1

docker build -t chanwit/routing_fn:$VERSION .
docker push chanwit/routing_fn:$VERSION

fn routes delete demo /routing_fn
fn routes create /routing_fn -i chanwit/routing_fn:$VERSION demo

Then we can start the build and push process by calling the script with a certain version number, as in the following:

./buildAndPush v1

In the next section, we will discuss how the WebHook function looks up account data from a blockchain and how we can track the states of each money transfer transaction.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset