001package org.hl7.fhir.validation.cli.services; 002 003import java.util.Set; 004import java.util.UUID; 005import java.util.concurrent.TimeUnit; 006 007import org.apache.commons.collections4.map.PassiveExpiringMap; 008import org.hl7.fhir.validation.ValidationEngine; 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 * When called, this actively checks the cache for expired entries and removes 064 * them. 065 */ 066 public void removeExpiredSessions() { 067 /* 068 The PassiveExpiringMap will remove entries when accessing the mapped value 069 for a key, OR when invoking methods that involve accessing the entire map 070 contents. So, we call keySet below to force removal of all expired entries. 071 * */ 072 cachedSessions.keySet(); 073 } 074 075 /** 076 * Checks if the passed in {@link String} id exists in the set of stored session id. 077 * @param sessionId The {@link String} id to search for. 078 * @return {@link Boolean#TRUE} if such id exists. 079 */ 080 public boolean sessionExists(String sessionId) { 081 return cachedSessions.containsKey(sessionId); 082 } 083 084 /** 085 * Returns the stored {@link ValidationEngine} associated with the passed in session id, if one such instance exists. 086 * @param sessionId The {@link String} session id. 087 * @return The {@link ValidationEngine} associated with the passed in id, or null if none exists. 088 */ 089 public ValidationEngine fetchSessionValidatorEngine(String sessionId) { 090 return cachedSessions.get(sessionId); 091 } 092 093 /** 094 * Returns the set of stored session ids. 095 * @return {@link Set} of session ids. 096 */ 097 public Set<String> getSessionIds() { 098 return cachedSessions.keySet(); 099 } 100 101 /** 102 * Session ids generated internally are UUID {@link String}. 103 * @return A new {@link String} session id. 104 */ 105 private String generateID() { 106 return UUID.randomUUID().toString(); 107 } 108}