Java tutorial
/* * Copyright 2017 redlink GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.redlink.solrlib.embedded; import com.google.common.base.Preconditions; import io.redlink.solrlib.SolrCoreContainer; import io.redlink.solrlib.SolrCoreDescriptor; import io.redlink.utils.PathUtils; import org.apache.commons.lang3.StringUtils; import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer; import org.apache.solr.client.solrj.request.CoreAdminRequest; import org.apache.solr.common.util.NamedList; import org.apache.solr.core.CoreContainer; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.util.Date; import java.util.Objects; import java.util.Properties; import java.util.Set; import java.util.concurrent.ExecutorService; /** * SolrCoreContainer */ public class EmbeddedCoreContainer extends SolrCoreContainer { private CoreContainer coreContainer = null; private Path solrHome; private boolean deleteOnShutdown; public EmbeddedCoreContainer(Set<SolrCoreDescriptor> coreDescriptors, EmbeddedCoreContainerConfiguration configuration) { this(coreDescriptors, configuration, null); } public EmbeddedCoreContainer(Set<SolrCoreDescriptor> coreDescriptors, EmbeddedCoreContainerConfiguration configuration, ExecutorService executorService) { super(coreDescriptors, executorService); deleteOnShutdown = configuration.isDeleteOnShutdown(); solrHome = configuration.getHome(); } @Override @SuppressWarnings({ "squid:S3725", "squid:S3776" }) protected synchronized void init(ExecutorService executorService) throws IOException { Preconditions.checkState(Objects.isNull(coreContainer), "Already initialized!"); if (solrHome == null) { solrHome = Files.createTempDirectory("solr-home"); log.debug("No solr-home set, using temp directory {}", solrHome); deleteOnShutdown = true; } final Path absoluteSolrHome = this.solrHome.toAbsolutePath(); if (Files.isDirectory(absoluteSolrHome)) { log.trace("solr-home exists: {}", absoluteSolrHome); } else { Files.createDirectories(absoluteSolrHome); log.debug("Created solr-home: {}", absoluteSolrHome); } final Path lib = absoluteSolrHome.resolve("lib"); if (Files.isDirectory(lib)) { log.trace("lib-directory exists: {}", lib); } else { Files.createDirectories(lib); log.debug("Created solr-lib directory: {}", lib); } final Path solrXml = absoluteSolrHome.resolve("solr.xml"); if (!Files.exists(solrXml)) { log.info("no solr.xml found, creating new at {}", solrXml); try (PrintStream writer = new PrintStream(Files.newOutputStream(solrXml, StandardOpenOption.CREATE))) { writer.printf("<!-- Generated by %s on %tF %<tT -->%n", getClass().getSimpleName(), new Date()); writer.println("<solr>"); writer.printf(" <str name=\"%s\">%s</str>%n", "sharedLib", absoluteSolrHome.relativize(lib)); writer.println("</solr>"); } } else { log.trace("found solr.xml: {}", solrXml); } for (SolrCoreDescriptor coreDescriptor : coreDescriptors) { final String coreName = coreDescriptor.getCoreName(); if (availableCores.containsKey(coreName)) { log.warn("CoreName-Clash: {} already initialized. Skipping {}", coreName, coreDescriptor.getClass()); continue; } final Path coreDir = absoluteSolrHome.resolve(coreName); Files.createDirectories(coreDir); coreDescriptor.initCoreDirectory(coreDir, lib); final Properties coreProperties = new Properties(); final Path corePropertiesFile = coreDir.resolve("core.properties"); if (Files.exists(corePropertiesFile)) { try (InputStream inStream = Files.newInputStream(corePropertiesFile, StandardOpenOption.CREATE)) { coreProperties.load(inStream); } log.debug("core.properties for {} found, updating", coreName); } else { log.debug("Creating new core {} in {}", coreName, coreDir); } coreProperties.setProperty("name", coreName); try (OutputStream outputStream = Files.newOutputStream(corePropertiesFile)) { coreProperties.store(outputStream, null); } if (coreDescriptor.getNumShards() > 1 || coreDescriptor.getReplicationFactor() > 1) { log.warn("Deploying {} to EmbeddedCoreContainer, ignoring config of shards={},replication={}", coreName, coreDescriptor.getNumShards(), coreDescriptor.getReplicationFactor()); } availableCores.put(coreName, coreDescriptor); } log.info("Starting {} in solr-home '{}'", getClass().getSimpleName(), absoluteSolrHome); coreContainer = CoreContainer.createAndLoad(absoluteSolrHome, solrXml); availableCores.values().forEach(coreDescriptor -> { final String coreName = coreDescriptor.getCoreName(); try (SolrClient solrClient = createSolrClient(coreName)) { final NamedList<Object> coreStatus = CoreAdminRequest.getStatus(coreName, solrClient) .getCoreStatus(coreName); final NamedList<Object> indexStatus = coreStatus == null ? null : (NamedList<Object>) coreStatus.get("index"); final Object lastModified = indexStatus == null ? null : indexStatus.get("lastModified"); // lastModified is null if there was never a update scheduleCoreInit(executorService, coreDescriptor, lastModified == null); } catch (SolrServerException | IOException e) { if (log.isDebugEnabled()) { log.error("Error initializing core {}", coreName, e); } //noinspection ThrowableResultOfMethodCallIgnored coreInitExceptions.put(coreName, e); } }); } @Override public final void shutdown() throws IOException { Preconditions.checkState(Objects.nonNull(this.coreContainer), "Not initialized!"); try { final CoreContainer cc = this.coreContainer; this.coreContainer = null; cc.shutdown(); } catch (final Exception t) { log.error("Unexpected Error during CoreContainer.shutdown(): {}", t.getMessage()); throw t; } if (deleteOnShutdown) { log.debug("Cleaning up solr-home {}", solrHome); PathUtils.deleteRecursive(solrHome); } } @Override protected SolrClient createSolrClient(String coreName) { Preconditions.checkState(Objects.nonNull(coreContainer), "CoreContainer not initialized!"); Preconditions.checkArgument(StringUtils.isNotBlank(coreName)); return new EmbeddedSolrServer(coreContainer, coreName) { @Override public void close() throws IOException { //nop } }; } /** * For testing */ @Override protected void scheduleCoreInit(ExecutorService executorService, SolrCoreDescriptor coreDescriptor, boolean newCore) { super.scheduleCoreInit(executorService, coreDescriptor, newCore); } public CoreContainer getCoreContainer() { try { awaitInitCompletion(); return coreContainer; } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new IllegalStateException("Could not retrieve CoreContainer", e); } } }