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