| :index-group: Serverless |
| :jbake-type: page |
| :jbake-status: status=published |
| = Serverless Builder API |
| |
| A API `Server.Builder` permite que você construa uma instância embutida(embedded) ou sem servidor(serverless) de Tomcat/TomEE dentro da sua JVM, efetivamente executando Tomcat/TomEE como uma biblioteca simples. |
| |
| [source,java] |
| ---- |
| import org.apache.tomee.bootstrap.Server; |
| |
| public class Main { |
| public static void main(String[] args) { |
| final Server server = Server.builder().build(); |
| |
| System.out.println("Listening for requests at " + server.getURI()); |
| } |
| } |
| ---- |
| |
| O design da API pode ser melhor descrito como uma API de construtor funcional (FBA) e permite efetivamente fornecer funções e referências de método que realmente auxiliam no processo de construção do servidor. É por meio dessas funções que você pode implantar aplicativos, modificar configurações e executar com eficácia qualquer código de que você precisa para ajudar a preparar a instância do servidor. |
| |
| Uma visão geral de alto nível dos métodos builder disponíveis após chamar `Server.builder ()` são os seguintes: |
| |
| [source,java] |
| ---- |
| public static class Builder |
| public Builder httpPort(final int port) |
| public Builder ajpPort(final int port) |
| public Builder add(final String name, final byte[] bytes) |
| public Builder add(final String name, final Supplier<byte[]> content) |
| public Builder add(final String name, final String content) |
| public Builder add(final String name, final File content) |
| public Builder add(final String name, final Archive contents) |
| public Builder home(final Consumer<File> customization) |
| public Builder and(final Consumer<Builder> consumer) |
| public Server build() |
| ---- |
| |
| Para realmente saber como usar a API, primeiramente devemos entender os conceitos `catalina.home` e `catalina.base` do Tomcat e o que realmente acontece quando chamamos `Server.builder().Build()`. |
| |
| === Compreendendo a home e base do Tomcat |
| |
| É um fato pouco conhecido que por décadas o Tomcat teve a capacidade de executar várias instâncias a partir de um único zip do Tomcat. O Tomcat usa uma variável `catalina.home` para identificar a localização do zip extraído onde as bibliotecas do servidor podem ser encontradas e um `catalina.base` por instância para definir a localização dos arquivos de configuração, arquivos de log e aplicativos da web dessa instância. |
| |
| Em nossa situação, seu classpath JVM é efetivamente o `catalina.home` e quando usamos a API do `Server` estamos criando um `catalina.base` muito fino que contém os arquivos de configuração, arquivos de log e webapps para essa instância de servidor construído (Tomcat). Se você usar a API `Server` dez vezes na mesma JVM, terá 10 diretórios ` catalina.base`. No entanto, eles são considerados locais de trabalho temporários e serão excluídos na saída da JVM. |
| |
| === Chamando o `Server.builder().build()` |
| |
| Quando o método `build()` do `Server.Builder` é chamado, as seguintes ações são realizadas nesta ordem: |
| |
| 1. Quaisquer funções adicionadas via `and(final Consumer<Builder> consumer)` são executadas. Isso permite que seja fornecida uma função que modifique ainda mais o construtor antes de qualquer construção ser executada. Várias modificações do construtor podem ser agrupadas em uma função que as instala todas. |
| 1. É criado um diretório temporário que servirá como `catalina.home` e `catalina.base` e as configurações padrão como `server.xml`,`logging.properties` e `tomee.xml` são copiadas. |
| 1. AQuaisquer funções adicionadas por meio de `add(final String destinationPath, final Supplier<byte[]> content)` são executadas e quaisquer bytes fornecidos, Strings ou Arquivos são gravados em `destinationPath` dentro do diretório temporário. Isso permite que as configurações padrão como `server.xml` sejam sobrescritas ou aplicativos sejam escritos no diretório `webapps/`. |
| 1. As portas são definidas modificando-se `conf/server.xml`. Se `httpPort` não foi definido, as portas serão aleatórias. |
| 1. Todas as funções adicionadas via `home(final Consumer<File> customization)` são executadas. O diretório temporário será fornecido como o valor de `File`. |
| 1. A instância Tomcat/TomEE é iniciada e retornada como uma instância de `Server`. |
| |
| === Vendo o resultado de `Server.builder().Build()` |
| |
| Ajuda muito poder ver o que foi construído. Podemos fazer isso instalando uma referência de função ou método como mostrada abaixo. |
| |
| [source,java] |
| ---- |
| import org.apache.tomee.bootstrap.Server; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.UncheckedIOException; |
| import java.nio.file.Files; |
| import java.nio.file.Path; |
| import java.util.stream.Stream; |
| |
| public class Main { |
| |
| public static void main(String[] args) { |
| Server.builder() |
| .home(Main::list) |
| .build(); |
| } |
| |
| private static void list(final File home) { |
| try { |
| Files.walk(home.toPath()) |
| .sorted() |
| .forEach(System.out::println); |
| } catch (IOException e) { |
| throw new UncheckedIOException(e); |
| } |
| } |
| } |
| ---- |
| |
| Quando o executamos, devemos ver uma saída semelhante a esta: |
| |
| [source,console] |
| ---- |
| /var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee |
| /var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf |
| /var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/catalina.policy |
| /var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/catalina.properties |
| /var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/context.xml |
| /var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/jaspic-providers.xml |
| /var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/jaspic-providers.xsd |
| /var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/logging.properties |
| /var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/server.xml |
| /var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/system.properties |
| /var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/tomcat-users.xml |
| /var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/tomcat-users.xsd |
| /var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/tomee.xml |
| /var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/conf/web.xml |
| /var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/logs |
| /var/folders/bd/f9ntqy1m8xj_fs006s6crtjh0000gn/T/temp9107162877421339516dir/apache-tomee/webapps |
| ---- |
| |
| O acima representa o que sai da caixa ao chamar `Server.builder().Build()` sem modificações. |
| |
| == Criação de aplicativos com `Archive` |
| |
| A segunda classe a aprender é `Archive` e é essencialmente um construtor de aplicativos simples. Com essa abordagem, todas as suas classes já estão efetivamente no classpath e visíveis, portanto, em última análise, as únicas classes que precisam ser incluídas são Servlets anotados, EJBs, CDI Beans, classes JAX-RS, etc. |
| |
| [source,java] |
| ---- |
| public class Archive |
| public static Archive archive() |
| public Archive manifest(final String key, final Object value) |
| public Archive manifest(final String key, final Class value) |
| public Archive add(final String name, final byte[] bytes) |
| public Archive add(final String name, final Supplier<byte[]> content) |
| public Archive add(final String name, final String content) |
| public Archive add(final String name, final File content) |
| public Archive add(final String name, final Archive archive) |
| public Archive add(final String name, final URL content) |
| public Archive add(final Class<?> clazz) |
| public Archive addDir(final File dir) |
| public Archive addJar(final File file) |
| public File toJar() |
| public File toJar(final File file) |
| public File toDir() |
| public void toDir(final File dir) |
| ---- |
| |
| NOTE: Você pode usar APIs como ShrinkWrap para construir os jars e arquivos war como uma alternativa para `Archive`. Qualquer coisa que possa produzir um arquivo jar, um arquivo war ou uma estrutura de diretório war explodida (descompactada) funcionará. |
| |
| === Creating a ROOT war |
| |
| Neste exemplo, estamos efetivamente adicionando três classes a um `Archive` que é adicionado a um novo diretório `webapps/ROOT/WEB-INF/classes`. |
| |
| [source,java] |
| ---- |
| import org.apache.tomee.bootstrap.Archive; |
| import org.apache.tomee.bootstrap.Server; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.UncheckedIOException; |
| import java.nio.file.Files; |
| |
| public class Main { |
| |
| public static void main(String[] args) { |
| |
| final Server server = Server.builder() |
| .add("webapps/ROOT/WEB-INF/classes", Archive.archive() |
| .add(Api.class) |
| .add(Movie.class) |
| .add(MovieService.class)) |
| .home(Main::list) |
| .build(); |
| |
| System.out.println("Listening for requests at " + server.getURI()); |
| } |
| |
| private static void list(final File home) { |
| try { |
| Files.walk(home.toPath()) |
| .map(Path::toFile) |
| .filter(File::isFile) |
| .map(File::getAbsolutePath) |
| .map(s -> "..." + s.substring(49)) |
| .sorted() |
| .forEach(System.out::println); |
| } catch (IOException e) { |
| throw new UncheckedIOException(e); |
| } |
| } |
| } |
| ---- |
| |
| Quando isso for executado, veremos o método `Main.list`, que é executado logo antes do início do servidor, imprimirá o seguinte: |
| |
| [source,console] |
| ---- |
| ...temp710654453954858189dir/apache-tomee/conf/catalina.policy |
| ...temp710654453954858189dir/apache-tomee/conf/catalina.properties |
| ...temp710654453954858189dir/apache-tomee/conf/context.xml |
| ...temp710654453954858189dir/apache-tomee/conf/jaspic-providers.xml |
| ...temp710654453954858189dir/apache-tomee/conf/jaspic-providers.xsd |
| ...temp710654453954858189dir/apache-tomee/conf/logging.properties |
| ...temp710654453954858189dir/apache-tomee/conf/server.xml |
| ...temp710654453954858189dir/apache-tomee/conf/system.properties |
| ...temp710654453954858189dir/apache-tomee/conf/tomcat-users.xml |
| ...temp710654453954858189dir/apache-tomee/conf/tomcat-users.xsd |
| ...temp710654453954858189dir/apache-tomee/conf/tomee.xml |
| ...temp710654453954858189dir/apache-tomee/conf/web.xml |
| ...temp710654453954858189dir/apache-tomee/webapps/ROOT/WEB-INF/classes/org/superbiz/movie/Api.class |
| ...temp710654453954858189dir/apache-tomee/webapps/ROOT/WEB-INF/classes/org/superbiz/movie/Movie.class |
| ...temp710654453954858189dir/apache-tomee/webapps/ROOT/WEB-INF/classes/org/superbiz/movie/MovieService.class |
| ---- |