SOLR-2610 -- Add an option to delete index through CoreAdmin UNLOAD action

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1138405 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Shalin Shekhar Mangar 2011-06-22 11:18:43 +00:00
parent cdf12071bf
commit 77e3dfc016
9 changed files with 128 additions and 35 deletions

View File

@ -251,6 +251,12 @@ Documentation
================== 3.3.0 ==================
Upgrading from Solr 3.2.0
----------------------
The SolrCore's CloseHook API has been changed in a backward-incompatible way.
Any custom components which use the SolrCore.addCloseHook method will need to
be modified accordingly.
New Features
----------------------
@ -276,6 +282,8 @@ New Features
* SOLR-1331 -- Added a srcCore parameter to CoreAdminHandler's mergeindexes action
to merge one or more cores' indexes to a target core (shalin)
* SOLR-2610 -- Add an option to delete index through CoreAdmin UNLOAD action (shalin)
Optimizations
----------------------

View File

@ -69,6 +69,9 @@ public interface CoreAdminParams
/** The shard id in solr cloud */
public final static String SHARD = "shard";
/** If you unload a core, delete the index too */
public final static String DELETE_INDEX = "deleteIndex";
public enum CoreAdminAction {
STATUS,
LOAD,

View File

@ -18,27 +18,40 @@ package org.apache.solr.core;
/**
* Interface to request notification when the core is closed.
*<p/>
* Used to request notification when the core is closed.
* <p/>
* Call {@link org.apache.solr.core.SolrCore#addCloseHook(org.apache.solr.core.CloseHook)} during the {@link org.apache.solr.util.plugin.SolrCoreAware#inform(SolrCore)} method to
* add a close hook to your object.
* <p/>
* The close hook can be useful for releasing objects related to the request handler (for instance, if you have a JDBC DataSource or something like that)
*
*
*/
* The close hook can be useful for releasing objects related to the request handler (for instance, if you have a JDBC DataSource or something like that)
*/
public interface CloseHook {
/**
* Method called when the given SolrCore object is closing / shutting down.
* <br />
* <b>Important:</b> Keep the method implementation as short as possible. If it were to use any heavy i/o , network connections -
* it might be a better idea to launch in a separate Thread so as to not to block the process of
* shutting down a given SolrCore instance.
*
*
* @param core SolrCore object that is shutting down / closing
*/
void close( SolrCore core );
}
public abstract class CloseHook {
/**
* Method called when the given SolrCore object is closing / shutting down but before the update handler and
* searcher(s) are actually closed
* <br />
* <b>Important:</b> Keep the method implementation as short as possible. If it were to use any heavy i/o , network connections -
* it might be a better idea to launch in a separate Thread so as to not to block the process of
* shutting down a given SolrCore instance.
*
* @param core SolrCore object that is shutting down / closing
*/
public abstract void preClose(SolrCore core);
/**
* Method called when the given SolrCore object has been shut down and update handlers and searchers are closed
* <br/>
* Use this method for post-close clean up operations e.g. deleting the index from disk.
* <br/>
* <b>The core's passed to the method is already closed and therefore, it's update handler or searcher should *NOT* be used</b>
*
* <b>Important:</b> Keep the method implementation as short as possible. If it were to use any heavy i/o , network connections -
* it might be a better idea to launch in a separate Thread so as to not to block the process of
* shutting down a given SolrCore instance.
*
* @param core
*/
public abstract void postClose(SolrCore core);
}

View File

@ -654,7 +654,7 @@ public final class SolrCore implements SolrInfoMBean {
if( closeHooks != null ) {
for( CloseHook hook : closeHooks ) {
try {
hook.close( this );
hook.preClose( this );
} catch (Throwable e) {
SolrException.log(log, e);
}
@ -693,7 +693,15 @@ public final class SolrCore implements SolrInfoMBean {
SolrException.log(log,e);
}
if( closeHooks != null ) {
for( CloseHook hook : closeHooks ) {
try {
hook.postClose( this );
} catch (Throwable e) {
SolrException.log(log, e);
}
}
}
}
/** Current core usage count. */

View File

@ -889,11 +889,15 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
*/
private void registerCloseHook() {
core.addCloseHook(new CloseHook() {
public void close(SolrCore core) {
@Override
public void preClose(SolrCore core) {
if (snapPuller != null) {
snapPuller.destroy();
}
}
@Override
public void postClose(SolrCore core) {}
});
}

View File

@ -18,7 +18,6 @@
package org.apache.solr.handler.admin;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.util.IOUtils;
import org.apache.solr.cloud.CloudDescriptor;
import org.apache.solr.common.SolrException;
@ -28,10 +27,7 @@ import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.params.UpdateParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.CoreDescriptor;
import org.apache.solr.core.SolrCore;
import org.apache.solr.core.DirectoryFactory;
import org.apache.solr.core.*;
import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.LocalSolrQueryRequest;
@ -41,19 +37,19 @@ import org.apache.solr.util.RefCounted;
import org.apache.solr.update.MergeIndexesCommand;
import org.apache.solr.update.processor.UpdateRequestProcessor;
import org.apache.solr.update.processor.UpdateRequestProcessorChain;
import org.apache.lucene.store.Directory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
*
* @since solr 1.3
*/
public class CoreAdminHandler extends RequestHandlerBase {
protected static Logger log = LoggerFactory.getLogger(CoreAdminHandler.class);
protected final CoreContainer coreContainer;
public CoreAdminHandler() {
@ -397,6 +393,23 @@ public class CoreAdminHandler extends RequestHandlerBase {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
"No such core exists '"+cname+"'");
}
if (params.getBool(CoreAdminParams.DELETE_INDEX, false)) {
core.addCloseHook(new CloseHook() {
@Override
public void preClose(SolrCore core) {}
@Override
public void postClose(SolrCore core) {
File dataDir = new File(core.getIndexDir());
for (File file : dataDir.listFiles()) {
if (!file.delete()) {
log.error(file.getAbsolutePath() + " could not be deleted on core unload");
}
}
if (!dataDir.delete()) log.error(dataDir.getAbsolutePath() + " could not be deleted on core unload");
}
});
}
core.close();
return coreContainer.isPersistent();

View File

@ -163,6 +163,30 @@ public class CoreAdminRequest extends SolrRequest
}
}
public static class Unload extends CoreAdminRequest {
protected boolean deleteIndex;
public Unload(boolean deleteIndex) {
action = CoreAdminAction.UNLOAD;
this.deleteIndex = deleteIndex;
}
public boolean isDeleteIndex() {
return deleteIndex;
}
public void setDeleteIndex(boolean deleteIndex) {
this.deleteIndex = deleteIndex;
}
@Override
public SolrParams getParams() {
ModifiableSolrParams params = (ModifiableSolrParams) super.getParams();
params.set(CoreAdminParams.DELETE_INDEX, deleteIndex);
return params;
}
}
public CoreAdminRequest()
{
super( METHOD.GET, "/admin/cores" );
@ -244,11 +268,15 @@ public class CoreAdminRequest extends SolrRequest
public static CoreAdminResponse unloadCore( String name, SolrServer server ) throws SolrServerException, IOException
{
CoreAdminRequest req = new CoreAdminRequest();
return unloadCore(name, false, server);
}
public static CoreAdminResponse unloadCore( String name, boolean deleteIndex, SolrServer server ) throws SolrServerException, IOException
{
Unload req = new Unload(deleteIndex);
req.setCoreName( name );
req.setAction( CoreAdminAction.UNLOAD );
return req.process( server );
}
}
public static CoreAdminResponse renameCore(String coreName, String newName, SolrServer server ) throws SolrServerException, IOException
{

View File

@ -23,11 +23,15 @@ import org.apache.solr.client.solrj.request.UpdateRequest;
import org.apache.solr.client.solrj.request.UpdateRequest.ACTION;
import org.apache.solr.client.solrj.response.CoreAdminResponse;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.SolrCore;
import org.apache.solr.request.SolrRequestInfo;
import org.apache.solr.util.ExternalPaths;
import org.junit.Test;
import java.io.File;
/**
*
@ -161,5 +165,13 @@ public abstract class MultiCoreExampleTestBase extends SolrExampleTestBase
}
catch( Exception ex ) {}
assertEquals( 1, getSolrCore("corefoo").query( new SolrQuery( "id:BBB" ) ).getResults().size() );
NamedList<Object> response = getSolrCore("corefoo").query(new SolrQuery().setQueryType("/admin/system")).getResponse();
NamedList<Object> coreInfo = (NamedList<Object>) response.get("core");
String indexDir = (String) ((NamedList<Object>) coreInfo.get("directory")).get("index");
// test delete index on core
CoreAdminRequest.unloadCore("corefoo", true, coreadmin);
File dir = new File(indexDir);
assertFalse("Index directory exists after core unload with deleteIndex=true", dir.exists());
}
}

View File

@ -207,9 +207,13 @@ class ClosingRequestHandler extends EmptyRequestHandler implements SolrCoreAware
public void inform(SolrCore core) {
core.addCloseHook( new CloseHook() {
public void close(SolrCore core) {
@Override
public void preClose(SolrCore core) {
closed = true;
}
@Override
public void postClose(SolrCore core) {}
});
}
}