org.infinispan.spring.session.AbstractInfinispanSessionRepository Maven / Gradle / Ivy
package org.infinispan.spring.session;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.infinispan.spring.provider.SpringCache;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.MapSession;
import org.springframework.session.SessionRepository;
/**
* Infinispan implementation for Spring Session with basic functionality.
*
* @author Sebastian Łaskawiec
* @see Spring Session Web Page
* @see SessionRepository
* @see ApplicationEventPublisherAware
* @see FindByIndexNameSessionRepository
* @since 9.0
*/
public abstract class AbstractInfinispanSessionRepository implements SessionRepository, FindByIndexNameSessionRepository, ApplicationEventPublisherAware, InitializingBean, DisposableBean {
protected final AbstractApplicationPublisherBridge applicationEventPublisher;
protected final SpringCache cache;
protected final PrincipalNameResolver principalNameResolver = new PrincipalNameResolver();
protected AbstractInfinispanSessionRepository(SpringCache cache, AbstractApplicationPublisherBridge eventsBridge) {
Objects.requireNonNull(cache, "SpringCache can not be null");
Objects.requireNonNull(eventsBridge, "EventBridge can not be null");
applicationEventPublisher = eventsBridge;
this.cache = cache;
}
@Override
public void afterPropertiesSet() throws Exception {
applicationEventPublisher.registerListener();
}
@Override
public void destroy() throws Exception {
applicationEventPublisher.unregisterListener();
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher.setApplicationEventPublisher(applicationEventPublisher);
}
@Override
public MapSession createSession() {
MapSession result = new MapSession();
result.setCreationTime(System.currentTimeMillis());
return result;
}
@Override
public void save(MapSession session) {
cache.put(session.getId(), session, session.getMaxInactiveIntervalInSeconds(), TimeUnit.SECONDS);
}
@Override
public MapSession getSession(String id) {
return getSession(id, true);
}
/**
* Returns session with optional parameter whether or not update time accessed.
*
* @param id Session ID.
* @param updateTTL true
if time accessed needs to be updated.
* @return Session or null
if it doesn't exist.
*/
public MapSession getSession(String id, boolean updateTTL) {
return Optional.ofNullable(cache.get(id))
.map(v -> (MapSession) v.get())
.map(v -> updateTTL(v, updateTTL))
.orElse(null);
}
protected MapSession updateTTL(MapSession session, boolean updateTTL) {
if (updateTTL) {
session.setLastAccessedTime(System.currentTimeMillis());
cache.put(session.getId(), session, session.getMaxInactiveIntervalInSeconds(), TimeUnit.SECONDS);
}
return session;
}
@Override
public void delete(String id) {
applicationEventPublisher.emitSessionDeletedEvent(id);
cache.evict(id);
}
@Override
public Map findByIndexNameAndIndexValue(String indexName, String indexValue) {
if (!PRINCIPAL_NAME_INDEX_NAME.equals(indexName)) {
return Collections.emptyMap();
}
return cache.getNativeCache().values().stream()
.map(cacheValue -> (MapSession) cacheValue)
.filter(session -> indexValue.equals(principalNameResolver.resolvePrincipal(session)))
.collect(Collectors.toMap(MapSession::getId, Function.identity()));
}
}