Search in sources :

Example 6 with LogEntry

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;
}
Also used : SearchRequest(org.elasticsearch.action.search.SearchRequest) LogEntryImpl(org.nuxeo.ecm.platform.audit.impl.LogEntryImpl) SearchHit(org.elasticsearch.search.SearchHit) ArrayList(java.util.ArrayList) SearchHits(org.elasticsearch.search.SearchHits) IOException(java.io.IOException) LogEntry(org.nuxeo.ecm.platform.audit.api.LogEntry) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) SearchSourceBuilder(org.elasticsearch.search.builder.SearchSourceBuilder) SearchResponse(org.elasticsearch.action.search.SearchResponse)

Example 7 with LogEntry

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");
    }
}
Also used : EventContext(org.nuxeo.ecm.core.event.EventContext) AuditLogger(org.nuxeo.ecm.platform.audit.api.AuditLogger) ArrayList(java.util.ArrayList) Event(org.nuxeo.ecm.core.event.Event) LogEntry(org.nuxeo.ecm.platform.audit.api.LogEntry)

Example 8 with LogEntry

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;
}
Also used : SearchRequest(org.elasticsearch.action.search.SearchRequest) LogEntryImpl(org.nuxeo.ecm.platform.audit.impl.LogEntryImpl) SearchHit(org.elasticsearch.search.SearchHit) ArrayList(java.util.ArrayList) TermsQueryBuilder(org.elasticsearch.index.query.TermsQueryBuilder) QueryBuilder(org.elasticsearch.index.query.QueryBuilder) RangeQueryBuilder(org.elasticsearch.index.query.RangeQueryBuilder) BoolQueryBuilder(org.elasticsearch.index.query.BoolQueryBuilder) IOException(java.io.IOException) LogEntry(org.nuxeo.ecm.platform.audit.api.LogEntry) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) SearchSourceBuilder(org.elasticsearch.search.builder.SearchSourceBuilder) SearchResponse(org.elasticsearch.action.search.SearchResponse)

Example 9 with LogEntry

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;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) AuditReader(org.nuxeo.ecm.platform.audit.api.AuditReader) ExtendedInfo(org.nuxeo.ecm.platform.audit.api.ExtendedInfo) LogEntry(org.nuxeo.ecm.platform.audit.api.LogEntry)

Example 10 with LogEntry

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();
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) List(java.util.List) AuditReader(org.nuxeo.ecm.platform.audit.api.AuditReader) Date(java.util.Date) LogEntry(org.nuxeo.ecm.platform.audit.api.LogEntry)

Aggregations

LogEntry (org.nuxeo.ecm.platform.audit.api.LogEntry)10 ArrayList (java.util.ArrayList)9 ExtendedInfo (org.nuxeo.ecm.platform.audit.api.ExtendedInfo)4 HashMap (java.util.HashMap)3 List (java.util.List)3 AuditLogger (org.nuxeo.ecm.platform.audit.api.AuditLogger)3 AuditReader (org.nuxeo.ecm.platform.audit.api.AuditReader)3 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)2 IOException (java.io.IOException)2 Date (java.util.Date)2 SearchRequest (org.elasticsearch.action.search.SearchRequest)2 SearchResponse (org.elasticsearch.action.search.SearchResponse)2 SearchHit (org.elasticsearch.search.SearchHit)2 SearchSourceBuilder (org.elasticsearch.search.builder.SearchSourceBuilder)2 Event (org.nuxeo.ecm.core.event.Event)2 EventContext (org.nuxeo.ecm.core.event.EventContext)2 LogEntryImpl (org.nuxeo.ecm.platform.audit.impl.LogEntryImpl)2 BoolQueryBuilder (org.elasticsearch.index.query.BoolQueryBuilder)1 QueryBuilder (org.elasticsearch.index.query.QueryBuilder)1 RangeQueryBuilder (org.elasticsearch.index.query.RangeQueryBuilder)1