FileVO
O FileVO é o objeto oferecido pelo framework para simplificar a persistência de arquivos.
Usando o FileVO
O FileVO deve ser usado sempre com o relacionamento do tipo ASSOCIATION. Para evitar que o FileVO seja persistido diretamente como uma composição do objeto que tem o arquivo.
![]() |
Exemplo de Utilização do FileVO |
@RFWMetaRelationshipField(caption = "Arquivo do Objeto", relationship = RelationshipTypes.ASSOCIATION, required = true, column = "idfile")
private FileVO fileVO = null;
|
![]() |
|
![]() |
|
Modos de Persistência
Atualmente são oferecidas as seguintes soluções de persistência do arquivo:
Banco de Dados (DB)
O modo de persistência DB persiste o arquivo como um Blob dentro do próprio banco de dados. Fazendo com que o conteúdo do arquivo sofra rollback ou commit junto com o resto da transação.
Vantagens deste Método
- Não deixa arquivos "lixo" para trás durante as atualizações dos objetos.
- Tem um acesso rápido sendo recuperado na mesma transação que o FileVO (se solicitado, uma vez que o conteúdo fica em um objeto composto FileContentVO).
Desvantagens deste Método
- Sobrecarrega os arquivos da base de dados, podendo deixar o banco lento e atingindo a capacidade de tamanho da tabela cedo.
- Deixa os arquivos do banco maiores, e cada snapshot inclui o conteúdo completo do arquivo, mesmo que ele seja igual ao seu anterior.
Amazon S3 (S3)
Este método faz o post do arquivo em um bucket próprio da aplicação na Amazon. O FileVO continua sendo salvo no banco de dados mas apenas com as informações de meta-dados do arquivo, seu conteúdo é enviado para o S3.
Vantagens deste Método
- Mantém a base de dados apenas com as informações de meta-dados, não sobrecarregando os arquivos do banco.
- Os arquivos na S3 são salvos todos separados, os arquivos não são replicados a cada backup do banco de dados.
- Passando versões antigas para o Glacier, o custo do armazenamento e de backups se torna muito menor do que o gasto com espaço no banco de dados.
Desvantagens deste método
- O arquivo quando salvo/recuperado precisa abrir uma nova conexão HTTPS com o servidor da S3 para realizar a operação. Tirando a performance da ação.
- Uma vez que a operação não está inclusa na transaction, um rollback da operação não exclui o arquivo já postado ou marcado como excluído. Gerando versões e deixando lixo dentro do Bucket.
Arquivos Locais
Ainda não implementado, o sistema deve ganhar este método de armazenamento para arquivos que são grandes e/ou volumosos demais para estarem no banco de dados, mas precisamos da velocidade do acesso local. Ainda com a arquitetura a ser definida, a intenção é ter uma pasta com os arquivos salvos conforme UUID do FileVO permitindo que os arquivos sejam lidos e recuperados com velocidade localmente. O backup ficará por conta do administrador do ambiente. Os arquivos não devem ser substituídos diretamente, mas ter alguma lógica como a do S3 para contemplar rollback (embora para isso possamos incluir o arquivo na transaction), e restauração de backups anteriores.
A partir desta implementação também devemos incluir a opção de S3 com cache local. Permitindo que um arquivo seja versionado na S3 (fazendo toda a parte de backup funcionar como no modo S3 isolado), mas mantendo uma cópia do arquivo no servidor local. E aí implementar regras de limpeza e gerenciamento do cache.
Lógica de Funcionamento
![]() |
|
![]() |
|
Por não fazer parte da transação do Container o sistema de persistência do S3 nunca excluí nenhum arquivo diretamente. O Bucket utilizado obrigatoriamente deve ter o sistema de versionamento funcionando inclusive para arquivos excluídos.
O Framework saberá qual é a versão correta a ser obtida de acordo com o VersionID fornecido pelo S3. Assim, mesmo que o Banco de dados sofra uma restauração de backup anterior, o banco trará o VersionID da época do banco de dados que foi restaurado, permitindo que o S3 continue devolvendo o arquivo correto quando necessário. Dito isso, o bucket não deve ter nenhuma regra de exclusão automática.
Em um cenário em que um arquivo foi atualizado, no bucket teremos uma versão antiga e uma nova. Caso o banco de dados seja restaurado, fazendo com que a versão antiga volte a ser a vigente, o bucket ainda terá todas as versões antigas do arquivo. Uma regra de exclusão automática pode acabar excluindo o conteúdo que não estava no backup e tornar o backup cheio de inconsistências.
Há métodos de limpeza discutidos mais a frente na sessão de manutenção e limpeza.
Como escolher o método de persistência adequado?
Dada as vantagens e desvantagens de cada modelo de persistência, eles devem ser escolhidos conforme os seguintes critérios:
- Utilizar o S3 quando:
- Sempre que tivermos um grande volume de arquivos para serem salvos
- Os arquivos tendem a ser mais "estocados" do que "utilizados"
- O overhead da conexão adicional é aceitável para a operação.
- Exemplos: Arquivos XML de Notas Fiscais, Arquivos do SAT, Digitalizações de comprovantes e outros documentos.
- Utilizar o DB quando:
- Há uma quantidade pequena de arquivos que serão utilizadas
- Os arquivos são utilizados com frequência pelo tempo que existirem na base de dados.
- Quando os arquivos são utilizados com frequência por um pequeno período de tempo, e depois ficam estocados, deve-se utilizar o S3. Sempre pensando a relação uso/estoque em relação ao tempo que o arquivo ficará na base de dados.
- O overhead da conexão adicional não é aceitável
- Neste caso devemos ainda pensar se a quantidade de arquivos no Banco não será grande de mais. Se for o caso trabalhar uma ideia de um cache de arquivos temporários.
- Utilizar quando precisamos persistir arquivos que são temporários (como relatórios que demoram a ficar pronto e devem ficar disponíveis por um período) e não podemos perde-los em arquivos temporários do sistema. Quando puder, utilizar o sistema de arquivos temporários de qualquer forma.
Persistindo com RFWDAO
Para persistir com o RFWDAO será necessário implementar o DAOResolver para informar o Schema, Tabelas e coluna da FK dos objetos FileVO e FileContentVO. Como no exemplo a seguir:
![]() |
Implementação do DAOResolver |
@Override
public String getSchema(Class<? extends RFWVO> entityType, RFWDAOAnnotation entityDAOAnn) throws RFWException {
if (entityType.equals(FileVO.class)) {
return "appSchema";
} else if (entityType.equals(FileContentVO.class)) {
return "appSchema";
}
return null;
}
@Override
public String getTable(Class<? extends RFWVO> entityType, RFWDAOAnnotation entityDAOAnn) throws RFWException {
if (entityType.equals(FileVO.class)) {
return "file";
} else if (entityType.equals(FileContentVO.class)) {
return "filecontent";
}
return null;
}
@Override
public String getMetaRelationColumnMapped(Field field, RFWMetaRelationshipField ann) throws RFWException {
if (field.getDeclaringClass().equals(FileVO.class) && field.getName().equals(FileVO_._fileContentVO)) {
return "idfile";
}
return null;
}
|
A DOCUMENTAÇÃO ABAIXO PRECISA SER REVISADA
A DOCUMENTAÇÃO ABAIXO PRECISA SER REVISADA, NÃO FOI ADAPTADA AINDA DESDE A MIGRAÇÃO DO FILEVO PARA O RFW!!
Limpeza e Manutenção - FileMaintenanceTask
O Framework tem uma rotina de manutenção que temporariamente tenta excluir os FileVOs que não estão em uso. A maneira de saber se o FileVO está em uso é tentando excluí-lo e descobrir se o banco impede por restrição de alguma FK com ON DELETE RESTRICT, por isso torna-se obrigatório que qualquer objeto que utilize o FileVO coloque na sua constraint o ON DELETE RESTRICT. Essa manutenção é obrigatória porque, uma vez que o FileVO não é um objeto de composição de outros objetos, durante a alteração ou exclusão do FileVO dos outros objetos, o velho fica abandonado no banco de dados.
Limpeza e Manutenção do S3
Após a limpeza dos FileVOs da base de dados, o sistema deve recuperar uma lista de todos os arquivos, incluindo suas versões, no S3. Com base nessa lista conseguimos comprar com os FileVOs da base de dados e descobrir quais arquivos/versões estão órfãos no S3.
Assim, temos as seguintes regras de exclusão de arquivos do S3:
Regra 1:
- Arquivos no S3 que não tenham correspondência com nenhum FileVO da base de dados, e;
- Não forem a versão atual do arquivo, e;
- O arquivo deixou de ser a versão atual à mais de X meses, onde X Meses é o mesmo tempo de retenção dos backups.
Regra 2: É necessário um jeito de excluir os arquivos que são a versão atual de um objeto no S3. Porém não basta excluir o objeto que não tem correspondência no FileVO atualmente pois ele pode ter correspondência com um objeto do Backup. Se for possível realizar algum tipo de marca/tag/attributo no arquivo. A tarefa de manutenção pode marcar o arquivo com a data em que pela primeira vez percebeu que o arquivo estava órfão, e excluir em uma próxima execução da tarefa ao perceber que a data ficou velha em pelo menos X meses.