VRaptor + ThreadLocal - Auditoria de serviços

7 respostas
o_lalertom

Boa tarde,

Estou tentando auditar as minhas entidades e me deparei com um problema.

Utilizo o VRaptor 3.4.0 e com ele fiz um interceptador[1] para as minhas requisições
capturar um cabeçalho especifico e definir em um ThreadLocal[2] o nome do usuário
na aplicação.

Tenho um “listener”[3] do Hibernate para interceptar as iterações com as minhas
entidades.

O meu problema é quando eu tenho requisições simultâneas de vários usuários e acesso
a ThreadLocal no “listener” do Hibernate o nome do usuário varia entre os já definidos
na ThreadLocal.

Fiz uma depuração na aplicação que exibe na saída do arquivo de log os valores de
Thread.currentThread().getId() e AuditThreadLocal.get() na classe que intercepta a
requisação[1] e no repositório[4] onde eu insiro o registro na base
de dados.

Esta sendo registrado no arquivo de log de origem do interceptador de requisições
o Thread.currentThread().getId() com o mesmo número duas vezes para usuários
diferentes e não executando o repositório nesse intervalo.

A alguma restrições em utilizar um TheadLocal com essa estrutura sitada juntamente
com o VRaptor?

Se alguém souber de uma propriedade, classe ou projeto que eu possa fazer esse trabalho
será de grande ajuda.

[1] - http://pastebin.com/JJ5sLGfr
[2] - http://pastebin.com/dc8tuqcC
[3] - http://pastebin.com/2nWv0caF
[4] - http://pastebin.com/Qn4Wvnzn

Obrigado,
Nycholas de Oliveira e Oliveira.

7 Respostas

Lucas_Camara

Não entendi 100% seu problema, mas pode ter algo a ver com sincronismo.

Alexandre_Saudate

Não entendí muito bem seu problema, mas se você precisa de auditoria com o Hibernate, já pensou em usar o Envers?

o_lalertom

O meu problema não é a auditoria em si, é como trafegar o nome de usuário da aplicação
capturado na minha requisição até o meu “listener” do Hibernate.

O problema seria o mesmo se eu utilizasse o Hibernate Envers, certo?

Lucas_Cavalcanti

vc não precisa criar esse threadLocal…

apague a classe que faz isso (e acho que o interceptor tb) e faça:

HttpServletRequest request = VRaptorRequestHolder.currentRequest().getRequest();

de dentro do seu listener.

dê preferencia pra injeção de dependências sempre que possível.

o_lalertom

Lucas Cavalcanti:
vc não precisa criar esse threadLocal…

apague a classe que faz isso (e acho que o interceptor tb) e faça:

HttpServletRequest request = VRaptorRequestHolder.currentRequest().getRequest();

de dentro do seu listener.

dê preferencia pra injeção de dependências sempre que possível.

Bacana! Deixou a implementação mais elegante, desconhecia o VRaptorRequestHolder,
já estou utilizando.

Infelizmente não deu certo os registros de auditoria por usuário, você sabe me
dizer se o VRaptor utiliza um pool de threads diferente com algum método de chavear
entre as threads de requisições abertas, ou estou pensando longe?

Lucas_Cavalcanti

bom, se as operações no banco acontecerem dentro de uma request, teoricamente é a mesma thread.

o VRaptor não abre novas threads, isso é com o servidor que vc está usando.

o que não está funcionando?

o_lalertom

Lucas Cavalcanti:
bom, se as operações no banco acontecerem dentro de uma request, teoricamente é a mesma thread.

o VRaptor não abre novas threads, isso é com o servidor que vc está usando.

o que não está funcionando?

Descobrimos que o problema esta ocorrendo em uma parte do sistema que é legada.

Obrigado.

Criado 10 de fevereiro de 2012
Ultima resposta 14 de fev. de 2012
Respostas 7
Participantes 4