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