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.config;
020
021import java.io.IOException;
022import java.nio.file.Path;
023import java.time.Duration;
024
025import javax.annotation.PostConstruct;
026
027import org.slf4j.Logger;
028import org.slf4j.LoggerFactory;
029import org.springframework.beans.factory.annotation.Value;
030import org.springframework.context.annotation.Configuration;
031import org.springframework.core.io.Resource;
032
033/**
034 * General Fedora properties
035 *
036 * @author pwinckles
037 * @since 6.0.0
038 */
039@Configuration
040public class FedoraPropsConfig extends BasePropsConfig {
041
042    private static final Logger LOGGER = LoggerFactory.getLogger(FedoraPropsConfig.class);
043
044    public static final String FCREPO_JMS_HOST = "fcrepo.jms.host";
045    public static final String FCREPO_DYNAMIC_JMS_PORT = "fcrepo.dynamic.jms.port";
046    public static final String FCREPO_DYNAMIC_STOMP_PORT = "fcrepo.dynamic.stomp.port";
047    public static final String FCREPO_ACTIVEMQ_CONFIGURATION = "fcrepo.activemq.configuration";
048    public static final String FCREPO_NAMESPACE_REGISTRY = "fcrepo.namespace.registry";
049    public static final String FCREPO_EXTERNAL_CONTENT_ALLOWED = "fcrepo.external.content.allowed";
050    private static final String FCREPO_ACTIVEMQ_DIRECTORY = "fcrepo.activemq.directory";
051    private static final String FCREPO_SESSION_TIMEOUT = "fcrepo.session.timeout";
052    private static final String FCREPO_VELOCITY_RUNTIME_LOG = "fcrepo.velocity.runtime.log";
053    private static final String FCREPO_REBUILD_VALIDATION_FIXITY = "fcrepo.rebuild.validation.fixity";
054    private static final String FCREPO_REBUILD_ON_START = "fcrepo.rebuild.on.start";
055    private static final String FCREPO_JMS_BASEURL = "fcrepo.jms.baseUrl";
056    private static final String FCREPO_SERVER_MANAGED_PROPS_MODE = "fcrepo.properties.management";
057    private static final String FCREPO_JMS_DESTINATION_TYPE = "fcrepo.jms.destination.type";
058    private static final String FCREPO_JMS_DESTINATION_NAME = "fcrepo.jms.destination.name";
059    public static final String FCREPO_JMS_ENABLED = "fcrepo.jms.enabled";
060    private static final String FCREPO_EVENT_THREADS = "fcrepo.event.threads";
061
062    private static final String DATA_DIR_DEFAULT_VALUE = "data";
063    private static final String LOG_DIR_DEFAULT_VALUE = "logs";
064    private static final String ACTIVE_MQ_DIR_DEFAULT_VALUE = "ActiveMQ/kahadb";
065
066    @Value("${" + FCREPO_HOME_PROPERTY + ":" + DEFAULT_FCREPO_HOME_VALUE + "}")
067    protected Path fedoraHome;
068
069    @Value("#{fedoraPropsConfig.fedoraHome.resolve('" + DATA_DIR_DEFAULT_VALUE + "')}")
070    private Path fedoraData;
071
072    @Value("#{fedoraPropsConfig.fedoraHome.resolve('" + LOG_DIR_DEFAULT_VALUE + "')}")
073    private Path fedoraLogs;
074
075    @Value("${" + FCREPO_JMS_HOST + ":localhost}")
076    private String jmsHost;
077
078    @Value("${" + FCREPO_DYNAMIC_JMS_PORT + ":61616}")
079    private String jmsPort;
080
081    @Value("${" + FCREPO_DYNAMIC_STOMP_PORT + ":61613}")
082    private String stompPort;
083
084    @Value("${" + FCREPO_ACTIVEMQ_CONFIGURATION + ":classpath:/config/activemq.xml}")
085    private Resource activeMQConfiguration;
086
087    @Value("${" + FCREPO_ACTIVEMQ_DIRECTORY + ":#{fedoraPropsConfig.fedoraData.resolve('" +
088            ACTIVE_MQ_DIR_DEFAULT_VALUE + "').toAbsolutePath().toString()}}")
089    private String activeMqDirectory;
090
091    @Value("${" + FCREPO_NAMESPACE_REGISTRY + ":classpath:/namespaces.yml}")
092    private String namespaceRegistry;
093
094    @Value("${" + FCREPO_EXTERNAL_CONTENT_ALLOWED + ":#{null}}")
095    private String externalContentAllowed;
096
097    @Value("${" + FCREPO_SESSION_TIMEOUT + ":180000}")
098    private Long sessionTimeoutLong;
099    private Duration sessionTimeout;
100
101    @Value("${" + FCREPO_VELOCITY_RUNTIME_LOG + ":" +
102            "#{fedoraPropsConfig.fedoraLogs.resolve('velocity.log').toString()}}")
103    private Path velocityLog;
104
105    @Value("${" + FCREPO_REBUILD_VALIDATION_FIXITY + ":false}")
106    private boolean rebuildFixityCheck;
107
108    @Value("${" + FCREPO_REBUILD_ON_START + ":false}")
109    private boolean rebuildOnStart;
110
111    @Value("${" + FCREPO_JMS_BASEURL + ":#{null}}")
112    private String jmsBaseUrl;
113
114    @Value("${" + FCREPO_SERVER_MANAGED_PROPS_MODE + ":strict}")
115    private String serverManagedPropsModeStr;
116    private ServerManagedPropsMode serverManagedPropsMode;
117
118    @Value("${" + FCREPO_JMS_DESTINATION_TYPE + ":topic}")
119    private String jmsDestinationTypeStr;
120    private JmsDestination jmsDestinationType;
121
122    @Value("${" + FCREPO_JMS_DESTINATION_NAME + ":fedora}")
123    private String jmsDestinationName;
124
125    @Value("${" + FCREPO_EVENT_THREADS + ":1}")
126    private int eventBusThreads;
127
128    @Value("${fcrepo.cache.db.containment.size.entries:1024}")
129    private long containmentCacheSize;
130
131    @Value("${fcrepo.cache.db.containment.timeout.minutes:10}")
132    private long containmentCacheTimeout;
133
134    @Value("${fcrepo.cache.webac.acl.size.entries:1024}")
135    private long webacCacheSize;
136
137    @Value("${fcrepo.cache.webac.acl.timeout.minutes:10}")
138    private long webacCacheTimeout;
139
140    @PostConstruct
141    private void postConstruct() throws IOException {
142        LOGGER.info("Fedora home: {}", fedoraHome);
143        LOGGER.debug("Fedora home data: {}", fedoraData);
144        try {
145            createDirectories(fedoraHome);
146        } catch (final IOException e) {
147            throw new IOException(String.format("Failed to create Fedora home directory at %s." +
148                    " Fedora home can be configured by setting the %s property.", fedoraHome, FCREPO_HOME_PROPERTY), e);
149        }
150        createDirectories(fedoraData);
151        serverManagedPropsMode = ServerManagedPropsMode.fromString(serverManagedPropsModeStr);
152        sessionTimeout = Duration.ofMillis(sessionTimeoutLong);
153        jmsDestinationType = JmsDestination.fromString(jmsDestinationTypeStr);
154    }
155
156    /**
157     * @return Path to Fedora home directory
158     */
159    public Path getFedoraHome() {
160        return fedoraHome;
161    }
162
163    /**
164     * Sets the path to the Fedora home directory -- should only be used for testing purposes.
165     *
166     * @param fedoraHome Path to Fedora home directory
167     */
168    public void setFedoraHome(final Path fedoraHome) {
169        this.fedoraHome = fedoraHome;
170    }
171
172    /**
173     * @return Path to Fedora home data directory
174     */
175    public Path getFedoraData() {
176        return fedoraData;
177    }
178
179    /**
180     * @return Path to Fedora home logs directory
181     */
182    public Path getFedoraLogs() {
183        return fedoraLogs;
184    }
185
186    /**
187     * Sets the path to the Fedora home data directory -- should only be used for testing purposes.
188     *
189     * @param fedoraData Path to Fedora home data directory
190     */
191    public void setFedoraData(final Path fedoraData) {
192        this.fedoraData = fedoraData;
193    }
194
195    /**
196     * @return The JMS host
197     */
198    public String getJmsHost() {
199        return jmsHost;
200    }
201
202    /**
203     * @return The JMS/Open Wire port
204     */
205    public String getJmsPort() {
206        return jmsPort;
207    }
208
209    /**
210     * @return The STOMP protocol port
211     */
212    public String getStompPort() {
213        return stompPort;
214    }
215
216    /**
217     * @return The ActiveMQ data directory
218     */
219    public String getActiveMqDirectory() {
220        return activeMqDirectory;
221    }
222
223    /**
224     * @return The path to the ActiveMQ xml spring configuration.
225     */
226    public Resource getActiveMQConfiguration() {
227        return activeMQConfiguration;
228    }
229
230    /**
231     * @return The path to the allowed external content pattern definitions.
232     */
233    public String getExternalContentAllowed() {
234        return externalContentAllowed;
235    }
236
237    /**
238     * @return The path to the namespace registry file.
239     */
240    public String getNamespaceRegistry() {
241        return namespaceRegistry;
242    }
243
244    /**
245     * @return The timeout in milliseconds of the persistence session
246     */
247    public Duration getSessionTimeout() {
248        return sessionTimeout;
249    }
250
251    /**
252     * @param sessionTimeout the session timeout duration
253     */
254    public void setSessionTimeout(final Duration sessionTimeout) {
255        this.sessionTimeout = sessionTimeout;
256    }
257
258    /**
259     * @return The path to the velocity log.
260     */
261    public Path getVelocityLog() {
262        return velocityLog;
263    }
264
265    /**
266     * @return true if the rebuild validation should also check file fixity
267     */
268    public boolean isRebuildFixityCheck() {
269        return rebuildFixityCheck;
270    }
271
272    /**
273     * @return true if the internal indices should be rebuilt when Fedora starts up.
274     */
275    public boolean isRebuildOnStart() {
276        return rebuildOnStart;
277    }
278
279    /**
280     * @param rebuildOnStart A boolean flag indicating whether or not to rebuild on start
281     */
282    public void setRebuildOnStart(final boolean rebuildOnStart) {
283        this.rebuildOnStart = rebuildOnStart;
284    }
285
286    /**
287     * @return the JMS base url, if specified
288     */
289    public String getJmsBaseUrl() {
290        return jmsBaseUrl;
291    }
292
293    /**
294     * @return the server managed properties mode, default strict
295     */
296    public ServerManagedPropsMode getServerManagedPropsMode() {
297        return serverManagedPropsMode;
298    }
299
300    /**
301     * @param serverManagedPropsMode the server managed props mode
302     */
303    public void setServerManagedPropsMode(final ServerManagedPropsMode serverManagedPropsMode) {
304        this.serverManagedPropsMode = serverManagedPropsMode;
305    }
306
307    /**
308     * @return the jms destination type
309     */
310    public JmsDestination getJmsDestinationType() {
311        return jmsDestinationType;
312    }
313
314    /**
315     * @return the jms destination name
316     */
317    public String getJmsDestinationName() {
318        return jmsDestinationName;
319    }
320
321    /**
322     * @return the number of threads to allocate in the event bus thread pool
323     *         if this number is less than 1, 1 is returned
324     */
325    public int getEventBusThreads() {
326        if (eventBusThreads < 1) {
327            return 1;
328        }
329        return eventBusThreads;
330    }
331
332    /**
333     * @return The number of entries in the containment cache.
334     */
335    public long getContainmentCacheSize() {
336        return containmentCacheSize;
337    }
338
339    /**
340     * @return The number of minutes before items in the containment cache expire.
341     */
342    public long getContainmentCacheTimeout() {
343        return containmentCacheTimeout;
344    }
345
346    /**
347     * @return The number of entries in the WebAC effective ACL cache.
348     */
349    public long getWebacCacheSize() {
350        return webacCacheSize;
351    }
352
353    /**
354     * @return The number of minutes before items in the WebAC ACL cache expire.
355     */
356    public long getWebacCacheTimeout() {
357        return webacCacheTimeout;
358    }
359}