package org.tests.readaudit;
import io.ebean.BaseTestCase;
import io.ebean.EbeanServerFactory;
import io.ebean.FutureList;
import io.ebean.cache.ServerCache;
import io.ebean.cache.ServerCacheStatistics;
import io.ebean.config.ServerConfig;
import io.ebean.event.readaudit.ReadAuditLogger;
import io.ebean.event.readaudit.ReadAuditPrepare;
import io.ebean.event.readaudit.ReadAuditQueryPlan;
import io.ebean.event.readaudit.ReadEvent;
import io.ebeaninternal.api.SpiEbeanServer;
import org.tests.model.basic.Country;
import org.tests.model.basic.EBasicChangeLog;
import org.ebeantest.LoggedSqlCollector;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
import static org.assertj.core.api.Assertions.assertThat;
public class TestReadAudit extends BaseTestCase {
TDReadAuditPrepare readAuditPrepare = new TDReadAuditPrepare(true);
TDReadAuditLogger readAuditLogger = new TDReadAuditLogger(true);
SpiEbeanServer server;
Long id1;
Long id2;
@Before
public void setup() {
server = getServer();
EBasicChangeLog bean = new EBasicChangeLog();
bean.setName("readAudito1");
bean.setShortDescription("readAudit hello");
server.save(bean);
id1 = bean.getId();
EBasicChangeLog bean2 = new EBasicChangeLog();
bean2.setName("readAudito2");
bean2.setShortDescription("readAudit hi");
server.save(bean2);
id2 = bean2.getId();
Country ar = new Country();
ar.setCode("AR");
ar.setName("Argentina");
server.save(ar);
}
@After
public void shutdown() {
server.shutdown(true, false);
}
@Test
public void test_findById() {
resetCounters();
EBasicChangeLog found = server.find(EBasicChangeLog.class, id1);
assertThat(found).isNotNull();
assertThat(readAuditPrepare.count).isEqualTo(1);
assertThat(readAuditLogger.plans).hasSize(1);
assertThat(readAuditLogger.beans).hasSize(1);
assertThat(readAuditLogger.beans.get(0).getBeanType()).isEqualTo(EBasicChangeLog.class.getName());
assertThat(readAuditLogger.beans.get(0).getId()).isEqualTo(id1);
}
@Test
public void test_findById_usingL2Cache() {
resetCounters();
EBasicChangeLog found = server.find(EBasicChangeLog.class, id1);
assertThat(found).isNotNull();
assertThat(readAuditPrepare.count).isEqualTo(1);
assertThat(readAuditLogger.plans).hasSize(1);
assertThat(readAuditLogger.beans).hasSize(1);
assertThat(readAuditLogger.beans.get(0).getBeanType()).isEqualTo(EBasicChangeLog.class.getName());
assertThat(readAuditLogger.beans.get(0).getId()).isEqualTo(id1);
ServerCache beanCache = server.getServerCacheManager().getBeanCache(EBasicChangeLog.class);
ServerCacheStatistics statistics = beanCache.getStatistics(false);
assertThat(statistics.getSize()).isEqualTo(1);
assertThat(statistics.getHitCount()).isEqualTo(0);
EBasicChangeLog found2 = server.find(EBasicChangeLog.class, id1);
assertThat(found2).isNotNull();
statistics = beanCache.getStatistics(false);
assertThat(statistics.getSize()).isEqualTo(1);
assertThat(statistics.getHitCount()).isEqualTo(1);
assertThat(readAuditLogger.beans).hasSize(2);
}
@Test
public void test_findById_usingL2Cache_sharedBean() {
resetCounters();
Country found = server.find(Country.class, "AR");
assertThat(found).isNotNull();
assertThat(readAuditPrepare.count).isEqualTo(1);
assertThat(readAuditLogger.plans).hasSize(1);
assertThat(readAuditLogger.beans).hasSize(1);
assertThat(readAuditLogger.beans.get(0).getBeanType()).isEqualTo(Country.class.getName());
assertThat(readAuditLogger.beans.get(0).getId()).isEqualTo("AR");
ServerCache beanCache = server.getServerCacheManager().getBeanCache(Country.class);
ServerCacheStatistics statistics = beanCache.getStatistics(false);
assertThat(statistics.getSize()).isEqualTo(1);
assertThat(statistics.getHitCount()).isEqualTo(0);
Country found2 = server.find(Country.class, "AR");
assertThat(found2).isNotNull();
statistics = beanCache.getStatistics(false);
assertThat(statistics.getSize()).isEqualTo(1);
assertThat(statistics.getHitCount()).isEqualTo(1);
assertThat(readAuditLogger.beans).hasSize(2);
Country ref = server.getReference(Country.class, "AR");
assertThat(readAuditLogger.beans).hasSize(3);
assertThat(ref).isSameAs(found2);
}
@Test
public void test_findList() {
resetCounters();
List<EBasicChangeLog> list = server.find(EBasicChangeLog.class)
.where().startsWith("shortDescription", "readAudit")
.findList();
assertThat(list).hasSize(2);
assertThat(readAuditPrepare.count).isEqualTo(1);
assertThat(readAuditLogger.plans).hasSize(1);
assertThat(readAuditLogger.many).hasSize(1);
assertThat(readAuditLogger.many.get(0).getBeanType()).isEqualTo(EBasicChangeLog.class.getName());
assertThat(readAuditLogger.many.get(0).getIds()).contains(id1, id2);
server.find(EBasicChangeLog.class)
.where().startsWith("shortDescription", "readAudit")
.findList();
assertThat(readAuditPrepare.count).isEqualTo(2);
assertThat(readAuditLogger.plans).hasSize(1);
assertThat(readAuditLogger.many).hasSize(2);
}
@Test
public void test_findList_useL2Cache() {
resetCounters();
LoggedSqlCollector.start();
List<EBasicChangeLog> list = server.find(EBasicChangeLog.class)
.setUseQueryCache(true)
.where().startsWith("shortDescription", "readAudit")
.findList();
System.out.println("test_findList_useL2Cache> first query");
assertThat(list).hasSize(2);
assertThat(readAuditPrepare.count).isEqualTo(1);
assertThat(readAuditLogger.plans).hasSize(1);
assertThat(readAuditLogger.many).hasSize(1);
assertThat(readAuditLogger.many.get(0).getBeanType()).isEqualTo(EBasicChangeLog.class.getName());
assertThat(readAuditLogger.many.get(0).getIds()).contains(id1, id2);
List<EBasicChangeLog> list1 = server.find(EBasicChangeLog.class)
.setUseQueryCache(true)
.where().startsWith("shortDescription", "readAudit")
.findList();
System.out.println("test_findList_useL2Cache> second query " + list1.size());
assertThat(list1).hasSize(2);
List<String> sql = LoggedSqlCollector.stop();
System.out.println("test_findList_useL2Cache> sql: " + sql);
//assertThat(sql).hasSize(1);
System.out.println("test_findList_useL2Cache> prepare:" + readAuditPrepare.count
+ " plans:" + readAuditLogger.plans
+ " many:" + readAuditLogger.many);
assertThat(readAuditPrepare.count).isEqualTo(2);
assertThat(readAuditLogger.plans).hasSize(1);
assertThat(readAuditLogger.many).hasSize(2);
}
@Test
public void test_findFutureList() throws ExecutionException, InterruptedException {
resetCounters();
FutureList<EBasicChangeLog> futureList = server.find(EBasicChangeLog.class)
.where().startsWith("shortDescription", "readAudit")
.findFutureList();
List<EBasicChangeLog> list = futureList.get();
assertThat(list).hasSize(2);
assertThat(readAuditPrepare.count).isEqualTo(1);
assertThat(readAuditLogger.plans).hasSize(1);
assertThat(readAuditLogger.many).hasSize(1);
assertThat(readAuditLogger.many.get(0).getBeanType()).isEqualTo(EBasicChangeLog.class.getName());
assertThat(readAuditLogger.many.get(0).getIds()).contains(id1, id2);
server.find(EBasicChangeLog.class)
.where().startsWith("shortDescription", "readAudit")
.findList();
assertThat(readAuditPrepare.count).isEqualTo(2);
assertThat(readAuditLogger.plans).hasSize(1);
assertThat(readAuditLogger.many).hasSize(2);
}
@Test
public void test_findSet() {
resetCounters();
Set<EBasicChangeLog> list = server.find(EBasicChangeLog.class)
.where().startsWith("shortDescription", "readAudit")
.findSet();
assertThat(list).hasSize(2);
assertThat(readAuditPrepare.count).isEqualTo(1);
assertThat(readAuditLogger.plans).hasSize(1);
assertThat(readAuditLogger.many).hasSize(1);
assertThat(readAuditLogger.many.get(0).getIds()).contains(id1, id2);
server.find(EBasicChangeLog.class)
.where().startsWith("shortDescription", "readAudit")
.findSet();
assertThat(readAuditPrepare.count).isEqualTo(2);
assertThat(readAuditLogger.plans).hasSize(1);
assertThat(readAuditLogger.many).hasSize(2);
}
@Test
public void test_findMap() {
resetCounters();
Map<Long, EBasicChangeLog> list = server.find(EBasicChangeLog.class)
.where().startsWith("shortDescription", "readAudit")
.findMap();
assertThat(list).hasSize(2);
assertThat(readAuditPrepare.count).isEqualTo(1);
assertThat(readAuditLogger.plans).hasSize(1);
assertThat(readAuditLogger.many).hasSize(1);
assertThat(readAuditLogger.many.get(0).getIds()).contains(id1, id2);
server.find(EBasicChangeLog.class)
.where().startsWith("shortDescription", "readAudit")
.findMap();
assertThat(readAuditPrepare.count).isEqualTo(2);
assertThat(readAuditLogger.plans).hasSize(1);
assertThat(readAuditLogger.many).hasSize(2);
}
@Test
public void test_findEach() {
resetCounters();
final AtomicInteger count = new AtomicInteger();
server.find(EBasicChangeLog.class)
.where().startsWith("shortDescription", "readAudit")
.findEach(bean -> count.incrementAndGet());
assertThat(count.get()).isEqualTo(2);
assertThat(readAuditPrepare.count).isEqualTo(1);
assertThat(readAuditLogger.plans).hasSize(1);
assertThat(readAuditLogger.many).hasSize(1);
assertThat(readAuditLogger.many.get(0).getIds()).contains(id1, id2);
server.find(EBasicChangeLog.class)
.where().startsWith("shortDescription", "readAudit")
.findEach(bean -> count.incrementAndGet());
assertThat(readAuditPrepare.count).isEqualTo(2);
assertThat(readAuditLogger.plans).hasSize(1);
assertThat(readAuditLogger.many).hasSize(2);
}
private SpiEbeanServer getServer() {
System.setProperty("ebean.ignoreExtraDdl", "true");
ServerConfig config = new ServerConfig();
config.setName("h2other");
config.loadFromProperties();
config.setDdlGenerate(true);
config.setDdlRun(true);
config.setDefaultServer(false);
config.setRegister(false);
config.addClass(Country.class);
config.addClass(EBasicChangeLog.class);
config.setReadAuditLogger(readAuditLogger);
config.setReadAuditPrepare(readAuditPrepare);
return (SpiEbeanServer) EbeanServerFactory.create(config);
}
private void resetCounters() {
readAuditLogger.resetCounters();
readAuditPrepare.resetCounters();
}
class TDReadAuditPrepare implements ReadAuditPrepare {
int count;
TDReadAuditPrepare(boolean dummy) {
}
void resetCounters() {
count = 0;
}
@Override
public void prepare(ReadEvent event) {
count++;
event.setUserId("appUser1");
event.setUserIpAddress("1.1.1.1");
event.getUserContext().put("some", "thing");
}
}
class TDReadAuditLogger implements ReadAuditLogger {
Set<ReadAuditQueryPlan> plans = new HashSet<>();
List<ReadEvent> beans = new ArrayList<>();
List<ReadEvent> many = new ArrayList<>();
TDReadAuditLogger(boolean dummy) {
}
void resetCounters() {
plans.clear();
beans.clear();
many.clear();
}
@Override
public void queryPlan(ReadAuditQueryPlan queryPlan) {
plans.add(queryPlan);
}
@Override
public void auditBean(ReadEvent readBean) {
beans.add(readBean);
}
@Override
public void auditMany(ReadEvent readMany) {
many.add(readMany);
}
}
}