001package com.identityworksllc.iiq.common.cache;
002
003import sailpoint.object.Bundle;
004import sailpoint.object.Configuration;
005import sailpoint.object.Custom;
006import sailpoint.object.SailPointObject;
007
008import java.util.concurrent.TimeUnit;
009
010/**
011 * Static implementations of specific commonly-used caches
012 */
013public class Caches {
014    /**
015     * A static Bundle cache map
016     */
017    private static final CacheMap<String, Bundle> bundleCacheMap = createBundleCache();
018    /**
019     * A static Configuration cache map
020     */
021    private static final CacheMap<String, Configuration> configurationCacheMap = createConfigurationCache();
022    /**
023     * A static Custom cache map
024     */
025    private static final CacheMap<String, Custom> customCacheMap = createCustomCache();
026
027    /**
028     * Private constructor to prevent instantiation
029     */
030    private Caches() {
031        /* This class cannot be constructed */
032        throw new UnsupportedOperationException();
033    }
034
035    /**
036     * Clears all items in the Bundle, Configuration, and Custom caches
037     */
038    public static void clear() {
039        bundleCacheMap.clear();
040        configurationCacheMap.clear();
041        customCacheMap.clear();
042    }
043
044    /**
045     * Creates a new to hold Bundle objects, with the configured timeout
046     * @return a CacheMap that holds Bundle objects
047     */
048    public static CacheMap<String, Bundle> createBundleCache() {
049        return createCache(Bundle.class);
050    }
051
052    /**
053     * Creates a new instance of a cache to hold the given type. The default cache will
054     * expire its entries after 60 seconds, but this can be configured as described in
055     * {@link #getDefaultTimeoutSeconds(Class)}.
056     *
057     * @param type The type of object to store in the cache
058     * @return The newly created cache
059     * @param <T> The type reference of the SailPointObject to construct
060     */
061    public static <T extends SailPointObject> CacheMap<String, T> createCache(Class<T> type) {
062        return new CacheMap<>(getDefaultTimeoutSeconds(type), TimeUnit.SECONDS, new SailPointObjectCacheGenerator<>(type));
063    }
064
065    /**
066     * Creates a new to hold Configuration objects, with the configured timeout
067     * @return a CacheMap that holds Configuration objects
068     */
069    public static CacheMap<String, Configuration> createConfigurationCache() {
070        return createCache(Configuration.class);
071    }
072
073    /**
074     * Creates a new to hold Custom objects, with the configured timeout
075     * @return a CacheMap that holds Custom objects
076     */
077    public static CacheMap<String, Custom> createCustomCache() {
078        return createCache(Custom.class);
079    }
080
081    /**
082     * Retrieves a Bundle from the cache, or from the DB if the cache has
083     * expired
084     * @param nameOrId The name or ID of the Bundle to retrieve
085     * @return The resulting Bundle, if one exists with that name
086     */
087    public static Bundle getBundle(String nameOrId) {
088        return bundleCacheMap.get(nameOrId);
089    }
090
091    /**
092     * Gets the static Bundle cache map
093     * @return The static Bundle cache map
094     */
095    public static CacheMap<String, Bundle> getBundleCache() {
096        return bundleCacheMap;
097    }
098
099    /**
100     * Gets the Configuration object (cached or newly loaded) that corresponds to the given name or ID
101     * @param nameOrId The name or ID
102     * @return the Configuration object
103     */
104    public static Configuration getConfiguration(String nameOrId) {
105        return configurationCacheMap.get(nameOrId);
106    }
107
108    /**
109     * Gets the static Configuration cache map created on startup
110     * @return The static Configuration cache map
111     */
112    public static CacheMap<String, Configuration> getConfigurationCache() {
113        return configurationCacheMap;
114    }
115
116    /**
117     * Gets the Custom (cached or newly loaded) that corresponds to the given name or ID
118     * @param nameOrId The name or ID
119     * @return the Custom object
120     */
121    public static Custom getCustom(String nameOrId) {
122        return customCacheMap.get(nameOrId);
123    }
124
125    /**
126     * Gets the static Custom cache map created on startup
127     * @return The static Custom cache map created on startup
128     */
129    public static CacheMap<String, Custom> getCustomCacheMap() {
130        return customCacheMap;
131    }
132
133    /**
134     * Returns the configured cache timeout in seconds. This will consult the following
135     * configuration keys in SystemConfiguration:
136     *
137     *  IIQCommon.Caches.(type).Timeout
138     *  IIQCommon.Caches.Default.Timeout
139     *
140     * If none are present, or if both are less than 1, the default of 60 seconds is used.
141     *
142     * @return The timeout in seconds, with a default of 60
143     */
144    public static int getDefaultTimeoutSeconds(Class<? extends SailPointObject> type) {
145        int timeout = 60;
146
147        Configuration systemConfig = Configuration.getSystemConfig();
148        if (systemConfig != null) {
149            int configuredTimeoutSpecific = systemConfig.getInt("IIQCommon.Caches." + type.getSimpleName() + ".Timeout");
150            if (configuredTimeoutSpecific > 0) {
151                timeout = configuredTimeoutSpecific;
152            } else {
153                int configuredTimeout = systemConfig.getInt("IIQCommon.Caches.Default.Timeout");
154                if (configuredTimeout > 0) {
155                    timeout = configuredTimeout;
156                }
157            }
158        }
159
160        return timeout;
161    }
162}