Mudanças entre as edições de "FileVO"

De Wiki do Leitão
Ir para: navegação, pesquisa
 
Linha 2: Linha 2:




= Associando o FileVO =
= 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.  
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.  
Linha 14: Linha 14:




{{nota|Efeitos Colaterais|Uma vez que o '''FileVO''' deve ser do tipo Association, ao persistir o objeto que tem o '''FileVO''', e o '''FileVO''' seja um objeto novo (sem ID), o [[RFWValidator]] falhará reclamando que o objeto não pode ter uma associação de objeto sem ID, bem como o [[RFWDAO]] falhará pelo mesmo problema.
{{nota|Efeitos Colaterais|Uma vez que o '''FileVO''' deve ser do tipo Association, ao persistir o objeto que carregue o '''FileVO''', e o '''FileVO''' seja um objeto novo (sem ID), o [[RFWValidator]] falhará reclamando que o objeto não pode ter uma associação de objeto sem ID, bem como o [[RFWDAO]] falhará pelo mesmo problema.


A solução é que antes de validar e persistir o objeto principal, todos os '''FileVO'''s devem ser persistidos (atualizados/inseridos) antes de se iniciar o processo de validação do objeto principal.
A solução é que antes de validar e persistir o objeto principal, todos os '''FileVO'''s devem ser persistidos (atualizados/inseridos) antes de se iniciar o processo de validação do objeto principal.

Edição atual tal como às 14h42min de 9 de agosto de 2023

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.


Java 256.png Exemplo de Utilização do FileVO
  @RFWMetaRelationshipField(caption = "Arquivo do Objeto", relationship = RelationshipTypes.ASSOCIATION, required = true, column = "idfile")
  private FileVO fileVO = null;


Note 64.png
Efeitos Colaterais
Uma vez que o FileVO deve ser do tipo Association, ao persistir o objeto que carregue o FileVO, e o FileVO seja um objeto novo (sem ID), o RFWValidator falhará reclamando que o objeto não pode ter uma associação de objeto sem ID, bem como o RFWDAO falhará pelo mesmo problema.

A solução é que antes de validar e persistir o objeto principal, todos os FileVOs devem ser persistidos (atualizados/inseridos) antes de se iniciar o processo de validação do objeto principal.

Mesmo em casos de falhas posterior, o FileVO sofrerá RollBack e as alterações serão desfeitas.


Stop 256.png
FK com ON DELETE RESTRICT
Ao montar o relacionamento do banco de dados, sempre utilizar o ON DELETE RESTRICT. Isso evita que o sistema de manutenção exclua um arquivo que ainda esteja em uso. A rotina de manutenção do sistema procura arquivos que estão na base de dados e não estão mais em uso (arquivos esquecidos) e os exclui.

Manter a FK restringindo a exclusão é a maneira que o sistema tem de perceber que o arquivo está em uso. Veja mais na seção de Limpeza e Manutenção desta página.

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

Stop 256.png
Versionamento do Arquivo no S3
Quando o modo de persistência é DB o conteúdo será persistido no banco diretamente. Ou seja, sempre que houver alterações no conteúdo do arquivo ele será substituído imadiatamente e "pronto".

Já no modo S3, não queremos que a cada atualização do objeto FileVO faça com que um novo arquivo seja postado. Tanto pelo overhead de conexão, quando pelo excesso de versões sem necessidade sendo criado dentro do Bucket. Assim, para saber que o arquivo precisa ser versionado (seu conteúdo sofreu alteração), o desenvolvedor deve deixar nulo o valor do atributo VersionID. Somente quando o FileVO não apresenta um VersionID é que o conteúdo será postado para o S3 gerando uma nova versão.

Caso o arquivo já exista no S3 ele ganhará uma nova versão, do contrário será sua primeira versão.


Note 64.png
Configuração do Bucket do S3
O bucket do S3 deve ter as seguintes características definidas:
  • Ter a regra de versionamento ativa.


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:


Java 256.png 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.