mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
[15x] Remove Read Auditing feature
This commit is contained in:
@@ -670,16 +670,6 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
Query<T> setDisableLazyLoading(boolean disableLazyLoading);
|
||||
|
||||
/**
|
||||
* Disable read auditing for this query.
|
||||
* <p>
|
||||
* This is intended to be used when the query is not a user initiated query and instead
|
||||
* part of the internal processing in an application to load a cache or document store etc.
|
||||
* In these cases we don't want the query to be part of read auditing.
|
||||
* </p>
|
||||
*/
|
||||
Query<T> setDisableReadAuditing();
|
||||
|
||||
/**
|
||||
* Set a label on the query (to help identify query execution statistics).
|
||||
*/
|
||||
|
||||
@@ -424,16 +424,6 @@ public interface Query<T> extends CancelableQuery {
|
||||
*/
|
||||
Query<T> setIncludeSoftDeletes();
|
||||
|
||||
/**
|
||||
* Disable read auditing for this query.
|
||||
* <p>
|
||||
* This is intended to be used when the query is not a user initiated query and instead
|
||||
* part of the internal processing in an application to load a cache or document store etc.
|
||||
* In these cases we don't want the query to be part of read auditing.
|
||||
* </p>
|
||||
*/
|
||||
Query<T> setDisableReadAuditing();
|
||||
|
||||
/**
|
||||
* Specify the properties to fetch on the root level entity bean in comma delimited format.
|
||||
* <p>
|
||||
|
||||
@@ -14,8 +14,6 @@ import io.ebean.event.*;
|
||||
import io.ebean.event.changelog.ChangeLogListener;
|
||||
import io.ebean.event.changelog.ChangeLogPrepare;
|
||||
import io.ebean.event.changelog.ChangeLogRegister;
|
||||
import io.ebean.event.readaudit.ReadAuditLogger;
|
||||
import io.ebean.event.readaudit.ReadAuditPrepare;
|
||||
import io.ebean.meta.MetricNamingMatch;
|
||||
import io.ebean.util.StringHelper;
|
||||
|
||||
@@ -416,8 +414,6 @@ public class DatabaseConfig {
|
||||
private ChangeLogListener changeLogListener;
|
||||
private ChangeLogRegister changeLogRegister;
|
||||
private boolean changeLogAsync = true;
|
||||
private ReadAuditLogger readAuditLogger;
|
||||
private ReadAuditPrepare readAuditPrepare;
|
||||
private EncryptKeyManager encryptKeyManager;
|
||||
private EncryptDeployManager encryptDeployManager;
|
||||
private Encryptor encryptor;
|
||||
@@ -1197,40 +1193,6 @@ public class DatabaseConfig {
|
||||
this.changeLogAsync = changeLogAsync;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ReadAuditLogger to use.
|
||||
*/
|
||||
public ReadAuditLogger getReadAuditLogger() {
|
||||
return readAuditLogger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ReadAuditLogger to use. If not set the default implementation is used
|
||||
* which logs the read events in JSON format to a standard named SLF4J logger
|
||||
* (which can be configured in say logback to log to a separate log file).
|
||||
*/
|
||||
public void setReadAuditLogger(ReadAuditLogger readAuditLogger) {
|
||||
this.readAuditLogger = readAuditLogger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ReadAuditPrepare to use.
|
||||
*/
|
||||
public ReadAuditPrepare getReadAuditPrepare() {
|
||||
return readAuditPrepare;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ReadAuditPrepare to use.
|
||||
* <p>
|
||||
* It is expected that an implementation is used that read user context information
|
||||
* (user id, user ip address etc) and sets it on the ReadEvent bean before it is sent
|
||||
* to the ReadAuditLogger.
|
||||
*/
|
||||
public void setReadAuditPrepare(ReadAuditPrepare readAuditPrepare) {
|
||||
this.readAuditPrepare = readAuditPrepare;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configuration for profiling.
|
||||
*/
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
package io.ebean.event.readaudit;
|
||||
|
||||
/**
|
||||
* Log that the query was executed
|
||||
*/
|
||||
public interface ReadAuditLogger {
|
||||
|
||||
/**
|
||||
* Called when a new query plan is created.
|
||||
* <p>
|
||||
* The query plan has the full sql and logging the query plan separately means that each of
|
||||
* the bean and many read events can log the query plan key and not the full sql (reducing the
|
||||
* bulk size of the read audit logs).
|
||||
* </p>
|
||||
*/
|
||||
void queryPlan(ReadAuditQueryPlan queryPlan);
|
||||
|
||||
/**
|
||||
* Audit a find bean query that returned a bean.
|
||||
* <p>
|
||||
* Finds that did not return a bean are excluded.
|
||||
* </p>
|
||||
*/
|
||||
void auditBean(ReadEvent readBean);
|
||||
|
||||
/**
|
||||
* Audit a find many query that returned some beans.
|
||||
* <p>
|
||||
* Finds that did not return any beans are excluded.
|
||||
* </p>
|
||||
* <p>
|
||||
* For large queries executed via findEach() etc the ids are collected in batches
|
||||
* and logged. Hence the ids list has a maximum size of the batch size.
|
||||
* </p>
|
||||
*/
|
||||
void auditMany(ReadEvent readMany);
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package io.ebean.event.readaudit;
|
||||
|
||||
/**
|
||||
* Set user context information into the read event prior to it being logged.
|
||||
*/
|
||||
public interface ReadAuditPrepare {
|
||||
|
||||
/**
|
||||
* Prepare the read event by setting any user context information into the read event such as the
|
||||
* application user id and ip address.
|
||||
* <p>
|
||||
* This method is called prior to the read event being sent to the ReadAuditLogger.
|
||||
* </p>
|
||||
* <p>
|
||||
* Note that for findFutureList() queries prepare() is called early in the foreground thread
|
||||
* prior to the query executing and at that point the ReadEvent bean only has the bean type
|
||||
* and no other details (which are populated later when the query is executed in the background
|
||||
* thread).
|
||||
* </p>
|
||||
*/
|
||||
void prepare(ReadEvent readEvent);
|
||||
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
package io.ebean.event.readaudit;
|
||||
|
||||
/**
|
||||
* A SQL query and associated keys.
|
||||
* <p>
|
||||
* This is logged as a separate event so that the
|
||||
* </p>
|
||||
*/
|
||||
public class ReadAuditQueryPlan {
|
||||
|
||||
String beanType;
|
||||
|
||||
String queryKey;
|
||||
|
||||
String sql;
|
||||
|
||||
/**
|
||||
* Construct given the beanType, queryKey and sql.
|
||||
*/
|
||||
public ReadAuditQueryPlan(String beanType, String queryKey, String sql) {
|
||||
this.beanType = beanType;
|
||||
this.queryKey = queryKey;
|
||||
this.sql = sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct for JSON tools.
|
||||
*/
|
||||
public ReadAuditQueryPlan() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "beanType:" + beanType + " queryKey:" + queryKey + " sql:" + sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the bean type.
|
||||
*/
|
||||
public String getBeanType() {
|
||||
return beanType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the bean type.
|
||||
*/
|
||||
public void setBeanType(String beanType) {
|
||||
this.beanType = beanType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the query key (relative to the bean type).
|
||||
*/
|
||||
public String getQueryKey() {
|
||||
return queryKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the query key.
|
||||
*/
|
||||
public void setQueryKey(String queryKey) {
|
||||
this.queryKey = queryKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the sql statement.
|
||||
*/
|
||||
public String getSql() {
|
||||
return sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the sql statement.
|
||||
*/
|
||||
public void setSql(String sql) {
|
||||
this.sql = sql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
ReadAuditQueryPlan that = (ReadAuditQueryPlan) o;
|
||||
if (!beanType.equals(that.beanType)) return false;
|
||||
if (!queryKey.equals(that.queryKey)) return false;
|
||||
return sql.equals(that.sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = beanType.hashCode();
|
||||
result = 92821 * result + queryKey.hashCode();
|
||||
result = 92821 * result + sql.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,261 +0,0 @@
|
||||
package io.ebean.event.readaudit;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Read event sent to the ReadEventLogger.
|
||||
* <p>
|
||||
* This is a flattened in that it contains either a read bean or list of beans. It is flattened
|
||||
* in this way to simplify logging and processing and simply means that it either contains an
|
||||
* id or a list of ids.
|
||||
* </p>
|
||||
*/
|
||||
public class ReadEvent {
|
||||
|
||||
/**
|
||||
* User defined 'source' such as the application name.
|
||||
*/
|
||||
protected String source;
|
||||
|
||||
/**
|
||||
* Application user id expected to be optionally populated by ChangeLogPrepare.
|
||||
*/
|
||||
protected String userId;
|
||||
|
||||
/**
|
||||
* Application user ip address expected to be optionally populated by ChangeLogPrepare.
|
||||
*/
|
||||
protected String userIpAddress;
|
||||
|
||||
/**
|
||||
* Arbitrary user context information expected to be optionally populated by ChangeLogPrepare.
|
||||
*/
|
||||
protected Map<String, String> userContext;
|
||||
|
||||
/**
|
||||
* The time the bean change was created.
|
||||
*/
|
||||
protected long eventTime;
|
||||
|
||||
/**
|
||||
* The type of the bean(s) read.
|
||||
*/
|
||||
protected String beanType;
|
||||
|
||||
/**
|
||||
* The query key (relative to the bean type).
|
||||
*/
|
||||
protected String queryKey;
|
||||
|
||||
/**
|
||||
* The bind log when the query was executed.
|
||||
*/
|
||||
protected String bindLog;
|
||||
|
||||
/**
|
||||
* The id of the bean read.
|
||||
*/
|
||||
protected Object id;
|
||||
|
||||
/**
|
||||
* The ids of the beans read.
|
||||
*/
|
||||
protected List<Object> ids;
|
||||
|
||||
/**
|
||||
* Common constructor for single bean and multi-bean read events.
|
||||
*/
|
||||
protected ReadEvent(String beanType, String queryKey, String bindLog) {
|
||||
this.beanType = beanType;
|
||||
this.queryKey = queryKey;
|
||||
this.bindLog = bindLog;
|
||||
this.eventTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct for a single bean read.
|
||||
*/
|
||||
public ReadEvent(String beanType, String queryKey, String bindLog, Object id) {
|
||||
this(beanType, queryKey, bindLog);
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct for many beans read.
|
||||
*/
|
||||
public ReadEvent(String beanType, String queryKey, String bindLog, List<Object> ids) {
|
||||
this(beanType, queryKey, bindLog);
|
||||
this.ids = ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct for many future list query.
|
||||
*/
|
||||
public ReadEvent(String beanType) {
|
||||
this.beanType = beanType;
|
||||
this.eventTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for JSON tools.
|
||||
*/
|
||||
public ReadEvent() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a code that identifies the source of the change (like the name of the application).
|
||||
*/
|
||||
public String getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the source of the change (like the name of the application).
|
||||
*/
|
||||
public void setSource(String source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the application user Id.
|
||||
*/
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the application user Id.
|
||||
* <p>
|
||||
* This can be set by the ChangeLogListener in the prepare() method which is called
|
||||
* in the foreground thread.
|
||||
* </p>
|
||||
*/
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the application users ip address.
|
||||
*/
|
||||
public String getUserIpAddress() {
|
||||
return userIpAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the application users ip address.
|
||||
* <p>
|
||||
* This can be set by the ChangeLogListener in the prepare() method which is called
|
||||
* in the foreground thread.
|
||||
* </p>
|
||||
*/
|
||||
public void setUserIpAddress(String userIpAddress) {
|
||||
this.userIpAddress = userIpAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a user context value - anything you set yourself in ChangeLogListener prepare().
|
||||
*/
|
||||
public Map<String, String> getUserContext() {
|
||||
if (userContext == null) {
|
||||
userContext = new LinkedHashMap<>();
|
||||
}
|
||||
return userContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a user context value (anything you like).
|
||||
* <p>
|
||||
* This can be set by the ChangeLogListener in the prepare() method which is called
|
||||
* in the foreground thread.
|
||||
* </p>
|
||||
*/
|
||||
public void setUserContext(Map<String, String> userContext) {
|
||||
this.userContext = userContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of bean read.
|
||||
*/
|
||||
public String getBeanType() {
|
||||
return beanType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type of bean read.
|
||||
*/
|
||||
public void setBeanType(String beanType) {
|
||||
this.beanType = beanType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the query key (relative to the bean type).
|
||||
*/
|
||||
public String getQueryKey() {
|
||||
return queryKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the query key (relative to the bean type).
|
||||
*/
|
||||
public void setQueryKey(String queryKey) {
|
||||
this.queryKey = queryKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the bind log used when executing the query.
|
||||
*/
|
||||
public String getBindLog() {
|
||||
return bindLog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the bind log used when executing the query.
|
||||
*/
|
||||
public void setBindLog(String bindLog) {
|
||||
this.bindLog = bindLog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the event date time.
|
||||
*/
|
||||
public long getEventTime() {
|
||||
return eventTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the event date time.
|
||||
*/
|
||||
public void setEventTime(long eventTime) {
|
||||
this.eventTime = eventTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the id of the bean read.
|
||||
*/
|
||||
public Object getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the id of the bean read.
|
||||
*/
|
||||
public void setId(Object id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ids of the beans read.
|
||||
*/
|
||||
public List<Object> getIds() {
|
||||
return ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ids of the beans read.
|
||||
*/
|
||||
public void setIds(List<Object> ids) {
|
||||
this.ids = ids;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
/**
|
||||
* Provides Auditing of read events including queries and L2 cache.
|
||||
* <p>
|
||||
* Provides a built support for supplied an audit of all the 'read events' for beans annotated
|
||||
* with <code>@ReadAudit</code>
|
||||
* </p>
|
||||
*/
|
||||
package io.ebean.event.readaudit;
|
||||
@@ -30,7 +30,6 @@ module io.ebean.api {
|
||||
exports io.ebean.config;
|
||||
exports io.ebean.config.dbplatform;
|
||||
exports io.ebean.event;
|
||||
exports io.ebean.event.readaudit;
|
||||
exports io.ebean.event.changelog;
|
||||
exports io.ebean.common;
|
||||
exports io.ebean.docstore;
|
||||
|
||||
@@ -4,8 +4,6 @@ import io.avaje.lang.Nullable;
|
||||
import io.ebean.*;
|
||||
import io.ebean.bean.BeanCollectionLoader;
|
||||
import io.ebean.bean.CallOrigin;
|
||||
import io.ebean.event.readaudit.ReadAuditLogger;
|
||||
import io.ebean.event.readaudit.ReadAuditPrepare;
|
||||
import io.ebean.meta.MetricVisitor;
|
||||
import io.ebean.plugin.SpiServer;
|
||||
import io.ebeaninternal.api.SpiQuery.Type;
|
||||
@@ -190,17 +188,6 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectio
|
||||
*/
|
||||
boolean isSupportedType(java.lang.reflect.Type genericType);
|
||||
|
||||
/**
|
||||
* Return the ReadAuditLogger to use for logging all read audit events.
|
||||
*/
|
||||
ReadAuditLogger readAuditLogger();
|
||||
|
||||
/**
|
||||
* Return the ReadAuditPrepare used to populate the read audit events with
|
||||
* user context information (user id, user ip address etc).
|
||||
*/
|
||||
ReadAuditPrepare readAuditPrepare();
|
||||
|
||||
/**
|
||||
* Return the DataTimeZone to use when reading/writing timestamps via JDBC.
|
||||
*/
|
||||
|
||||
@@ -10,7 +10,6 @@ import io.ebean.Query;
|
||||
import io.ebean.bean.CallOrigin;
|
||||
import io.ebean.bean.ObjectGraphNode;
|
||||
import io.ebean.bean.PersistenceContext;
|
||||
import io.ebean.event.readaudit.ReadEvent;
|
||||
import io.ebean.plugin.BeanType;
|
||||
import io.ebeaninternal.server.autotune.ProfilingListener;
|
||||
import io.ebeaninternal.server.core.SpiOrmQueryRequest;
|
||||
@@ -867,21 +866,6 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
||||
*/
|
||||
int bufferFetchSizeHint();
|
||||
|
||||
/**
|
||||
* Return true if read auditing is disabled on this query.
|
||||
*/
|
||||
boolean isDisableReadAudit();
|
||||
|
||||
/**
|
||||
* Set the readEvent for future queries (as prepared in foreground thread).
|
||||
*/
|
||||
void setFutureFetchAudit(ReadEvent event);
|
||||
|
||||
/**
|
||||
* Read the readEvent for future queries (null otherwise).
|
||||
*/
|
||||
ReadEvent futureFetchAudit();
|
||||
|
||||
/**
|
||||
* Return the base table to use if user defined on the query.
|
||||
*/
|
||||
|
||||
@@ -13,8 +13,6 @@ import io.ebean.config.*;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebean.event.BeanPersistController;
|
||||
import io.ebean.event.ShutdownManager;
|
||||
import io.ebean.event.readaudit.ReadAuditLogger;
|
||||
import io.ebean.event.readaudit.ReadAuditPrepare;
|
||||
import io.ebean.meta.*;
|
||||
import io.ebean.migration.auto.AutoMigrationRunner;
|
||||
import io.ebean.plugin.BeanType;
|
||||
@@ -92,8 +90,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
private final DtoBeanManager dtoBeanManager;
|
||||
private final BeanDescriptorManager descriptorManager;
|
||||
private final AutoTuneService autoTuneService;
|
||||
private final ReadAuditPrepare readAuditPrepare;
|
||||
private final ReadAuditLogger readAuditLogger;
|
||||
private final CQueryEngine cqueryEngine;
|
||||
private final List<Plugin> serverPlugins;
|
||||
private final SpiDdlGenerator ddlGenerator;
|
||||
@@ -145,8 +141,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
this.relationalQueryEngine = config.createRelationalQueryEngine();
|
||||
this.dtoQueryEngine = config.createDtoQueryEngine();
|
||||
this.autoTuneService = config.createAutoTuneService(this);
|
||||
this.readAuditPrepare = config.getReadAuditPrepare();
|
||||
this.readAuditLogger = config.getReadAuditLogger();
|
||||
this.beanLoader = new DefaultBeanLoader(this);
|
||||
this.jsonContext = config.createJsonContext(this);
|
||||
this.dataTimeZone = config.getDataTimeZone();
|
||||
@@ -282,16 +276,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
return transactionManager.readOnlyDataSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadAuditPrepare readAuditPrepare() {
|
||||
return readAuditPrepare;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadAuditLogger readAuditLogger() {
|
||||
return readAuditLogger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run any initialisation required before registering with the ClusterManager.
|
||||
*/
|
||||
@@ -1276,10 +1260,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
SpiQuery<T> spiQuery = query.copy();
|
||||
// FutureList query always run in it's own persistence content
|
||||
spiQuery.setPersistenceContext(new DefaultPersistenceContext());
|
||||
if (!spiQuery.isDisableReadAudit()) {
|
||||
BeanDescriptor<T> desc = descriptorManager.descriptor(spiQuery.getBeanType());
|
||||
desc.readAuditFutureList(spiQuery);
|
||||
}
|
||||
// Create a new transaction solely to execute the findList() at some future time
|
||||
boolean createdTransaction = false;
|
||||
SpiTransaction transaction = query.transaction();
|
||||
|
||||
@@ -13,8 +13,6 @@ import io.ebean.config.dbplatform.DbHistorySupport;
|
||||
import io.ebean.event.changelog.ChangeLogListener;
|
||||
import io.ebean.event.changelog.ChangeLogPrepare;
|
||||
import io.ebean.event.changelog.ChangeLogRegister;
|
||||
import io.ebean.event.readaudit.ReadAuditLogger;
|
||||
import io.ebean.event.readaudit.ReadAuditPrepare;
|
||||
import io.ebean.plugin.Plugin;
|
||||
import io.ebean.plugin.SpiServer;
|
||||
import io.ebeaninternal.api.*;
|
||||
@@ -44,8 +42,6 @@ import io.ebeaninternal.server.persist.DefaultPersister;
|
||||
import io.ebeaninternal.server.persist.platform.MultiValueBind;
|
||||
import io.ebeaninternal.server.persist.platform.PostgresMultiValueBind;
|
||||
import io.ebeaninternal.server.query.*;
|
||||
import io.ebeaninternal.server.readaudit.DefaultReadAuditLogger;
|
||||
import io.ebeaninternal.server.readaudit.DefaultReadAuditPrepare;
|
||||
import io.ebeaninternal.server.json.DJsonContext;
|
||||
import io.ebeaninternal.server.transaction.*;
|
||||
import io.ebeaninternal.server.type.DefaultTypeManager;
|
||||
@@ -231,22 +227,6 @@ public final class InternalConfiguration {
|
||||
return plugin((listener != null) ? listener : jacksonCorePresent ? new DefaultChangeLogListener() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ReadAuditLogger implementation to use.
|
||||
*/
|
||||
ReadAuditLogger getReadAuditLogger() {
|
||||
ReadAuditLogger found = bootupClasses.getReadAuditLogger();
|
||||
return plugin(found != null ? found : jacksonCorePresent ? new DefaultReadAuditLogger() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ReadAuditPrepare implementation to use.
|
||||
*/
|
||||
ReadAuditPrepare getReadAuditPrepare() {
|
||||
ReadAuditPrepare found = bootupClasses.getReadAuditPrepare();
|
||||
return plugin(found != null ? found : new DefaultReadAuditPrepare());
|
||||
}
|
||||
|
||||
/**
|
||||
* For 'As Of' queries return the number of bind variables per predicate.
|
||||
*/
|
||||
|
||||
@@ -648,17 +648,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
}
|
||||
|
||||
Object cached = beanDescriptor.queryCacheGet(cacheKey);
|
||||
if (cached != null && isAuditReads() && readAuditQueryType()) {
|
||||
if (cached instanceof BeanCollection) {
|
||||
// raw sql can't use L2 cache so normal queries only in here
|
||||
Collection<T> actualDetails = ((BeanCollection<T>) cached).actualDetails();
|
||||
List<Object> ids = new ArrayList<>(actualDetails.size());
|
||||
for (T bean : actualDetails) {
|
||||
ids.add(beanDescriptor.idForJson(bean));
|
||||
}
|
||||
beanDescriptor.readAuditMany(queryPlanKey.partialKey(), "l2-query-cache", ids);
|
||||
}
|
||||
}
|
||||
if (Boolean.FALSE.equals(query.isReadOnly())) {
|
||||
// return shallow copies if readonly is explicitly set to false
|
||||
if (cached instanceof BeanCollection) {
|
||||
@@ -674,24 +663,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
return cached;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the query type contains bean data (not just ids etc) and hence we want to include
|
||||
* it in read auditing. Return false for row count and find ids queries.
|
||||
*/
|
||||
private boolean readAuditQueryType() {
|
||||
Type type = query.type();
|
||||
switch (type) {
|
||||
case BEAN:
|
||||
case ITERATE:
|
||||
case LIST:
|
||||
case SET:
|
||||
case MAP:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void putToQueryCache(Object result) {
|
||||
beanDescriptor.queryCachePut(cacheKey, new QueryCacheEntry(result, dependentTables, transaction.startNanoTime()));
|
||||
}
|
||||
@@ -718,15 +689,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
return (batchSize > 0) ? batchSize : server.lazyLoadBatchSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if read auditing is on for this query request.
|
||||
* <p>
|
||||
* This means that read audit is on for this bean type and that query has not explicitly disabled it.
|
||||
*/
|
||||
public boolean isAuditReads() {
|
||||
return beanDescriptor.isReadAuditing() && !query.isDisableReadAudit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the base table alias for this query.
|
||||
*/
|
||||
|
||||
@@ -9,8 +9,6 @@ import io.ebean.event.*;
|
||||
import io.ebean.event.changelog.ChangeLogListener;
|
||||
import io.ebean.event.changelog.ChangeLogPrepare;
|
||||
import io.ebean.event.changelog.ChangeLogRegister;
|
||||
import io.ebean.event.readaudit.ReadAuditLogger;
|
||||
import io.ebean.event.readaudit.ReadAuditPrepare;
|
||||
import io.ebean.util.AnnotationUtil;
|
||||
import io.ebeaninternal.api.CoreLog;
|
||||
|
||||
@@ -68,14 +66,10 @@ public class BootupClasses implements Predicate<Class<?>> {
|
||||
private Class<? extends ChangeLogPrepare> changeLogPrepareClass;
|
||||
private Class<? extends ChangeLogListener> changeLogListenerClass;
|
||||
private Class<? extends ChangeLogRegister> changeLogRegisterClass;
|
||||
private Class<? extends ReadAuditPrepare> readAuditPrepareClass;
|
||||
private Class<? extends ReadAuditLogger> readAuditLoggerClass;
|
||||
|
||||
private ChangeLogPrepare changeLogPrepare;
|
||||
private ChangeLogListener changeLogListener;
|
||||
private ChangeLogRegister changeLogRegister;
|
||||
private ReadAuditPrepare readAuditPrepare;
|
||||
private ReadAuditLogger readAuditLogger;
|
||||
|
||||
public BootupClasses() {
|
||||
}
|
||||
@@ -173,19 +167,11 @@ public class BootupClasses implements Predicate<Class<?>> {
|
||||
}
|
||||
|
||||
public void addChangeLogInstances(DatabaseConfig config) {
|
||||
readAuditPrepare = config.getReadAuditPrepare();
|
||||
readAuditLogger = config.getReadAuditLogger();
|
||||
changeLogPrepare = config.getChangeLogPrepare();
|
||||
changeLogListener = config.getChangeLogListener();
|
||||
changeLogRegister = config.getChangeLogRegister();
|
||||
// if not already set create the implementations found
|
||||
// via classpath scanning
|
||||
if (readAuditPrepare == null && readAuditPrepareClass != null) {
|
||||
readAuditPrepare = create(readAuditPrepareClass, false);
|
||||
}
|
||||
if (readAuditLogger == null && readAuditLoggerClass != null) {
|
||||
readAuditLogger = create(readAuditLoggerClass, false);
|
||||
}
|
||||
if (changeLogPrepare == null && changeLogPrepareClass != null) {
|
||||
changeLogPrepare = create(changeLogPrepareClass, false);
|
||||
}
|
||||
@@ -252,14 +238,6 @@ public class BootupClasses implements Predicate<Class<?>> {
|
||||
return changeLogRegister;
|
||||
}
|
||||
|
||||
public ReadAuditPrepare getReadAuditPrepare() {
|
||||
return readAuditPrepare;
|
||||
}
|
||||
|
||||
public ReadAuditLogger getReadAuditLogger() {
|
||||
return readAuditLogger;
|
||||
}
|
||||
|
||||
public List<IdGenerator> getIdGenerators() {
|
||||
return createAdd(idGeneratorInstances, idGeneratorCandidates);
|
||||
}
|
||||
@@ -424,15 +402,6 @@ public class BootupClasses implements Predicate<Class<?>> {
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (ReadAuditPrepare.class.isAssignableFrom(cls)) {
|
||||
readAuditPrepareClass = (Class<? extends ReadAuditPrepare>) cls;
|
||||
interesting = true;
|
||||
}
|
||||
if (ReadAuditLogger.class.isAssignableFrom(cls)) {
|
||||
readAuditLoggerClass = (Class<? extends ReadAuditLogger>) cls;
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
return interesting;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,9 +14,6 @@ import io.ebean.event.*;
|
||||
import io.ebean.event.changelog.BeanChange;
|
||||
import io.ebean.event.changelog.ChangeLogFilter;
|
||||
import io.ebean.event.changelog.ChangeType;
|
||||
import io.ebean.event.readaudit.ReadAuditLogger;
|
||||
import io.ebean.event.readaudit.ReadAuditPrepare;
|
||||
import io.ebean.event.readaudit.ReadEvent;
|
||||
import io.ebean.meta.MetaQueryPlan;
|
||||
import io.ebean.meta.MetricVisitor;
|
||||
import io.ebean.meta.QueryPlanInit;
|
||||
@@ -123,7 +120,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
private final TablespaceMeta tablespaceMeta;
|
||||
private final String storageEngine;
|
||||
private final String dbComment;
|
||||
private final boolean readAuditing;
|
||||
private final boolean draftable;
|
||||
private final boolean draftableElement;
|
||||
private final BeanProperty unmappedJson;
|
||||
@@ -260,7 +256,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
this.selectLastInsertedIdDraft = deploy.getSelectLastInsertedIdDraft();
|
||||
this.concurrencyMode = deploy.getConcurrencyMode();
|
||||
this.indexDefinitions = deploy.getIndexDefinitions();
|
||||
this.readAuditing = deploy.isReadAuditing();
|
||||
this.draftable = deploy.isDraftable();
|
||||
this.draftableElement = deploy.isDraftableElement();
|
||||
this.historySupport = deploy.isHistorySupport();
|
||||
@@ -719,20 +714,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ReadAuditLogger for logging read audit events.
|
||||
*/
|
||||
public ReadAuditLogger readAuditLogger() {
|
||||
return ebeanServer.readAuditLogger();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ReadAuditPrepare for preparing read audit events prior to logging.
|
||||
*/
|
||||
private ReadAuditPrepare readAuditPrepare() {
|
||||
return ebeanServer.readAuditPrepare();
|
||||
}
|
||||
|
||||
public boolean isChangeLog() {
|
||||
return changeLogFilter != null;
|
||||
}
|
||||
@@ -1354,52 +1335,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
cacheHelp.cacheBeanUpdate(key, changes, updateNaturalKey, version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the read audit of a findFutureList() query.
|
||||
*/
|
||||
public void readAuditFutureList(SpiQuery<T> spiQuery) {
|
||||
if (isReadAuditing()) {
|
||||
ReadEvent event = new ReadEvent(fullName);
|
||||
// prepare in the foreground thread while we have the user context
|
||||
// information (query is processed/executed later in bg thread)
|
||||
readAuditPrepare(event);
|
||||
spiQuery.setFutureFetchAudit(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a bean read to the read audit log.
|
||||
*/
|
||||
public void readAuditBean(String queryKey, String bindLog, Object bean) {
|
||||
ReadEvent event = new ReadEvent(fullName, queryKey, bindLog, idForJson(bean));
|
||||
readAuditPrepare(event);
|
||||
readAuditLogger().auditBean(event);
|
||||
}
|
||||
|
||||
private void readAuditPrepare(ReadEvent event) {
|
||||
ReadAuditPrepare prepare = readAuditPrepare();
|
||||
if (prepare != null) {
|
||||
prepare.prepare(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a many bean read to the read audit log.
|
||||
*/
|
||||
public void readAuditMany(String queryKey, String bindLog, List<Object> ids) {
|
||||
ReadEvent event = new ReadEvent(fullName, queryKey, bindLog, ids);
|
||||
readAuditPrepare(event);
|
||||
readAuditLogger().auditMany(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a futureList many read to the read audit log.
|
||||
*/
|
||||
public void readAuditFutureMany(ReadEvent event) {
|
||||
// this has already been prepared (in foreground thread)
|
||||
readAuditLogger().auditMany(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the base table alias. This is always the first letter of the bean name.
|
||||
*/
|
||||
@@ -1777,9 +1712,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
if (d != null) {
|
||||
Object shareableBean = d.getSharableBean();
|
||||
if (shareableBean != null) {
|
||||
if (isReadAuditing()) {
|
||||
readAuditBean("ref", "", shareableBean);
|
||||
}
|
||||
return (T) shareableBean;
|
||||
}
|
||||
}
|
||||
@@ -2708,13 +2640,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
return draftTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if read auditing is on this entity bean.
|
||||
*/
|
||||
public boolean isReadAuditing() {
|
||||
return readAuditing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSoftDelete() {
|
||||
return softDelete;
|
||||
|
||||
@@ -594,9 +594,6 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
if (beanLog.isLoggable(TRACE)) {
|
||||
beanLog.log(TRACE, " GET {0}({1}) - hit shared bean", cacheName, id);
|
||||
}
|
||||
if (desc.isReadAuditing()) {
|
||||
desc.readAuditBean("l2", "", bean);
|
||||
}
|
||||
return (T) bean;
|
||||
}
|
||||
}
|
||||
@@ -648,9 +645,6 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
}
|
||||
|
||||
CachedBeanDataToBean.load(desc, bean, data, context);
|
||||
if (desc.isReadAuditing()) {
|
||||
desc.readAuditBean("l2", "", bean);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
|
||||
-20
@@ -20,7 +20,6 @@ import io.ebeaninternal.server.deploy.parse.DeployBeanInfo;
|
||||
import io.ebeaninternal.server.idgen.UuidV1IdGenerator;
|
||||
import io.ebeaninternal.server.idgen.UuidV1RndIdGenerator;
|
||||
import io.ebeaninternal.server.idgen.UuidV4IdGenerator;
|
||||
import io.ebeaninternal.server.rawsql.SpiRawSql;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
@@ -31,10 +30,6 @@ import java.util.*;
|
||||
*/
|
||||
public class DeployBeanDescriptor<T> {
|
||||
|
||||
private static final Map<String, String> EMPTY_NAMED_QUERY = new HashMap<>();
|
||||
|
||||
private static final Map<String, SpiRawSql> EMPTY_RAW_MAP = new HashMap<>();
|
||||
|
||||
private static class PropOrder implements Comparator<DeployBeanProperty> {
|
||||
|
||||
@Override
|
||||
@@ -84,7 +79,6 @@ public class DeployBeanDescriptor<T> {
|
||||
private String draftTable;
|
||||
private String[] dependentTables;
|
||||
private boolean historySupport;
|
||||
private boolean readAuditing;
|
||||
private boolean draftable;
|
||||
private boolean draftableElement;
|
||||
private TableName baseTableFull;
|
||||
@@ -193,20 +187,6 @@ public class DeployBeanDescriptor<T> {
|
||||
return historySupport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set read auditing on for this entity bean.
|
||||
*/
|
||||
public void setReadAuditing() {
|
||||
readAuditing = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if read auditing is on for this entity bean.
|
||||
*/
|
||||
public boolean isReadAuditing() {
|
||||
return readAuditing;
|
||||
}
|
||||
|
||||
public void setDbComment(String dbComment) {
|
||||
this.dbComment = dbComment;
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ final class AnnotationClass extends AnnotationParser {
|
||||
}
|
||||
ReadAudit readAudit = typeGet(cls, ReadAudit.class);
|
||||
if (readAudit != null) {
|
||||
descriptor.setReadAuditing();
|
||||
// TODO: Not supported
|
||||
}
|
||||
History history = typeGet(cls, History.class);
|
||||
if (history != null) {
|
||||
|
||||
@@ -536,11 +536,6 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
|
||||
return query.setDisableLazyLoading(disableLazyLoading);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<T> setDisableReadAuditing() {
|
||||
return query.setDisableReadAuditing();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<T> setLabel(String label) {
|
||||
return query.setLabel(label);
|
||||
|
||||
@@ -995,11 +995,6 @@ final class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expr
|
||||
return exprList.setDisableLazyLoading(disableLazyLoading);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<T> setDisableReadAuditing() {
|
||||
return exprList.setDisableReadAuditing();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<T> setCountDistinct(CountDistinctOrder orderBy) {
|
||||
return exprList.setCountDistinct(orderBy);
|
||||
|
||||
@@ -31,7 +31,6 @@ public final class DLoadContext implements LoadContext {
|
||||
private final CacheMode useBeanCache;
|
||||
private final int defaultBatchSize;
|
||||
private final boolean disableLazyLoading;
|
||||
private final boolean disableReadAudit;
|
||||
private final boolean includeSoftDeletes;
|
||||
final boolean useDocStore;
|
||||
|
||||
@@ -64,7 +63,6 @@ public final class DLoadContext implements LoadContext {
|
||||
this.asOf = null;
|
||||
this.readOnly = false;
|
||||
this.disableLazyLoading = false;
|
||||
this.disableReadAudit = false;
|
||||
this.includeSoftDeletes = false;
|
||||
this.relativePath = null;
|
||||
this.planLabel = null;
|
||||
@@ -91,7 +89,6 @@ public final class DLoadContext implements LoadContext {
|
||||
this.asDraft = query.isAsDraft();
|
||||
this.includeSoftDeletes = query.isIncludeSoftDeletes() && query.mode() == SpiQuery.Mode.NORMAL;
|
||||
this.readOnly = query.isReadOnly();
|
||||
this.disableReadAudit = query.isDisableReadAudit();
|
||||
this.disableLazyLoading = query.isDisableLazyLoading();
|
||||
this.useBeanCache = query.beanCacheMode();
|
||||
this.profilingListener = query.profilingListener();
|
||||
@@ -331,9 +328,6 @@ public final class DLoadContext implements LoadContext {
|
||||
if (includeSoftDeletes) {
|
||||
query.setIncludeSoftDeletes();
|
||||
}
|
||||
if (disableReadAudit) {
|
||||
query.setDisableReadAuditing();
|
||||
}
|
||||
if (profilingListener != null) {
|
||||
query.setProfilingListener(profilingListener);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import io.ebean.QueryIterator;
|
||||
import io.ebean.Version;
|
||||
import io.ebean.bean.*;
|
||||
import io.ebean.core.type.DataReader;
|
||||
import io.ebean.event.readaudit.ReadEvent;
|
||||
import io.ebean.util.JdbcClose;
|
||||
import io.ebeaninternal.api.CoreLog;
|
||||
import io.ebeaninternal.api.SpiProfileTransactionEvent;
|
||||
@@ -159,28 +158,12 @@ public final class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfi
|
||||
|
||||
private long executionTimeMicros;
|
||||
|
||||
/**
|
||||
* Flag set when read auditing.
|
||||
*/
|
||||
private final boolean audit;
|
||||
|
||||
/**
|
||||
* Flag set when findIterate is being read audited meaning we log in batches.
|
||||
*/
|
||||
private boolean auditFindIterate;
|
||||
|
||||
/**
|
||||
* A buffer of Ids collected for findIterate auditing.
|
||||
*/
|
||||
private List<Object> auditIds;
|
||||
|
||||
/**
|
||||
* Create the Sql select based on the request.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public CQuery(OrmQueryRequest<T> request, CQueryPredicates predicates, CQueryPlan queryPlan) {
|
||||
this.request = request;
|
||||
this.audit = request.isAuditReads();
|
||||
this.queryPlan = queryPlan;
|
||||
this.query = request.query();
|
||||
this.queryMode = query.mode();
|
||||
@@ -349,13 +332,6 @@ public final class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfi
|
||||
* The JDBC resultSet and statement need to be closed. Its important that this method is called.
|
||||
*/
|
||||
public void close() {
|
||||
try {
|
||||
if (auditFindIterate && auditIds != null && !auditIds.isEmpty()) {
|
||||
auditIterateLogMessage();
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
CoreLog.log.log(ERROR, "Error logging read audit logs", e);
|
||||
}
|
||||
try {
|
||||
if (dataReader != null) {
|
||||
dataReader.close();
|
||||
@@ -475,9 +451,6 @@ public final class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfi
|
||||
}
|
||||
|
||||
EntityBean next() {
|
||||
if (audit) {
|
||||
auditNextBean();
|
||||
}
|
||||
hasNextCache = false;
|
||||
if (nextBean == null) {
|
||||
throw new NoSuchElementException();
|
||||
@@ -682,66 +655,6 @@ public final class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfi
|
||||
this.currentPathMap = currentPathMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* A find bean query with read auditing so build and log the ReadEvent.
|
||||
*/
|
||||
void auditFind(EntityBean bean) {
|
||||
if (bean != null) {
|
||||
// only audit when a bean was actually found
|
||||
desc.readAuditBean(queryPlan.auditQueryKey(), bindLog, bean);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* a find many query with read auditing so build the ReadEvent and log it.
|
||||
*/
|
||||
void auditFindMany() {
|
||||
if (auditIds != null && !auditIds.isEmpty()) {
|
||||
// get the id values of the underlying collection
|
||||
ReadEvent futureReadEvent = query.futureFetchAudit();
|
||||
if (futureReadEvent == null) {
|
||||
// normal query execution
|
||||
desc.readAuditMany(queryPlan.auditQueryKey(), bindLog, auditIds);
|
||||
} else {
|
||||
// this query was executed via findFutureList() and the prepare()
|
||||
// has already been called so set the details and log
|
||||
futureReadEvent.setQueryKey(queryPlan.auditQueryKey());
|
||||
futureReadEvent.setBindLog(bindLog);
|
||||
futureReadEvent.setIds(auditIds);
|
||||
desc.readAuditFutureMany(futureReadEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that read auditing is occurring on this findIterate query.
|
||||
*/
|
||||
void auditFindIterate() {
|
||||
auditFindIterate = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the current buffer of findIterate collected ids to the audit log.
|
||||
*/
|
||||
private void auditIterateLogMessage() {
|
||||
desc.readAuditMany(queryPlan.auditQueryKey(), bindLog, auditIds);
|
||||
// create a new list on demand with the next bean/id
|
||||
auditIds = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the id to the audit id buffer and flush if needed in batches of 100.
|
||||
*/
|
||||
private void auditNextBean() {
|
||||
if (auditIds == null) {
|
||||
auditIds = new ArrayList<>(100);
|
||||
}
|
||||
auditIds.add(desc.idForJson(nextBean));
|
||||
if (auditFindIterate && auditIds.size() >= 100) {
|
||||
auditIterateLogMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the underlying PreparedStatement.
|
||||
*/
|
||||
|
||||
@@ -9,7 +9,6 @@ import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebean.config.dbplatform.SqlLimitRequest;
|
||||
import io.ebean.config.dbplatform.SqlLimitResponse;
|
||||
import io.ebean.config.dbplatform.SqlLimiter;
|
||||
import io.ebean.event.readaudit.ReadAuditQueryPlan;
|
||||
import io.ebean.text.PathProperties;
|
||||
import io.ebean.util.SplitName;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
@@ -345,11 +344,6 @@ final class CQueryBuilder {
|
||||
} else {
|
||||
queryPlan = new CQueryPlan(request, res, sqlTree.plan(), false, predicates.logWhereSql());
|
||||
}
|
||||
BeanDescriptor<T> desc = request.descriptor();
|
||||
if (desc.isReadAuditing()) {
|
||||
// log the query plan based bean type (i.e. ignoring query disabling for logging the sql/plan)
|
||||
desc.readAuditLogger().queryPlan(new ReadAuditQueryPlan(desc.fullName(), queryPlan.auditQueryKey(), queryPlan.sql()));
|
||||
}
|
||||
// cache the query plan because we can reuse it and also
|
||||
// gather query performance statistics based on it.
|
||||
request.putQueryPlan(queryPlan);
|
||||
|
||||
@@ -207,10 +207,6 @@ public final class CQueryEngine {
|
||||
if (request.logSummary()) {
|
||||
logFindManySummary(cquery);
|
||||
}
|
||||
if (request.isAuditReads()) {
|
||||
// indicates we need to audit as the iterator progresses
|
||||
cquery.auditFindIterate();
|
||||
}
|
||||
return readIterate;
|
||||
|
||||
} catch (SQLException e) {
|
||||
@@ -253,9 +249,6 @@ public final class CQueryEngine {
|
||||
if (request.logSummary()) {
|
||||
logFindManySummary(cquery);
|
||||
}
|
||||
if (request.isAuditReads()) {
|
||||
cquery.auditFindMany();
|
||||
}
|
||||
return versions;
|
||||
|
||||
} catch (SQLException e) {
|
||||
@@ -348,9 +341,6 @@ public final class CQueryEngine {
|
||||
if (request.logSummary()) {
|
||||
logFindManySummary(cquery);
|
||||
}
|
||||
if (request.isAuditReads()) {
|
||||
cquery.auditFindMany();
|
||||
}
|
||||
request.executeSecondaryQueries(false);
|
||||
if (request.isQueryCachePut()) {
|
||||
request.addDependentTables(cquery.dependentTables());
|
||||
@@ -383,9 +373,6 @@ public final class CQueryEngine {
|
||||
if (request.logSummary()) {
|
||||
logFindBeanSummary(cquery);
|
||||
}
|
||||
if (request.isAuditReads()) {
|
||||
cquery.auditFind(bean);
|
||||
}
|
||||
request.executeSecondaryQueries(false);
|
||||
return (T) bean;
|
||||
} catch (SQLException e) {
|
||||
|
||||
@@ -210,11 +210,6 @@ final class DefaultFetchGroupQuery<T> implements SpiFetchGroupQuery<T>, SpiQuery
|
||||
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<T> setDisableReadAuditing() {
|
||||
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<T> apply(FetchPath fetchPath) {
|
||||
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
|
||||
|
||||
@@ -7,7 +7,6 @@ import io.ebean.bean.ObjectGraphNode;
|
||||
import io.ebean.bean.ObjectGraphOrigin;
|
||||
import io.ebean.bean.PersistenceContext;
|
||||
import io.ebean.event.BeanQueryRequest;
|
||||
import io.ebean.event.readaudit.ReadEvent;
|
||||
import io.ebean.plugin.BeanType;
|
||||
import io.ebeaninternal.api.*;
|
||||
import io.ebeaninternal.server.autotune.ProfilingListener;
|
||||
@@ -86,11 +85,6 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
*/
|
||||
private boolean distinct;
|
||||
|
||||
/**
|
||||
* Only used for read auditing with findFutureList() query.
|
||||
*/
|
||||
private ReadEvent futureFetchAudit;
|
||||
|
||||
private int timeout;
|
||||
|
||||
/**
|
||||
@@ -1899,27 +1893,6 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
return bufferFetchSizeHint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Query<T> setDisableReadAuditing() {
|
||||
this.disableReadAudit = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isDisableReadAudit() {
|
||||
return disableReadAudit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setFutureFetchAudit(ReadEvent event) {
|
||||
this.futureFetchAudit = event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ReadEvent futureFetchAudit() {
|
||||
return futureFetchAudit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Query<T> setBaseTable(String baseTable) {
|
||||
this.baseTable = baseTable;
|
||||
|
||||
-128
@@ -1,128 +0,0 @@
|
||||
package io.ebeaninternal.server.readaudit;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import io.avaje.applog.AppLog;
|
||||
import io.ebean.event.readaudit.ReadAuditLogger;
|
||||
import io.ebean.event.readaudit.ReadAuditQueryPlan;
|
||||
import io.ebean.event.readaudit.ReadEvent;
|
||||
import io.ebean.text.json.EJson;
|
||||
import io.ebeaninternal.api.CoreLog;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.lang.System.Logger.Level.ERROR;
|
||||
import static java.lang.System.Logger.Level.INFO;
|
||||
|
||||
/**
|
||||
* Default implementation of ReadAuditLogger that writes the event in JSON format to standard loggers.
|
||||
*/
|
||||
public class DefaultReadAuditLogger implements ReadAuditLogger {
|
||||
|
||||
private static final System.Logger queryLogger = AppLog.getLogger("io.ebean.ReadAuditQuery");
|
||||
private static final System.Logger auditLogger = AppLog.getLogger("io.ebean.ReadAudit");
|
||||
|
||||
protected final JsonFactory jsonFactory = new JsonFactory();
|
||||
protected final int defaultQueryBuffer = 500;
|
||||
protected final int defaultReadBuffer = 150;
|
||||
|
||||
/**
|
||||
* Write the query plan details in JSON format to the logger.
|
||||
*/
|
||||
@Override
|
||||
public void queryPlan(ReadAuditQueryPlan queryPlan) {
|
||||
StringWriter writer = new StringWriter(defaultQueryBuffer);
|
||||
try (JsonGenerator gen = jsonFactory.createGenerator(writer)) {
|
||||
gen.writeStartObject();
|
||||
String beanType = queryPlan.getBeanType();
|
||||
if (beanType != null) {
|
||||
gen.writeStringField("beanType", beanType);
|
||||
}
|
||||
String queryKey = queryPlan.getQueryKey();
|
||||
if (queryKey != null) {
|
||||
gen.writeStringField("queryKey", queryKey);
|
||||
}
|
||||
String sql = queryPlan.getSql();
|
||||
if (sql != null) {
|
||||
gen.writeStringField("sql", sql);
|
||||
}
|
||||
gen.writeEndObject();
|
||||
gen.flush();
|
||||
queryLogger.log(INFO, writer.toString());
|
||||
} catch (IOException e) {
|
||||
CoreLog.log.log(ERROR, "Error writing Read audit event", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the bean read event details in JSON format to the logger.
|
||||
*/
|
||||
@Override
|
||||
public void auditBean(ReadEvent beanEvent) {
|
||||
writeEvent(beanEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the many beans read event details in JSON format to the logger.
|
||||
*/
|
||||
@Override
|
||||
public void auditMany(ReadEvent readMany) {
|
||||
writeEvent(readMany);
|
||||
}
|
||||
|
||||
protected void writeEvent(ReadEvent event) {
|
||||
try {
|
||||
StringWriter writer = new StringWriter(defaultReadBuffer);
|
||||
JsonGenerator gen = jsonFactory.createGenerator(writer);
|
||||
writeDetails(gen, event);
|
||||
auditLogger.log(INFO, writer.toString());
|
||||
} catch (IOException e) {
|
||||
CoreLog.log.log(ERROR, "Error writing Read audit event", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the details for the read bean or read many beans event.
|
||||
*/
|
||||
protected void writeDetails(JsonGenerator gen, ReadEvent event) throws IOException {
|
||||
gen.writeStartObject();
|
||||
String source = event.getSource();
|
||||
if (source != null) {
|
||||
gen.writeStringField("source", source);
|
||||
}
|
||||
String userId = event.getUserId();
|
||||
if (userId != null) {
|
||||
gen.writeStringField("userId", userId);
|
||||
}
|
||||
String userIpAddress = event.getUserIpAddress();
|
||||
if (userIpAddress != null) {
|
||||
gen.writeStringField("userIpAddress", userIpAddress);
|
||||
}
|
||||
Map<String, String> userContext = event.getUserContext();
|
||||
if (userContext != null && !userContext.isEmpty()) {
|
||||
gen.writeObjectFieldStart("userContext");
|
||||
for (Map.Entry<String, String> entry : userContext.entrySet()) {
|
||||
gen.writeStringField(entry.getKey(), entry.getValue());
|
||||
}
|
||||
gen.writeEndObject();
|
||||
}
|
||||
gen.writeNumberField("eventTime", event.getEventTime());
|
||||
gen.writeStringField("beanType", event.getBeanType());
|
||||
gen.writeStringField("queryKey", event.getQueryKey());
|
||||
gen.writeStringField("bindLog", event.getBindLog());
|
||||
Object id = event.getId();
|
||||
if (id != null) {
|
||||
gen.writeFieldName("id");
|
||||
EJson.write(id, gen);
|
||||
} else {
|
||||
gen.writeFieldName("ids");
|
||||
EJson.writeCollection(event.getIds(), gen);
|
||||
}
|
||||
gen.writeEndObject();
|
||||
gen.flush();
|
||||
gen.close();
|
||||
}
|
||||
|
||||
}
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
package io.ebeaninternal.server.readaudit;
|
||||
|
||||
import io.ebean.event.readaudit.ReadAuditPrepare;
|
||||
import io.ebean.event.readaudit.ReadEvent;
|
||||
|
||||
/**
|
||||
* A placeholder implementation for ReadAuditPrepare.
|
||||
* <p>
|
||||
* A real application specific implementation is required to obtain and set
|
||||
* the user context information on the readEvent bean (like user id).
|
||||
* </p>
|
||||
*/
|
||||
public final class DefaultReadAuditPrepare implements ReadAuditPrepare {
|
||||
|
||||
@Override
|
||||
public void prepare(ReadEvent readEvent) {
|
||||
// do nothing by default.
|
||||
}
|
||||
}
|
||||
@@ -1048,19 +1048,6 @@ public abstract class TQRootBean<T, R> {
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable read auditing for this query.
|
||||
* <p>
|
||||
* This is intended to be used when the query is not a user initiated query and instead
|
||||
* part of the internal processing in an application to load a cache or document store etc.
|
||||
* In these cases we don't want the query to be part of read auditing.
|
||||
* </p>
|
||||
*/
|
||||
public R setDisableReadAuditing() {
|
||||
query.setDisableReadAuditing();
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this to true to use the query cache.
|
||||
*/
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
package io.ebean.xtest.event.readaudit;
|
||||
|
||||
|
||||
import io.ebean.event.readaudit.ReadAuditQueryPlan;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
|
||||
public class ReadAuditQueryPlanTest {
|
||||
|
||||
@Test
|
||||
public void testEquals() {
|
||||
|
||||
ReadAuditQueryPlan plan1 = new ReadAuditQueryPlan("org.Bean", "queryKey", "select id from foo");
|
||||
|
||||
assertEquals(plan1, new ReadAuditQueryPlan("org.Bean", "queryKey", "select id from foo"));
|
||||
assertNotEquals(plan1, new ReadAuditQueryPlan("org.Bean", "queryKey", "select id from Notfoo"));
|
||||
assertNotEquals(plan1, new ReadAuditQueryPlan("org.Bean", "notQueryKey", "select id from foo"));
|
||||
assertNotEquals(plan1, new ReadAuditQueryPlan("org.NotBean", "queryKey", "select id from foo"));
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,6 @@ import io.ebean.bean.CallOrigin;
|
||||
import io.ebean.cache.ServerCacheManager;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebean.event.readaudit.ReadAuditLogger;
|
||||
import io.ebean.event.readaudit.ReadAuditPrepare;
|
||||
import io.ebean.meta.MetaInfoManager;
|
||||
import io.ebean.meta.MetricVisitor;
|
||||
import io.ebean.plugin.Property;
|
||||
@@ -150,16 +148,6 @@ public class TDSpiEbeanServer extends TDSpiServer implements SpiEbeanServer {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadAuditLogger readAuditLogger() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadAuditPrepare readAuditPrepare() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearQueryStatistics() {
|
||||
|
||||
|
||||
@@ -1,375 +0,0 @@
|
||||
package org.tests.readaudit;
|
||||
|
||||
import io.ebean.xtest.BaseTestCase;
|
||||
import io.ebean.Database;
|
||||
import io.ebean.DatabaseFactory;
|
||||
import io.ebean.FutureList;
|
||||
import io.ebean.cache.ServerCache;
|
||||
import io.ebean.cache.ServerCacheStatistics;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
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.ebean.test.LoggedSql;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.tests.model.basic.Country;
|
||||
import org.tests.model.basic.EBasicChangeLog;
|
||||
|
||||
import java.util.*;
|
||||
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();
|
||||
|
||||
TDReadAuditLogger readAuditLogger = new TDReadAuditLogger();
|
||||
|
||||
Database server;
|
||||
|
||||
Long id1;
|
||||
Long id2;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
server = createServer();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void shutdown() {
|
||||
server.shutdown();
|
||||
}
|
||||
|
||||
@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();
|
||||
|
||||
ServerCache beanCache = server.cacheManager().beanCache(EBasicChangeLog.class);
|
||||
beanCache.statistics(true);
|
||||
|
||||
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);
|
||||
|
||||
ServerCacheStatistics statistics = beanCache.statistics(false);
|
||||
assertThat(statistics.getSize()).isEqualTo(1);
|
||||
assertThat(statistics.getHitCount()).isEqualTo(0);
|
||||
|
||||
EBasicChangeLog found2 = server.find(EBasicChangeLog.class, id1);
|
||||
assertThat(found2).isNotNull();
|
||||
statistics = beanCache.statistics(false);
|
||||
assertThat(statistics.getSize()).isEqualTo(1);
|
||||
assertThat(statistics.getHitCount()).isEqualTo(1);
|
||||
|
||||
assertThat(readAuditLogger.beans).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_findById_usingL2Cache_sharedBean() {
|
||||
resetCounters();
|
||||
|
||||
ServerCache beanCache = server.cacheManager().beanCache(Country.class);
|
||||
beanCache.statistics(true);
|
||||
|
||||
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");
|
||||
|
||||
ServerCacheStatistics statistics = beanCache.statistics(false);
|
||||
assertThat(statistics.getSize()).isEqualTo(1);
|
||||
assertThat(statistics.getHitCount()).isEqualTo(0);
|
||||
|
||||
Country found2 = server.find(Country.class, "AR");
|
||||
assertThat(found2).isNotNull();
|
||||
statistics = beanCache.statistics(false);
|
||||
assertThat(statistics.getSize()).isEqualTo(1);
|
||||
assertThat(statistics.getHitCount()).isEqualTo(1);
|
||||
|
||||
assertThat(readAuditLogger.beans).hasSize(2);
|
||||
|
||||
Country ref = server.reference(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();
|
||||
|
||||
LoggedSql.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 = LoggedSql.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 Database createServer() {
|
||||
|
||||
DatabaseConfig config = new DatabaseConfig();
|
||||
config.setName("h2other");
|
||||
config.loadFromProperties();
|
||||
|
||||
config.setDdlGenerate(true);
|
||||
config.setDdlRun(true);
|
||||
config.setDdlExtra(false);
|
||||
|
||||
config.setDefaultServer(false);
|
||||
config.setRegister(false);
|
||||
|
||||
config.addClass(Country.class);
|
||||
config.addClass(EBasicChangeLog.class);
|
||||
|
||||
config.setReadAuditLogger(readAuditLogger);
|
||||
config.setReadAuditPrepare(readAuditPrepare);
|
||||
|
||||
return DatabaseFactory.create(config);
|
||||
}
|
||||
|
||||
private void resetCounters() {
|
||||
readAuditLogger.resetCounters();
|
||||
readAuditPrepare.resetCounters();
|
||||
}
|
||||
|
||||
static class TDReadAuditPrepare implements ReadAuditPrepare {
|
||||
|
||||
int count;
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
static class TDReadAuditLogger implements ReadAuditLogger {
|
||||
|
||||
Set<ReadAuditQueryPlan> plans = new HashSet<>();
|
||||
List<ReadEvent> beans = new ArrayList<>();
|
||||
List<ReadEvent> many = new ArrayList<>();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user