001/* 002 * The contents of this file are subject to the license and copyright 003 * detailed in the LICENSE and NOTICE files at the root of the source 004 * tree. 005 */ 006package org.fcrepo.persistence.ocfl.impl; 007 008import org.fcrepo.kernel.api.ReadOnlyTransaction; 009import org.fcrepo.kernel.api.Transaction; 010import org.fcrepo.persistence.api.PersistentStorageSession; 011import org.fcrepo.persistence.api.PersistentStorageSessionManager; 012import org.fcrepo.persistence.ocfl.api.FedoraToOcflObjectIndex; 013import org.fcrepo.storage.ocfl.OcflObjectSessionFactory; 014import org.slf4j.Logger; 015import org.slf4j.LoggerFactory; 016import org.springframework.beans.factory.annotation.Autowired; 017import org.springframework.stereotype.Component; 018 019import javax.inject.Inject; 020import java.util.Map; 021import java.util.concurrent.ConcurrentHashMap; 022 023/** 024 * OCFL implementation of PersistentStorageSessionManager 025 * 026 * @author whikloj 027 * @author dbernstein 028 * @since 2019-09-20 029 */ 030@Component 031public class OcflPersistentSessionManager implements PersistentStorageSessionManager { 032 033 private static final Logger LOGGER = LoggerFactory.getLogger(OcflPersistentSessionManager.class); 034 035 private volatile PersistentStorageSession readOnlySession; 036 037 private Map<String, PersistentStorageSession> sessionMap; 038 039 @Inject 040 private OcflObjectSessionFactory objectSessionFactory; 041 042 @Inject 043 private FedoraToOcflObjectIndex ocflIndex; 044 045 @Inject 046 private ReindexService reindexService; 047 048 /** 049 * Default constructor 050 */ 051 @Autowired 052 public OcflPersistentSessionManager() { 053 this.sessionMap = new ConcurrentHashMap<>(); 054 } 055 056 @Override 057 public PersistentStorageSession getSession(final Transaction transaction) { 058 if (transaction == null) { 059 throw new IllegalArgumentException("session id must be non-null"); 060 } 061 062 return sessionMap.computeIfAbsent(transaction.getId(), key -> { 063 LOGGER.debug("Creating storage session {}", transaction); 064 return new OcflPersistentStorageSessionMetrics( 065 new OcflPersistentStorageSession( 066 transaction, 067 ocflIndex, 068 objectSessionFactory, 069 reindexService)); 070 }); 071 } 072 073 @Override 074 public PersistentStorageSession getReadOnlySession() { 075 var localSession = this.readOnlySession; 076 077 if (localSession == null) { 078 synchronized (this) { 079 localSession = this.readOnlySession; 080 if (localSession == null) { 081 this.readOnlySession = new OcflPersistentStorageSessionMetrics( 082 new OcflPersistentStorageSession(ReadOnlyTransaction.INSTANCE, 083 ocflIndex, objectSessionFactory, reindexService)); 084 localSession = this.readOnlySession; 085 } 086 } 087 } 088 089 return localSession; 090 } 091 092 @Override 093 public PersistentStorageSession removeSession(final String sessionId) { 094 LOGGER.debug("Removing storage session {}", sessionId); 095 return sessionMap.remove(sessionId); 096 } 097}