Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 org.apache.jackrabbit.oak.plugins.index.solr.server; import javax.annotation.CheckForNull; import java.io.File; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; import org.apache.commons.io.FileUtils; import org.apache.jackrabbit.oak.commons.IOUtils; import org.apache.jackrabbit.oak.plugins.index.solr.configuration.EmbeddedSolrServerConfiguration; import org.apache.jackrabbit.oak.plugins.index.solr.configuration.SolrServerConfigurationDefaults; import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer; import org.apache.solr.client.solrj.embedded.JettySolrRunner; import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.core.CoreContainer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Default implementation of {@link org.apache.jackrabbit.oak.plugins.index.solr.server.SolrServerProvider} which uses an * {@link EmbeddedSolrServer} configured as per passed {@link org.apache.jackrabbit.oak.plugins.index.solr.configuration.SolrServerConfiguration}. */ public class EmbeddedSolrServerProvider implements SolrServerProvider { private final Logger log = LoggerFactory.getLogger(getClass()); private final EmbeddedSolrServerConfiguration solrServerConfiguration; public EmbeddedSolrServerProvider(EmbeddedSolrServerConfiguration solrServerConfiguration) { this.solrServerConfiguration = solrServerConfiguration; } private SolrServer createSolrServer() throws Exception { log.info("creating new embedded solr server with config: {}", solrServerConfiguration); String solrHomePath = solrServerConfiguration.getSolrHomePath(); String coreName = solrServerConfiguration.getCoreName(); EmbeddedSolrServerConfiguration.HttpConfiguration httpConfiguration = solrServerConfiguration .getHttpConfiguration(); if (solrHomePath != null && coreName != null) { checkSolrConfiguration(solrHomePath, coreName); if (httpConfiguration != null) { if (log.isInfoEnabled()) { log.info("starting embedded Solr server with http bindings"); } ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(JettySolrRunner.class.getClassLoader()); Integer httpPort = httpConfiguration.getHttpPort(); String context = httpConfiguration.getContext(); JettySolrRunner jettySolrRunner = null; try { jettySolrRunner = new JettySolrRunner(solrHomePath, context, httpPort, "solrconfig.xml", "schema.xml", true); if (log.isInfoEnabled()) { log.info("Jetty runner instantiated"); } jettySolrRunner.start(true); if (log.isInfoEnabled()) { log.info("Jetty runner started"); } } catch (Exception t) { if (log.isErrorEnabled()) { log.error("an error has occurred while starting Solr Jetty", t); } } finally { if (jettySolrRunner != null && !jettySolrRunner.isRunning()) { try { jettySolrRunner.stop(); if (log.isInfoEnabled()) { log.info("Jetty runner stopped"); } } catch (Exception e) { if (log.isErrorEnabled()) { log.error("error while stopping the Jetty runner", e); } } } Thread.currentThread().setContextClassLoader(classLoader); } if (log.isInfoEnabled()) { log.info("starting HTTP Solr server"); } return new HttpWithJettySolrServer( SolrServerConfigurationDefaults.LOCAL_BASE_URL + ':' + httpPort + context + '/' + coreName, jettySolrRunner); } else { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(CoreContainer.class.getClassLoader()); CoreContainer coreContainer = new CoreContainer(solrHomePath); try { if (!coreContainer.isLoaded(coreName)) { coreContainer.load(); } } catch (Exception e) { log.error("cannot load core {}, shutting down embedded Solr..", coreName, e); try { coreContainer.shutdown(); } catch (Exception se) { log.error("could not shutdown embedded Solr", se); } return null; } finally { Thread.currentThread().setContextClassLoader(classLoader); } EmbeddedSolrServer server = new EmbeddedSolrServer(coreContainer, coreName); if (server.ping().getStatus() == 0) { return server; } else { throw new IOException("the embedded Solr server is not alive"); } } } else { throw new Exception("SolrServer configuration proprties not set"); } } private void checkSolrConfiguration(String solrHomePath, String coreName) throws IOException { File solrHomePathFile = new File(solrHomePath); log.info("checking configuration at {}", solrHomePathFile.getAbsolutePath()); // check if solrHomePath exists if (!solrHomePathFile.exists()) { if (!solrHomePathFile.mkdirs()) { throw new IOException("could not create solrHomePath directory"); } else { // copy all the needed files to the just created directory copy("/solr/solr.xml", solrHomePath); copy("/solr/zoo.cfg", solrHomePath); } } else if (!solrHomePathFile.isDirectory()) { throw new IOException( "a non directory file with the specified name already exists for the given solrHomePath '" + solrHomePath); } File solrCorePathFile = new File(solrHomePathFile, coreName); if (!solrCorePathFile.exists()) { if (!new File(solrCorePathFile, "conf").mkdirs()) { throw new IOException("could not create nested core directory in solrHomePath/solrCoreName/conf"); } String solrCoreDir = solrCorePathFile.getAbsolutePath(); File coreProperties = new File(new File(solrCoreDir), "core.properties"); assert coreProperties.createNewFile(); FileOutputStream out = new FileOutputStream(coreProperties); IOUtils.writeBytes(out, ("name=" + coreName).getBytes("UTF-8")); out.flush(); out.close(); String coreConfDir = solrCoreDir + "/conf/"; copy("/solr/oak/conf/currency.xml", coreConfDir); copy("/solr/oak/conf/schema.xml", coreConfDir); copy("/solr/oak/conf/solrconfig.xml", coreConfDir); } else if (!solrCorePathFile.isDirectory()) { throw new IOException( "a non directory file with the specified name already exists for the given Solr core path'" + solrCorePathFile.getAbsolutePath()); } // clean data dir File solrDataPathFile = new File(solrHomePathFile + "/" + coreName + "/data/index"); if (solrDataPathFile.exists()) { log.debug("deleting stale lock files"); File[] locks = solrDataPathFile.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return "write.lock".equals(name); } }); log.debug("found {} lock files", locks.length); // remove eventaul previous lock files (e.g. due to ungraceful shutdown) if (locks.length > 0) { for (File f : locks) { FileUtils.forceDelete(f); log.debug("deleted {}", f.getAbsolutePath()); } } } // check if the a core with the given coreName exists String[] files = solrHomePathFile.list(); Arrays.sort(files); if (Arrays.binarySearch(files, coreName) < 0) { throw new IOException("could not find a directory with the coreName '" + coreName + "' in the solrHomePath '" + solrHomePath + "'"); } } private void copy(String resource, String dir) throws IOException { String fileName = dir + resource.substring(resource.lastIndexOf("/")); File outputFile = new File(fileName); if (outputFile.createNewFile()) { InputStream inputStream = null; FileOutputStream outputStream = null; try { inputStream = getClass().getResourceAsStream(resource); outputStream = new FileOutputStream(outputFile); IOUtils.copy(inputStream, outputStream); } finally { if (inputStream != null) { try { inputStream.close(); } catch (Exception e) { // do nothing } } if (outputStream != null) { try { outputStream.close(); } catch (Exception e) { // do nothing } } } } } @CheckForNull @Override public SolrServer getSolrServer() throws Exception { return createSolrServer(); } @CheckForNull @Override public SolrServer getIndexingSolrServer() throws Exception { return getSolrServer(); } @CheckForNull @Override public SolrServer getSearchingSolrServer() throws Exception { return getSolrServer(); } private class HttpWithJettySolrServer extends HttpSolrServer { private final JettySolrRunner jettySolrRunner; public HttpWithJettySolrServer(String s, JettySolrRunner jettySolrRunner) { super(s); this.jettySolrRunner = jettySolrRunner; } @Override public void shutdown() { super.shutdown(); try { if (jettySolrRunner != null) { if (jettySolrRunner.isRunning()) { jettySolrRunner.stop(); } } } catch (Exception e) { log.warn("could not stop JettySolrRunner {}", jettySolrRunner); } } } @Override public void close() throws IOException { // do nothing } }