SOLR-1621 :Allow current single core deployments to be specified by solr.xml

SOLR-1637 : Remove ALIAS command

git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@890675 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Noble Paul 2009-12-15 07:05:58 +00:00
parent 8e2e344157
commit 0b1f7d579d
8 changed files with 134 additions and 122 deletions

View File

@ -24,6 +24,7 @@ $Id$
================== 1.5.0-dev ================== ================== 1.5.0-dev ==================
Upgrading from Solr 1.4 Upgrading from Solr 1.4
---------------------- ----------------------
The experimental ALIAS command is removed in Solr 1.5 (SOLR-1637).
Versions of Major Components Versions of Major Components
--------------------- ---------------------
@ -64,6 +65,8 @@ New Features
* SOLR-1177: Distributed Search support for TermsComponent (Matt Weber via shalin) * SOLR-1177: Distributed Search support for TermsComponent (Matt Weber via shalin)
* SOLR-1621: Allow current single core deployments to be specified by solr.xml (Mark Miller , noble)
Optimizations Optimizations
---------------------- ----------------------
@ -157,6 +160,8 @@ Other Changes
* SOLR-1610: Generify SolrCache (Jason Rutherglen via shalin) * SOLR-1610: Generify SolrCache (Jason Rutherglen via shalin)
* SOLR-1637: Remove ALIAS command
Build Build
---------------------- ----------------------

34
example/solr/solr.xml Normal file
View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
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.
-->
<!--
All (relative) paths are relative to the installation path
persistent: Save changes made via the API to this file
sharedLib: path to a lib directory that will be shared across all cores
-->
<solr persistent="false">
<!--
adminPath: RequestHandler path to manage cores.
If 'null' (or absent), cores will not be manageable via request handler
-->
<cores adminPath="/admin/cores">
<core name="DEFAULT_CORE" instanceDir="." />
</cores>
</solr>

View File

@ -66,6 +66,7 @@ public interface CoreAdminParams
PERSIST, PERSIST,
SWAP, SWAP,
RENAME, RENAME,
@Deprecated
ALIAS, ALIAS,
MERGEINDEXES; MERGEINDEXES;

View File

