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 (https://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: https://www.alkacon.com 023 * 024 * For further information about OpenCms, please see the 025 * project website: https://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 public SolrConfig getSolrConfig() { 205 206 if (m_solrConfig == null) { 207 try (FileInputStream fis = new FileInputStream(getSolrConfigFile())) { 208 Path instanceDir = Paths.get(getHome(), DEFAULT_CONFIGSET_FOLDER); 209 @SuppressWarnings("resource") 210 SolrResourceLoader loader = new SolrResourceLoader(instanceDir); 211 m_solrConfig = SolrConfig.readFromResourceLoader(loader, getSolrConfigFile().getName(), null); // the former loader.getCoreProperties() yielded null anyway 212 } catch (FileNotFoundException e) { 213 CmsConfigurationException ex = new CmsConfigurationException( 214 Messages.get().container(Messages.LOG_SOLR_ERR_CONFIG_XML_NOT_FOUND_1, getSolrConfigFile()), 215 e); 216 LOG.error(ex.getLocalizedMessage(), ex); 217 } catch (Exception e) { 218 CmsConfigurationException ex = new CmsConfigurationException( 219 Messages.get().container(Messages.LOG_SOLR_ERR_CONFIG_XML_NOT_READABLE_1, getSolrConfigFile()), 220 e); 221 LOG.error(ex.getLocalizedMessage(), ex); 222 } 223 } 224 return m_solrConfig; 225 } 226 227 /** 228 * Returns the solr configuration file, default: <code>'conf/solrconfig.xml'</code>.<p> 229 * 230 * @return the solr configuration file 231 */ 232 public File getSolrConfigFile() { 233 234 return new File(getHome() + DEFAULT_CONFIGSET_FOLDER + CONF_FOLDER + SolrConfig.DEFAULT_CONF_FILE); 235 } 236 237 /** 238 * Returns the Solr xml file, default: <code>'solr.xml'</code>.<p> 239 * 240 * @return the Solr xml file 241 */ 242 public File getSolrFile() { 243 244 if (m_solrFile == null) { 245 String solrFileName = m_solrFileName != null ? m_solrFileName : SOLR_CONFIG_FILE; 246 m_solrFile = new File(getHome() + File.separator + solrFileName); 247 } 248 return m_solrFile; 249 } 250 251 /** 252 * Returns the Solr xml file name, default: <code>'solr.xml'</code>.<p> 253 * 254 * @return the Solr xml file name 255 */ 256 public String getSolrFileName() { 257 258 return m_solrFileName; 259 } 260 261 /** 262 * Returns the Solr index schema.<p> 263 * 264 * @return the Solr index schema 265 */ 266 @SuppressWarnings("resource") 267 public IndexSchema getSolrSchema() { 268 269 if (m_schema == null) { 270 try (FileInputStream fis = new FileInputStream(getSolrSchemaFile())) { 271 ConfigResource configRes = IndexSchemaFactory.getConfigResource( 272 null /* only used if it's a CloudConfigSetService */, 273 fis, 274 getSolrConfig().getResourceLoader(), 275 SOLR_CONFIG_NAME); 276 m_schema = new IndexSchema( 277 SOLR_SCHEMA_NAME, 278 configRes, 279 getSolrConfig().luceneMatchVersion, 280 getSolrConfig().getResourceLoader(), 281 getSolrConfig().getSubstituteProperties()); 282 } catch (IOException e) { 283 CmsConfigurationException ex = new CmsConfigurationException( 284 Messages.get().container( 285 Messages.LOG_SOLR_ERR_SCHEMA_XML_NOT_FOUND_1, 286 getSolrSchemaFile().getPath()), 287 e); 288 LOG.error(ex.getLocalizedMessage(), ex); 289 } 290 } 291 return m_schema; 292 } 293 294 /** 295 * Returns the Solr index schema file.<p> 296 * 297 * @return the Solr index schema file 298 */ 299 public File getSolrSchemaFile() { 300 301 final String dir = getHome() + DEFAULT_CONFIGSET_FOLDER + CONF_FOLDER; 302 //SOLR7 Schema took a new name, also removed the file extension. 303 File file = new File(dir, "managed-schema"); 304 if (file.exists()) { 305 return file; 306 } 307 308 //If use the old Schema.xml, it will automatically "upgrade" to a new filename. 309 file = new File(dir, IndexSchema.DEFAULT_SCHEMA_FILE); 310 return file; 311 } 312 313 /** 314 * Returns <code>true</code> if the Solr server is embedded, <code>false</code> otherwise.<p> 315 * 316 * @return <code>true</code> if the Solr server is embedded, <code>false</code> otherwise 317 */ 318 public boolean isEnabled() { 319 320 return m_enabled; 321 } 322 323 /** 324 * Sets the enabled flag.<p> 325 * 326 * @param isEnabled <code>true</code>, if the Solr server should be used, <code>false</code> otherwise 327 */ 328 public void setEnabled(String isEnabled) { 329 330 m_enabled = Boolean.valueOf(isEnabled).booleanValue(); 331 } 332 333 /** 334 * Sets the home folder for Solr.<p> 335 * 336 * @param homeFolderPath the Solr home folder to set 337 */ 338 public void setHomeFolderPath(String homeFolderPath) { 339 340 m_homeFolderPath = homeFolderPath; 341 } 342 343 /** 344 * Sets the maximal number of results processed for a query to a Solr index.<p> 345 * 346 * The globally set value can be overwritten for each index. 347 * 348 * @param maxProcessedResults the maximal number of results processed for a query to a Solr index. 349 */ 350 public void setMaxProcessedResults(String maxProcessedResults) { 351 352 try { 353 m_maxProcessedResults = Integer.parseInt(maxProcessedResults); 354 } catch (Exception e) { 355 LOG.warn( 356 "Could not parse value " 357 + maxProcessedResults 358 + " as Integer to set the limit for the number of results a Solr index can return."); 359 } 360 if (m_maxProcessedResults <= 0) { 361 m_maxProcessedResults = DEFAULT_MAX_PROCESSED_RESULTS; 362 LOG.warn( 363 "The maximal number of results to return by a Solr index should be greater than 0. Reset it to the default value " 364 + DEFAULT_MAX_PROCESSED_RESULTS 365 + "."); 366 } 367 } 368 369 /** 370 * Sets the external servers URL, should be not null if the embedded falg is <code>false</code>.<p> 371 * 372 * @param url the URL 373 */ 374 public void setServerUrl(String url) { 375 376 m_serverUrl = url; 377 } 378 379 /** 380 * Sets the max time (in ms) before a commit will happen.<p> 381 * 382 * @param time the time as long value 383 */ 384 public void setSolrCommitMs(String time) { 385 386 m_commitMs = Long.parseLong(time); 387 } 388 389 /** 390 * Sets the Solr file name.<p> 391 * 392 * @param name the file name to set 393 */ 394 public void setSolrFileName(String name) { 395 396 m_solrFileName = name; 397 } 398}