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}