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; 007 008 009import org.fcrepo.config.FedoraPropsConfig; 010import org.fcrepo.config.OcflPropsConfig; 011import org.fcrepo.kernel.api.TransactionManager; 012import org.fcrepo.kernel.api.exception.RepositoryRuntimeException; 013import org.fcrepo.kernel.api.identifiers.FedoraId; 014import org.fcrepo.kernel.api.operations.RdfSourceOperation; 015import org.fcrepo.kernel.api.operations.RdfSourceOperationFactory; 016import org.fcrepo.kernel.api.operations.VersionResourceOperationFactory; 017import org.fcrepo.persistence.api.PersistentStorageSession; 018import org.fcrepo.persistence.api.exceptions.PersistentItemNotFoundException; 019import org.fcrepo.persistence.api.exceptions.PersistentStorageException; 020import org.fcrepo.persistence.ocfl.api.IndexBuilder; 021import org.fcrepo.persistence.ocfl.impl.OcflPersistentSessionManager; 022import org.slf4j.Logger; 023import org.slf4j.LoggerFactory; 024import org.springframework.context.ConfigurableApplicationContext; 025import org.springframework.context.event.ContextRefreshedEvent; 026import org.springframework.context.event.EventListener; 027import org.springframework.scheduling.annotation.Async; 028import org.springframework.stereotype.Component; 029 030import javax.inject.Inject; 031 032import static org.fcrepo.kernel.api.RdfLexicon.BASIC_CONTAINER; 033 034import java.util.concurrent.atomic.AtomicBoolean; 035 036/** 037 * This class is responsible for initializing the repository on start-up. 038 * 039 * @author dbernstein 040 */ 041@Component 042public class RepositoryInitializer { 043 044 private static final Logger LOGGER = LoggerFactory.getLogger(RepositoryInitializer.class); 045 046 @Inject 047 private OcflPersistentSessionManager sessionManager; 048 049 @Inject 050 private RdfSourceOperationFactory operationFactory; 051 052 @Inject 053 private IndexBuilder indexBuilder; 054 055 @Inject 056 private VersionResourceOperationFactory versionResourceOperationFactory; 057 058 @Inject 059 private OcflPropsConfig config; 060 061 @Inject 062 private FedoraPropsConfig fedoraPropsConfig; 063 064 @Inject 065 private TransactionManager txManager; 066 067 private final AtomicBoolean initializationComplete = new AtomicBoolean(false); 068 069 // This is used in-place of @PostConstruct so that it is called _after_ the rest of context has been 070 // completely initialized. 071 @Async 072 @EventListener 073 public void onApplicationEvent(final ContextRefreshedEvent event) { 074 try { 075 initialize(); 076 } catch (Exception e) { 077 LOGGER.error("Failed to initialize repository", e); 078 ((ConfigurableApplicationContext) event.getApplicationContext()).close(); 079 } finally { 080 initializationComplete.set(true); 081 } 082 } 083 084 /** 085 * Initializes the repository 086 */ 087 public void initialize() { 088 LOGGER.info("Initializing repository"); 089 090 indexBuilder.rebuildIfNecessary(); 091 092 final var root = FedoraId.getRepositoryRootId(); 093 094 try { 095 //check that the root is initialized 096 final var transaction = txManager.create(); 097 transaction.setShortLived(true); 098 final PersistentStorageSession session = this.sessionManager.getSession(transaction); 099 100 try { 101 session.getHeaders(root, null); 102 } catch (final PersistentItemNotFoundException e) { 103 LOGGER.debug("Repository root ({}) not found. Creating...", root); 104 final RdfSourceOperation operation = this.operationFactory.createBuilder(transaction, root, 105 BASIC_CONTAINER.getURI(), fedoraPropsConfig.getServerManagedPropsMode()) 106 .parentId(root).build(); 107 108 session.persist(operation); 109 110 //if auto versioning is not enabled, be sure to create an immutable version 111 if (!config.isAutoVersioningEnabled()) { 112 final var versionOperation = this.versionResourceOperationFactory 113 .createBuilder(transaction, root).build(); 114 session.persist(versionOperation); 115 } 116 117 transaction.commit(); 118 119 LOGGER.debug("Successfully created repository root ({}).", root); 120 } 121 122 } catch (final PersistentStorageException ex) { 123 throw new RepositoryRuntimeException(ex.getMessage(), ex); 124 } 125 } 126 127 public boolean isInitializationComplete() { 128 return initializationComplete.get(); 129 } 130 131}