org.nuxeo.elasticsearch.audit.pageprovider.ESAuditPageProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.nuxeo.elasticsearch.audit.pageprovider.ESAuditPageProvider.java

Source

/*
 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Contributors:
 *     Nuxeo - initial API and implementation
 *
 * $Id$
 */
package org.nuxeo.elasticsearch.audit.pageprovider;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortOrder;
import org.nuxeo.ecm.core.api.CoreSession;
import org.nuxeo.ecm.core.api.NuxeoException;
import org.nuxeo.ecm.core.api.SortInfo;
import org.nuxeo.ecm.platform.audit.api.LogEntry;
import org.nuxeo.ecm.platform.audit.api.comment.CommentProcessorHelper;
import org.nuxeo.ecm.platform.audit.service.AuditBackend;
import org.nuxeo.ecm.platform.audit.service.NXAuditEventsService;
import org.nuxeo.ecm.platform.query.api.AbstractPageProvider;
import org.nuxeo.ecm.platform.query.api.PageProvider;
import org.nuxeo.ecm.platform.query.api.PageProviderDefinition;
import org.nuxeo.ecm.platform.query.api.QuickFilter;
import org.nuxeo.ecm.platform.query.api.WhereClauseDefinition;
import org.nuxeo.ecm.platform.query.nxql.NXQLQueryBuilder;
import org.nuxeo.elasticsearch.audit.ESAuditBackend;
import org.nuxeo.elasticsearch.audit.io.AuditEntryJSONReader;
import org.nuxeo.runtime.api.Framework;

public class ESAuditPageProvider extends AbstractPageProvider<LogEntry> implements PageProvider<LogEntry> {

    private static final long serialVersionUID = 1L;

    protected SearchRequestBuilder searchBuilder;

    public static final String CORE_SESSION_PROPERTY = "coreSession";

    public static final String UICOMMENTS_PROPERTY = "generateUIComments";

    protected static String emptyQuery = "{ \"match_all\" : { }\n }";

    @Override
    public String toString() {
        buildAuditQuery(true);
        StringBuffer sb = new StringBuffer();
        sb.append(searchBuilder.toString());
        return sb.toString();
    }

    protected CoreSession getCoreSession() {
        Object session = getProperties().get(CORE_SESSION_PROPERTY);
        if (session != null && session instanceof CoreSession) {
            return (CoreSession) session;
        }
        return null;
    }

    protected void preprocessCommentsIfNeeded(List<LogEntry> entries) {
        Serializable preprocess = getProperties().get(UICOMMENTS_PROPERTY);

        if (preprocess != null && "true".equalsIgnoreCase(preprocess.toString())) {
            CoreSession session = getCoreSession();
            if (session != null) {
                CommentProcessorHelper cph = new CommentProcessorHelper(session);
                cph.processComments(entries);
            }
        }
    }

    @Override
    public List<LogEntry> getCurrentPage() {

        buildAuditQuery(true);
        searchBuilder.setFrom((int) (getCurrentPageIndex() * pageSize));
        searchBuilder.setSize((int) getMinMaxPageSize());

        for (SortInfo sortInfo : getSortInfos()) {
            searchBuilder.addSort(sortInfo.getSortColumn(),
                    sortInfo.getSortAscending() ? SortOrder.ASC : SortOrder.DESC);
        }

        SearchResponse searchResponse = searchBuilder.execute().actionGet();
        List<LogEntry> entries = new ArrayList<>();
        SearchHits hits = searchResponse.getHits();

        // set total number of hits ?
        setResultsCount(hits.getTotalHits());

        for (SearchHit hit : hits) {
            try {
                entries.add(AuditEntryJSONReader.read(hit.getSourceAsString()));
            } catch (IOException e) {
                log.error("Error while reading Audit Entry from ES", e);
            }
        }
        preprocessCommentsIfNeeded(entries);

        long t0 = System.currentTimeMillis();

        CoreSession session = getCoreSession();
        if (session != null) {
            // send event for statistics !
            fireSearchEvent(session.getPrincipal(), searchBuilder.toString(), entries,
                    System.currentTimeMillis() - t0);
        }

        return entries;
    }

