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
019
020package org.fcrepo.search.impl;
021
022import com.google.common.collect.Sets;
023import com.google.common.eventbus.AllowConcurrentEvents;
024import com.google.common.eventbus.EventBus;
025import com.google.common.eventbus.Subscribe;
026import org.fcrepo.kernel.api.models.ResourceHelper;
027import org.fcrepo.kernel.api.observer.Event;
028import org.fcrepo.kernel.api.observer.EventType;
029import org.fcrepo.persistence.api.PersistentStorageSessionManager;
030import org.fcrepo.persistence.api.exceptions.PersistentStorageException;
031import org.fcrepo.search.api.SearchIndex;
032import org.slf4j.Logger;
033import org.slf4j.LoggerFactory;
034import org.springframework.beans.factory.annotation.Autowired;
035import org.springframework.beans.factory.annotation.Qualifier;
036import org.springframework.stereotype.Component;
037
038import javax.annotation.PostConstruct;
039import javax.annotation.PreDestroy;
040import javax.inject.Inject;
041import java.util.Set;
042
043import static org.fcrepo.kernel.api.observer.EventType.RESOURCE_CREATION;
044import static org.fcrepo.kernel.api.observer.EventType.RESOURCE_DELETION;
045import static org.fcrepo.kernel.api.observer.EventType.RESOURCE_MODIFICATION;
046
047/**
048 * This class listens to events from the event bus and updates the search
049 * index accordingly.
050 *
051 * @author dbernstein
052 */
053@Component
054public class SearchIndexUpdater {
055
056    @Inject
057    private EventBus eventBus;
058
059    @Autowired
060    @Qualifier("searchIndex")
061    private SearchIndex searchIndex;
062
063    @Inject
064    private ResourceHelper resourceHelper;
065
066    @Inject
067    private PersistentStorageSessionManager persistentStorageSessionManager;
068
069    private static Logger LOGGER = LoggerFactory.getLogger(SearchIndexUpdater.class);
070    private static final Set<EventType> HANDLED_TYPES = Sets.newHashSet(RESOURCE_CREATION, RESOURCE_MODIFICATION,
071            RESOURCE_DELETION);
072
073    @Subscribe
074    @AllowConcurrentEvents
075    public void onEvent(final Event event) {
076        LOGGER.debug("event={}", event);
077        try {
078            final var fedoraId = event.getFedoraId();
079            final var types = event.getTypes();
080            if (types.contains(RESOURCE_DELETION) && !resourceHelper.doesResourceExist(null, fedoraId, false)) {
081                this.searchIndex.removeFromIndex(fedoraId);
082            } else if (types.contains(RESOURCE_CREATION) || types.contains(RESOURCE_MODIFICATION)) {
083                final var session = persistentStorageSessionManager.getReadOnlySession();
084                final var headers = session.getHeaders(fedoraId, null);
085                this.searchIndex.addUpdateIndex(headers);
086            }
087        } catch (final PersistentStorageException e) {
088            LOGGER.error("Failed to handle event: " + event, e);
089        }
090    }
091
092    /**
093     * Register listener
094     */
095    @PostConstruct
096    public void register() {
097        LOGGER.debug("Registering: {}", this.getClass().getCanonicalName());
098        eventBus.register(this);
099    }
100
101    /**
102     * Unregister listener
103     */
104    @PreDestroy
105    public void releaseConnections() {
106        LOGGER.debug("Unregistering: {}", this.getClass().getCanonicalName());
107        eventBus.unregister(this);
108    }
109}