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