Skip to content

Latest commit

 

History

History
733 lines (585 loc) · 29.9 KB

README.pt-br.md

File metadata and controls

733 lines (585 loc) · 29.9 KB
drawing

REST API Java Version Spring Boot Version License

Leia esse documento em outro idioma: Inglês, Português

O FileHub é um serviço que padroniza o gerenciamento de arquivos, independente da plataforma de armazenamento utilizada. Além disso, ele facilita a persistência de arquivos em mais de uma plataforma de armazenamento, servindo como gateway de requisições, de forma segura e prática.

Seções

Configuração

         O FileHub utiliza um arquivo de configuração XML, onde são definidas as propriedades e como o serviço irá se comportar. Este arquivo poderá ser criado localmente onde o serviço será executado ou remotamente em um repositório Git.

         Para informar ao serviço onde está o arquivo de configuração, utiliza-se as seguintes variáveis de ambiente:

* Informação Obrigatória
Nome da variável Descrição
CONFIG_TYPE * Define se o arquivo está localizado localmente ou remotamente.
Valor padrão: LOCAL_FILE
Valores possíveis:
  • LOCAL_FILE
  • GIT_FILE
  • LOCAL_FILE_PATH Caminho do arquivo no Sistema Operacional
    Exemplo: C:/filehub/example.xml
    CONFIG_GIT_FILE_PATH Endereço do arquivo no repositório Git
    Obs: Use a URL raw do arquivo no repositório (texto plano) (plain text)
    CONFIG_GIT_FILE_TOKEN Token de autenticação do repositório Git
    MAX_FILE_SIZE Tamanho máximo do arquivo.
    Valor padrão: 7000000000
    MAX_REQUEST_SIZE Tamanho máximo da requisição.
    Valor padrão: 7000000000

    Conceitos

             Antes de executar o serviço é necessário definir quais plataformas de armazenamento serão utilizadas, além de configurar os parâmetros de acesso de cada plataforma de forma independente. Para isso o FileHub utiliza um arquivo XML que será lido quando o serviço iniciar. Nele existem elementos que irão determinar como o FileHub irá processar as requisições. Cada elemento é descrito a seguir:

    Storage

             É o elemento que representa uma plataforma de armazenamento. Um storage possui um ID para identificá-lo no sistema e um tipo. Cada tipo corresponde a um serviço ou plataforma de armazenamento, como por exemplo, um servidor FTP, um serviço em cloud como o S3 da AWS ou um diretório do servidor onde o FileHub está sendo executado, ou seja, cada tipo de storage possui suas propriedades para acesso e especificações.

             No arquivo de configuração os storages são definidos dentro da tag storages, como no exemplo abaixo:

    <filehub>
       <storages>
           <storage id="S3-Test" type="AWS_S3">
               <region>us-east-2</region>
               <secretKeyId>G5HG4G66RDYIYE1</secretKeyId>
               <secretKey>6F51E6f1e6F7A2E4F761F61fd51s1F</secretKey>
               <bucket>test</bucket>
           </storage>
           <storage id="FileSystem-Test" type="FILE_SYSTEM">
               <baseDir>C:\Users\user\filehub</baseDir>
           </storage>
       </storages>
    </filehub>

    Exemplo de declaração de storage


             Todo elemento storage possui um ID e um type. O ID irá identificar o storage e o type irá definir quais as propriedades de configuração o storage possui. Os tipos de storages são listados a seguir:

    drawing
    Local File System
    Define um diretório do servidor onde o FileHub está sendo executado como storage.
    Type: FILE_SYSTEM
    Propriedades:
  • baseDir: diretório raiz
  • drawing
    Amazon S3
    Define um bucket do serviço S3 da AWS como storage.
    Type: AWS_S3
    Propriedades:
  • region: região onde o S3 está localizado (e.g.: sa-east-1)
  • secretKeyId: ID do usuário no IAM
  • secretKey: código do secret do usuário no IAM
  • bucket: nome do bucket do S3
  • baseDir: diretório raiz
  • drawing
    Google Cloud Storage
    Cria um link com um bucket do google cloud storage
    Type: GOOGLE_CLOUD
    Propriedades:
  • jsonCredentials: Objeto JSON gerado por uma conta de serviço
    (APIs e serviços > Credenciais > Contas de serviço > Chaves)
    Faça o download do arquivo da chave, copie o conteúdo do arquivo (objeto JSON) e cole dentro da tag jsonCredentials
  • bucket: nome do bucket do storage
  • baseDir: diretório raiz
  • drawing
    Dropbox
    Cria um link com uma conta do dropbox
    Type: DROPBOX
    Limitação da Integração: A operação de atualização do token não foi implementada. É necessário gerar um token toda vez que for utilizar esse tipo de storage.
    Limitação da Integração:
  • Access Token: A operação de atualização do token não foi implementada. É necessário gerar um token toda vez que for utilizar esse tipo de storage.
  • Tamanho dos arquivosFile Size: O tamanho máximo do arquivo é de 150 Mb. Operações com arquivos maiores são irão funcionar.
  • Propriedades:
  • accessToken: token de acesso
  • baseDir: diretório raiz
  • Schema

             Um schema representa um conjunto de storages. Ao realizar qualquer operação no FileHub, seja de upload ou download, será necessário informar qual o schema que deverá ser considerado. Em outras palavras, o serviço FileHub não realiza operações diretamente em um elemento Storage, mas sim em um schema que representa um ou mais storages.

             Os schemas são declarados dentro da tag schemas, sendo possível a declaração de mais de um schema. Todo registro de schema possui um name que será o identificador do mesmo nas requisições realizadas no FileHub. Para vincular os storages a determinado schema utilizamos a tag storage-id. O exemplo abaixo mostra como fica uma configuração de um schema que possui dois storages vinculados.

    <filehub>
        <storages>
            <storage id="S3-Test" type="AWS_S3">
                <region>us-east-2</region>
                <secretKeyId>G5HG4G66RDYIYE1</secretKeyId>
                <secretKey>6F51E6f1e6F7A2E4F761F61fd51s1F</secretKey>
                <bucket>test</bucket>
            </storage>
            <storage id="FileSystem-Test" type="FILE_SYSTEM">
                <baseDir>C:\Users\user\filehub</baseDir>
            </storage>
        </storages>
        <schemas>
            <schema name="MySchema">
                <storage-id>FileSystem-Test</storage-id>
                <storage-id>S3-Test</storage-id>
            </schema>
        </schemas>
    </filehub>

    Exemplo de declaração de schema


    Schemas Auto Gerados

             Não é necessário declarar um schema para cada storage caso exista a necessidade de realizar operações nos storages de forma individual. É possível fazer com que o FileHub realize a leitura do arquivo de configuração, criando um schema para cada storage existente. Para isso, utilize o atributo generate-schema, informando como valor, o nome do schema que deverá ser criado. Veja o exemplo abaixo:

    <filehub>
        <storages>
            <storage id="S3-Test" type="AWS_S3" generate-schema="s3test">
                <region>us-east-2</region>
                <secretKeyId>G5HG4G66RDYIYE1</secretKeyId>
                <secretKey>6F51E6f1e6F7A2E4F761F61fd51s1F</secretKey>
                <bucket>test</bucket>
            </storage>
            <storage id="FileSystem-Test" type="FILE_SYSTEM">
                <baseDir>C:\Users\user\filehub</baseDir>
            </storage>
        </storages>
    </filehub>

    Exemplo de geração de schema diretamente no storage


             Utilize o atributo generate-schema no elemento storages caso seja necessário criar um schema com todos os storages existentes. Veja o exemplo abaixo:

    <filehub>
        <storages generate-schema="all">
            <storage id="S3-Test" type="AWS_S3">
                <region>us-east-2</region>
                <secretKeyId>G5HG4G66RDYIYE1</secretKeyId>
                <secretKey>6F51E6f1e6F7A2E4F761F61fd51s1F</secretKey>
                <bucket>test</bucket>
            </storage>
            <storage id="FileSystem-Test" type="FILE_SYSTEM">
                <baseDir>C:\Users\user\filehub</baseDir>
            </storage>
        </storages>
    </filehub>

    Exemplo de geração de schema com todos os storages existentes


    Warning Se um schema auto gerado foi criado sem uma trigger default configurada, o schema não terá nenhum tipo de segurança.


    Trigger

             Triggers são utilizadas para garantir a segurança das operações. Funcionam como web hooks que irão validar se determinada operação está autorizada ou não por sua aplicação.

             O elemento trigger possui um ID para identificação e também um atributo action, que poderá assumir dois valores possíveis:

    1. ALL: irá considerar a trigger para qualquer tipo de operação, seja de escrita (upload/criação/exclusão) ou leitura (download);
    2. UPDATE: a trigger só será aplicada para operações de escrita (upload/criação/exclusão).

    Warning O termo default é um valor especial e não pode ser utilizado como ID para uma trigger.


             Ao configurar uma trigger três propriedades deverão ser informadas:

    1. header: é o nome do header que deverá ser enviado ao serviço de autorização.
    2. url: é o endpoint do serviço que irá validar se a requisição é válida ou não. Seu objetivo é verificar se o valor do header é válido. Caso a requisição enviada para este endpoint retornar um código HTTP diferente de 200 (OK) a operação é cancelada.
    3. http-method (optional): define qual o tipo do método HTTP utilizado na requisição (GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS). O valor padrão é GET.

             No XML de configuração as triggers são definidas dentro da tag triggers. Uma trigger deverá ser vinculada a um schema. Esse vínculo é criado através do atributo trigger do schema, isso faz com que todos os storages do schema passem a considerar a trigger em suas operações.

             Para deixar mais claro, considere o seguinte exemplo de configuração:

    <filehub>
        <storages>
            <storage id="example" type="FILE_SYSTEM">
                <baseDir>C:\Users\user\filehub</baseDir>
            </storage>
        </storages>
        <trigger id="user-auth" action="ALL">
            <url>http://10.0.0.10:8080/auth</url>
            <header>myheader</header>
            <http-method>GET</http-method>
        </trigger>
        <schemas>
            <schema name="test" trigger="user-auth">
                <storage-id>example</storage-id>
            </schema>
        </schemas>
    </filehub>

    Exemplo de declaração de trigger


             Observe que a trigger user-auth foi criada e o schema test faz o uso da mesma, ou seja, cada operação realizada para o storage example irá chamar a trigger para verificação de autorização.

             O fluxograma abaixo apresenta o processo considerando a operação de upload para a configuração anterior.

    drawing

    Fluxograma de upload de arquivo com trigger

             A aplicação que consome o serviço FileHub deverá enviar o header configurado na trigger com um valor, ao receber a requisição, o FileHub irá chamar o endpoint configurado na trigger repassando o header para que o serviço de autorização faça a devida validação. Um token JWT é um bom exemplo do uso desse processo.

             Quando uma trigger realiza uma request para a URL configurada, ela enviará as seguintes informações no corpo da requisição (request body):

    • schema: o nome do schema selecionado na operação
    • operation: o tipo de operação está sendo executada (CREATE_DIRECTORY, RENAME_DIRECTORY, DELETE_DIRECTORY, LIST_FILES, EXIST_DIRECTORY, UPLOAD_MULTIPART_FILE, UPLOAD_BASE64_FILE, DOWNLOAD_FILE, DELETE_FILE, EXIST_FILE, GET_FILE_DETAILS)
    • path: o caminho informado
    • filenames: uma lista com os nomes dos arquivos que estão sendo manipulados na operação

             O seguinte JSON mostra um exemplo desse request body:

    {
            "schema": "test", 
            "operation": "UPLOAD_MULTIPART_FILE", 
            "path": "/accounts/users/avatar/", 
            "filenames": [ "MyAvatar.jpeg" ]
    }

             Outra função das triggers é permitir a criação de caminhos customizáveis para os arquivos. Para deixar mais claro essa função da trigger, imagine um sistema onde cada usuário possui um diretório para armazenar suas imagens, teríamos URLs semelhantes a seguinte lista:

    • /schema/example/user/paul/photo01
    • /schema/example/user/paul/photo02
    • /schema/example/user/john/photo01
    • /schema/example/user/john/photo02
    • /schema/example/user/john/photo03

             Observe que para realizar uma operação de upload ou download, a aplicação que irá consumir o FileHub deverá gerenciar os identificadores dos usuários logados. Porém, se essa aplicação consumidora for uma interface web, seria possível alterar esse identificador, comprometendo a segurança no acesso aos arquivos gerenciados pelo FileHub. Para contornar esse problema existe a possibilidade do endpoint configurado na trigger, retornar uma lista de parâmetros que deverão ser utilizados para substituir partes da URL nas operações. O diagrama de sequência a seguir mostra esse processo:

    drawing

    Diagrama de sequência do processo de comunicação com trigger

             Note que o parâmetro retornado da resposta do Authorization Service deverá ter o mesmo nome que o parâmetro informado na URL da operação ($user = user).


    Note O nome do arquivo também pode ser alterado pelo retorno da requisição através do parâmetro chamado filename.

    Warning Caso uma trigger esteja configurada com o atributo action como UPDATE e o header de autorização configurado, seja enviado na requisição, a trigger irá chamar o endpoint configurado.


    Trigger Padrão

             Existe a possibilidade de criar uma trigger que será chamada em todos os schemas que não definirem uma trigger de forma explícita. Para isso, utiliza-se o atributo default na trigger como mostrado no exemplo abaixo:

    <filehub>
        <storages>
            <storage id="example" type="FILE_SYSTEM">
                <baseDir>C:\Users\user\filehub</baseDir>
            </storage>
        </storages>
        <trigger id="user-auth" action="ALL" default="true">
            <url>http://10.0.0.10:8080/auth</url>
            <header>myheader</header>
            <http-method>GET</http-method>
        </trigger>
    </filehub>

    Exemplo de trigger padrão


    Operações

             Após o entendimento dos principais conceitos do FileHub, o próximo passo é saber quais as possíveis operações que podem ser executadas pelo serviço.

    Diretórios

             Os diretórios podem ser vistos como uma forma de agrupar e organizar os arquivos. A maioria dos storages tratam os diretórios como um tipo especial de arquivo, porém existem casos como o S3 da AWS que tratam os diretórios como prefixos, que juntamente com o nome do arquivo, compõem a chave de identificação do arquivo dentro de um bucket. O FileHub facilita o gerenciamento de diretórios, permitindo as seguintes operações:

    • Criar um novo diretório
    • Renomear um diretório
    • Deletar um diretório
    • Listar os arquivos existentes dentro do diretório, incluindo outros diretórios
    • Verificar se o diretório existe
    Desativar operações em diretórios

             Caso exista a necessidade de desativar as operações em diretórios, pode-se utilizar o atributo no-dir em uma trigger como mostrado no exemplo abaixo.

    <trigger id="user-auth" action="ALL" no-dir="true">
        <url>http://10.0.0.10:8080/auth</url>
        <header>myheader</header>
        <http-method>GET</http-method>
    </trigger>

    Exemplo de trigger com desativação de diretórios

    Upload

             A operação de upload permite que sejam enviados arquivos que serão salvos em todos os storages vinculados a determinado schema. Quando o FileHub recebe a requisição de upload e a transferência dos arquivos inicia, o FileHub pode enviar o arquivo para os storages de duas maneiras:

    • Transferência sequencial: É o tipo de transferência padrão. O FileHub irá transferir os arquivos para cada um dos storages de forma sequencial, obedecendo a ordem de declaração dos storages no schema.
    • Transferência paralela: O FileHub transfere os arquivos para os storages ao mesmo tempo. Nesse caso não existe uma ordem de transferência. Para utilizar essa configuração é necessário colocar o atributo parallel-upload na tag schema com o valor true.
    <schemas>
        <schema name="test-parallel" parallel-upload="true">
            <storage-id>example</storage-id>
        </schema>
    </schemas>

    Exemplo de configuração de tranferência paralela


             Independente do tipo de transferência realizada, a requisição de upload só irá retornar uma resposta após o término da transferência dos arquivos para todos os storages do schema.

    Middle-Storage

             Em alguns cenários, onde se tem apenas 1 storage no schema e os arquivos são pequenos, a operação de transferência é executada rapidamente. Porém, existem casos onde é necessário transferir arquivos maiores para mais de 1 storage, e nesses casos a requisição pode levar um tempo considerável. Para amenizar este problema, utiliza-se o conceito de middle-storage.

             O middle-storage define qual dos storages do schema irá servir como intermediário entre a aplicação consumidora e o restante dos storages. Veja o exemplo a seguir:

    <filehub>
        <storages>
            <storage id="S3-Test" type="AWS_S3">
                <region>us-east-2</region>
                <secretKeyId>G5HG4G66RDYIYE1</secretKeyId>
                <secretKey>6F51E6f1e6F7A2E4F761F61fd51s1F</secretKey>
                <bucket>test</bucket>
            </storage>
            <storage id="FileSystem-Test" type="FILE_SYSTEM">
                <baseDir>C:\Users\user\filehub</baseDir>
            </storage>
        </storages>
        <schemas>
            <schema name="myschema" middle="FileSystem-Test">
                <storage-id>FileSystem-Test</storage-id>
                <storage-id>S3-Test</storage-id>
            </schema>
        </schemas>
    </filehub>

    Exemplo de middle-storage


             No exemplo acima, em uma operação de upload, o storage FileSystem-Test irá receber o arquivo, retornar a resposta para a aplicação consumidora e depois irá transferir o arquivo para o storage S3-Test.

    Middle-Storage Temporário

             Um storage definido como middle-storage e não incluído como um dos storage do schema será considerado um storage temporário. Esse storage irá funcionar igual ao middle-storage, porém irá deletar os arquivos após a operação de upload.

    <schemas>
        <schema name="myschema" middle="FileSystem-Test">
            <storage-id>S3-Test</storage-id>
        </schema>
    </schemas>

    Exemplo de middle-storage temporário


             Como mostrado no exemplo acima, o storage FileSystem-Test não está declarado em nenhum elemento storage-id dentro do schema, ou seja, ele é um middle-storage temporário.

    Download

             Diferente do upload que faz a comunicação com todos os storages de um schema, o download irá utilizar o primeiro storage declarado para fazer a operação de download.

    Cache-Storage

             O uso do atributo cache no schema irá afetar a operação de download. Caso o arquivo não exista no primeiro storage do schema, o FileHub irá verificar a existência do arquivo no próximo storage. Se o arquivo existir, o FileHub fará o download do mesmo, porém deixando o arquivo salvo no primeiro storage também.

    <schemas>
        <schema name="myschema" middle="FileSystem-Test" cache="true">
            <storage-id>S3-Test</storage-id>
        </schema>
    </schemas>

    Exemplo de schema com cache


             No exemplo anterior, caso seja realizado o download de um arquivo que não exista no FileSystem-Test, o FileHub irá verificar se o S3-Test possui o arquivo. Em caso positivo o download será executado, porém transferindo o arquivo também para o FileSystem-Test, o primeiro storage consultado.


    Warning Caso exista um middle-storage associado ao schema, o mesmo será utilizado para o cache, caso contrário, será o primeiro storage do schema.

    Warning Não é possível ter um cache-storage atuando como middle-storage temporário.



    Documentação da API


    Configuração Docker

    Link do DockerHub: https://hub.docker.com/repository/docker/paulophgf/filehub

    Comando Docker Run

    docker run -d --name filehub -v {LOCAL_DIR}:/filehub paulophgf/filehub:{FILEHUB_VERSION}

    Exemplo:

    docker run -d --name filehub -v //c/Users/user/filehub:/filehub paulophgf/filehub:1.0.0

    Compose

    version: '3.1'
    
    services:
    
      filehub:
        image: paulophgf/filehub:1.0.0
        hostname: filehub
        container_name: filehub
        restart: always
        networks:
          - filehub-default
        ports:
          - "8088:8088"
        volumes:
          - /etc/hosts:/etc/hosts:ro
          - {LOCAL_DIR}:/filehub # Substitua o valor da variável {LOCAL_DIR} | Exemplos: Win: C:\Users\%user%\filehub ou Linux: /filehub
        environment:
          CONFIG_TYPE: "LOCAL_FILE" # Escolha umas das opções LOCAL_FILE ou GIT_FILE
          LOCAL_FILE_PATH: "filehub/fh-config.xml"
          CONFIG_GIT_FILE_PATH: "" # Preencha esta variável caso tenha escolhido GIT_FILE como CONFIG_TYPE
          CONFIG_GIT_FILE_TOKEN: "" # Preencha esta variável caso tenha escolhido GIT_FILE como CONFIG_TYPE
          JAVA_OPTS : "-Xms512m -Xmx1024m"
    
    networks:
      filehub-default:
        name: filehub-default