/** * Copyright (c) Codice Foundation * <p> * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation, either version 3 of the * License, or any later version. * <p> * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. A copy of the GNU Lesser General Public License * is distributed along with this program and can be found at * <http://www.gnu.org/licenses/lgpl.html>. */ package org.codice.ddf.ui.searchui.query.solr; import static org.codice.solr.factory.impl.EmbeddedSolrFactory.IMMEMORY_SOLRCONFIG_XML; import static org.codice.solr.factory.impl.EmbeddedSolrFactory.getConfigFile; import static org.codice.solr.factory.impl.HttpSolrClientFactory.DEFAULT_SCHEMA_XML; import java.io.File; import java.io.IOException; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.io.FileUtils; import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer; import org.apache.solr.core.CoreDescriptor; import org.apache.solr.core.SolrConfig; import org.apache.solr.core.SolrCore; import org.apache.solr.core.SolrResourceLoader; import org.apache.solr.schema.IndexSchema; import org.codice.solr.factory.impl.ConfigurationFileProxy; import org.codice.solr.factory.impl.ConfigurationStore; import org.codice.solr.factory.impl.EmbeddedSolrFactory; import org.codice.solr.factory.impl.SolrCoreContainer; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import ddf.catalog.data.Metacard; import ddf.catalog.data.Result; import ddf.catalog.filter.FilterAdapter; import ddf.catalog.operation.CreateResponse; import ddf.catalog.operation.QueryRequest; import ddf.catalog.operation.SourceResponse; import ddf.catalog.operation.impl.CreateRequestImpl; import ddf.catalog.source.IngestException; import ddf.catalog.source.UnsupportedQueryException; import ddf.catalog.source.solr.SolrCatalogProvider; import ddf.catalog.source.solr.SolrFilterDelegateFactory; import ddf.catalog.source.solr.SolrFilterDelegateFactoryImpl; public class FilteringSolrIndex { private static volatile IndexSchema indexSchema; private SolrCatalogProvider provider; FilteringSolrIndex(SolrCatalogProvider provider) { this.provider = provider; } public FilteringSolrIndex(String queryId, FilterAdapter filterAdapter, QueryRequest request) { this(createInMemorySolrProvider(queryId, filterAdapter, request)); } private static SolrCatalogProvider createInMemorySolrProvider(String queryId, FilterAdapter filterAdapter, QueryRequest request) { ConfigurationStore.getInstance() .setInMemory(true); ConfigurationStore.getInstance() .setForceAutoCommit(true); ConfigurationFileProxy configurationFileProxy = new ConfigurationFileProxy( ConfigurationStore.getInstance()); SolrFilterDelegateFactory solrFilterDelegateFactory = new SolrFilterDelegateFactoryImpl(); return new SolrCatalogProvider(createSolrServer(queryId, configurationFileProxy), filterAdapter, solrFilterDelegateFactory, new FilteringDynamicSchemaResolver(filterAdapter, solrFilterDelegateFactory, request)); } private static EmbeddedSolrServer createSolrServer(String coreName, ConfigurationFileProxy configProxy) { File configFile = getConfigFile(IMMEMORY_SOLRCONFIG_XML, configProxy, coreName); if (configFile == null) { throw new IllegalArgumentException("Unable to find Solr configuration file"); } File schemaFile = getConfigFile(DEFAULT_SCHEMA_XML, configProxy, coreName); if (schemaFile == null) { throw new IllegalArgumentException("Unable to find Solr schema file"); } File solrConfigHome = new File(configFile.getParent()); ClassLoader tccl = Thread.currentThread() .getContextClassLoader(); try { Thread.currentThread() .setContextClassLoader(EmbeddedSolrFactory.class.getClassLoader()); SolrConfig solrConfig = new SolrConfig(Paths.get(solrConfigHome.getParent()), IMMEMORY_SOLRCONFIG_XML, new InputSource(FileUtils.openInputStream(configFile))); if (indexSchema == null) { indexSchema = new IndexSchema(solrConfig, DEFAULT_SCHEMA_XML, new InputSource(FileUtils.openInputStream(schemaFile))); } SolrResourceLoader loader = new SolrResourceLoader(Paths.get(solrConfigHome.getAbsolutePath())); SolrCoreContainer container = new SolrCoreContainer(loader); CoreDescriptor coreDescriptor = new CoreDescriptor(container, coreName, solrConfig.getResourceLoader() .getInstancePath()); SolrCore core = new SolrCore(coreName, null, solrConfig, indexSchema, null, coreDescriptor, null, null, null); container.register(coreName, core, false, true); return new EmbeddedSolrServer(container, coreName); } catch (ParserConfigurationException | SAXException | IOException e) { throw new IllegalArgumentException("Unable to parse Solr configuration file", e); } finally { Thread.currentThread() .setContextClassLoader(tccl); } } /** * Must be synchronized since force auto commit is enabled. If too many commits happen at * the same time, performance is impacted and might log “too many warming searchers” warnings. */ public synchronized CreateResponse add(List<Result> results) throws IngestException { return provider.create(new CreateRequestImpl(getMetacards(results))); } public SourceResponse query(QueryRequest request) throws UnsupportedQueryException { return provider.query(request); } public void shutdown() { provider.shutdown(); } private List<Metacard> getMetacards(List<Result> results) { List<Metacard> metacards = new ArrayList<>(results.size()); for (Result result : results) { if (result != null && result.getMetacard() != null) { metacards.add(result.getMetacard()); } } return metacards; } }