001/*
002 * The contents of this file are subject to the license and copyright
003 * detailed in the LICENSE and NOTICE files at the root of the source
004 * tree.
005 */
006
007package org.fcrepo.search.impl;
008
009import io.micrometer.core.instrument.Metrics;
010import io.micrometer.core.instrument.Timer;
011
012import org.fcrepo.kernel.api.Transaction;
013import org.fcrepo.kernel.api.identifiers.FedoraId;
014import org.fcrepo.kernel.api.models.ResourceHeaders;
015import org.fcrepo.search.api.InvalidQueryException;
016import org.fcrepo.search.api.SearchIndex;
017import org.fcrepo.search.api.SearchParameters;
018import org.fcrepo.search.api.SearchResult;
019import org.springframework.beans.factory.annotation.Autowired;
020import org.springframework.beans.factory.annotation.Qualifier;
021import org.springframework.stereotype.Component;
022
023/**
024 * SearchIndex wrapper for collecting metrics
025 *
026 * @author pwinckles
027 */
028@Component("searchIndex")
029public class SearchIndexMetrics implements SearchIndex {
030
031    private static final String METRIC_NAME = "fcrepo.db";
032    private static final String DB = "db";
033    private static final String SEARCH = "search";
034    private static final String OPERATION = "operation";
035
036    private static final Timer addUpdateIndexTimer = Metrics.timer(METRIC_NAME,
037            DB, SEARCH, OPERATION, "addUpdateIndex");
038    private static final Timer removeFromIndexTimer = Metrics.timer(METRIC_NAME,
039            DB, SEARCH, OPERATION, "removeFromIndex");
040    private static final Timer doSearchTimer = Metrics.timer(METRIC_NAME,
041            DB, SEARCH, OPERATION, "doSearch");
042    private static final Timer resetTimer = Metrics.timer(METRIC_NAME,
043            DB, SEARCH, OPERATION, "reset");
044    private static final Timer commitTransactionTimer = Metrics.timer(METRIC_NAME,
045            DB, SEARCH, OPERATION, "commitTransaction");
046    private static final Timer rollbackTransactionTimer = Metrics.timer(METRIC_NAME,
047            DB, SEARCH, OPERATION, "rollbackTransaction");
048    private static final Timer clearAllTransactionsTimer = Metrics.timer(METRIC_NAME,
049            DB, SEARCH, OPERATION, "clearAllTransactions");
050
051    @Autowired
052    @Qualifier("searchIndexImpl")
053    private SearchIndex searchIndexImpl;
054
055    @Override
056    public void addUpdateIndex(final Transaction transaction, final ResourceHeaders resourceHeaders) {
057        addUpdateIndexTimer.record(() -> {
058            searchIndexImpl.addUpdateIndex(transaction, resourceHeaders);
059        });
060    }
061
062    @Override
063    public void removeFromIndex(final Transaction transaction, final FedoraId fedoraId) {
064        removeFromIndexTimer.record(() -> {
065            searchIndexImpl.removeFromIndex(transaction, fedoraId);
066        });
067    }
068
069    @Override
070    public SearchResult doSearch(final SearchParameters parameters) throws InvalidQueryException {
071        final var stopwatch = Timer.start();
072        try {
073            return searchIndexImpl.doSearch(parameters);
074        } finally {
075            stopwatch.stop(doSearchTimer);
076        }
077    }
078
079    @Override
080    public void reset() {
081        resetTimer.record(() -> {
082            searchIndexImpl.reset();
083        });
084    }
085
086    @Override
087    public void commitTransaction(final Transaction tx) {
088        commitTransactionTimer.record(() -> {
089            searchIndexImpl.commitTransaction(tx);
090        });
091    }
092
093    @Override
094    public void rollbackTransaction(final Transaction tx) {
095        rollbackTransactionTimer.record(() -> {
096            searchIndexImpl.rollbackTransaction(tx);
097        });
098    }
099
100    @Override
101    public void clearAllTransactions() {
102        clearAllTransactionsTimer.record(() -> {
103            searchIndexImpl.clearAllTransactions();
104        });
105    }
106}