diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CoreShibUiConfiguration.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CoreShibUiConfiguration.java index 5b9d330bf..18a8a4953 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CoreShibUiConfiguration.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CoreShibUiConfiguration.java @@ -1,25 +1,36 @@ package edu.internet2.tier.shibboleth.admin.ui.configuration; import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityIdsSearchResultRepresentation; -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolversPositionOrderContainer; import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects; import edu.internet2.tier.shibboleth.admin.ui.repository.EntityDescriptorRepository; import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository; import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolversPositionOrderContainerRepository; import edu.internet2.tier.shibboleth.admin.ui.scheduled.EntityDescriptorFilesScheduledTasks; -import edu.internet2.tier.shibboleth.admin.ui.service.*; +import edu.internet2.tier.shibboleth.admin.ui.service.DefaultMetadataResolversPositionOrderContainerService; +import edu.internet2.tier.shibboleth.admin.ui.service.DirectoryService; +import edu.internet2.tier.shibboleth.admin.ui.service.DirectoryServiceImpl; +import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorService; +import edu.internet2.tier.shibboleth.admin.ui.service.EntityIdsSearchService; +import edu.internet2.tier.shibboleth.admin.ui.service.EntityService; +import edu.internet2.tier.shibboleth.admin.ui.service.FilterService; +import edu.internet2.tier.shibboleth.admin.ui.service.FilterTargetService; +import edu.internet2.tier.shibboleth.admin.ui.service.JPAEntityDescriptorServiceImpl; +import edu.internet2.tier.shibboleth.admin.ui.service.JPAEntityServiceImpl; +import edu.internet2.tier.shibboleth.admin.ui.service.JPAFilterServiceImpl; +import edu.internet2.tier.shibboleth.admin.ui.service.JPAFilterTargetServiceImpl; +import edu.internet2.tier.shibboleth.admin.ui.service.JPAMetadataResolverServiceImpl; +import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverService; +import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolversPositionOrderContainerService; import edu.internet2.tier.shibboleth.admin.util.AttributeUtility; +import edu.internet2.tier.shibboleth.admin.util.LuceneUtility; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.index.DirectoryReader; -import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexReader; import org.apache.lucene.queryparser.classic.ParseException; import org.apache.lucene.queryparser.classic.QueryParser; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TopDocs; -import org.apache.lucene.store.Directory; -import org.apache.lucene.store.RAMDirectory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -37,9 +48,7 @@ import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; @Configuration public class CoreShibUiConfiguration { @@ -95,6 +104,9 @@ public AttributeUtility attributeUtility() { @Autowired ResourceBundleMessageSource messageSource; + @Autowired + LuceneUtility luceneUtility; + @Bean public EntityDescriptorFilesScheduledTasks entityDescriptorFilesScheduledTasks(EntityDescriptorRepository entityDescriptorRepository) { return new EntityDescriptorFilesScheduledTasks(this.metadataDir, entityDescriptorRepository, openSamlObjects()); @@ -104,9 +116,9 @@ public EntityDescriptorFilesScheduledTasks entityDescriptorFilesScheduledTasks(E public EntityIdsSearchService entityIdsSearchService() { return (resourceId, term, limit) -> { List entityIds = new ArrayList<>(); - Directory directory = directoryService.getDirectory(resourceId); try { - IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(directory)); + IndexReader indexReader = luceneUtility.getIndexReader(resourceId); + IndexSearcher searcher = new IndexSearcher(indexReader); QueryParser parser = new QueryParser("content", fullTokenAnalyzer); TopDocs topDocs = searcher.search(parser.parse(term.trim()), limit); for (ScoreDoc scoreDoc : topDocs.scoreDocs) { @@ -180,4 +192,14 @@ public void addInterceptors(InterceptorRegistry registry) { return new DefaultMetadataResolversPositionOrderContainerService(positionOrderContainerRepository, resolverRepository); } + + @Bean + public DirectoryService directoryService() { + return new DirectoryServiceImpl(); + } + + @Bean + public LuceneUtility luceneUtility() { + return new LuceneUtility(); + } } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/SearchConfiguration.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/SearchConfiguration.java index 0ae1cc79f..fab39d551 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/SearchConfiguration.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/SearchConfiguration.java @@ -12,7 +12,6 @@ import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.store.Directory; -import org.apache.lucene.store.RAMDirectory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -76,18 +75,4 @@ public IndexWriterService indexWriterService() { return indexWriter; }; } - - @Bean - public DirectoryService directoryService() { - Map directoryMap = new HashMap<>(); - - return resourceId -> { - Directory directory = directoryMap.get(resourceId); - if (directory == null) { - directory = new RAMDirectory(); - directoryMap.put(resourceId, directory); - } - return directory; - }; - } } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityIdsSearchController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityIdsSearchController.java index 2e910f365..034556c92 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityIdsSearchController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityIdsSearchController.java @@ -19,7 +19,7 @@ public EntityIdsSearchController(EntityIdsSearchService entityIdsSearchService) } @GetMapping - ResponseEntity search(@RequestParam String resourceId, + ResponseEntity search(@RequestParam(required = false) String resourceId, @RequestParam String term, @RequestParam(required = false) Integer limit) { //Zero indicates no-limit diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/DirectoryService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/DirectoryService.java index 720a64ca0..a3cf9fe2f 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/DirectoryService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/DirectoryService.java @@ -2,10 +2,11 @@ import org.apache.lucene.store.Directory; +import java.util.List; + /** * API component responsible for entity ids search. */ -@FunctionalInterface public interface DirectoryService { /** * Return a Directory for a given resource id. If one is not found, it will be created. @@ -13,4 +14,6 @@ public interface DirectoryService { * @return Directory */ Directory getDirectory(String resourceId); + + List getDirectories(); } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/DirectoryServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/DirectoryServiceImpl.java new file mode 100644 index 000000000..553af3094 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/DirectoryServiceImpl.java @@ -0,0 +1,30 @@ +package edu.internet2.tier.shibboleth.admin.ui.service; + +import org.apache.lucene.store.Directory; +import org.apache.lucene.store.RAMDirectory; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Bill Smith (wsmith@unicon.net) + */ +public class DirectoryServiceImpl implements DirectoryService { + private Map directoryMap = new HashMap<>(); + + @Override + public Directory getDirectory(String resourceId) { + Directory directory = directoryMap.get(resourceId); + if (directory == null) { + directory = new RAMDirectory(); + directoryMap.put(resourceId, directory); + } + return directory; + } + + @Override + public List getDirectories() { + return (List) directoryMap.values(); + } +} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/LuceneUtility.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/LuceneUtility.java new file mode 100644 index 000000000..9b53ebdbb --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/LuceneUtility.java @@ -0,0 +1,45 @@ +package edu.internet2.tier.shibboleth.admin.util; + +import edu.internet2.tier.shibboleth.admin.ui.service.DirectoryService; +import org.apache.commons.lang.StringUtils; +import org.apache.lucene.index.DirectoryReader; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.MultiReader; +import org.apache.lucene.store.Directory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Bill Smith (wsmith@unicon.net) + */ +public class LuceneUtility { + private static final Logger logger = LoggerFactory.getLogger(LuceneUtility.class); + + @Autowired + private DirectoryService directoryService; + + public IndexReader getIndexReader(String resourceId) throws IOException { + IndexReader indexReader; + if (StringUtils.isBlank(resourceId)) { + List directories = directoryService.getDirectories(); + List indexReaderList = new ArrayList<>(); + directories.forEach(it -> { + try { + indexReaderList.add(DirectoryReader.open(it)); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + }); + IndexReader[] indexReaders = (IndexReader[]) indexReaderList.toArray(); + indexReader = new MultiReader(indexReaders, true); + } else { + indexReader = DirectoryReader.open(directoryService.getDirectory(resourceId)); + } + return indexReader; + } +}