|
|
@ -1,5 +1,5 @@
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* Copyright 2012-2015 the original author or authors.
|
|
|
|
* Copyright 2012-2016 the original author or authors.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
@ -20,11 +20,14 @@ import java.util.Date;
|
|
|
|
import java.util.LinkedList;
|
|
|
|
import java.util.LinkedList;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.util.Assert;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* In-memory {@link AuditEventRepository} implementation.
|
|
|
|
* In-memory {@link AuditEventRepository} implementation.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @author Dave Syer
|
|
|
|
* @author Dave Syer
|
|
|
|
* @author Phillip Webb
|
|
|
|
* @author Phillip Webb
|
|
|
|
|
|
|
|
* @author Vedran Pavic
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public class InMemoryAuditEventRepository implements AuditEventRepository {
|
|
|
|
public class InMemoryAuditEventRepository implements AuditEventRepository {
|
|
|
|
|
|
|
|
|
|
|
@ -33,7 +36,7 @@ public class InMemoryAuditEventRepository implements AuditEventRepository {
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Circular buffer of the event with tail pointing to the last element.
|
|
|
|
* Circular buffer of the event with tail pointing to the last element.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
private AuditEvent[] events;
|
|
|
|
private final AuditEvent[] events;
|
|
|
|
|
|
|
|
|
|
|
|
private volatile int tail = -1;
|
|
|
|
private volatile int tail = -1;
|
|
|
|
|
|
|
|
|
|
|
@ -45,39 +48,84 @@ public class InMemoryAuditEventRepository implements AuditEventRepository {
|
|
|
|
this.events = new AuditEvent[capacity];
|
|
|
|
this.events = new AuditEvent[capacity];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@Override
|
|
|
|
* Set the capacity of this event repository.
|
|
|
|
public List<AuditEvent> find(Date after) {
|
|
|
|
* @param capacity the capacity
|
|
|
|
LinkedList<AuditEvent> events = new LinkedList<AuditEvent>();
|
|
|
|
*/
|
|
|
|
synchronized (this.events) {
|
|
|
|
public synchronized void setCapacity(int capacity) {
|
|
|
|
for (int i = 0; i < this.events.length; i++) {
|
|
|
|
this.events = new AuditEvent[capacity];
|
|
|
|
AuditEvent event = resolveTailEvent(i);
|
|
|
|
|
|
|
|
if (event == null) {
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isMatch(event, after)) {
|
|
|
|
|
|
|
|
events.addFirst(event);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return events;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public synchronized List<AuditEvent> find(String principal, Date after) {
|
|
|
|
public List<AuditEvent> find(String principal, Date after) {
|
|
|
|
|
|
|
|
Assert.notNull(principal, "Principal must not be null");
|
|
|
|
LinkedList<AuditEvent> events = new LinkedList<AuditEvent>();
|
|
|
|
LinkedList<AuditEvent> events = new LinkedList<AuditEvent>();
|
|
|
|
for (int i = 0; i < this.events.length; i++) {
|
|
|
|
synchronized (this.events) {
|
|
|
|
int index = ((this.tail + this.events.length - i) % this.events.length);
|
|
|
|
for (int i = 0; i < this.events.length; i++) {
|
|
|
|
AuditEvent event = this.events[index];
|
|
|
|
AuditEvent event = resolveTailEvent(i);
|
|
|
|
if (event == null) {
|
|
|
|
if (event == null) {
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (isMatch(event, principal, after)) {
|
|
|
|
if (isMatch(event, principal, after)) {
|
|
|
|
events.addFirst(event);
|
|
|
|
events.addFirst(event);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return events;
|
|
|
|
return events;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private boolean isMatch(AuditEvent auditEvent, String principal, Date after) {
|
|
|
|
@Override
|
|
|
|
return (principal == null || auditEvent.getPrincipal().equals(principal))
|
|
|
|
public List<AuditEvent> find(String principal, String type, Date after) {
|
|
|
|
&& (after == null || auditEvent.getTimestamp().compareTo(after) >= 0);
|
|
|
|
Assert.notNull(principal, "Principal must not be null");
|
|
|
|
|
|
|
|
Assert.notNull(type, "Type must not be null");
|
|
|
|
|
|
|
|
LinkedList<AuditEvent> events = new LinkedList<AuditEvent>();
|
|
|
|
|
|
|
|
synchronized (this.events) {
|
|
|
|
|
|
|
|
for (int i = 0; i < this.events.length; i++) {
|
|
|
|
|
|
|
|
AuditEvent event = resolveTailEvent(i);
|
|
|
|
|
|
|
|
if (event == null) {
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isMatch(event, principal, type, after)) {
|
|
|
|
|
|
|
|
events.addFirst(event);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return events;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public synchronized void add(AuditEvent event) {
|
|
|
|
public void add(AuditEvent event) {
|
|
|
|
this.tail = (this.tail + 1) % this.events.length;
|
|
|
|
Assert.notNull(event, "AuditEvent must not be null");
|
|
|
|
this.events[this.tail] = event;
|
|
|
|
synchronized (this.events) {
|
|
|
|
|
|
|
|
this.tail = (this.tail + 1) % this.events.length;
|
|
|
|
|
|
|
|
this.events[this.tail] = event;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private AuditEvent resolveTailEvent(int offset) {
|
|
|
|
|
|
|
|
int index = ((this.tail + this.events.length - offset) % this.events.length);
|
|
|
|
|
|
|
|
return this.events[index];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean isMatch(AuditEvent event, Date after) {
|
|
|
|
|
|
|
|
return (after == null || event.getTimestamp().compareTo(after) >= 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean isMatch(AuditEvent event, String principal, Date after) {
|
|
|
|
|
|
|
|
return (event.getPrincipal().equals(principal) && isMatch(event, after));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean isMatch(AuditEvent event, String principal, String type, Date after) {
|
|
|
|
|
|
|
|
return (event.getType().equals(type) && isMatch(event, principal, after));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|