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.kernel.impl;
008
009import io.micrometer.core.instrument.Metrics;
010import io.micrometer.core.instrument.Timer;
011import org.fcrepo.common.metrics.MetricsHelper;
012import org.fcrepo.kernel.api.ContainmentIndex;
013import org.fcrepo.kernel.api.Transaction;
014import org.fcrepo.kernel.api.identifiers.FedoraId;
015import org.springframework.beans.factory.annotation.Autowired;
016import org.springframework.beans.factory.annotation.Qualifier;
017import org.springframework.stereotype.Component;
018
019import java.time.Instant;
020import java.util.stream.Stream;
021
022/**
023 * ContainmentIndex wrapper for adding metrics
024 *
025 * @author pwinckles
026 */
027@Component("containmentIndex")
028public class ContainmentIndexMetrics implements ContainmentIndex {
029
030    private static final String METRIC_NAME = "fcrepo.db";
031    private static final String DB = "db";
032    private static final String CONTAINMENT = "containment";
033    private static final String OPERATION = "operation";
034
035    private static final Timer getContainsTimer = Metrics.timer(METRIC_NAME,
036            DB, CONTAINMENT, OPERATION, "getContains");
037    private static final Timer getContainsDeletedTimer = Metrics.timer(METRIC_NAME,
038            DB, CONTAINMENT, OPERATION, "getContainsDeleted");
039    private static final Timer getContainsByTimer = Metrics.timer(METRIC_NAME,
040            DB, CONTAINMENT, OPERATION, "getContainsBy");
041    private static final Timer removeContainedByTimer = Metrics.timer(METRIC_NAME,
042            DB, CONTAINMENT, OPERATION, "removeContainedBy");
043    private static final Timer removeResourceTimer = Metrics.timer(METRIC_NAME,
044            DB, CONTAINMENT, OPERATION, "removeResource");
045    private static final Timer purgeResourceTimer = Metrics.timer(METRIC_NAME,
046            DB, CONTAINMENT, OPERATION, "purgeResource");
047    private static final Timer addContainedByTimer = Metrics.timer(METRIC_NAME,
048            DB, CONTAINMENT, OPERATION, "addContainedBy");
049    private static final Timer commitTransactionTimer = Metrics.timer(METRIC_NAME,
050            DB, CONTAINMENT, OPERATION, "commitTransaction");
051    private static final Timer rollbackTransactionTimer = Metrics.timer(METRIC_NAME,
052            DB, CONTAINMENT, OPERATION, "rollbackTransaction");
053    private static final Timer resourceExistsTimer = Metrics.timer(METRIC_NAME,
054            DB, CONTAINMENT, OPERATION, "resourceExists");
055    private static final Timer getContainerIdByPathTimer = Metrics.timer(METRIC_NAME,
056            DB, CONTAINMENT, OPERATION, "getContainerIdByPath");
057    private static final Timer resetTimer = Metrics.timer(METRIC_NAME,
058            DB, CONTAINMENT, OPERATION, "reset");
059    private static final Timer clearAllTransactionsTimer = Metrics.timer(METRIC_NAME,
060            DB, CONTAINMENT, OPERATION, "clearAllTransactions");
061    private static final Timer hasResourcesStartingWithTimer = Metrics.timer(METRIC_NAME,
062            DB, CONTAINMENT, OPERATION, "hasResourcesStartingWith");
063    private static final Timer containmentLastUpdateTimer = Metrics.timer(METRIC_NAME, DB, CONTAINMENT, OPERATION,
064            "containmentLastUpdated");
065
066    @Autowired
067    @Qualifier("containmentIndexImpl")
068    private ContainmentIndex containmentIndexImpl;
069
070    @Override
071    public Stream<String> getContains(final Transaction tx, final FedoraId fedoraId) {
072        return MetricsHelper.time(getContainsTimer, () -> {
073            return containmentIndexImpl.getContains(tx, fedoraId);
074        });
075    }
076
077    @Override
078    public Stream<String> getContainsDeleted(final Transaction tx, final FedoraId fedoraId) {
079        return MetricsHelper.time(getContainsDeletedTimer, () -> {
080            return containmentIndexImpl.getContainsDeleted(tx, fedoraId);
081        });
082    }
083
084    @Override
085    public String getContainedBy(final Transaction tx, final FedoraId resource) {
086        return MetricsHelper.time(getContainsByTimer, () -> {
087            return containmentIndexImpl.getContainedBy(tx, resource);
088        });
089    }
090
091    @Override
092    public void removeContainedBy(final Transaction tx, final FedoraId parent, final FedoraId child) {
093        removeContainedByTimer.record(() -> {
094            containmentIndexImpl.removeContainedBy(tx, parent, child);
095        });
096    }
097
098    @Override
099    public void removeResource(final Transaction tx, final FedoraId resource) {
100        removeResourceTimer.record(() -> {
101            containmentIndexImpl.removeResource(tx, resource);
102        });
103    }
104
105    @Override
106    public void purgeResource(final Transaction tx, final FedoraId resource) {
107        purgeResourceTimer.record(() -> {
108            containmentIndexImpl.purgeResource(tx, resource);
109        });
110    }
111
112    @Override
113    public void addContainedBy(final Transaction tx, final FedoraId parent, final FedoraId child) {
114        addContainedByTimer.record(() -> {
115            containmentIndexImpl.addContainedBy(tx, parent, child);
116        });
117    }
118
119    @Override
120    public void addContainedBy(final Transaction tx, final FedoraId parent, final FedoraId child,
121                               final Instant startTime, final Instant endTime) {
122        addContainedByTimer.record(() -> containmentIndexImpl.addContainedBy(tx, parent, child, startTime, endTime));
123    }
124
125    @Override
126    public void commitTransaction(final Transaction tx) {
127        commitTransactionTimer.record(() -> {
128            containmentIndexImpl.commitTransaction(tx);
129        });
130    }
131
132    @Override
133    public void rollbackTransaction(final Transaction tx) {
134        rollbackTransactionTimer.record(() -> {
135            containmentIndexImpl.rollbackTransaction(tx);
136        });
137    }
138
139    @Override
140    public void clearAllTransactions() {
141        clearAllTransactionsTimer.record(() -> {
142            containmentIndexImpl.clearAllTransactions();
143        });
144    }
145
146    @Override
147    public boolean resourceExists(final Transaction tx, final FedoraId fedoraId, final boolean includeDeleted) {
148        return MetricsHelper.time(resourceExistsTimer, () -> {
149            return containmentIndexImpl.resourceExists(tx, fedoraId, includeDeleted);
150        });
151    }
152
153    @Override
154    public FedoraId getContainerIdByPath(final Transaction tx, final FedoraId fedoraId, final boolean checkDeleted) {
155        return MetricsHelper.time(getContainerIdByPathTimer, () -> {
156            return containmentIndexImpl.getContainerIdByPath(tx, fedoraId, checkDeleted);
157        });
158    }
159
160    @Override
161    public void reset() {
162        resetTimer.record(() -> {
163            containmentIndexImpl.reset();
164        });
165    }
166
167    @Override
168    public boolean hasResourcesStartingWith(final Transaction tx, final FedoraId fedoraId) {
169        return MetricsHelper.time(hasResourcesStartingWithTimer, () ->
170                containmentIndexImpl.hasResourcesStartingWith(tx, fedoraId));
171    }
172
173    @Override
174    public Instant containmentLastUpdated(final Transaction tx, final FedoraId fedoraId) {
175        return MetricsHelper.time(containmentLastUpdateTimer, () ->
176                containmentIndexImpl.containmentLastUpdated(tx, fedoraId));
177    }
178}