    protected boolean isNonNullParam(Object[] val) {
        if (val == null) {
            return false;
        }
        for (Object v : val) {
            if (v != null) {
                if (v instanceof String) {
                    if (!((String) v).isEmpty()) {
                        return true;
                    }
                } else if (v instanceof String[]) {
                    if (((String[]) v).length > 0) {
                        return true;
                    }
                } else {
                    return true;
                }
            }
        }
        return false;
    }

    protected String getFixedPart() {
        if (getDefinition().getWhereClause() == null) {
            return null;
        } else {
            String fixedPart = getDefinition().getWhereClause().getFixedPart();
            if (fixedPart == null || fixedPart.isEmpty()) {
                fixedPart = emptyQuery;
            }
            return fixedPart;
        }
    }

    protected boolean allowSimplePattern() {
        return true;
    }

    protected ESAuditBackend getESBackend() {
        NXAuditEventsService audit = (NXAuditEventsService) Framework.getRuntime()
                .getComponent(NXAuditEventsService.NAME);
        AuditBackend backend = audit.getBackend();
        if (backend instanceof ESAuditBackend) {
            return (ESAuditBackend) backend;
        }
        throw new NuxeoException(
                "Unable to use ESAuditPageProvider if audit service is not configured to run with ElasticSearch");
    }

    protected void buildAuditQuery(boolean includeSort) {
        PageProviderDefinition def = getDefinition();
        Object[] params = getParameters();
        List<QuickFilter> quickFilters = getQuickFilters();
        String quickFiltersClause = "";

        if (quickFilters != null && !quickFilters.isEmpty()) {
            for (QuickFilter quickFilter : quickFilters) {
                String clause = quickFilter.getClause();
                if (!quickFiltersClause.isEmpty() && clause != null) {
                    quickFiltersClause = NXQLQueryBuilder.appendClause(quickFiltersClause, clause);
                } else {
                    quickFiltersClause = clause != null ? clause : "";
                }
            }
        }

        WhereClauseDefinition whereClause = def.getWhereClause();
        if (whereClause == null) {
            // Simple Pattern

            if (!allowSimplePattern()) {
                throw new UnsupportedOperationException("This page provider requires a explicit Where Clause");
            }
            String originalPattern = def.getPattern();
            String pattern = quickFiltersClause.isEmpty() ? originalPattern
                    : StringUtils.containsIgnoreCase(originalPattern, " WHERE ")
                            ? NXQLQueryBuilder.appendClause(originalPattern, quickFiltersClause)
                            : originalPattern + " WHERE " + quickFiltersClause;

            String baseQuery = getESBackend().expandQueryVariables(pattern, params);
            searchBuilder = getESBackend().buildQuery(baseQuery, null);
        } else {

            // Add the quick filters clauses to the fixed part
            String fixedPart = getFixedPart();
            if (!StringUtils.isBlank(quickFiltersClause)) {
                fixedPart = (!StringUtils.isBlank(fixedPart))
                        ? NXQLQueryBuilder.appendClause(fixedPart, quickFiltersClause)
                        : quickFiltersClause;
            }

            // Where clause based on DocumentModel
            String baseQuery = getESBackend().expandQueryVariables(fixedPart, params);
            searchBuilder = getESBackend().buildSearchQuery(baseQuery, whereClause.getPredicates(),
                    getSearchDocumentModel());
        }
    }

    @Override
    public void refresh() {
        setCurrentPageOffset(0);
        super.refresh();
    }

    @Override
    public long getResultsCount() {
        return resultsCount;
    }

    @Override
    public List<SortInfo> getSortInfos() {

        // because ContentView can reuse PageProVider without redefining columns
        // ensure compat for ContentView configured with JPA log.* sort syntax
        List<SortInfo> sortInfos = super.getSortInfos();
        for (SortInfo si : sortInfos) {
            if (si.getSortColumn().startsWith("log.")) {
                si.setSortColumn(si.getSortColumn().substring(4));
            }
        }
        return sortInfos;
    }

}