001/*
002 * (C) Copyright 2006-2017 Nuxeo (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Nuxeo - initial API and implementation
018 */
019package org.nuxeo.ecm.platform.audit.api;
020
021import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_DOC_UUID;
022import static org.nuxeo.ecm.platform.audit.api.BuiltinLogEntryData.LOG_REPOSITORY_ID;
023
024import java.util.Date;
025import java.util.LinkedList;
026import java.util.List;
027import java.util.Map;
028import java.util.stream.Collectors;
029
030import org.nuxeo.ecm.core.query.sql.model.Predicates;
031import org.nuxeo.ecm.core.query.sql.model.QueryBuilder;
032import org.nuxeo.ecm.platform.audit.api.query.AuditQueryException;
033import org.nuxeo.ecm.platform.audit.api.query.DateRangeParser;
034
035/**
036 * Interface for reading data from the Audit service.
037 *
038 * @author tiry
039 */
040public interface AuditReader {
041
042    /**
043     * Returns the logs given a doc uuid and a repository id.
044     *
045     * @param uuid the document uuid
046     * @param repositoryId the repository id
047     * @return a list of log entries
048     * @since 8.4
049     */
050    default List<LogEntry> getLogEntriesFor(String uuid, String repositoryId) {
051        return queryLogs(new AuditQueryBuilder().predicate(Predicates.eq(LOG_DOC_UUID, uuid))
052                                                .and(Predicates.eq(LOG_REPOSITORY_ID, repositoryId))
053                                                .defaultOrder());
054    }
055
056    /**
057     * Returns the logs given a doc uuid.
058     *
059     * @param uuid the document uuid
060     * @return a list of log entries
061     * @deprecated since 8.4, use {@link #getLogEntriesFor(String, String)} instead.
062     */
063    @Deprecated
064    default List<LogEntry> getLogEntriesFor(String uuid) {
065        return queryLogs(
066                new AuditQueryBuilder().predicate(Predicates.eq(LOG_DOC_UUID, uuid))
067                                       .defaultOrder());
068    }
069
070    /**
071     * Returns the logs given a doc uuid, a map of filters and a default sort.
072     *
073     * @param uuid the document uuid
074     * @param filterMap the map of filters to apply
075     * @param doDefaultSort the default sort to set (eventDate desc)
076     * @return a list of log entries
077     * @deprecated since 9.3, this method doesn't take into account the document repository, use
078     *             {@link #queryLogs(QueryBuilder)} instead.
079     */
080    @Deprecated
081    List<LogEntry> getLogEntriesFor(String uuid, Map<String, FilterMapEntry> filterMap, boolean doDefaultSort);
082
083    /**
084     * Returns a given log entry given its id.
085     *
086     * @param id the log entry identifier
087     * @return a LogEntry instance
088     */
089    LogEntry getLogEntryByID(long id);
090
091    /**
092     * Returns the logs given a collection of predicates and a default sort.
093     *
094     * @param builder the query builder to fetch log entries
095     * @return a list of log entries
096     * @since 9.3
097     */
098    List<LogEntry> queryLogs(QueryBuilder builder);
099
100    /**
101     * Returns the list of log entries.
102     * <p>
103     * Note we will use NXQL in the future when the search engine will index history.
104     *
105     * @see org.nuxeo.ecm.platform.audit.api.query.DateRangeQueryConstants
106     * @param eventIds the event ids.
107     * @param dateRange a preset date range.
108     * @return a list of log entries.
109     */
110    default List<LogEntry> queryLogs(String[] eventIds, String dateRange) {
111        return queryLogsByPage(eventIds, (String) null, (String[]) null, null, 0, 10000);
112    }
113
114    /**
115     * Returns the batched list of log entries.
116     * <p>
117     * Note we will use NXQL in the future when the search engine will index history.
118     *
119     * @see org.nuxeo.ecm.platform.audit.api.query.DateRangeQueryConstants
120     * @param eventIds the event ids.
121     * @param dateRange a preset date range.
122     * @param category add filter on events category
123     * @param path add filter on document path
124     * @param pageNb page number (ignore if &lt;=1)
125     * @param pageSize number of results per page
126     * @return a list of log entries.
127     */
128    default List<LogEntry> queryLogsByPage(String[] eventIds, String dateRange, String category, String path, int pageNb,
129            int pageSize) {
130        return queryLogsByPage(eventIds, dateRange, new String[] { category }, path, pageNb, pageSize);
131    }
132
133    default List<LogEntry> queryLogsByPage(String[] eventIds, String dateRange, String[] categories, String path, int pageNb,
134            int pageSize) {
135
136        Date limit = null;
137        if (dateRange != null) {
138            try {
139                limit = DateRangeParser.parseDateRangeQuery(new Date(), dateRange);
140            } catch (AuditQueryException aqe) {
141                aqe.addInfo("Wrong date range query. Query was " + dateRange);
142                throw aqe;
143            }
144        }
145        return queryLogsByPage(eventIds, limit, categories, path, pageNb, pageSize);
146    }
147
148    /**
149     * Returns the batched list of log entries.
150     * <p>
151     * Note we will use NXQL in the future when the search engine will index history.
152     *
153     * @see org.nuxeo.ecm.platform.audit.api.query.DateRangeQueryConstants
154     * @param eventIds the event ids.
155     * @param limit filter events by date from limit to now
156     * @param category add filter on events category
157     * @param path add filter on document path
158     * @param pageNb page number (ignore if &lt;=1)
159     * @param pageSize number of results per page
160     * @return a list of log entries.
161     */
162    default List<LogEntry> queryLogsByPage(String[] eventIds, Date limit, String category, String path, int pageNb,
163            int pageSize) {
164        return queryLogsByPage(eventIds, limit, new String[] { category }, path, pageNb, pageSize);
165    }
166
167    List<LogEntry> queryLogsByPage(String[] eventIds, Date limit, String[] categories, String path, int pageNb,
168            int pageSize);
169
170    /**
171     * Returns a batched list of log entries. WhereClause is a native where clause for the backend: here EJBQL 3.0 must
172     * be used if implementation of audit backend is JPA (&lt; 7.3 or audit.elasticsearch.enabled=false) and JSON if
173     * implementation is Elasticsearch.
174     */
175    default List<LogEntry> nativeQueryLogs(String whereClause, int pageNb, int pageSize) {
176        return nativeQuery(whereClause, pageNb, pageSize).stream()
177                                                         .filter(LogEntry.class::isInstance)
178                                                         .map(LogEntry.class::cast)
179                                                         .collect(Collectors.toCollection(LinkedList::new));
180    }
181
182    /**
183     * Returns a batched list of entries. query string is a native query clause for the backend : here EJBQL 3.0 must be
184     * used if implementation of audit backend is JPA (&lt; 7.3 or audit.elasticsearch.enabled=false) and JSON if
185     * implementation is Elasticsearch.
186     */
187    default List<?> nativeQuery(String query, int pageNb, int pageSize) {
188        return nativeQuery(query, Map.of(), pageNb, pageSize);
189    }
190
191    /**
192     * Returns a batched list of entries.
193     *
194     * @param query a JPA query language query if implementation of audit backend is JPA (&lt; 7.3 or
195     *            audit.elasticsearch.enabled=false) and JSON if implementation is Elasticsearch
196     * @param params parameters for the query
197     * @param pageNb the page number (starts at 1)
198     * @param pageSize the number of results per page
199     */
200    List<?> nativeQuery(String query, Map<String, Object> params, int pageNb, int pageSize);
201
202    /**
203     * Returns the latest log id matching events and repository or 0 when no match found.
204     *
205     * @since 9.3
206     */
207    long getLatestLogId(String repositoryId, String... eventIds);
208
209    /**
210     * Returns up to limit log entries matching events and repository with log id greater or equal to logIdOffset.
211     *
212     * @since 9.3
213     */
214    List<LogEntry> getLogEntriesAfter(long logIdOffset, int limit, String repositoryId, String... eventIds);
215
216}