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