001/* 002 * Licensed to DuraSpace under one or more contributor license agreements. 003 * See the NOTICE file distributed with this work for additional information 004 * regarding copyright ownership. 005 * 006 * DuraSpace licenses this file to you under the Apache License, 007 * Version 2.0 (the "License"); you may not use this file except in 008 * compliance with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.fcrepo.persistence.ocfl.impl; 019 020import org.fcrepo.kernel.api.ReadOnlyTransaction; 021import org.fcrepo.kernel.api.Transaction; 022import org.fcrepo.persistence.api.PersistentStorageSession; 023import org.fcrepo.persistence.api.PersistentStorageSessionManager; 024import org.fcrepo.persistence.ocfl.api.FedoraToOcflObjectIndex; 025import org.fcrepo.storage.ocfl.OcflObjectSessionFactory; 026import org.slf4j.Logger; 027import org.slf4j.LoggerFactory; 028import org.springframework.beans.factory.annotation.Autowired; 029import org.springframework.stereotype.Component; 030 031import javax.inject.Inject; 032import java.util.Map; 033import java.util.concurrent.ConcurrentHashMap; 034 035/** 036 * OCFL implementation of PersistentStorageSessionManager 037 * 038 * @author whikloj 039 * @author dbernstein 040 * @since 2019-09-20 041 */ 042@Component 043public class OcflPersistentSessionManager implements PersistentStorageSessionManager { 044 045 private static final Logger LOGGER = LoggerFactory.getLogger(OcflPersistentSessionManager.class); 046 047 private volatile PersistentStorageSession readOnlySession; 048 049 private Map<String, PersistentStorageSession> sessionMap; 050 051 @Inject 052 private OcflObjectSessionFactory objectSessionFactory; 053 054 @Inject 055 private FedoraToOcflObjectIndex ocflIndex; 056 057 @Inject 058 private ReindexService reindexService; 059 060 /** 061 * Default constructor 062 */ 063 @Autowired 064 public OcflPersistentSessionManager() { 065 this.sessionMap = new ConcurrentHashMap<>(); 066 } 067 068 @Override 069 public PersistentStorageSession getSession(final Transaction transaction) { 070 if (transaction == null) { 071 throw new IllegalArgumentException("session id must be non-null"); 072 } 073 074 return sessionMap.computeIfAbsent(transaction.getId(), key -> { 075 LOGGER.debug("Creating storage session {}", transaction); 076 return new OcflPersistentStorageSessionMetrics( 077 new OcflPersistentStorageSession( 078 transaction, 079 ocflIndex, 080 objectSessionFactory, 081 reindexService)); 082 }); 083 } 084 085 @Override 086 public PersistentStorageSession getReadOnlySession() { 087 var localSession = this.readOnlySession; 088 089 if (localSession == null) { 090 synchronized (this) { 091 localSession = this.readOnlySession; 092 if (localSession == null) { 093 this.readOnlySession = new OcflPersistentStorageSessionMetrics( 094 new OcflPersistentStorageSession(ReadOnlyTransaction.INSTANCE, 095 ocflIndex, objectSessionFactory, reindexService)); 096 localSession = this.readOnlySession; 097 } 098 } 099 } 100 101 return localSession; 102 } 103 104 @Override 105 public PersistentStorageSession removeSession(final String sessionId) { 106 LOGGER.debug("Removing storage session {}", sessionId); 107 return sessionMap.remove(sessionId); 108 } 109}