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 ==================
Upgrading from Solr 1.4
----------------------
The experimental ALIAS command is removed in Solr 1.5 (SOLR-1637).
Versions of Major Components
---------------------
@ -64,6 +65,8 @@ New Features
* 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
----------------------
@ -157,6 +160,8 @@ Other Changes
* SOLR-1610: Generify SolrCache (Jason Rutherglen via shalin)
* SOLR-1637: Remove ALIAS command
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,
SWAP,
RENAME,
@Deprecated
ALIAS,
MERGEINDEXES;

View File

@ -17,14 +17,7 @@
package org.apache.solr.core;
import java.io.BufferedWriter;
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.io.*;
import java.nio.channels.FileChannel;
import java.util.*;
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.util.DOMUtil;
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.handler.admin.CoreAdminHandler;
import org.apache.solr.schema.IndexSchema;
@ -58,6 +50,8 @@ import org.xml.sax.SAXException;
*/
public class CoreContainer
{
private static final String DEFAULT_CORE_NAME = "DEFAULT_CORE";
protected static Logger log = LoggerFactory.getLogger(CoreContainer.class);
protected final Map<String, SolrCore> cores = new LinkedHashMap<String, SolrCore>();
@ -69,12 +63,14 @@ public class CoreContainer
protected String libDir = null;
protected ClassLoader libLoader = null;
protected SolrResourceLoader loader = null;
@Deprecated
protected java.lang.ref.WeakReference<SolrCore> adminCore = null;
protected Properties containerProperties;
protected Map<String ,IndexSchema> indexSchemaCache;
protected String adminHandler;
protected boolean shareSchema;
protected String solrHome;
protected String solrConfigFilenameOverride;
public CoreContainer() {
solrHome = SolrResourceLoader.locateSolrHome();
@ -100,21 +96,27 @@ public class CoreContainer
public String getSolrConfigFilename() {
return solrConfigFilename;
}
@Deprecated
public void setSolrConfigFilename(String solrConfigFilename) {
this.solrConfigFilename = solrConfigFilename;
}
// core container instantiation
public CoreContainer initialize() throws IOException, ParserConfigurationException, SAXException {
public CoreContainer initialize() throws IOException,
ParserConfigurationException, SAXException {
CoreContainer cores = null;
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());
if (fconf.exists()) {
cores = new CoreContainer();
cores.solrConfigFilenameOverride = solrConfigFilename;
if (fconf.exists())
cores.load(solrHome, fconf);
else {
cores.load(solrHome, new ByteArrayInputStream(DEF_SOLR_XML.getBytes()));
cores.configFile = fconf;
}
abortOnConfigurationError = false;
// if any core aborts on startup, then abort
for (SolrCore c : cores.getCores()) {
@ -124,23 +126,7 @@ public class CoreContainer
}
}
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();
}
return cores;
}
}
@ -208,9 +194,23 @@ public class CoreContainer
*/
public void load(String dir, File configFile ) throws ParserConfigurationException, IOException, SAXException {
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);
solrHome = loader.getInstanceDir();
FileInputStream cfgis = new FileInputStream(configFile);
try {
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);
boolean defaultCoreFound = false;
for (int i=0; i<nodes.getLength(); i++) {
Node node = nodes.item(i);
try {
String names = DOMUtil.getAttr(node, "name", null);
List<String> aliases = StrUtils.splitSmart(names,',');
String name = aliases.get(0);
String name = DOMUtil.getAttr(node, "name", null);
if(name.equals(DEFAULT_CORE_NAME)){
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));
// deal with optional settings
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);
}
opt = DOMUtil.getAttr(node, "schema", null);
@ -276,12 +281,6 @@ public class CoreContainer
p.setCoreProperties(readProperties(cfg, node));
SolrCore core = create(p);
for (int a=1; a<aliases.size(); a++) {
core.open();
register(aliases.get(a), core, false);
}
register(name, core, false);
}
catch (Throwable ex) {
@ -479,6 +478,7 @@ public class CoreContainer
*/
public void reload(String name) throws ParserConfigurationException, IOException, SAXException {
name= checkDefault(name);
SolrCore core;
synchronized(cores) {
core = cores.get(name);
@ -487,18 +487,12 @@ public class CoreContainer
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "No such core: " + name );
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);
}
private String checkDefault(String name) {
return name.length() == 0 || DEFAULT_CORE_NAME.equals(name) || name.trim().length() == 0 ? "" : name;
}
/**
* Swaps two SolrCore descriptors.
@ -509,6 +503,8 @@ public class CoreContainer
if( n0 == null || n1 == null ) {
throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "Can not swap unnamed cores." );
}
n0 = checkDefault(n0);
n1 = checkDefault(n1);
synchronized( cores ) {
SolrCore c0 = cores.get(n0);
SolrCore c1 = cores.get(n1);
@ -520,7 +516,9 @@ public class CoreContainer
cores.put(n1, c0);
c0.setName(n1);
c0.getCoreDescriptor().name = n1;
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 */
public SolrCore remove( String name ) {
name = checkDefault(name);
synchronized(cores) {
return cores.remove( name );
}
@ -542,6 +541,7 @@ public class CoreContainer
* @return the core if found
*/
public SolrCore getCore(String name) {
name= checkDefault(name);
synchronized(cores) {
SolrCore core = cores.get(name);
if (core != null)
@ -708,24 +708,10 @@ public class CoreContainer
if(shareSchema) writeAttribute(w, "shareSchema","true");
w.write(">\n");
Map<SolrCore, LinkedList<String>> aliases = new HashMap<SolrCore,LinkedList<String>>();
synchronized(cores) {
for (Map.Entry<String, SolrCore> entry : cores.entrySet()) {
String name = entry.getKey();
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);
for (SolrCore solrCore : cores.values()) {
persist(w,solrCore.getCoreDescriptor());
}
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");
@ -742,9 +728,9 @@ public class CoreContainer
}
/** 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");
writeAttribute(w,"name",StrUtils.join(aliases,','));
writeAttribute(w,"name",dcore.name);
writeAttribute(w,"instanceDir",dcore.getInstanceDir());
//write config (if not default)
String opt = dcore.getConfigName();
@ -819,4 +805,10 @@ public class CoreContainer
public String getSolrHome() {
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.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Set;
/**
* @version $Id$
@ -118,8 +120,8 @@ public class CoreAdminHandler extends RequestHandlerBase {
}
case ALIAS: {
doPersist = this.handleAliasAction(req, rsp);
break;
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "'ALIAS' is not supported " +
req.getParams().get(CoreAdminParams.ACTION));
}
case UNLOAD: {
@ -291,6 +293,7 @@ public class CoreAdminHandler extends RequestHandlerBase {
* @return true if a modification has resulted that requires persistance
* of the CoreContainer configuration.
*/
@Deprecated
protected boolean handleAliasAction(SolrQueryRequest req, SolrQueryResponse rsp) {
SolrParams params = req.getParams();

View File

@ -17,8 +17,6 @@
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.QueryRequest;
import org.apache.solr.client.solrj.request.UpdateRequest;
@ -132,35 +130,6 @@ public abstract class MultiCoreExampleTestBase extends SolrExampleTestBase
long after = mcr.getStartTime( name ).getTime();
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
CoreAdminRequest.renameCore("core1","corea",coreadmin);
CoreAdminRequest.renameCore("corea","coreb",coreadmin);

View File

@ -58,10 +58,11 @@
<%-- 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");
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><%
for (String name : names) {
%>[<a href="../../<%=name%>/admin/"><%=name%></a>]<%
for (SolrCore name : names) {
if(name.equals(core.getName())) continue;
%>[<a href="../../<%=name.getName()%>/admin/"><%=name%></a>]<%
}%></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
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");
Collection<SolrCore> solrCores = cores.getCores();
if( cores != null
&& cores.getCores().size() > 0 // HACK! check that we have valid names...
&& cores.getCores().iterator().next().getName().length() != 0 ) {
for( org.apache.solr.core.SolrCore core : cores.getCores() ) {%>
<a href="<%= core.getName() %>/admin/">Admin <%= core.getName() %></a><br/>
&& solrCores.size() > 0 // HACK! check that we have valid names...
&& solrCores.iterator().next().getName().length() != 0 ) {
for( org.apache.solr.core.SolrCore core : cores.getCores() ) {
String coreName = core.getName();
if("".equals(coreName) ) coreName =".";
%>
<a href="<%= coreName %>/admin/">Admin <%= core.getName() %></a>
<br/>
<% }} else { %>
<a href="admin/">Solr Admin</a>
<% } %>