Estou a utilizar o vrpator, hibernate.
Como eu faço para pegar as ações do usuário e salvar no banco?
Isso mesmo, um log de acesso.
Guardando o que ele acessou, o que ele fez e tal…
Grato,
Estou a utilizar o vrpator, hibernate.
Como eu faço para pegar as ações do usuário e salvar no banco?
Isso mesmo, um log de acesso.
Guardando o que ele acessou, o que ele fez e tal…
Grato,
Pode fazer um interceptor que salva a URL que determinado usuário está acessando.
Boa ideia!
Muito interessante.
Alguém teria alguma outra ideia?
Você pode fazer um filter, e salvar onde ele está acessando ou se quiser algo mais refinado, você no próprio método manda salvar no db.
Na minha opinião, um log de acesso, além de não ser muito útil, vai deixar as suas requisições mais lentas…
Eu verificaria a real necessidade.
Filter é o interceptor no vraptor.
No caso de salvar no db, toda alteração e inclusão, seria uma boa.
Mas não vai de encontro com os principios de OO?
Obrigado!
Na minha opinião, um log de acesso, além de não ser muito útil, vai deixar as suas requisições mais lentas…Já trabalhei com aplicações onde cada ação do usuário tinha que ser auditada. ^^Eu verificaria a real necessidade.
As vezes, é um mau necessário. Dependendo da aplicação tudo poderá ocorrer sem problemas, por exemplo, caso a aplicação utilize EJB basta chamar um MDB e passar as informações a serem persistidas; desse modo não haverá problemas quanto ao desempenho ou atraso da requisição do cliente.
Preciso, porque a aplicação vai ter vários usuários.
Cada usuário representa uma empresa.
Nossa aplicação, vai disponibilizar os produtos e as empresas vão falar quais produtos elas querem, e quais sãos seus preços.
Posteriormente, ela pode reclamar, falando que não adicionou tal produto, e tal preço não foi ela que colocou.
Dessa forma, precisamos sim de um log de acesso.
Entende?
Valeus.
101574,
O que você precisa auditar? Alterações e inclusões?
Pode criar uma anotação @Audit onde todo método que estiver anotado com ela, vai ser auditado. Pode fazer essa anotação para classe, assim todos os métodos serão auditatos.
Outra solução:
Hebert Coelho,
Concordo com você, mas em casos onde vão fazer relatórios. Se não, eu acho que um log de acesso fica muito inflado. É mta informação para pouca utilização.
Hebert Coelho,Eu vi caso onde ñ era utilizado para relatório, mas sim para caso o algum usuário faça alguma caca. Para dedo duro mesmo, o cara deu mole e fica registrado lá. [=
Concordo com você, mas em casos onde vão fazer relatórios. Se não, eu acho que um log de acesso fica muito inflado. É mta informação para pouca utilização.
Eu só não sou fã de trigger. É uma ação executada que você não sabe de onde veio e para onde vai, caso você não conheça o sistema. [=
Poww galera,
Vocês são muito bons.
Gostei da anotação @Audit.
Vou utilizar essa.
Minha anotação vai salvar o usuário e açao no banco.
Seria basicamente isso né?
-> Vou precisar gerar relatórios de 3 em 3 meses das ações das empresas e enviar por e-mail.
Por isso que precisamos salvar no banco.
Voltei!rsrsrs
Seguinte.
Fiz o interceptor.
Agora minha dúvida e como eu vou fazer para pegar os dados do usuário, o nome do metodo e salvar isso no banco.
Meu interceptor.
package br.com.softsol.compresempre.infra.interceptor;
import br.com.caelum.vraptor.InterceptionException;
import br.com.caelum.vraptor.Intercepts;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.core.InterceptorStack;
import br.com.caelum.vraptor.interceptor.Interceptor;
import br.com.caelum.vraptor.resource.ResourceMethod;
import br.com.softsol.compresempre.interfaces.Auditoria;
@Intercepts
public class AuditoriaInterceptor implements Interceptor{
private final Result result;
/*
* Anotação - Interceptar
* Onde encontrar a anotação, vai ser interceptada
* Metodo intercept vai ser executado.
*/
//Construtor
public AuditoriaInterceptor(Result result){
this.result = result;
}
public boolean accepts(ResourceMethod method) {
return method.containsAnnotation(Auditoria.class);
}
//Metodo intercept - o que deve ser feito quando é encontrado a anotação
public void intercept(InterceptorStack stack, ResourceMethod method,
Object resourceInstance) throws InterceptionException {
System.out.println("Encontrou Intercept");
// segue o curso padrão
stack.next(method, resourceInstance);
}
}
Anotação Auditoria
package br.com.softsol.compresempre.interfaces;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//Disponivel em tempo de execução
@Retention(RetentionPolicy.RUNTIME)
//Anotação para métodos
@Target(ElementType.METHOD)
public @interface Auditoria {
}
To criando uma classe chamada auditoria que vai ser persitida no bd.
Vou criar o dao para incluir.
Agora, como eu vou preencher que eu não to conseguindo pensar.
Valeus…
Cria um DAO com @Component que recebe uma session.
Dai você pega o construtor do interceptor e recebe o seu dao e a sessão do seu usuário.
E para pegar a URL você pode receber o HTTPServletRequest no construtor. Se eu não me engano, lá também tem o método HTTP da requisição (GET ou POST).
E acho que você consegue pegar os parâmetros da requisição também. Se for útil saber O QUE o seu usuário enviou.
Vou tentar aqui.
Novamente obrigado!
Mano o que eu fiz.
[quote=Rafael Guerreiro]Cria um DAO com @Component que recebe uma session.[quote]
@Component
public class AuditoriaDAO {
private final Session session;
public AuditoriaDAO(Session session) {
this.session = session;
}
public void salva(Auditoria auditoria) {
Transaction tx = session.beginTransaction();
session.save(auditoria);
tx.commit();
}
}
@Intercepts
public class AuditoriaInterceptor implements Interceptor{
private final Result result;
private final AuditoriaDAO dao;
private final EmpresaWeb empresa;
/*
* Anotação - Interceptar
* Onde encontrar a anotação, vai ser interceptada
* Metodo intercept vai ser executado.
*/
//Construtor
public AuditoriaInterceptor(Result result, AuditoriaDAO dao,
EmpresaWeb empresa){
this.result = result;
this.dao = dao;
this.empresa = empresa;
}
E para pegar a URL você pode receber o HTTPServletRequest no construtor. Se eu não me engano, lá também tem o método HTTP da requisição (GET ou POST).
E acho que você consegue pegar os parâmetros da requisição também. Se for útil saber O QUE o seu usuário enviou.
Como eu passo o paramentro?
//Metodo intercept - o que deve ser feito quando é encontrado a anotação
public void intercept(InterceptorStack stack, ResourceMethod method,
Object resourceInstance) throws InterceptionException {
System.out.println("Encontrou Intercept");
//Salvar no banco as informações
//Como passar os paramentros?
dao.salva();
// segue o curso padrão
stack.next(method, resourceInstance);
}
}
Grato.
public AuditoriaInterceptor(Result result, AuditoriaDAO dao,
EmpresaWeb empresa, HTTPServletRequest req){
this.result = result;
this.dao = dao;
this.empresa = empresa;
this.req = req;
}
Faz assim ué:
Não consegui.
Meu interceptor completo.
package br.com.softsol.compresempre.infra.interceptor;
import javax.servlet.http.HttpServletRequest;
import br.com.caelum.vraptor.InterceptionException;
import br.com.caelum.vraptor.Intercepts;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.core.InterceptorStack;
import br.com.caelum.vraptor.interceptor.Interceptor;
import br.com.caelum.vraptor.resource.ResourceMethod;
import br.com.softsol.compresempre.controller.EmpresaController;
import br.com.softsol.compresempre.dao.AuditoriaDAO;
import br.com.softsol.compresempre.modelo.Auditoria;
import br.com.softsol.compresempre.modelo.Bairro;
import br.com.softsol.compresempre.modelo.EmpresaWeb;
@Intercepts
public class AuditoriaInterceptor implements Interceptor{
private final Result result;
private final AuditoriaDAO dao;
private final EmpresaWeb empresa;
private final HttpServletRequest req;
/*
* Anotação - Interceptar
* Onde encontrar a anotação, vai ser interceptada
* Metodo intercept vai ser executado.
*/
//Construtor
public AuditoriaInterceptor(Result result, AuditoriaDAO dao,
EmpresaWeb empresa,HttpServletRequest req){
this.result = result;
this.dao = dao;
this.empresa = empresa;
this.req = req;
}
public boolean accepts(ResourceMethod method) {
return method.containsAnnotation(br.com.softsol.compresempre.interfaces.Auditoria.class);
}
//Metodo intercept - o que deve ser feito quando é encontrado a anotação
public void intercept(InterceptorStack stack, ResourceMethod method,
Object resourceInstance) throws InterceptionException {
System.out.println("Encontrou Intercept");
//Salvar no banco as informações
this.dao.salva(new Auditoria(empresa.getId(),req.getContextPath()));
// segue o curso padrão
stack.next(method, resourceInstance);
}
}
Meu Auditoria Completo
package br.com.softsol.compresempre.modelo;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Auditoria {
// Variáveis
@Id
@GeneratedValue
private Long id;
private Long usuario;
private String metodo;
// Método set e get
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getUsuario() {
return usuario;
}
public void setUsuario(Long usuario) {
this.usuario = usuario;
}
public String getMetodo() {
return metodo;
}
public void setMetodo(String metodo) {
this.metodo = metodo;
}
}
Meu AuditoriaDAO Completo.
package br.com.softsol.compresempre.dao;
import org.hibernate.Session;
import org.hibernate.Transaction;
import br.com.caelum.vraptor.ioc.Component;
import br.com.softsol.compresempre.modelo.Auditoria;
@Component
public class AuditoriaDAO {
private final Session session;
public AuditoriaDAO(Session session) {
this.session = session;
}
public void salva(Auditoria auditoria) {
Transaction tx = session.beginTransaction();
session.save(auditoria);
tx.commit();
}
}
Não to conseguindo. Eu entendi a lógica, mas não to conseguindo fazer.
Você pode fazer por setter…
Acho que você não entendeu o que está sendo feito.
Você vai instanciar um objeto da classe a ser persisitida (Auditoria) e depois você vai popular as informações que você quer que sejam persistidas.
Existem 2 formas de fazer:
Auditoria audit = new Auditoria();
audit.setUsuario(empresa.getId());
audit.setMetodo(req.getContextPath());
this.dao.salva(audit);
Cara,
Desculpa, mas as vezes eu faço as coisas sem pensar.
Entendi, agora.
Agora, a ação ele ta pegando sempre /compresempre.
Sem querer abusar, mas já abusando.
Você sabe pq?
Valeus.Obrigadão.
Por que esse é o nome do seu projeto, correto?
Então ele vai pegar o path do seu projeto.
Quando você for fazer o deploy da aplicação, imagino que vá fazer como ROOT. Assim o nome some da sua URL.
Você pode fazer um replace de “/compresempre” para “”
Isso o nome é esse.
Agora não entendi.
Tem como eu pegar a url que esta anotada @auditoria?
TIpo.
Incluir produtos.
@auditoria
@Post("produto/novo")
public void novo(produto){
dao.salva(produto);
}
Tem sim. O problema é que você não vai conseguir ver as variáveis na URL…
Além do problema de você ter mais de uma url para uma action. Você nunca vai saber qual o usuário está usando.
Então eu sugiro você usar o request mesmo.
Isso que eu disse é para você fazer isso:
Hum,
Entendi.
Mas eu preciso saber qual foi o metodo que a pessoa fez.
Não é um controlle de acesso.
Posso fazer duas, três … anotações.
Não vai contra o OO
Uma para inclusão.
@auditoria_inclusao
req.getContextPath().replace("/compresempre", "Inclusao")
Exclusão
@auditoria_exclusao
req.getContextPath().replace("/compresempre", "Exclusão")
Obrigado!
Ah, espera! :oops:
Usa esse cara aqui:
Você pode fazer uma anotação só e passar a funcionalidade como parâmetro…
Consegui!!!
// Metodo intercept - o que deve ser feito quando é encontrado a anotação
public void intercept(InterceptorStack stack, ResourceMethod method,
Object resourceInstance) throws InterceptionException {
// Salvar no banco as informações
Auditoria auditoria = new Auditoria();
// Adiciona Id da empresa na sessão
auditoria.setUsuario(empresa.getId());
// Adiciona Nome do metodo
String metodo = req.getMethod();
if (metodo.equals("POST")) {
auditoria.setMetodo("SALVAR");
}
if (metodo.equals("PUT")) {
auditoria.setMetodo("EDITAR");
}
// Hora e data
Date dataAtual = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
String dataStr = sdf.format(dataAtual);
auditoria.setData(dataStr);
Date horaAtual = new Date();
SimpleDateFormat sdf2 = new SimpleDateFormat("hh:mm:ss");
String horaStr = sdf2.format(horaAtual);
auditoria.setHora(horaStr);
// Salva no banco o objeto
this.dao.salva(auditoria);
// segue o curso padrão
stack.next(method, resourceInstance);
}
Fiz um if para testar o retorno, conforme o tipo do método eu sei se estar alterando ou removendo.
Agora, so falta colocar na tabela, o cod_produto. TInha esquecido. Mas agora está facil.
Valeu brother.
Tudo de bom!!!
Sugiro você trocar tudo isso:
// Hora e data
Date dataAtual = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
String dataStr = sdf.format(dataAtual);
auditoria.setData(dataStr);
Date horaAtual = new Date();
SimpleDateFormat sdf2 = new SimpleDateFormat("hh:mm:ss");
String horaStr = sdf2.format(horaAtual);
auditoria.setHora(horaStr);
Coloca essas instruções no seu construtor. Assim:
public Auditoria (){
// Hora e data
Date dataAtual = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
String dataStr = sdf.format(dataAtual);
this.setData(dataStr);
Date horaAtual = new Date();
SimpleDateFormat sdf2 = new SimpleDateFormat("hh:mm:ss");
String horaStr = sdf2.format(horaAtual);
this.setHora(horaStr);
}
Ok!
Valeus!
Brother,
Ainda não terminei aquela classe.
To querendo colocar o id do produto.
O que eu fiz.
Auditoria.
@Entity
public class Auditoria {
// Variáveis
@Id
@GeneratedValue
private Long id;
private Long usuario;
private String metodo;
private Long produto;
private String hora;
private String data;
//Construtor
//Insere a hora e a data
public Auditoria (){
// Hora e data
Date dataAtual = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
String dataStr = sdf.format(dataAtual);
this.setData(dataStr);
Date horaAtual = new Date();
SimpleDateFormat sdf2 = new SimpleDateFormat("hh:mm:ss");
String horaStr = sdf2.format(horaAtual);
this.setHora(horaStr);
}
// Método set e get
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getUsuario() {
return usuario;
}
public void setUsuario(Long usuario) {
this.usuario = usuario;
}
public String getMetodo() {
return metodo;
}
public void setMetodo(String metodo) {
this.metodo = metodo;
}
public String getHora() {
return hora;
}
public void setHora(String hora) {
this.hora = hora;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public Long getProduto() {
return produto;
}
public void setProduto(Long produto) {
this.produto = produto;
}
}
Como eu faço no interceptor, para pegar o id do produto?
Obrigado!
Como que você consegue pegar o produto?
Cara, Olha so.
Eu coloquei a interface audit.
Nesse metodo.
//Alteração - Gera a interface para alterar
//Envia o ID para alterar
@Audit
@Put("/produtoEmpresa/{produtoEmpresa.id}")
public void altera(final ProdutoEmpresa produtoEmpresa) {
dao.atualiza(produtoEmpresa);
//Redireciona para a listagem, após a inserção.
result.redirectTo(this).lista();
}
Como funciona.
Eu tenho:
Empresa
Produto
ProdutoEmpresa
Onde a empresa escolhe o produto, e coloca o seu preço.
O que eu preciso e controllar quando a empresa fizer alguma alteração.
O que eu pensei…
Pegar a URL que está me enviando.
Com o código.
Tipo …
/produtoEmpresa/50
Tem como isso?
Porque ai, eu faria assim, se metodo igual a Put.
Salvaria no metodo - Alteração - /produtoEmpresa/50
Eu ja consigo o id da empresa, então já está bom.
Já dá pra fazer uma auditoria.
Valeus!
Eu ainda não entendi muito bem isso tudo…
Mas você pode pegar os últimos números da sua URL com RegEx…
Seguinte,
Eu preciso de um controlle de acesso.
Discutimos, e vimos que o melhor era, criar um interceptor, e uma anotação chamada @Audit.
Criei, com sua ajuda, pego o endereço da URL que está enviando. E salvo no banco de dados, o usuário e a URL.
Eu tenho três métodos, que precisam ser auditados.
2º Excluir - OK
Porque eu recebo a URL e o metodo que eu sei que está excluindo.
3º Alterar - OK
Porque eu recebo a URL e o metodo que eu sei que está alterando.
1º Salvar - Não OK!
O que eu tentei fazer, que resolveria, mas está dando um erro.
for (ProdutoEmpresa s : dao2.listaTudo()) {
Long ss = s.getId();
System.out.println("Número " + ss);
ss += (long)1;
System.out.println(" Novo " + ss);
auditoria.setProduto(ss);
}
Eu estou pegando o último Produto adicionado, e acrescentar + 1;
O problema, e que o hibernate, traz para mim a sessão, e não renova. Dessa forma, somente o primeiro fica correto, o restante que é adicionando não. Porque pega sempre o mesmo id.
Como eu resolvo isso?
Para salvar você precisa pegar o ID. Mas não tem como ter certeza se o registro foi salvo ou não. Certo?
O que eu faria:
Colocaria toda essa inteligência no interceptor DEPOIS do stack.next… Assim você estará interceptando o resultado da requisição.
Quando você fizer a alteração, envie para a tela o ID do objeto alterado (ou salvo) e assim você não precisa pegar na URL…
Agora sim!
rsrsrs.
Não estou entendo uma coisa, porque ele ta pegando o nome do metodo, sempre POST?
// Faz a ação no banco normalmente
stack.next(method, resourceInstance);
// Salvar no banco as informações
Auditoria auditoria = new Auditoria();
// Adiciona Id da empresa na sessão
auditoria.setUsuario(empresa.getId());
// Adiciona Nome do metodo
String metodo = req.getMethod();
if (metodo.equals("POST")) {
auditoria.setMetodo("SALVAR");
}
if (metodo.equals("PUT")) {
auditoria.setMetodo("EDITAR");
}
if (metodo.equals("DELETE")) {
auditoria.setMetodo("REMOVER");
}
// Pega o ID do Produto
auditoria.setProduto(produtoEmpresa.getSprodutoEmpresa().getProduto()
.getId());
// Hora e data
// Construtor da classe
// Salva no banco o objeto
this.dao.salva(auditoria);
Fiz uma inclusão, alteração e removação.
Sempre vem SALVAR.
Salvar
Editar
Remover
Restante está perfeito!
Valeu brother.
Isso acontece porque as requisições PUT e DELETE são tratadas como POST e o VRaptor as redireciona para o método correto através da variável _METHOD…
Você pode fazer um req.getParameter("_METHOD") para saber se é put ou delete.
Esta vindo vazio.
System.out.println(req.getParameter("_METHOD"));
Console
null
Tem outro?
está indo vazio quando é POST(insert) ou em qualquer um dos casos?
Em todos.
Tem nada errado com a minha anotação?
//Disponivel em tempo de execução
@Retention(RetentionPolicy.RUNTIME)
//Anotação para métodos
@Target(ElementType.METHOD)
public @interface Audit{
}
Sua annotation está certa.
Debuga e olha os valores dentro do request para saber quais deles definem o método http que está sendo chamado pelo browser.
Esse method da sua annotation define que ela só pode anotar métodos.
Não entendo muito esse negócio de Debug.
Seria isso?
"method" (id=83)
method Method (id=92)
annotationDefault null
annotations (id=283)
clazz Class<T> (br.com.softsol.compresempre.controller.ProdutoEmpresaController) (id=86)
declaredAnnotations LinkedHashMap<K,V> (id=279)
accessOrder false
entrySet HashMap$EntrySet (id=5483)
header LinkedHashMap$Entry<K,V> (id=5484)
keySet null
loadFactor 0.75
modCount 2
size 2
table HashMap$Entry<K,V>[16] (id=5485)
threshold 12
values HashMap$Values (id=5486)
exceptionTypes Class<T>[0] (id=281)
genericInfo null
methodAccessor DelegatingMethodAccessorImpl (id=265)
delegate NativeMethodAccessorImpl (id=284)
modifiers 1
name "altera" (id=268)
override false
parameterAnnotations null
parameterTypes Class<T>[1] (id=272)
returnType Class<T> (void) (id=276)
annotations null
annotationType null
cachedConstructor null
classRedefinedCount 0
declaredAnnotations null
declaredConstructors null
declaredFields null
declaredMethods null
declaredPublicFields null
declaredPublicMethods null
enumConstantDirectory null
enumConstants null
genericInfo null
lastRedefinedCount 0
name "void" (id=327)
newInstanceCallerCache null
publicConstructors null
publicFields null
publicMethods null
root Method (id=277)
securityCheckCache null
securityCheckTargetClassCache null
signature null
slot 6
resource DefaultResourceClass (id=262)
Ou seria isso.
req VRaptorRequest (id=102)
extraParameters Hashtable<K,V> (id=207)
request RequestFacade (id=109)
request Request (id=111)
asyncContext null
asyncSupported Boolean (id=181)
value false
attributes HashMap<K,V> (id=183)
entrySet HashMap$EntrySet (id=5551)
keySet null
loadFactor 0.75
modCount 489
size 54
table HashMap$Entry<K,V>[128] (id=5539)
threshold 96
values null
authType null
comet false
connector Connector (id=184)
context StandardContext (id=169)
cookies null
cookiesParsed false
coyoteRequest Request (id=167)
event null
facade RequestFacade (id=109)
filterChain ApplicationFilterChain (id=148)
formats SimpleDateFormat[3] (id=151)
inputBuffer InputBuffer (id=154)
inputStream CoyoteInputStream (id=159)
internalDispatcherType DispatcherType (id=161)
localAddr null
locales ArrayList<E> (id=140)
localesParsed true
localName null
localPort -1
mappingData MappingData (id=113)
notes HashMap<K,V> (id=115)
parameterMap ParameterMap<K,V> (id=121)
parametersParsed true
parser StringParser (id=123)
parts null
partsParseException null
pathParameters HashMap<K,V> (id=125)
postData (id=126)
reader CoyoteReader (id=128)
readOnlyAttributes HashMap<K,V> (id=131)
remoteAddr null
remoteHost null
remotePort -1
requestDispatcherPath MessageBytes (id=135)
requestedSessionCookie true
requestedSessionId "37A25EAC75364AC5C80E62173FFF6980" (id=5515)
requestedSessionSSL false
requestedSessionURL false
response Response (id=5516)
secure false
session StandardSession (id=5517)
sessionParsed false
sslAttributesParsed false
subject null
URIConverter null
userPrincipal null
usingInputStream false
usingReader false
wrapper StandardWrapper (id=5518)
Primeiro, você está confundindo os methods…
Existe o que chamamos de HTTP Methods que são os métodos (tipos de envio) do protocolo HTTP… Ou seja: GET, POST, PUT, DELETE e outros…
Existem os methods do java, que são métodos normais. Esse method que você está me mostrando é do interceptor, certo? Esse cara é o método que você está indo acessar com o interceptor. NADA a ver com os http methods…
Como eu disse: “Debuga e olha os valores dentro do request” ou seja: olhe o que está vindo dentro do HttpServletRequest, pois você quer pegar o http method usado nessa requisição. Algo me diz que está aqui…
Segundo, precisa aprender a debugar e a fazer log da sua aplicação, o tempo de desenvolvimento diminui MUITO!
-EDIT-
Terceiro, não adianta você me postar essa estrutura dos atributos. É para você olhar isso ai e descobrir o que fazer.
Desculpa ae,
Vcê tinha falado dessa anotação.
@Audit(Feature.REMOVE)
Fica mais fácil, porque eu so preciso diferenciar o que é inclusão, alteração ou removação?
Não. Use sem passar parâmetros mesmo.
é mais fácil você verificar se o método tem a anotação @Post ou se tem @Put, ou se tem @Delete…
Cara, desculpe não entrar na conversa anteriormente, vi que você já fez bastante coisa.
Como um amigo aqui já disse não tenho dúvidas que seu sistema poderá ficar com as requisições mais lentas e você terá muita dificuldade em manter isso posteriormente.
O que você pode e deveria fazer é delegar essa funcionalidade para um sistema externo e lá criar seus relatórios bases exclusivas e acessos restritos.
Você poderia fazer isso utilizando um ESB e aplicar a Event Driven, ou seja, fazer com que seus interceptors enviarem de forma assincrona para ESB suas mensagens de log e ele se encarregará do resto, apartir dai você abre um leque gigante de soluções e tratamentos desta informação e não somente como LOG.
Outra coisa, da maneira como você está fazendo imagine que se algo acontecer com sua base ou essa transação de log falhar, toda sua requisição falhará e acredito que nenhum sistema deveria falha por causa de um log.
abs.
Poww brother,
Valeu, nunca é tarde para ajudar um colega.rsrs.
Você poderia me informar a documentação, para eu dar uma estudada, e implementar.
Gostei da ideia.
Obrigado.
Vc acha que mesmo sendo somente em três métodos, o sistema pode ficar lento?
Pq vamos precisar somente do log desses.
Valeu.
Isso tudo depende do volume de requisições e os servidores que serão utilizados na solução.
O que eu realmente não gosto é deixar o método dependente de uma operação que não está diretamente relacionada ao negócio. E como eu disse em caso de falha de gravação desse log, sua operação para.
Quanto a documentação você pode verificar o ESB da Mule soft, tem uma versão community. Todos os ESB seguem o mesmo padrão pois são desenvolvidos em cima dos patterns de integração, procure no google sobre o tema você vai encontrar muita coisa.
Procure também sobre a arquitetura SOA, todas essas ideias vem dela. Não esqueça SOA é o conceito e não ferramenta.
abs.
Tranquilo,
Vou estudar um pouco. To ligado, em SOA. Terminando esse projeto, vou ter tempo de estudar mais esses conceitos.
Onde eu trabalhava(IBTI) eles estão desenvolvendo, utilizando SOA.
Muito interessante!
Eu dei uma lida, sobre o ESB e o Event Driver.
E o que eu entendi foi.
Eu devo criar uma OUTRA APLICAÇÃO para tratar os logs.
E passar para ela, cuidar dessa parte.
Seria isso?
Valeus!
Sim isso mesmo.
Se você criar essa aplicação com os moldes de log de mercado, você pode criar pequenos robos para análisar os logs e já dar solução/decisão sobre o que fazer com eles independente do seu sistema central, assim você pode usar essa aplicação de log para outros sistemas de sua empresa e ter isso centralizado facilitando a auditoria de todos eles.
abs.
Se vc for para uma solução assim, provavelmente vai cair em JMS (que é uma solução muito boa). Se vc estiver usando um servidor JEE, a ideia é boa, mas se estiver usando um container leve (tomcat, jetty… etc…), uma solução com ESB vai deixar tua aplicação inchada, desnecessariamente.
Se vc vai fazer isso como um experimento para aprendizado, ESB é uma boa.
Mas se pensar no problema, primeiramente, sem focar em tecnologia, vc falou que a informação seria usada uma vez por mês, e não no momento. Então vc precisa dela no teu banco de dados de produção? vc precisa dela num banco de dados?
Eu fiz uma solução para um problema semelhante ao teu… usando simplesmente uma thread separada da aplicação, que controlava a escrita em um arquivo txt. De madrugada quando o acesso diminuía… tinha um script que lia e extraia desse arquivo txt e jogado para um banco de dados leve (não o mesmo da produção), no caso o H2 (um ótimo banco de dados), e em cima desse banco eu podia fazer qualquer consulta.
Esse meu arquivo de log, no fim do dia, era comum ficar em torno de 200Mb.
E segundo testes de carga que fiz, essa solução não alterou praticamente nada a performance da aplicação.
Uma solução simples e eficiente.