Serverless com Fn Project
O projeto FN facilita a construção de plataformas serverless possibilitando o deploy de funções desenvolvidas em qualquer linguagem. Há ainda facilitadores que criam estrutura de projetos prontos em diversas linguagens, como Go, Ruby e Java. E Java, especificamente, ainda possui um framework (FN Java FDK) para facilitar o desenvolvimento.
Requisitos
Únicos pré-requisitos são ambiente Unix (Linux, Mac, etc.) e docker (17.10.0-ce ou superior) instalados. Para instalar o docker no Ubuntu Linux, siga o procedimento abaixo:
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu artful stable"
$ sudo apt update
$ sudo apt install docker-ce
Caso esteja utilizando Windows recomenda-se a utilização de uma máquina virtual, como o VirtualBox ou VMWare, para execução de um sistema operacional compatível.
Instalação
Valide se o docker está corretamente configurado:
$ docker --version
Se estiver corretamente configurado, deverá ser exibida a versão, algo como:
Docker version 18.03.1-ce, build 9ee9f40
Observação: dependendo da instalação do docker, pode ser necessário adicionar o comando sudo antes para executar com privilégios de administrador.
Para iniciar a instalação da plataforma Fn, basta executar o comando abaixo que será baixado o instalador e executado:
$ curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | sh
Se a instalação tiver ocorrido normalmente, um logotipo com a versão do projeto deverá ser exibido:
fn version 0.4.123
______
/ ____/___
/ /_ / __ \
/ __/ / / / /
/_/ /_/ /_/`
Para iniciar a plataforma, basta digitar:
$ fn start
Novamente, para iniciar a plataforma, pode também ser necessário utilizar o comando sudo. A própria plataforma FN utiliza imagens docker.
Caso queira utilizar outra porta, é possível informar por parâmetro:
$ fn start -p 8081
Quando não é utilizada a porta padrão (8080) é necessário informar qual porta será utilizada, através da variável de ambiente FN_API_URL:
export FN_API_URL=http://127.0.0.1:8081
Para testar a instalação, basta executar o comando:
$ fn version
Deverá ser exibido além da versão do cliente, também a versão do servidor da plataforma:
Client version: 0.4.123
Server version: 0.3.506
Com tanto o fn client quanto fn server devidamente configurados, podemos iniciar nosso primeiro projeto.
Iniciando um projeto
Para iniciar um projeto java, basta utilizar o comando
$ fn init --runtime java [NOME DO PROJETO]
Será criada uma estrutura para o projeto:
├── func.yaml
├── hello.iml
├── pom.xml
└── src
├── main
│ └── java
│ └── com
│ └── example
│ └── fn
│ └── HelloFunction.java
└── test
└── java
└── com
└── example
└── fn
└── HelloFunctionTest.java
Notem que toda estrutura já foi criada, inclusive com classe de exemplo, respectivo teste e ainda um pom.xmlconfigurado para build com o maven.
Ao verificar o código, é possível ver que é bastante simples tratar uma requisição:
package com.example.fn;
public class HelloFunction {
public String handleRequest(String input) {
String name = (input == null || input.isEmpty()) ? "world" : input;
return "Hello, " + name + "!";
}
}
Executando
Para executar o projeto como uma função dentro da plataforma FN, basta executar o comando
$ fn run
Observação: novamente cabe aqui alertar que dependendo da instalação que foi feita do docker, pode ser necessário preceder o comando por sudo.
Será então compilado o seu projeto e criada uma imagem com seu projeto, que será executado em seguida.
Se quiser passar um parâmetro, basta executar da seguinte maneira:
$ echo "Zeca" | fn run
E caso precise executar com sudo:
$ echo "Zeca" | sudo fn run
Estendendo funcionalidades
É possível facilmente tornar a funcionalidade mais completa, sem necessidade de novas dependências. Vamos ajustar a função para receber e retornar parâmetros JSON ao invés de simples Strings.
package com.example.fn;
public class HelloFunction {
public static class Person {
public String name;
}
public static class Result {
public boolean authorized;
}
public Result handleRequest(Person person) {
Result result = new Result();
result.authorized = person.name.equalsIgnoreCase("zeca");
return result;
}
}
Para visualizar qualquer erro de compilação, basta executar com a opção --verbose:
$ fn --verbose run
Lembrando que por ter alterado a assinatura do serviço, é necessário ajustar os testes também:
package com.example.fn;
import com.fnproject.fn.testing.*;
import org.junit.*;
import static org.junit.Assert.*;
public class HelloFunctionTest {
@Rule
public final FnTestingRule testing = FnTestingRule.createDefault();
@Test
public void shouldReturnGreeting() {
testing.givenEvent().withBody("{\"name\":\"Zeca\"}").enqueue();
testing.thenRun(HelloFunction.class, "handleRequest");
FnResult result = testing.getOnlyResult();
assertEquals("{\"authorized\":true}", result.getBodyAsString());
}
}
Deploy da imagem
Garanta que o build esteja funcionando corretamente:
$ fn build
Faça o deploy local da imagem:
$ fn deploy --local --app apps
Para executar, basta chamar através do protocolo http:
$ curl --data '{"name": "Zeca"}' http://localhost:8080/r/apps/myfunction
Siga em frente
Com isto temos uma primeira aplicação serverless configurada. Diversas áreas estão tirando proveito desta técnica que pode economizar recursos e ao mesmo tempo garantir a disponibilidade de uma funcionalidade acessada de forma não uniforme.
Este guia se baseou na documentação oficial do projeto. Seguem links:
- http://fnproject.io - Site do Projeto FN
- http://fnproject.io/tutorials - Tutoriais
- https://github.com/shaunsmith/functionslab - Guia Completo com exercícios e exemplos
- https://github.com/henriquebjr/myfunction - Modelo Java gerado automaticamente
Comentários
Postar um comentário