@ -17,14 +17,7 @@
package org.apache.solr.core; package org.apache.solr.core;
import java.io.BufferedWriter; import java.io.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.io.InputStream;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -42,7 +35,6 @@ import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.CoreAdminParams; import org.apache.solr.common.params.CoreAdminParams;
import org.apache.solr.common.util.DOMUtil; import org.apache.solr.common.util.DOMUtil;
import org.apache.solr.common.util.XML; import org.apache.solr.common.util.XML;
import org.apache.solr.common.util.StrUtils;
import org.apache.solr.common.util.FileUtils; import org.apache.solr.common.util.FileUtils;
import org.apache.solr.handler.admin.CoreAdminHandler; import org.apache.solr.handler.admin.CoreAdminHandler;
import org.apache.solr.schema.IndexSchema; import org.apache.solr.schema.IndexSchema;
@ -58,6 +50,8 @@ import org.xml.sax.SAXException;
*/ */
public class CoreContainer public class CoreContainer
{ {
private static final String DEFAULT_CORE_NAME = "DEFAULT_CORE";
protected static Logger log = LoggerFactory.getLogger(CoreContainer.class); protected static Logger log = LoggerFactory.getLogger(CoreContainer.class);
protected final Map<String, SolrCore> cores = new LinkedHashMap<String, SolrCore>(); protected final Map<String, SolrCore> cores = new LinkedHashMap<String, SolrCore>();
@ -69,12 +63,14 @@ public class CoreContainer
protected String libDir = null; protected String libDir = null;
protected ClassLoader libLoader = null; protected ClassLoader libLoader = null;
protected SolrResourceLoader loader = null; protected SolrResourceLoader loader = null;
@Deprecated
protected java.lang.ref.WeakReference<SolrCore> adminCore = null; protected java.lang.ref.WeakReference<SolrCore> adminCore = null;
protected Properties containerProperties; protected Properties containerProperties;
protected Map<String ,IndexSchema> indexSchemaCache; protected Map<String ,IndexSchema> indexSchemaCache;
protected String adminHandler; protected String adminHandler;
protected boolean shareSchema; protected boolean shareSchema;
protected String solrHome; protected String solrHome;
protected String solrConfigFilenameOverride;
public CoreContainer() { public CoreContainer() {
solrHome = SolrResourceLoader.locateSolrHome(); solrHome = SolrResourceLoader.locateSolrHome();
@ -100,47 +96,37 @@ public class CoreContainer
public String getSolrConfigFilename() { public String getSolrConfigFilename() {
return solrConfigFilename; return solrConfigFilename;
} }
@Deprecated
public void setSolrConfigFilename(String solrConfigFilename) { public void setSolrConfigFilename(String solrConfigFilename) {
this.solrConfigFilename = solrConfigFilename; this.solrConfigFilename = solrConfigFilename;
} }
// core container instantiation // core container instantiation
public CoreContainer initialize() throws IOException, ParserConfigurationException, SAXException { public CoreContainer initialize() throws IOException,
ParserConfigurationException, SAXException {
CoreContainer cores = null; CoreContainer cores = null;
String solrHome = SolrResourceLoader.locateSolrHome(); String solrHome = SolrResourceLoader.locateSolrHome();
File fconf = new File(solrHome, solrConfigFilename == null? "solr.xml": solrConfigFilename); File fconf = new File(solrHome, solrConfigFilename == null ? "solr.xml"
: solrConfigFilename);
log.info("looking for solr.xml: " + fconf.getAbsolutePath()); log.info("looking for solr.xml: " + fconf.getAbsolutePath());
cores = new CoreContainer();
if (fconf.exists()) { cores.solrConfigFilenameOverride = solrConfigFilename;
cores = new CoreContainer(); if (fconf.exists())
cores.load(solrHome, fconf); cores.load(solrHome, fconf);
abortOnConfigurationError = false; else {
// if any core aborts on startup, then abort cores.load(solrHome, new ByteArrayInputStream(DEF_SOLR_XML.getBytes()));
for (SolrCore c : cores.getCores()) { cores.configFile = fconf;
if (c.getSolrConfig().getBool("abortOnConfigurationError", false)) {
abortOnConfigurationError = true;
break;
}
}
solrConfigFilename = cores.getConfigFile().getName();
} else {
// perform compatibility init
cores = new CoreContainer(solrHome);
CoreDescriptor dcore = new CoreDescriptor(cores, "", ".");
dcore.setCoreProperties(null);
SolrResourceLoader resourceLoader = new SolrResourceLoader(solrHome, null, getCoreProps(solrHome, null,dcore.getCoreProperties()));
cores.loader = resourceLoader;
SolrConfig cfg = solrConfigFilename == null ?
new SolrConfig(resourceLoader, SolrConfig.DEFAULT_CONF_FILE,null) :
new SolrConfig(resourceLoader, solrConfigFilename,null);
SolrCore singlecore = new SolrCore(null, null, cfg, null, dcore);
abortOnConfigurationError = cfg.getBool(
"abortOnConfigurationError", abortOnConfigurationError);
cores.register("", singlecore, false);
cores.setPersistent(false);
solrConfigFilename = cfg.getName();
} }
abortOnConfigurationError = false;
// if any core aborts on startup, then abort
for (SolrCore c : cores.getCores()) {
if (c.getSolrConfig().getBool("abortOnConfigurationError", false)) {
abortOnConfigurationError = true;
break;
}
}
solrConfigFilename = cores.getConfigFile().getName();
return cores; return cores;
} }
} }
@ -176,7 +162,7 @@ public class CoreContainer
* @throws IOException * @throws IOException
* @throws SAXException * @throws SAXException
*/ */
public CoreContainer(String dir, File configFile ) throws ParserConfigurationException, IOException, SAXException public CoreContainer(String dir, File configFile) throws ParserConfigurationException, IOException, SAXException
{ {
this.load(dir, configFile); this.load(dir, configFile);
} }
@ -208,9 +194,23 @@ public class CoreContainer
*/ */
public void load(String dir, File configFile ) throws ParserConfigurationException, IOException, SAXException { public void load(String dir, File configFile ) throws ParserConfigurationException, IOException, SAXException {
this.configFile = configFile; this.configFile = configFile;
this.load(dir, new FileInputStream(configFile));
}
/**
* Load a config file listing the available solr cores.
*
* @param dir the home directory of all resources.
* @param cfgis the configuration file InputStream
* @param configName
* @throws ParserConfigurationException
* @throws IOException
* @throws SAXException
*/
public void load(String dir, InputStream cfgis)
throws ParserConfigurationException, IOException, SAXException {
this.loader = new SolrResourceLoader(dir); this.loader = new SolrResourceLoader(dir);
solrHome = loader.getInstanceDir(); solrHome = loader.getInstanceDir();
FileInputStream cfgis = new FileInputStream(configFile);
try { try {
Config cfg = new Config(loader, null, cfgis, null); Config cfg = new Config(loader, null, cfgis, null);
@ -246,18 +246,23 @@ public class CoreContainer
} }
NodeList nodes = (NodeList)cfg.evaluate("solr/cores/core", XPathConstants.NODESET); NodeList nodes = (NodeList)cfg.evaluate("solr/cores/core", XPathConstants.NODESET);
boolean defaultCoreFound = false;
for (int i=0; i<nodes.getLength(); i++) { for (int i=0; i<nodes.getLength(); i++) {
Node node = nodes.item(i); Node node = nodes.item(i);
try { try {
String names = DOMUtil.getAttr(node, "name", null); String name = DOMUtil.getAttr(node, "name", null);
List<String> aliases = StrUtils.splitSmart(names,','); if(name.equals(DEFAULT_CORE_NAME)){
String name = aliases.get(0); if(defaultCoreFound) throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,"Only one 'DEFAULT_CORE' is allowed ");
defaultCoreFound = true;
name="";
}
CoreDescriptor p = new CoreDescriptor(this, name, DOMUtil.getAttr(node, "instanceDir", null)); CoreDescriptor p = new CoreDescriptor(this, name, DOMUtil.getAttr(node, "instanceDir", null));
// deal with optional settings // deal with optional settings
String opt = DOMUtil.getAttr(node, "config", null); String opt = DOMUtil.getAttr(node, "config", null);
if (opt != null) { if(solrConfigFilenameOverride != null && name.equals("")) {
p.setConfigName(solrConfigFilenameOverride);
} else if (opt != null) {
p.setConfigName(opt); p.setConfigName(opt);
} }
opt = DOMUtil.getAttr(node, "schema", null); opt = DOMUtil.getAttr(node, "schema", null);
@ -276,12 +281,6 @@ public class CoreContainer
p.setCoreProperties(readProperties(cfg, node)); p.setCoreProperties(readProperties(cfg, node));
SolrCore core = create(p); SolrCore core = create(p);
for (int a=1; a<aliases.size(); a++) {
core.open();
register(aliases.get(a), core, false);
}
register(name, core, false); register(name, core, false);
} }
catch (Throwable ex) { catch (Throwable ex) {
@ -479,6 +478,7 @@ public class CoreContainer
*/ */
public void reload(String name) throws ParserConfigurationException, IOException, SAXException { public void reload(String name) throws ParserConfigurationException, IOException, SAXException {
name= checkDefault(name);
SolrCore core; SolrCore core;
synchronized(cores) { synchronized(cores) {
core = cores.get(name); core = cores.get(name);
@ -487,18 +487,12 @@ public class CoreContainer
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "No such core: " + name ); throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "No such core: " + name );
SolrCore newCore = create(core.getCoreDescriptor()); SolrCore newCore = create(core.getCoreDescriptor());
// point all aliases to the reloaded core
for (String alias : getCoreNames(core)) {
if (!name.equals(alias)) {
newCore.open();
register(alias, newCore, false);
}
}
register(name, newCore, false); register(name, newCore, false);
} }
private String checkDefault(String name) {
return name.length() == 0 || DEFAULT_CORE_NAME.equals(name) || name.trim().length() == 0 ? "" : name;
}
/** /**
* Swaps two SolrCore descriptors. * Swaps two SolrCore descriptors.
@ -509,6 +503,8 @@ public class CoreContainer
if( n0 == null || n1 == null ) { if( n0 == null || n1 == null ) {
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "Can not swap unnamed cores." ); throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "Can not swap unnamed cores." );
} }
n0 = checkDefault(n0);
n1 = checkDefault(n1);
synchronized( cores ) { synchronized( cores ) {
SolrCore c0 = cores.get(n0); SolrCore c0 = cores.get(n0);
SolrCore c1 = cores.get(n1); SolrCore c1 = cores.get(n1);
@ -520,7 +516,9 @@ public class CoreContainer
cores.put(n1, c0); cores.put(n1, c0);
c0.setName(n1); c0.setName(n1);
c0.getCoreDescriptor().name = n1;
c1.setName(n0); c1.setName(n0);
c1.getCoreDescriptor().name = n0;
} }
@ -529,6 +527,7 @@ public class CoreContainer
/** Removes and returns registered core w/o decrementing it's reference count */ /** Removes and returns registered core w/o decrementing it's reference count */
public SolrCore remove( String name ) { public SolrCore remove( String name ) {
name = checkDefault(name);
synchronized(cores) { synchronized(cores) {
return cores.remove( name ); return cores.remove( name );
} }
@ -542,6 +541,7 @@ public class CoreContainer
* @return the core if found * @return the core if found
*/ */
public SolrCore getCore(String name) { public SolrCore getCore(String name) {
name= checkDefault(name);
synchronized(cores) { synchronized(cores) {
SolrCore core = cores.get(name); SolrCore core = cores.get(name);
if (core != null) if (core != null)
@ -708,26 +708,12 @@ public class CoreContainer
if(shareSchema) writeAttribute(w, "shareSchema","true"); if(shareSchema) writeAttribute(w, "shareSchema","true");
w.write(">\n"); w.write(">\n");
Map<SolrCore, LinkedList<String>> aliases = new HashMap<SolrCore,LinkedList<String>>();
synchronized(cores) { synchronized(cores) {
for (Map.Entry<String, SolrCore> entry : cores.entrySet()) { for (SolrCore solrCore : cores.values()) {
String name = entry.getKey(); persist(w,solrCore.getCoreDescriptor());
LinkedList<String> a = aliases.get(entry.getValue());
if (a==null) a = new LinkedList<String>();
if (name.equals(entry.getValue().getName())) {
a.addFirst(name);
} else {
a.addLast(name);
}
aliases.put(entry.getValue(), a);
} }
} }
for (Map.Entry<SolrCore, LinkedList<String>> entry : aliases.entrySet()) {
persist(w, entry.getValue(), entry.getKey().getCoreDescriptor());
}
w.write("</cores>\n"); w.write("</cores>\n");
w.write("</solr>\n"); w.write("</solr>\n");
} }
@ -742,9 +728,9 @@ public class CoreContainer
} }
/** Writes the cores configuration node for a given core. */ /** Writes the cores configuration node for a given core. */
void persist(Writer w, List<String> aliases, CoreDescriptor dcore) throws IOException { void persist(Writer w, CoreDescriptor dcore) throws IOException {
w.write(" <core"); w.write(" <core");
writeAttribute(w,"name",StrUtils.join(aliases,',')); writeAttribute(w,"name",dcore.name);
writeAttribute(w,"instanceDir",dcore.getInstanceDir()); writeAttribute(w,"instanceDir",dcore.getInstanceDir());
//write config (if not default) //write config (if not default)
String opt = dcore.getConfigName(); String opt = dcore.getConfigName();
@ -819,4 +805,10 @@ public class CoreContainer
public String getSolrHome() { public String getSolrHome() {
return solrHome; return solrHome;
} }
private static final String DEF_SOLR_XML ="<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" +
"<solr persistent=\"false\">\n" +
" <cores adminPath=\"/admin/cores\">\n" +
" <core name=\""+ DEFAULT_CORE_NAME + "\" instanceDir=\".\" />\n" +
" </cores>\n" +
"</solr>";
} }

View File

@ -41,7 +41,9 @@ import org.apache.lucene.store.Directory;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.Set;
/** /**
* @version $Id$ * @version $Id$
@ -118,8 +120,8 @@ public class CoreAdminHandler extends RequestHandlerBase {
} }
case ALIAS: { case ALIAS: {
doPersist = this.handleAliasAction(req, rsp); throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "'ALIAS' is not supported " +
break; req.getParams().get(CoreAdminParams.ACTION));
} }
case UNLOAD: { case UNLOAD: {
@ -291,6 +293,7 @@ public class CoreAdminHandler extends RequestHandlerBase {
* @return true if a modification has resulted that requires persistance * @return true if a modification has resulted that requires persistance
* of the CoreContainer configuration. * of the CoreContainer configuration.
*/ */
@Deprecated
protected boolean handleAliasAction(SolrQueryRequest req, SolrQueryResponse rsp) { protected boolean handleAliasAction(SolrQueryRequest req, SolrQueryResponse rsp) {
SolrParams params = req.getParams(); SolrParams params = req.getParams();

View File

@ -17,8 +17,6 @@
package org.apache.solr.client.solrj; package org.apache.solr.client.solrj;
import java.io.File;
import org.apache.solr.client.solrj.request.CoreAdminRequest; import org.apache.solr.client.solrj.request.CoreAdminRequest;
import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.client.solrj.request.QueryRequest;
import org.apache.solr.client.solrj.request.UpdateRequest; import org.apache.solr.client.solrj.request.UpdateRequest;
@ -132,35 +130,6 @@ public abstract class MultiCoreExampleTestBase extends SolrExampleTestBase
long after = mcr.getStartTime( name ).getTime(); long after = mcr.getStartTime( name ).getTime();
assertTrue( "should have more recent time: "+after+","+before, after > before ); assertTrue( "should have more recent time: "+after+","+before, after > before );
// test alias
CoreAdminRequest.aliasCore("core1","corefoo",coreadmin);
assertEquals( 1, getSolrCore1().query( new SolrQuery( "id:BBB" ) ).getResults().size() );
assertEquals( 1, getSolrCore("corefoo").query( new SolrQuery( "id:BBB" ) ).getResults().size() );
// test that reload affects aliases
CoreAdminRequest.reloadCore("core1", coreadmin);
// this is only an effective test for embedded, where we have
// direct access to the core container.
SolrCore c1 = cores.getCore("core1");
SolrCore c2 = cores.getCore("corefoo");
assertTrue(c1 == c2);
if (c1 != null) c1.close();
if (c2 != null) c2.close();
// retest core query
assertEquals( 1, getSolrCore1().query( new SolrQuery( "id:BBB" ) ).getResults().size() );
// test close
CoreAdminRequest.unloadCore("corefoo",coreadmin);
try {
getSolrCore("corefoo").query( new SolrQuery( "id:BBB" ) );
fail( "corefoo should be gone" );
}
catch( Exception ex ) {}
// aliased core should still work
assertEquals( 1, getSolrCore1().query( new SolrQuery( "id:BBB" ) ).getResults().size() );
// test move // test move
CoreAdminRequest.renameCore("core1","corea",coreadmin); CoreAdminRequest.renameCore("core1","corea",coreadmin);
CoreAdminRequest.renameCore("corea","coreb",coreadmin); CoreAdminRequest.renameCore("corea","coreb",coreadmin);

View File

@ -58,10 +58,11 @@
<%-- List the cores (that arent this one) so we can switch --%> <%-- List the cores (that arent this one) so we can switch --%>
<% org.apache.solr.core.CoreContainer cores = (org.apache.solr.core.CoreContainer)request.getAttribute("org.apache.solr.CoreContainer"); <% org.apache.solr.core.CoreContainer cores = (org.apache.solr.core.CoreContainer)request.getAttribute("org.apache.solr.CoreContainer");
if (cores!=null) { if (cores!=null) {
Collection<String> names = cores.getCoreNames(); Collection<SolrCore> names = cores.getCores();
if (names.size() > 1) {%><tr><td><strong>Cores:</strong><br></td><td><% if (names.size() > 1) {%><tr><td><strong>Cores:</strong><br></td><td><%
for (String name : names) { for (SolrCore name : names) {
%>[<a href="../../<%=name%>/admin/"><%=name%></a>]<% if(name.equals(core.getName())) continue;
%>[<a href="../../<%=name.getName()%>/admin/"><%=name%></a>]<%
}%></td></tr><% }%></td></tr><%
}}%> }}%>

View File

@ -1,3 +1,5 @@
<%@ page import="org.apache.solr.core.SolrCore" %>
<%@ page import="java.util.Collection" %>
<%-- <%--
Licensed to the Apache Software Foundation (ASF) under one or more Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with contributor license agreements. See the NOTICE file distributed with
@ -29,11 +31,16 @@
<% <%
org.apache.solr.core.CoreContainer cores = (org.apache.solr.core.CoreContainer)request.getAttribute("org.apache.solr.CoreContainer"); org.apache.solr.core.CoreContainer cores = (org.apache.solr.core.CoreContainer)request.getAttribute("org.apache.solr.CoreContainer");
Collection<SolrCore> solrCores = cores.getCores();
if( cores != null if( cores != null
&& cores.getCores().size() > 0 // HACK! check that we have valid names... && solrCores.size() > 0 // HACK! check that we have valid names...
&& cores.getCores().iterator().next().getName().length() != 0 ) { && solrCores.iterator().next().getName().length() != 0 ) {
for( org.apache.solr.core.SolrCore core : cores.getCores() ) {%> for( org.apache.solr.core.SolrCore core : cores.getCores() ) {
<a href="<%= core.getName() %>/admin/">Admin <%= core.getName() %></a><br/> String coreName = core.getName();
if("".equals(coreName) ) coreName =".";
%>
<a href="<%= coreName %>/admin/">Admin <%= core.getName() %></a>
<br/>
<% }} else { %> <% }} else { %>
<a href="admin/">Solr Admin</a> <a href="admin/">Solr Admin</a>
<% } %> <% } %>