001package com.identityworksllc.iiq.common;
002
003import com.identityworksllc.iiq.common.annotation.CoreStable;
004import sailpoint.api.Meter;
005import sailpoint.tools.GeneralException;
006
007/**
008 * Starts a {@link Meter} with the given name, then invokes the callback, then
009 * finally stops the meter before returning the output.
010 *
011 * Usage example:
012 *
013 * Metered.meter("Meter name", () -> {
014 *     // your code here
015 * })
016 *
017 */
018@CoreStable
019public class Metered {
020    /**
021     * Callback interface where no output is required
022     */
023    @FunctionalInterface
024    public interface MeterCallback {
025        /**
026         * Performs the action wrapped by the Meter
027         * @throws GeneralException if anything goes wrong
028         */
029        void run() throws GeneralException;
030    }
031
032    /**
033     * Callback interface where an output is required
034     * @param <T> The output type
035     */
036    @FunctionalInterface
037    public interface MeterCallbackWithOutput<T> {
038        /**
039         * Performs the action wrapped by the Meter, returning any output
040         * @return The output of the action
041         * @throws GeneralException if anything goes wrong
042         */
043        T run() throws GeneralException;
044    }
045
046    /**
047     * Meters the invocation of the callback, including an output
048     *
049     * @param meterName The meter name
050     * @param callback The callback to invoke
051     * @param <T> The output type
052     * @return The output of the callback
053     * @throws GeneralException on any errors in the callback
054     */
055    public static <T> T meter(String meterName, MeterCallbackWithOutput<T> callback) throws GeneralException {
056        Meter.enterByName(meterName);
057        try {
058            return callback.run();
059        } finally {
060            Meter.exitByName(meterName);
061        }
062    }
063
064    /**
065     * Meters the invocation of the callback, without an output
066     *
067     * @param meterName The meter name
068     * @param callback The callback to invoke
069     * @throws GeneralException on any errors in the callback
070     */
071    public static void meter(String meterName, MeterCallback callback) throws GeneralException {
072        Meter.enterByName(meterName);
073        try {
074            callback.run();
075        } finally {
076            Meter.exitByName(meterName);
077        }
078    }
079
080    /**
081     * Private utility constructor
082     */
083    private Metered() {
084
085    }
086}