1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.search.solr.internal

File EmbeddedSolrInstance.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart9.png
38% of files have more coverage

Code metrics

18
43
7
1
211
120
22
0.51
6.14
7
3.14

Classes

Class Line # Actions
EmbeddedSolrInstance 54 43 0% 22 9
0.8676470586.8%
 

Contributing tests

This file is covered by 3 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.search.solr.internal;
21   
22    import java.io.File;
23    import java.io.IOException;
24    import java.io.InputStream;
25    import java.util.zip.ZipEntry;
26    import java.util.zip.ZipInputStream;
27   
28    import javax.inject.Inject;
29    import javax.inject.Named;
30    import javax.inject.Singleton;
31   
32    import org.apache.commons.io.FileUtils;
33    import org.apache.commons.io.input.CloseShieldInputStream;
34    import org.apache.commons.lang3.StringUtils;
35    import org.apache.solr.client.solrj.SolrServerException;
36    import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
37    import org.apache.solr.core.CoreContainer;
38    import org.xwiki.component.annotation.Component;
39    import org.xwiki.component.manager.ComponentLifecycleException;
40    import org.xwiki.component.phase.Disposable;
41    import org.xwiki.component.phase.InitializationException;
42    import org.xwiki.environment.Environment;
43    import org.xwiki.search.solr.internal.api.SolrConfiguration;
44   
45    /**
46    * Embedded Solr instance running in the same JVM.
47    *
48    * @version $Id: c3c6aca47a26d69902f5675f0543aec9c908698d $
49    * @since 4.3M2
50    */
51    @Component
52    @Named(EmbeddedSolrInstance.TYPE)
53    @Singleton
 
54    public class EmbeddedSolrInstance extends AbstractSolrInstance implements Disposable
55    {
56    /**
57    * Solr instance type for this implementation.
58    */
59    public static final String TYPE = "embedded";
60   
61    /**
62    * Default directory name for Solr's configuration and index files.
63    */
64    public static final String DEFAULT_SOLR_DIRECTORY_NAME = "solr";
65   
66    /**
67    * Solr configuration.
68    */
69    @Inject
70    private SolrConfiguration solrConfiguration;
71   
72    /**
73    * Environment used to get the xwiki permanent directory.
74    */
75    @Inject
76    private Environment environment;
77   
78    /**
79    * Solr CoreContainer.
80    */
81    private CoreContainer container;
82   
 
83  6 toggle @Override
84    public void initialize() throws InitializationException
85    {
86  6 String solrHome = determineHomeDirectory();
87  6 try {
88    // Validate and initialize the home directory if needed.
89  6 validateAndInitializeHomeDirectory(solrHome);
90   
91    // Start embedded Solr server.
92  5 this.logger.info("Starting embedded Solr server...");
93  5 this.logger.info("Using Solr home directory: [{}]", solrHome);
94   
95    // Initialize the SOLR back-end using an embedded server.
96  5 this.container = createCoreContainer(solrHome);
97    // If we get here then there is at least one core found. We there are more, we use the first one.
98  5 String coreName = this.container.getCores().iterator().next().getName();
99  5 this.server = new EmbeddedSolrServer(container, coreName);
100   
101  5 this.logger.info("Started embedded Solr server.");
102    } catch (Exception e) {
103  1 throw new InitializationException(String.format(
104    "Failed to initialize the Solr embedded server with home directory set to [%s]", solrHome), e);
105    }
106    }
107   
 
108  5 toggle private CoreContainer createCoreContainer(String solrHome) throws SolrServerException
109    {
110  5 CoreContainer coreContainer = new CoreContainer(solrHome);
111  5 coreContainer.load();
112  5 if (coreContainer.getCores().size() == 0) {
113  0 throw new SolrServerException("Failed to initialize the Solr core. "
114    + "Please check the configuration and log messages.");
115  5 } else if (coreContainer.getCores().size() > 1) {
116  0 this.logger.warn("Multiple Solr cores detected: [{}]. Using the first one.",
117    StringUtils.join(coreContainer.getCoreNames(), ", "));
118    }
119  5 return coreContainer;
120    }
121   
 
122  5 toggle @Override
123    public void dispose() throws ComponentLifecycleException
124    {
125  5 if (this.server != null) {
126  5 try {
127  5 this.server.close();
128    } catch (IOException e) {
129  0 this.logger.error("Failed to close server", e);
130    }
131    }
132   
133  5 if (this.container != null) {
134  5 this.container.shutdown();
135    }
136    }
137   
138    /**
139    * Useful when testing.
140    *
141    * @return the container
142    */
 
143  2 toggle protected CoreContainer getContainer()
144    {
145  2 return this.container;
146    }
147   
148    /**
149    * Checks rights, creates paths and adds default config XML files if they don`t already exist.
150    *
151    * @param solrHome the directory to use as Solr home.
152    * @throws IllegalArgumentException if the provided directory is not usable (is a file, is not writable, etc.).
153    * @throws IOException if the XML files are not copied successfully.
154    */
 
155  6 toggle private void validateAndInitializeHomeDirectory(String solrHome) throws IllegalArgumentException, IOException
156    {
157    // Validate and create the directory if it does not already exist.
158  6 File solrHomeDirectory = new File(solrHome);
159  6 if (solrHomeDirectory.exists()) {
160    // Exists but is unusable.
161  1 if (!solrHomeDirectory.isDirectory() || !solrHomeDirectory.canWrite() || !solrHomeDirectory.canRead()) {
162  0 throw new IllegalArgumentException(String.format(
163    "The given path [%s] must be a readable and writable directory", solrHomeDirectory));
164    }
165    } else {
166    // Create the home directory
167  5 if (!solrHomeDirectory.mkdirs()) {
168    // Does not exist and can not be created.
169  1 throw new IllegalArgumentException(String.format(
170    "The given path [%s] could not be created due to and invalid value %s", solrHomeDirectory,
171    "or to insufficient filesystem permissions"));
172    }
173   
174    // Initialize the Solr Home with the default configuration files if the folder does not already exist.
175    // Add the configuration files required by Solr.
176   
177  4 InputStream stream = this.solrConfiguration.getHomeDirectoryConfiguration();
178  4 try (ZipInputStream zstream = new ZipInputStream(stream)) {
179  284 for (ZipEntry entry = zstream.getNextEntry(); entry != null; entry = zstream.getNextEntry()) {
180  280 if (entry.isDirectory()) {
181  36 File destinationDirectory = new File(solrHomeDirectory, entry.getName());
182  36 destinationDirectory.mkdirs();
183    } else {
184  244 File destinationFile = new File(solrHomeDirectory, entry.getName());
185  244 FileUtils.copyInputStreamToFile(new CloseShieldInputStream(zstream), destinationFile);
186    }
187    }
188    }
189    }
190    }
191   
192    /**
193    * @return the configured home directory location or the default value if no configuration is present.
194    */
 
195  6 toggle private String determineHomeDirectory()
196    {
197  6 String defaultValue = getDefaultHomeDirectory();
198   
199  6 return this.solrConfiguration.getInstanceConfiguration(TYPE, "home", defaultValue);
200    }
201   
202    /**
203    * @return the default home directory located inside the environment's permanent directory.
204    */
 
205  6 toggle String getDefaultHomeDirectory()
206    {
207  6 String result = new File(this.environment.getPermanentDirectory(), DEFAULT_SOLR_DIRECTORY_NAME).getPath();
208   
209  6 return result;
210    }
211    }