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 */ 006 007package org.fcrepo.webapp; 008 009import java.util.Optional; 010import java.util.concurrent.ExecutorService; 011import java.util.concurrent.Executors; 012import java.util.concurrent.TimeUnit; 013 014import javax.inject.Inject; 015import javax.servlet.Filter; 016 017import org.fcrepo.config.FedoraPropsConfig; 018import org.fcrepo.http.api.ExternalContentHandlerFactory; 019import org.fcrepo.http.api.ExternalContentPathValidator; 020import org.fcrepo.kernel.api.auth.ACLHandle; 021import org.fcrepo.kernel.api.rdf.RdfNamespaceRegistry; 022 023import org.apache.http.conn.HttpClientConnectionManager; 024import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; 025import org.fcrepo.persistence.ocfl.RepositoryInitializationFilter; 026import org.slf4j.Logger; 027import org.slf4j.LoggerFactory; 028import org.springframework.context.annotation.Bean; 029import org.springframework.context.annotation.Configuration; 030import org.springframework.scheduling.annotation.EnableAsync; 031import org.springframework.scheduling.annotation.EnableScheduling; 032import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; 033 034import com.github.benmanes.caffeine.cache.Cache; 035import com.github.benmanes.caffeine.cache.Caffeine; 036import com.google.common.eventbus.AsyncEventBus; 037import com.google.common.eventbus.EventBus; 038 039/** 040 * Spring config for the webapp 041 * 042 * @author pwinckles 043 */ 044@Configuration 045@EnableAsync 046@EnableScheduling 047public class WebappConfig { 048 049 private static final Logger LOGGER = LoggerFactory.getLogger(WebappConfig.class); 050 051 @Inject 052 private FedoraPropsConfig fedoraPropsConfig; 053 054 /** 055 * Task scheduler used for cleaning up transactions 056 * 057 * @return scheduler 058 */ 059 @Bean 060 public ThreadPoolTaskScheduler taskScheduler() { 061 final var scheduler = new ThreadPoolTaskScheduler(); 062 scheduler.setPoolSize(1); 063 scheduler.setThreadNamePrefix("ScheduledTask"); 064 return scheduler; 065 } 066 067 /** 068 * HTTP connection manager 069 * 070 * @return connection manager 071 */ 072 @Bean 073 public HttpClientConnectionManager connectionManager() { 074 return new PoolingHttpClientConnectionManager(); 075 } 076 077 /** 078 * Fedora's lightweight internal event bus. Currently memory-resident. 079 * 080 * @param propsConfig config 081 * @return event bus 082 */ 083 @Bean 084 public EventBus eventBus(final FedoraPropsConfig propsConfig) { 085 return new AsyncEventBus(eventBusExecutor(propsConfig)); 086 } 087 088 /** 089 * @param propsConfig config 090 * @return executor intended to be used by the Guava event bus 091 */ 092 @Bean 093 public ExecutorService eventBusExecutor(final FedoraPropsConfig propsConfig) { 094 LOGGER.debug("Event bus threads: {}", propsConfig); 095 return Executors.newFixedThreadPool(propsConfig.getEventBusThreads()); 096 } 097 098 /** 099 * Configuration of namespace prefixes 100 * 101 * @param propsConfig config properties 102 * @return rdf namespace registry 103 */ 104 @Bean(initMethod = "init", destroyMethod = "shutdown") 105 public RdfNamespaceRegistry rdfNamespaceRegistry(final FedoraPropsConfig propsConfig) { 106 final var registry = new RdfNamespaceRegistry(); 107 registry.setConfigPath(propsConfig.getNamespaceRegistry()); 108 registry.setMonitorForChanges(true); 109 return registry; 110 } 111 112 /** 113 * External content configuration 114 * 115 * @param propsConfig config properties 116 * @return external content path validator 117 */ 118 @Bean(initMethod = "init", destroyMethod = "shutdown") 119 public ExternalContentPathValidator externalContentPathValidator(final FedoraPropsConfig propsConfig) { 120 final var validator = new ExternalContentPathValidator(); 121 validator.setConfigPath(propsConfig.getExternalContentAllowed()); 122 validator.setMonitorForChanges(true); 123 return validator; 124 } 125 126 @Bean 127 public ExternalContentHandlerFactory externalContentHandlerFactory(final ExternalContentPathValidator validator) { 128 final var factory = new ExternalContentHandlerFactory(); 129 factory.setValidator(validator); 130 return factory; 131 } 132 133 /** 134 * Used to cache the effective ACL location and authorizations for a given resource. 135 * 136 * @return the cache 137 */ 138 @Bean 139 public Cache<String, Optional<ACLHandle>> authHandleCache() { 140 return Caffeine.newBuilder().weakValues() 141 .expireAfterAccess(fedoraPropsConfig.getWebacCacheTimeout(), TimeUnit.MINUTES) 142 .maximumSize(fedoraPropsConfig.getWebacCacheSize()).build(); 143 } 144 145 /** 146 * Filter to prevent http requests during repo init 147 * 148 * @return the filter 149 */ 150 @Bean 151 public Filter repositoryInitializationFilter() { 152 return new RepositoryInitializationFilter(); 153 } 154 155}