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 hasResourcesStartingWithTimer = Metrics.timer(METRIC_NAME,
060            DB, CONTAINMENT, OPERATION, "hasResourcesStartingWith");
061    private static final Timer containmentLastUpdateTimer = Metrics.timer(METRIC_NAME, DB, CONTAINMENT, OPERATION,
062            "containmentLastUpdated");
063
064    @Autowired
065    @Qualifier("containmentIndexImpl")
066    private ContainmentIndex containmentIndexImpl;
067
068    @Override
069    public Stream<String> getContains(final Transaction tx, final FedoraId fedoraId) {
070        return MetricsHelper.time(getContainsTimer, () -> {
071            return containmentIndexImpl.getContains(tx, fedoraId);
072        });
073    }
074
075    @Override
076    public Stream<String> getContainsDeleted(final Transaction tx, final FedoraId fedoraId) {
077        return MetricsHelper.time(getContainsDeletedTimer, () -> {
078            return containmentIndexImpl.getContainsDeleted(tx, fedoraId);
079        });
080    }
081
082    @Override
083    public String getContainedBy(final Transaction tx, final FedoraId resource) {
084        return MetricsHelper.time(getContainsByTimer, () -> {
085            return containmentIndexImpl.getContainedBy(tx, resource);
086        });
087    }
088
089    @Override
090    public void removeContainedBy(final Transaction tx, final FedoraId parent, final FedoraId child) {
091        removeContainedByTimer.record(() -> {
092            containmentIndexImpl.removeContainedBy(tx, parent, child);
093        });
094    }
095
096    @Override
097    public void removeResource(final Transaction tx, final FedoraId resource) {
098        removeResourceTimer.record(() -> {
099            containmentIndexImpl.removeResource(tx, resource);
100        });
101    }
102
103    @Override
104    public void purgeResource(final Transaction tx, final FedoraId resource) {
105        purgeResourceTimer.record(() -> {
106            containmentIndexImpl.purgeResource(tx, resource);
107        });
108    }
109
110    @Override
111    public void addContainedBy(final Transaction tx, final FedoraId parent, final FedoraId child) {
112        addContainedByTimer.record(() -> {
113            containmentIndexImpl.addContainedBy(tx, parent, child);
114        });
115    }
116
117    @Override
118    public void addContainedBy(final Transaction tx, final FedoraId parent, final FedoraId child,
119                               final Instant startTime, final Instant endTime) {
120        addContainedByTimer.record(() -> containmentIndexImpl.addContainedBy(tx, parent, child, startTime, endTime));
121    }
122
123    @Override
124    public void commitTransaction(final Transaction tx) {
125        commitTransactionTimer.record(() -> {
126            containmentIndexImpl.commitTransaction(tx);
127        });
128    }
129
130    @Override
131    public void rollbackTransaction(final Transaction tx) {
132        rollbackTransactionTimer.record(() -> {
133            containmentIndexImpl.rollbackTransaction(tx);
134        });
135    }
136
137    @Override
138    public boolean resourceExists(final Transaction tx, final FedoraId fedoraId, final boolean includeDeleted) {
139        return MetricsHelper.time(resourceExistsTimer, () -> {
140            return containmentIndexImpl.resourceExists(tx, fedoraId, includeDeleted);
141        });
142    }
143
144    @Override
145    public FedoraId getContainerIdByPath(final Transaction tx, final FedoraId fedoraId, final boolean checkDeleted) {
146        return MetricsHelper.time(getContainerIdByPathTimer, () -> {
147            return containmentIndexImpl.getContainerIdByPath(tx, fedoraId, checkDeleted);
148        });
149    }
150
151    @Override
152    public void reset() {
153        resetTimer.record(() -> {
154            containmentIndexImpl.reset();
155        });
156    }
157
158    @Override
159    public boolean hasResourcesStartingWith(final Transaction tx, final FedoraId fedoraId) {
160        return MetricsHelper.time(hasResourcesStartingWithTimer, () ->
161                containmentIndexImpl.hasResourcesStartingWith(tx, fedoraId));
162    }
163
164    @Override
165    public Instant containmentLastUpdated(final Transaction tx, final FedoraId fedoraId) {
166        return MetricsHelper.time(containmentLastUpdateTimer, () ->
167                containmentIndexImpl.containmentLastUpdated(tx, fedoraId));
168    }
169}