use of org.nuxeo.ecm.platform.audit.api.LogEntry in project nuxeo-drive-server by nuxeo.
the class ESAuditChangeFinder method getUpperBound.
@Override
public long getUpperBound() {
SearchRequest request = new SearchRequest(getESIndexName()).types(ElasticSearchConstants.ENTRY_TYPE).searchType(SearchType.DFS_QUERY_THEN_FETCH);
// TODO refactor this to use max clause
request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).sort("id", SortOrder.DESC).size(1));
logSearchRequest(request);
SearchResponse searchResponse = getClient().search(request);
logSearchResponse(searchResponse);
List<LogEntry> entries = new ArrayList<>();
SearchHits hits = searchResponse.getHits();
ObjectMapper mapper = new ObjectMapper();
for (SearchHit hit : hits) {
try {
entries.add(mapper.readValue(hit.getSourceAsString(), LogEntryImpl.class));
} catch (IOException e) {
log.error("Error while reading Audit Entry from ES", e);
}
}
return entries.size() > 0 ? entries.get(0).getId() : -1;
}
use of org.nuxeo.ecm.platform.audit.api.LogEntry in project nuxeo-drive-server by nuxeo.
the class NuxeoDriveVirtualEventLogger method handleEvent.
@Override
public void handleEvent(EventBundle events) {
AuditLogger logger = Framework.getService(AuditLogger.class);
if (logger != null) {
for (Event event : events) {
EventContext ctx = event.getContext();
Object[] args = ctx.getArguments();
if (ArrayUtils.isEmpty(args)) {
return;
}
List<LogEntry> logEntries = new ArrayList<>();
for (int i = 0; i < args.length; i++) {
Object arg = args[i];
if (arg instanceof LogEntry) {
logEntries.add((LogEntry) arg);
}
}
if (!logEntries.isEmpty()) {
logger.addLogEntries(logEntries);
}
}
} else {
log.error("Can not reach AuditLogger");
}
}
use of org.nuxeo.ecm.platform.audit.api.LogEntry in project nuxeo-drive-server by nuxeo.
the class ESAuditChangeFinder method queryESAuditEntries.
protected List<LogEntry> queryESAuditEntries(CoreSession session, SynchronizationRoots activeRoots, Set<String> collectionSyncRootMemberIds, long lowerBound, long upperBound, boolean integerBounds, int limit) {
SearchRequest request = new SearchRequest(getESIndexName()).types(ElasticSearchConstants.ENTRY_TYPE).searchType(SearchType.DFS_QUERY_THEN_FETCH);
QueryBuilder queryBuilder = QueryBuilders.matchAllQuery();
QueryBuilder filterBuilder = buildFilterClauses(session, activeRoots, collectionSyncRootMemberIds, lowerBound, upperBound, integerBounds, limit);
SearchSourceBuilder source = new SearchSourceBuilder().query(QueryBuilders.boolQuery().must(queryBuilder).filter(filterBuilder));
source.sort("repositoryId", SortOrder.ASC).sort("eventDate", SortOrder.DESC);
source.size(limit);
request.source(source);
List<LogEntry> entries = new ArrayList<>();
logSearchRequest(request);
SearchResponse searchResponse = getClient().search(request);
logSearchResponse(searchResponse);
ObjectMapper mapper = new ObjectMapper();
for (SearchHit hit : searchResponse.getHits()) {
try {
entries.add(mapper.readValue(hit.getSourceAsString(), LogEntryImpl.class));
} catch (IOException e) {
log.error("Error while reading Audit Entry from ES", e);
}
}
return entries;
}
use of org.nuxeo.ecm.platform.audit.api.LogEntry in project nuxeo-drive-server by nuxeo.
the class AuditChangeFinder method queryAuditEntries.
@SuppressWarnings("unchecked")
protected List<LogEntry> queryAuditEntries(CoreSession session, SynchronizationRoots activeRoots, Set<String> collectionSyncRootMemberIds, long lowerBound, long upperBound, boolean integerBounds, int limit) {
AuditReader auditService = Framework.getService(AuditReader.class);
// Set fixed query parameters
Map<String, Object> params = new HashMap<String, Object>();
params.put("repositoryId", session.getRepositoryName());
// Build query and set dynamic parameters
StringBuilder auditQuerySb = new StringBuilder("from LogEntry log where ");
auditQuerySb.append("log.repositoryId = :repositoryId");
auditQuerySb.append(" and ");
auditQuerySb.append("(");
if (!activeRoots.getPaths().isEmpty()) {
// detect changes under the currently active roots for the
// current user
auditQuerySb.append("(");
auditQuerySb.append("log.category = 'eventDocumentCategory'");
// TODO: don't hardcode event ids (contribute them?)
auditQuerySb.append(" and (log.eventId = 'documentCreated' or log.eventId = 'documentModified' or log.eventId = 'documentMoved' or log.eventId = 'documentCreatedByCopy' or log.eventId = 'documentRestored' or log.eventId = 'addedToCollection' or log.eventId = 'documentProxyPublished' or log.eventId = 'documentLocked' or log.eventId = 'documentUnlocked')");
auditQuerySb.append(" or ");
auditQuerySb.append("log.category = 'eventLifeCycleCategory'");
auditQuerySb.append(" and log.eventId = 'lifecycle_transition_event' and log.docLifeCycle != 'deleted' ");
auditQuerySb.append(") and (");
auditQuerySb.append("(");
auditQuerySb.append(getCurrentRootFilteringClause(activeRoots.getPaths(), params));
auditQuerySb.append(")");
if (collectionSyncRootMemberIds != null && !collectionSyncRootMemberIds.isEmpty()) {
auditQuerySb.append(" or (");
auditQuerySb.append(getCollectionSyncRootFilteringClause(collectionSyncRootMemberIds, params));
auditQuerySb.append(")");
}
auditQuerySb.append(") or ");
}
// Detect any root (un-)registration changes for the roots previously
// seen by the current user.
// Exclude 'rootUnregistered' since root unregistration is covered by a
// "deleted" virtual event.
auditQuerySb.append("(");
auditQuerySb.append("log.category = '");
auditQuerySb.append(NuxeoDriveEvents.EVENT_CATEGORY);
auditQuerySb.append("' and log.eventId != 'rootUnregistered'");
auditQuerySb.append(")");
auditQuerySb.append(") and (");
auditQuerySb.append(getJPARangeClause(lowerBound, upperBound, integerBounds, params));
// we intentionally sort by eventDate even if the range filtering is
// done on the log id: eventDate is useful to reflect the ordering of
// events occurring inside the same transaction while the
// monotonic behavior of log id is useful for ensuring that consecutive
// range queries to the audit won't miss any events even when long
// running transactions are logged after a delay.
auditQuerySb.append(") order by log.repositoryId asc, log.eventDate desc");
String auditQuery = auditQuerySb.toString();
if (log.isDebugEnabled()) {
log.debug("Querying audit log for changes: " + auditQuery + " with params: " + params);
}
List<LogEntry> entries = (List<LogEntry>) auditService.nativeQuery(auditQuery, params, 1, limit);
// Post filter the output to remove (un)registration that are unrelated
// to the current user.
List<LogEntry> postFilteredEntries = new ArrayList<LogEntry>();
String principalName = session.getPrincipal().getName();
for (LogEntry entry : entries) {
ExtendedInfo impactedUserInfo = entry.getExtendedInfos().get("impactedUserName");
if (impactedUserInfo != null && !principalName.equals(impactedUserInfo.getValue(String.class))) {
// ignore event that only impact other users
continue;
}
if (log.isDebugEnabled()) {
log.debug(String.format("Change detected: %s", entry));
}
postFilteredEntries.add(entry);
}
return postFilteredEntries;
}
use of org.nuxeo.ecm.platform.audit.api.LogEntry in project nuxeo-drive-server by nuxeo.
the class AuditChangeFinder method getUpperBound.
/**
* Returns the last available log id in the audit log table (primary key) considering events older than the last
* clustering invalidation date if clustering is enabled for at least one of the given repositories. This is to make
* sure the {@code DocumentModel} further fetched from the session using the audit entry doc id is fresh.
*/
@Override
@SuppressWarnings("unchecked")
public long getUpperBound(Set<String> repositoryNames) {
long clusteringDelay = getClusteringDelay(repositoryNames);
AuditReader auditService = Framework.getService(AuditReader.class);
Map<String, Object> params = new HashMap<String, Object>();
StringBuilder auditQuerySb = new StringBuilder("from LogEntry log");
if (clusteringDelay > -1) {
// Double the delay in case of overlapping, see https://jira.nuxeo.com/browse/NXP-14826
long lastClusteringInvalidationDate = System.currentTimeMillis() - 2 * clusteringDelay;
params.put("lastClusteringInvalidationDate", new Date(lastClusteringInvalidationDate));
auditQuerySb.append(" where log.logDate < :lastClusteringInvalidationDate");
}
auditQuerySb.append(" order by log.id desc");
String auditQuery = auditQuerySb.toString();
if (log.isDebugEnabled()) {
log.debug("Querying audit log for greatest id: " + auditQuery + " with params: " + params);
}
List<LogEntry> entries = (List<LogEntry>) auditService.nativeQuery(auditQuery, params, 1, 1);
if (entries.isEmpty()) {
if (clusteringDelay > -1) {
// Check for existing entries without the clustering invalidation date filter to not return -1 in this
// case and make sure the lower bound of the next call to NuxeoDriveManager#getChangeSummary will be >=
// 0
List<LogEntry> allEntries = (List<LogEntry>) auditService.nativeQuery("from LogEntry", 1, 1);
if (!allEntries.isEmpty()) {
log.debug("Found no audit log entries matching the criterias but some exist, returning 0");
return 0;
}
}
log.debug("Found no audit log entries, returning -1");
return -1;
}
return entries.get(0).getId();
}
Aggregations