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;
023import org.fcrepo.kernel.api.identifiers.FedoraId;
024import org.fcrepo.kernel.api.models.ResourceHeaders;
025import org.fcrepo.search.api.InvalidQueryException;
026import org.fcrepo.search.api.SearchIndex;
027import org.fcrepo.search.api.SearchParameters;
028import org.fcrepo.search.api.SearchResult;
029import org.springframework.beans.factory.annotation.Autowired;
030import org.springframework.beans.factory.annotation.Qualifier;
031import org.springframework.stereotype.Component;
032
033/**
034 * SearchIndex wrapper for collecting metrics
035 *
036 * @author pwinckles
037 */
038@Component("searchIndex")
039public class SearchIndexMetrics implements SearchIndex {
040
041    private static final String METRIC_NAME = "fcrepo.db";
042    private static final String DB = "db";
043    private static final String SEARCH = "search";
044    private static final String OPERATION = "operation";
045
046    private static final Timer addUpdateIndexTimer = Metrics.timer(METRIC_NAME,
047            DB, SEARCH, OPERATION, "addUpdateIndex");
048    private static final Timer removeFromIndexTimer = Metrics.timer(METRIC_NAME,
049            DB, SEARCH, OPERATION, "removeFromIndex");
050    private static final Timer doSearchTimer = Metrics.timer(METRIC_NAME,
051            DB, SEARCH, OPERATION, "doSearch");
052    private static final Timer resetTimer = Metrics.timer(METRIC_NAME,
053            DB, SEARCH, OPERATION, "reset");
054
055    @Autowired
056    @Qualifier("searchIndexImpl")
057    private SearchIndex searchIndexImpl;
058
059    @Override
060    public void addUpdateIndex(final ResourceHeaders resourceHeaders) {
061        addUpdateIndexTimer.record(() -> {
062            searchIndexImpl.addUpdateIndex(resourceHeaders);
063        });
064    }
065
066    @Override
067    public void addUpdateIndex(final String dbTxId, final ResourceHeaders resourceHeaders) {
068        addUpdateIndexTimer.record(() -> {
069            searchIndexImpl.addUpdateIndex(dbTxId, resourceHeaders);
070        });
071    }
072
073    @Override
074    public void removeFromIndex(final FedoraId fedoraId) {
075        removeFromIndexTimer.record(() -> {
076            searchIndexImpl.removeFromIndex(fedoraId);
077        });
078    }
079
080    @Override
081    public SearchResult doSearch(final SearchParameters parameters) throws InvalidQueryException {
082        final var stopwatch = Timer.start();
083        try {
084            return searchIndexImpl.doSearch(parameters);
085        } finally {
086            stopwatch.stop(doSearchTimer);
087        }
088    }
089
090    @Override
091    public void reset() {
092        resetTimer.record(() -> {
093            searchIndexImpl.reset();
094        });
095    }
096
097}