001/* 002 * File : $Source$ 003 * Date : $Date$ 004 * Version: $Revision$ 005 * 006 * This library is part of OpenCms - 007 * the Open Source Content Management System 008 * 009 * Copyright (C) 2002 - 2009 Alkacon Software (http://www.alkacon.com) 010 * 011 * This library is free software; you can redistribute it and/or 012 * modify it under the terms of the GNU Lesser General Public 013 * License as published by the Free Software Foundation; either 014 * version 2.1 of the License, or (at your option) any later version. 015 * 016 * This library is distributed in the hope that it will be useful, 017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 019 * Lesser General Public License for more details. 020 * 021 * For further information about Alkacon Software, please see the 022 * company website: http://www.alkacon.com 023 * 024 * For further information about OpenCms, please see the 025 * project website: http://www.opencms.org 026 * 027 * You should have received a copy of the GNU Lesser General Public 028 * License along with this library; if not, write to the Free Software 029 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 030 */ 031 032package org.opencms.search.solr; 033 034import org.opencms.configuration.CmsConfigurationException; 035import org.opencms.main.CmsLog; 036import org.opencms.main.OpenCms; 037import org.opencms.util.CmsStringUtil; 038 039import java.io.File; 040import java.io.FileInputStream; 041import java.io.FileNotFoundException; 042import java.io.IOException; 043import java.nio.file.Path; 044import java.nio.file.Paths; 045 046import org.apache.commons.logging.Log; 047import org.apache.solr.core.ConfigSetService.ConfigResource; 048import org.apache.solr.core.SolrConfig; 049import org.apache.solr.core.SolrResourceLoader; 050import org.apache.solr.schema.IndexSchema; 051import org.apache.solr.schema.IndexSchemaFactory; 052 053/** 054 * The Solr configuration class.<p> 055 * 056 * @since 8.5.0 057 */ 058public class CmsSolrConfiguration { 059 060 /** The default config set path. */ 061 public static final String DEFAULT_CONFIGSET_FOLDER = File.separatorChar 062 + "configsets" 063 + File.separatorChar 064 + "default"; 065 /** The 'conf' folder inside the Solr home directory. */ 066 public static final String CONF_FOLDER = File.separatorChar + "conf" + File.separatorChar; 067 068 /** The Solr configuration file name. */ 069 public static final String SOLR_CONFIG_FILE = "solr.xml"; 070 071 /** The default maximum number of results to return in a Solr search. */ 072 public static final int DEFAULT_MAX_PROCESSED_RESULTS = 400; 073 074 /** 075 * The default max time in ms before a commit will happen (10 seconds by default).<p> 076 * 077 * Can be configured in 'opencms-search.xml'.<p> 078 */ 079 public static final long SOLR_DEFAULT_COMMIT_MS = 10000; 080 081 /** The default name of the Solr home directory. */ 082 public static final String SOLR_HOME_DEFAULT = "solr" + File.separatorChar; 083 084 /** The system property name for the Solr home directory. */ 085 public static final String SOLR_HOME_PROPERTY = "solr.solr.home"; 086 087 /** The Solr schema name. */ 088 public static final String SOLR_SCHEMA_NAME = "OpenCms SOLR schema"; 089 090 /** The Solr configuration name. */ 091 public static final String SOLR_CONFIG_NAME = "OpenCms SOLR configuration"; 092 093 /** The log object for this class. */ 094 private static final Log LOG = CmsLog.getLog(CmsSolrConfiguration.class); 095 096 /** Max time (in ms) before a commit will happen. */ 097 private long m_commitMs = SOLR_DEFAULT_COMMIT_MS; 098 099 /** Signals whether the server is enabled or disabled. */ 100 private boolean m_enabled; 101 102 /** The Solr home. */ 103 private String m_home; 104 105 /** The configured path to the Solr home. */ 106 private String m_homeFolderPath; 107 108 /** The schema file. */ 109 private IndexSchema m_schema; 110 111 /** The servers URL, must be set if embedded is false. */ 112 private String m_serverUrl; 113 114 /** The Solr configuration. */ 115 private SolrConfig m_solrConfig; 116 117 /** The Solr configuration file "solr.xml". */ 118 private File m_solrFile; 119 120 /** The file name of the Solr configuration. */ 121 private String m_solrFileName; 122 123 /** The maximal number of results to be processed in a search request to a Solr index. */ 124 private int m_maxProcessedResults = DEFAULT_MAX_PROCESSED_RESULTS; 125 126 /** 127 * Default constructor.<p> 128 */ 129 public CmsSolrConfiguration() { 130 131 // needed for the digester 132 } 133 134 /** 135 * Returns the home directory of Solr as String.<p> 136 * 137 * @return the home directory of Solr as String 138 */ 139 public String getHome() { 140 141 if (m_homeFolderPath == null) { 142 if (CmsStringUtil.isNotEmpty(System.getProperty(SOLR_HOME_PROPERTY))) { 143 m_home = System.getProperty(SOLR_HOME_PROPERTY); 144 } else { 145 m_home = OpenCms.getSystemInfo().getAbsoluteRfsPathRelativeToWebInf(SOLR_HOME_DEFAULT); 146 } 147 m_home = (m_home.endsWith(File.separator) 148 ? m_home.substring(0, m_home.lastIndexOf(File.separator)) 149 : m_home); 150 } else { 151 m_home = m_homeFolderPath; 152 } 153 return m_home; 154 } 155 156 /** 157 * Returns the configured Solr home.<p> 158 * 159 * @return the configured Solr home 160 */ 161 public String getHomeFolderPath() { 162 163 return m_homeFolderPath; 164 } 165 166 /** 167 * Returns the maximal number of results processed when querying a Solr index. 168 * 169 * Each index has a configuration option to overwrite this global value. 170 * 171 * @return the maximal number of results processed when querying a Solr index. 172 */ 173 public int getMaxProcessedResults() { 174 175 return m_maxProcessedResults; 176 } 177 178 /** 179 * Returns the servers URL if embedded is set to <code>false</code>.<p> 180 * 181 * @return the external servers URL 182 */ 183 public String getServerUrl() { 184 185 return m_serverUrl; 186 } 187 188 /** 189 * Returns the max time (in ms) before a commit will happen.<p> 190 * 191 * @return the max time (in ms) before a commit will happen 192 */ 193 public long getSolrCommitMs() { 194 195 return m_commitMs; 196 } 197 198 /** 199 * Returns the Solr configuration (object representation of <code>'solrconfig.xml'</code>).<p> 200 * 201 * @return the Solr configuration 202 * 203 */ 204 @SuppressWarnings("deprecation") 205 public SolrConfig getSolrConfig() { 206 207 if (m_solrConfig == null) { 208 try (FileInputStream fis = new FileInputStream(getSolrConfigFile())) { 209 Path instanceDir = Paths.get(getHome(), DEFAULT_CONFIGSET_FOLDER); 210 @SuppressWarnings("resource") 211 SolrResourceLoader loader = new SolrResourceLoader(instanceDir); 212 m_solrConfig = SolrConfig.readFromResourceLoader( 213 loader, 214 getSolrConfigFile().getName(), 215 true, 216 null); // the former loader.getCoreProperties() yielded null anyway 217 } catch (FileNotFoundException e) { 218 CmsConfigurationException ex = new CmsConfigurationException( 219 Messages.get().container(Messages.LOG_SOLR_ERR_CONFIG_XML_NOT_FOUND_1, getSolrConfigFile()), 220 e); 221 LOG.error(ex.getLocalizedMessage(), ex); 222 } catch (Exception e) { 223 CmsConfigurationException ex = new CmsConfigurationException( 224 Messages.get().container(Messages.LOG_SOLR_ERR_CONFIG_XML_NOT_READABLE_1, getSolrConfigFile()), 225 e); 226 LOG.error(ex.getLocalizedMessage(), ex); 227 } 228 } 229 return m_solrConfig; 230 } 231 232 /** 233 * Returns the solr configuration file, default: <code>'conf/solrconfig.xml'</code>.<p> 234 * 235 * @return the solr configuration file 236 */ 237 public File getSolrConfigFile() { 238 239 return new File(getHome() + DEFAULT_CONFIGSET_FOLDER + CONF_FOLDER + SolrConfig.DEFAULT_CONF_FILE); 240 } 241 242 /** 243 * Returns the Solr xml file, default: <code>'solr.xml'</code>.<p> 244 * 245 * @return the Solr xml file 246 */ 247 public File getSolrFile() { 248 249 if (m_solrFile == null) { 250 String solrFileName = m_solrFileName != null ? m_solrFileName : SOLR_CONFIG_FILE; 251 m_solrFile = new File(getHome() + File.separator + solrFileName); 252 } 253 return m_solrFile; 254 } 255 256 /** 257 * Returns the Solr xml file name, default: <code>'solr.xml'</code>.<p> 258 * 259 * @return the Solr xml file name 260 */ 261 public String getSolrFileName() { 262 263 return m_solrFileName; 264 } 265 266 /** 267 * Returns the Solr index schema.<p> 268 * 269 * @return the Solr index schema 270 */ 271 @SuppressWarnings("resource") 272 public IndexSchema getSolrSchema() { 273 274 if (m_schema == null) { 275 try (FileInputStream fis = new FileInputStream(getSolrSchemaFile())) { 276 ConfigResource configRes = IndexSchemaFactory.getConfigResource( 277 null /* only used if it's a CloudConfigSetService */, 278 fis, 279 getSolrConfig().getResourceLoader(), 280 SOLR_CONFIG_NAME); 281 m_schema = new IndexSchema( 282 SOLR_SCHEMA_NAME, 283 configRes, 284 getSolrConfig().luceneMatchVersion, 285 getSolrConfig().getResourceLoader(), 286 getSolrConfig().getSubstituteProperties()); 287 } catch (IOException e) { 288 CmsConfigurationException ex = new CmsConfigurationException( 289 Messages.get().container( 290 Messages.LOG_SOLR_ERR_SCHEMA_XML_NOT_FOUND_1, 291 getSolrSchemaFile().getPath()), 292 e); 293 LOG.error(ex.getLocalizedMessage(), ex); 294 } 295 } 296 return m_schema; 297 } 298 299 /** 300 * Returns the Solr index schema file.<p> 301 * 302 * @return the Solr index schema file 303 */ 304 public File getSolrSchemaFile() { 305 306 final String dir = getHome() + DEFAULT_CONFIGSET_FOLDER + CONF_FOLDER; 307 //SOLR7 Schema took a new name, also removed the file extension. 308 File file = new File(dir, "managed-schema"); 309 if (file.exists()) { 310 return file; 311 } 312 313 //If use the old Schema.xml, it will automatically "upgrade" to a new filename. 314 file = new File(dir, IndexSchema.DEFAULT_SCHEMA_FILE); 315 return file; 316 } 317 318 /** 319 * Returns <code>true</code> if the Solr server is embedded, <code>false</code> otherwise.<p> 320 * 321 * @return <code>true</code> if the Solr server is embedded, <code>false</code> otherwise 322 */ 323 public boolean isEnabled() { 324 325 return m_enabled; 326 } 327 328 /** 329 * Sets the enabled flag.<p> 330 * 331 * @param isEnabled <code>true</code>, if the Solr server should be used, <code>false</code> otherwise 332 */ 333 public void setEnabled(String isEnabled) { 334 335 m_enabled = Boolean.valueOf(isEnabled).booleanValue(); 336 } 337 338 /** 339 * Sets the home folder for Solr.<p> 340 * 341 * @param homeFolderPath the Solr home folder to set 342 */ 343 public void setHomeFolderPath(String homeFolderPath) { 344 345 m_homeFolderPath = homeFolderPath; 346 } 347 348 /** 349 * Sets the maximal number of results processed for a query to a Solr index.<p> 350 * 351 * The globally set value can be overwritten for each index. 352 * 353 * @param maxProcessedResults the maximal number of results processed for a query to a Solr index. 354 */ 355 public void setMaxProcessedResults(String maxProcessedResults) { 356 357 try { 358 m_maxProcessedResults = Integer.parseInt(maxProcessedResults); 359 } catch (Exception e) { 360 LOG.warn( 361 "Could not parse value " 362 + maxProcessedResults 363 + " as Integer to set the limit for the number of results a Solr index can return."); 364 } 365 if (m_maxProcessedResults <= 0) { 366 m_maxProcessedResults = DEFAULT_MAX_PROCESSED_RESULTS; 367 LOG.warn( 368 "The maximal number of results to return by a Solr index should be greater than 0. Reset it to the default value " 369 + DEFAULT_MAX_PROCESSED_RESULTS 370 + "."); 371 } 372 } 373 374 /** 375 * Sets the external servers URL, should be not null if the embedded falg is <code>false</code>.<p> 376 * 377 * @param url the URL 378 */ 379 public void setServerUrl(String url) { 380 381 m_serverUrl = url; 382 } 383 384 /** 385 * Sets the max time (in ms) before a commit will happen.<p> 386 * 387 * @param time the time as long value 388 */ 389 public void setSolrCommitMs(String time) { 390 391 m_commitMs = Long.parseLong(time); 392 } 393 394 /** 395 * Sets the Solr file name.<p> 396 * 397 * @param name the file name to set 398 */ 399 public void setSolrFileName(String name) { 400 401 m_solrFileName = name; 402 } 403}