001/*
002 * Licensed to DuraSpace under one or more contributor license agreements.
003 * See the NOTICE file distributed with this work for additional information
004 * regarding copyright ownership.
005 *
006 * DuraSpace licenses this file to you under the Apache License,
007 * Version 2.0 (the "License"); you may not use this file except in
008 * compliance with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.fcrepo.search.impl;
020
021import io.micrometer.core.instrument.Metrics;
022import io.micrometer.core.instrument.Timer;
023
024import org.fcrepo.kernel.api.Transaction;
025import org.fcrepo.kernel.api.identifiers.FedoraId;
026import org.fcrepo.kernel.api.models.ResourceHeaders;
027import org.fcrepo.search.api.InvalidQueryException;
028import org.fcrepo.search.api.SearchIndex;
029import org.fcrepo.search.api.SearchParameters;
030import org.fcrepo.search.api.SearchResult;
031import org.springframework.beans.factory.annotation.Autowired;
032import org.springframework.beans.factory.annotation.Qualifier;
033import org.springframework.stereotype.Component;
034
035/**
036 * SearchIndex wrapper for collecting metrics
037 *
038 * @author pwinckles
039 */
040@Component("searchIndex")
041public class SearchIndexMetrics implements SearchIndex {
042
043    private static final String METRIC_NAME = "fcrepo.db";
044    private static final String DB = "db";
045    private static final String SEARCH = "search";
046    private static final String OPERATION = "operation";
047
048    private static final Timer addUpdateIndexTimer = Metrics.timer(METRIC_NAME,
049            DB, SEARCH, OPERATION, "addUpdateIndex");
050    private static final Timer removeFromIndexTimer = Metrics.timer(METRIC_NAME,
051            DB, SEARCH, OPERATION, "removeFromIndex");
052    private static final Timer doSearchTimer = Metrics.timer(METRIC_NAME,
053            DB, SEARCH, OPERATION, "doSearch");
054    private static final Timer resetTimer = Metrics.timer(METRIC_NAME,
055            DB, SEARCH, OPERATION, "reset");
056    private static final Timer commitTransactionTimer = Metrics.timer(METRIC_NAME,
057            DB, SEARCH, OPERATION, "commitTransaction");
058    private static final Timer rollbackTransactionTimer = Metrics.timer(METRIC_NAME,
059            DB, SEARCH, OPERATION, "rollbackTransaction");
060
061    @Autowired
062    @Qualifier("searchIndexImpl")
063    private SearchIndex searchIndexImpl;
064
065    @Override
066    public void addUpdateIndex(final Transaction transaction, final ResourceHeaders resourceHeaders) {
067        addUpdateIndexTimer.record(() -> {
068            searchIndexImpl.addUpdateIndex(transaction, resourceHeaders);
069        });
070    }
071
072    @Override
073    public void removeFromIndex(final Transaction transaction, final FedoraId fedoraId) {
074        removeFromIndexTimer.record(() -> {
075            searchIndexImpl.removeFromIndex(transaction, fedoraId);
076        });
077    }
078
079    @Override
080    public SearchResult doSearch(final SearchParameters parameters) throws InvalidQueryException {
081        final var stopwatch = Timer.start();
082        try {
083            return searchIndexImpl.doSearch(parameters);
084        } finally {
085            stopwatch.stop(doSearchTimer);
086        }
087    }
088
089    @Override
090    public void reset() {
091        resetTimer.record(() -> {
092            searchIndexImpl.reset();
093        });
094    }
095
096    @Override
097    public void commitTransaction(final Transaction tx) {
098        commitTransactionTimer.record(() -> {
099            searchIndexImpl.commitTransaction(tx);
100        });
101    }
102
103    @Override
104    public void rollbackTransaction(final Transaction tx) {
105        rollbackTransactionTimer.record(() -> {
106            searchIndexImpl.rollbackTransaction(tx);
107        });
108    }
109}