001package org.hl7.fhir.validation.cli.services;
002
003import org.apache.commons.collections4.map.PassiveExpiringMap;
004import org.hl7.fhir.validation.ValidationEngine;
005
006import java.util.Set;
007import java.util.UUID;
008import java.util.concurrent.TimeUnit;
009
010/**
011 * SessionCache for storing and retrieving ValidationEngine instances, so callers do not have to re-instantiate a new
012 * instance for each validation request.
013 */
014public class SessionCache {
015
016  protected static final long TIME_TO_LIVE = 60;
017  protected static final TimeUnit TIME_UNIT = TimeUnit.MINUTES;
018
019  private final PassiveExpiringMap<String, ValidationEngine> cachedSessions;
020
021  public SessionCache() {
022    cachedSessions = new PassiveExpiringMap<>(TIME_TO_LIVE, TIME_UNIT);
023  }
024
025  /**
026   * @param sessionLength the constant amount of time an entry is available before it expires. A negative value results
027   *                      in entries that NEVER expire. A zero value results in entries that ALWAYS expire.
028   * @param sessionLengthUnit the unit of time for the timeToLive parameter, must not be null
029   */
030  public SessionCache(long sessionLength, TimeUnit sessionLengthUnit) {
031    cachedSessions = new PassiveExpiringMap<>(sessionLength, sessionLengthUnit);
032  }
033
034  /**
035   * Stores the initialized {@link ValidationEngine} in the cache. Returns the session id that will be associated with
036   * this instance.
037   * @param validationEngine {@link ValidationEngine}
038   * @return The {@link String} id associated with the stored instance.
039   */
040  public String cacheSession(ValidationEngine validationEngine) {
041    String generatedId = generateID();
042    cachedSessions.put(generatedId, validationEngine);
043    return generatedId;
044  }
045
046  /**
047   * Stores the initialized {@link ValidationEngine} in the cache with the passed in id as the key. If a null key is
048   * passed in, a new key is generated and returned.
049   * @param sessionId The {@link String} key to associate with this stored {@link ValidationEngine}
050   * @param validationEngine The {@link ValidationEngine} instance to cache.
051   * @return The {@link String} id that will be associated with the stored {@link ValidationEngine}
052   */
053  public String cacheSession(String sessionId, ValidationEngine validationEngine) {
054    if(sessionId == null) {
055      sessionId = cacheSession(validationEngine);
056    } else {
057      cachedSessions.put(sessionId, validationEngine);
058    }
059    return sessionId;
060  }
061
062  /**
063   * Checks if the passed in {@link String} id exists in the set of stored session id.
064   * @param sessionId The {@link String} id to search for.
065   * @return {@link Boolean#TRUE} if such id exists.
066   */
067  public boolean sessionExists(String sessionId) {
068    return cachedSessions.containsKey(sessionId);
069  }
070
071  /**
072   * Returns the stored {@link ValidationEngine} associated with the passed in session id, if one such instance exists.
073   * @param sessionId The {@link String} session id.
074   * @return The {@link ValidationEngine} associated with the passed in id, or null if none exists.
075   */
076  public ValidationEngine fetchSessionValidatorEngine(String sessionId) {
077    return cachedSessions.get(sessionId);
078  }
079
080  /**
081   * Returns the set of stored session ids.
082   * @return {@link Set} of session ids.
083   */
084  public Set<String> getSessionIds() {
085    return cachedSessions.keySet();
086  }
087
088  /**
089   * Session ids generated internally are UUID {@link String}.
090   * @return A new {@link String} session id.
091   */
092  private String generateID() {
093    return UUID.randomUUID().toString();
094  }
095}