You are viewing a plain text version of this content. The canonical link for it is here.
Posted to solr-commits@lucene.apache.org by sh...@apache.org on 2009/04/24 08:30:56 UTC
svn commit: r768165 - in /lucene/solr/trunk: CHANGES.txt
src/java/org/apache/solr/core/CoreContainer.java
src/java/org/apache/solr/core/SolrResourceLoader.java
src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
Author: shalin
Date: Fri Apr 24 06:30:55 2009
New Revision: 768165
URL: http://svn.apache.org/viewvc?rev=768165&view=rev
Log:
SOLR-1106 -- Made CoreAdminHandler Actions pluggable so that additional actions may be plugged in or the existing ones can be overridden if needed.
Modified:
lucene/solr/trunk/CHANGES.txt
lucene/solr/trunk/src/java/org/apache/solr/core/CoreContainer.java
lucene/solr/trunk/src/java/org/apache/solr/core/SolrResourceLoader.java
lucene/solr/trunk/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
Modified: lucene/solr/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/CHANGES.txt?rev=768165&r1=768164&r2=768165&view=diff
==============================================================================
--- lucene/solr/trunk/CHANGES.txt (original)
+++ lucene/solr/trunk/CHANGES.txt Fri Apr 24 06:30:55 2009
@@ -205,6 +205,9 @@
FieldAnalysisRequestHandler and DocumentAnalysisRequestHandler is also provided in the Solrj client.
(Uri Boness, shalin)
+38. SOLR-1106: Made CoreAdminHandler Actions pluggable so that additional actions may be plugged in or the existing
+ ones can be overridden if needed. (Kay Kay, Noble Paul, shalin)
+
Optimizations
----------------------
1. SOLR-374: Use IndexReader.reopen to save resources by re-using parts of the
Modified: lucene/solr/trunk/src/java/org/apache/solr/core/CoreContainer.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/core/CoreContainer.java?rev=768165&r1=768164&r2=768165&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/core/CoreContainer.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/core/CoreContainer.java Fri Apr 24 06:30:55 2009
@@ -174,6 +174,7 @@
persistent = cfg.getBool( "solr/@persistent", false );
libDir = cfg.get( "solr/@sharedLib", null);
adminPath = cfg.get( "solr/cores/@adminPath", null );
+ String adminHandler = cfg.get( "solr/cores/@adminHandler", null );
managementPath = cfg.get("solr/cores/@managementPath", null );
if (libDir != null) {
@@ -182,8 +183,12 @@
libLoader = SolrResourceLoader.createClassLoader(f, null);
}
- if( adminPath != null ) {
- coreAdminHandler = this.createMultiCoreHandler();
+ if (adminPath != null) {
+ if (adminHandler == null) {
+ coreAdminHandler = new CoreAdminHandler(this);
+ } else {
+ coreAdminHandler = this.createMultiCoreHandler(adminHandler);
+ }
}
try {
@@ -506,15 +511,18 @@
* Creates a CoreAdminHandler for this MultiCore.
* @return a CoreAdminHandler
*/
- protected CoreAdminHandler createMultiCoreHandler() {
- return new CoreAdminHandler() {
- @Override
- public CoreContainer getCoreContainer() {
- return CoreContainer.this;
- }
- };
+ protected CoreAdminHandler createMultiCoreHandler(final String adminHandlerClass) {
+ SolrResourceLoader loader = new SolrResourceLoader(null, libLoader, null);
+ Object obj = loader.newAdminHandlerInstance(CoreContainer.this, adminHandlerClass);
+ if ( !(obj instanceof CoreAdminHandler))
+ {
+ throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,
+ "adminHandlerClass is not of type "+ CoreAdminHandler.class );
+
+ }
+ return (CoreAdminHandler) obj;
}
-
+
public CoreAdminHandler getMultiCoreHandler() {
return coreAdminHandler;
}
Modified: lucene/solr/trunk/src/java/org/apache/solr/core/SolrResourceLoader.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/core/SolrResourceLoader.java?rev=768165&r1=768164&r2=768165&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/core/SolrResourceLoader.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/core/SolrResourceLoader.java Fri Apr 24 06:30:55 2009
@@ -348,6 +348,33 @@
return obj;
}
+ public Object newAdminHandlerInstance(final CoreContainer coreContainer, String cname, String ... subpackages) {
+ Class clazz = findClass(cname,subpackages);
+ if( clazz == null ) {
+ throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,
+ "Can not find class: "+cname + " in " + classLoader, false);
+ }
+
+ Object obj = null;
+ try {
+ Constructor ctor = clazz.getConstructor(CoreContainer.class);
+ obj = ctor.newInstance(coreContainer);
+ }
+ catch (Exception e) {
+ throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,
+ "Error instantiating class: '" + clazz.getName()+"'", e, false );
+ }
+ //TODO: Does SolrCoreAware make sense here since in a multi-core context
+ // which core are we talking about ?
+ if( obj instanceof ResourceLoaderAware ) {
+ assertAwareCompatibility( ResourceLoaderAware.class, obj );
+ waitingForResources.add( (ResourceLoaderAware)obj );
+ }
+ return obj;
+ }
+
+
+
public Object newInstance(String cName, String [] subPackages, Class[] params, Object[] args){
Class clazz = findClass(cName,subPackages);
if( clazz == null ) {
Modified: lucene/solr/trunk/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
URL: http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java?rev=768165&r1=768164&r2=768165&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java Fri Apr 24 06:30:55 2009
@@ -17,197 +17,365 @@
package org.apache.solr.handler.admin;
-import java.io.IOException;
-import java.io.File;
-import java.util.Date;
-
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.CoreAdminParams;
-import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.params.CoreAdminParams.CoreAdminAction;
+import org.apache.solr.common.params.SolrParams;
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.SolrCore;
import org.apache.solr.core.CoreDescriptor;
+import org.apache.solr.core.SolrCore;
import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrQueryResponse;
import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.util.RefCounted;
+import java.io.File;
+import java.io.IOException;
+import java.util.Date;
+
/**
* @version $Id$
* @since solr 1.3
*/
-public abstract class CoreAdminHandler extends RequestHandlerBase
-{
- public CoreAdminHandler()
- {
+public class CoreAdminHandler extends RequestHandlerBase {
+ protected final CoreContainer coreContainer;
+
+ public CoreAdminHandler() {
super();
// Unlike most request handlers, CoreContainer initialization
// should happen in the constructor...
+ this.coreContainer = null;
}
-
-
+
+
+ /**
+ * Overloaded ctor to inject CoreContainer into the handler.
+ *
+ * @param coreContainer Core Container of the solr webapp installed.
+ */
+ public CoreAdminHandler(final CoreContainer coreContainer) {
+ this.coreContainer = coreContainer;
+ }
+
+
@Override
final public void init(NamedList args) {
- throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,
- "CoreAdminHandler should not be configured in solrconf.xml\n"+
- "it is a special Handler configured directly by the RequestDispatcher" );
+ throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
+ "CoreAdminHandler should not be configured in solrconf.xml\n" +
+ "it is a special Handler configured directly by the RequestDispatcher");
}
-
+
/**
- * The instance of CoreContainer this handler handles.
- * This should be the CoreContainer instance that created this handler.
+ * The instance of CoreContainer this handler handles. This should be the CoreContainer instance that created this
+ * handler.
+ *
* @return a CoreContainer instance
*/
- public abstract CoreContainer getCoreContainer();
-
+ public CoreContainer getCoreContainer() {
+ return this.coreContainer;
+ }
+
@Override
- public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception
- {
+ public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
// Make sure the cores is enabled
CoreContainer cores = getCoreContainer();
- if( cores == null ) {
- throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
- "Core container instance missing" );
+ if (cores == null) {
+ throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
+ "Core container instance missing");
}
- boolean do_persist = false;
-
+ boolean doPersist = false;
+
// Pick the action
SolrParams params = req.getParams();
- SolrParams required = params.required();
CoreAdminAction action = CoreAdminAction.STATUS;
- String a = params.get( CoreAdminParams.ACTION );
- if( a != null ) {
- action = CoreAdminAction.get( a );
- if( action == null ) {
- throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
- "Unknown 'action' value. Use: "+CoreAdminAction.values() );
+ String a = params.get(CoreAdminParams.ACTION);
+ if (a != null) {
+ action = CoreAdminAction.get(a);
+ if (action == null) {
+ doPersist = this.handleCustomAction(req, rsp);
}
}
- String cname = params.get( CoreAdminParams.CORE );
-
- switch(action) {
- case CREATE: {
- String name = params.get(CoreAdminParams.NAME);
- CoreDescriptor dcore = new CoreDescriptor(cores, name, params.get(CoreAdminParams.INSTANCE_DIR));
-
- // fillup optional parameters
- String opts = params.get(CoreAdminParams.CONFIG);
- if (opts != null)
- dcore.setConfigName(opts);
-
- opts = params.get(CoreAdminParams.SCHEMA);
- if (opts != null)
- dcore.setSchemaName(opts);
-
- opts = params.get(CoreAdminParams.DATA_DIR);
- if (opts != null)
- dcore.setDataDir(opts);
-
- SolrCore core = cores.create(dcore);
- cores.register(name, core,false);
- rsp.add("core", core.getName());
- do_persist = cores.isPersistent();
- break;
- }
+ if (action != null) {
+ switch (action) {
+ case CREATE: {
+ doPersist = this.handleCreateAction(req, rsp);
+ break;
+ }
- case RENAME: {
- String name = params.get(CoreAdminParams.OTHER);
- if (cname.equals(name)) break;
-
- SolrCore core = cores.getCore(cname);
- if (core != null) {
- do_persist = cores.isPersistent();
- cores.register(name, core, false);
- cores.remove(cname);
- core.close();
+ case RENAME: {
+ doPersist = this.handleRenameAction(req, rsp);
+ break;
}
- break;
- }
- case ALIAS: {
- String name = params.get(CoreAdminParams.OTHER);
- if (cname.equals(name)) break;
-
- SolrCore core = cores.getCore(cname);
- if (core != null) {
- do_persist = cores.isPersistent();
- cores.register(name, core, false);
- // no core.close() since each entry in the cores map should increase the ref
+ case ALIAS: {
+ doPersist = this.handleAliasAction(req, rsp);
+ break;
}
- break;
- }
- case UNLOAD: {
- SolrCore core = cores.remove(cname);
- core.close();
- do_persist = cores.isPersistent();
- break;
- }
+ case UNLOAD: {
+ doPersist = this.handleUnloadAction(req, rsp);
+ break;
+ }
- case STATUS: {
- NamedList<Object> status = new SimpleOrderedMap<Object>();
- if( cname == null ) {
- for (String name : cores.getCoreNames()) {
- status.add(name, getCoreStatus( cores, name ) );
- }
- }
- else {
- status.add(cname, getCoreStatus( cores, cname ) );
- }
- rsp.add( "status", status );
- do_persist = false; // no state change
- break;
-
- }
-
- case PERSIST: {
- String fileName = params.get( CoreAdminParams.FILE );
- if (fileName != null) {
- File file = new File(cores.getConfigFile().getParentFile(), fileName);
- cores.persistFile(file);
- rsp.add("saved", file.getAbsolutePath());
- do_persist = false;
- }
- else if (!cores.isPersistent()) {
- throw new SolrException (SolrException.ErrorCode.FORBIDDEN, "Persistence is not enabled");
- }
- else
- do_persist = true;
- break;
- }
+ case STATUS: {
+ doPersist = this.handleStatusAction(req, rsp);
+ break;
- case RELOAD: {
- cores.reload( cname );
- do_persist = false; // no change on reload
- break;
- }
+ }
- case SWAP: {
- do_persist = params.getBool(CoreAdminParams.PERSISTENT, cores.isPersistent());
- String other = required.get( CoreAdminParams.OTHER );
- cores.swap( cname, other );
- break;
- }
-
- default: {
- throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,
- "TODO: IMPLEMENT: " + action );
- }
- } // switch
-
+ case PERSIST: {
+ doPersist = this.handlePersistAction(req, rsp);
+ break;
+ }
+
+ case RELOAD: {
+ doPersist = this.handleReloadAction(req, rsp);
+ break;
+ }
+
+ case SWAP: {
+ doPersist = this.handleSwapAction(req, rsp);
+ break;
+ }
+
+ default: {
+ doPersist = this.handleCustomAction(req, rsp);
+ break;
+ }
+ } // switch
+ }
// Should we persist the changes?
- if (do_persist) {
+ if (doPersist) {
cores.persist();
rsp.add("saved", cores.getConfigFile().getAbsolutePath());
}
}
-
- private static NamedList<Object> getCoreStatus(CoreContainer cores, String cname ) throws IOException
- {
+
+ /**
+ * Handle Custom Action.
+ * <p/>
+ * This method could be overridden by derived classes to handle custom actions. <br> By default - this method throws a
+ * solr exception. Derived classes are free to write their derivation if necessary.
+ */
+ protected boolean handleCustomAction(SolrQueryRequest req, SolrQueryResponse rsp) {
+ throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Unsupported operation: " +
+ req.getParams().get(CoreAdminParams.ACTION));
+ }
+
+ /**
+ * Handle 'CREATE' action.
+ *
+ * @param req
+ * @param rsp
+ *
+ * @return persistence flag as necessary.
+ *
+ * @throws SolrException in case of a configuration error.
+ */
+ protected boolean handleCreateAction(SolrQueryRequest req, SolrQueryResponse rsp) throws SolrException {
+ try {
+ SolrParams params = req.getParams();
+ String name = params.get(CoreAdminParams.NAME);
+ CoreDescriptor dcore = new CoreDescriptor(coreContainer, name, params.get(CoreAdminParams.INSTANCE_DIR));
+
+ // fillup optional parameters
+ String opts = params.get(CoreAdminParams.CONFIG);
+ if (opts != null)
+ dcore.setConfigName(opts);
+
+ opts = params.get(CoreAdminParams.SCHEMA);
+ if (opts != null)
+ dcore.setSchemaName(opts);
+
+ opts = params.get(CoreAdminParams.DATA_DIR);
+ if (opts != null)
+ dcore.setDataDir(opts);
+
+ SolrCore core = coreContainer.create(dcore);
+ coreContainer.register(name, core, false);
+ rsp.add("core", core.getName());
+ return coreContainer.isPersistent();
+ } catch (Exception ex) {
+ throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
+ "Error executing default implementation of CREATE", ex);
+ }
+ }
+
+ /**
+ * Handle "RENAME" Action
+ *
+ * @param req
+ * @param rsp
+ *
+ * @return
+ *
+ * @throws SolrException
+ */
+ protected boolean handleRenameAction(SolrQueryRequest req, SolrQueryResponse rsp) throws SolrException {
+ SolrParams params = req.getParams();
+
+ String name = params.get(CoreAdminParams.OTHER);
+ String cname = params.get(CoreAdminParams.CORE);
+ boolean doPersist = false;
+
+ if (cname.equals(name)) return doPersist;
+
+ SolrCore core = coreContainer.getCore(cname);
+ if (core != null) {
+ doPersist = coreContainer.isPersistent();
+ coreContainer.register(name, core, false);
+ coreContainer.remove(cname);
+ core.close();
+ }
+ return doPersist;
+ }
+
+ /**
+ * Handle "ALIAS" action
+ *
+ * @param req
+ * @param rsp
+ *
+ * @return
+ */
+ protected boolean handleAliasAction(SolrQueryRequest req, SolrQueryResponse rsp) {
+ SolrParams params = req.getParams();
+
+ String name = params.get(CoreAdminParams.OTHER);
+ String cname = params.get(CoreAdminParams.CORE);
+ boolean doPersist = false;
+ if (cname.equals(name)) return doPersist;
+
+ SolrCore core = coreContainer.getCore(cname);
+ if (core != null) {
+ doPersist = coreContainer.isPersistent();
+ coreContainer.register(name, core, false);
+ // no core.close() since each entry in the cores map should increase the ref
+ }
+ return doPersist;
+ }
+
+
+ /**
+ * Handle "UNLOAD" Action
+ *
+ * @param req
+ * @param rsp
+ *
+ * @return
+ */
+ protected boolean handleUnloadAction(SolrQueryRequest req, SolrQueryResponse rsp) throws SolrException {
+ SolrParams params = req.getParams();
+ String cname = params.get(CoreAdminParams.CORE);
+ SolrCore core = coreContainer.remove(cname);
+ core.close();
+ return coreContainer.isPersistent();
+
+ }
+
+ /**
+ * Handle "STATUS" action
+ *
+ * @param req
+ * @param rsp
+ *
+ * @return
+ */
+ protected boolean handleStatusAction(SolrQueryRequest req, SolrQueryResponse rsp)
+ throws SolrException {
+ SolrParams params = req.getParams();
+
+ String cname = params.get(CoreAdminParams.CORE);
+ boolean doPersist = false;
+ NamedList<Object> status = new SimpleOrderedMap<Object>();
+ try {
+ if (cname == null) {
+ for (String name : coreContainer.getCoreNames()) {
+ status.add(name, getCoreStatus(coreContainer, name));
+ }
+ } else {
+ status.add(cname, getCoreStatus(coreContainer, cname));
+ }
+ rsp.add("status", status);
+ doPersist = false; // no state change
+ return doPersist;
+ } catch (Exception ex) {
+ throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
+ "Error handling 'status' action ", ex);
+ }
+ }
+
+ /**
+ * Handler "PERSIST" action
+ *
+ * @param req
+ * @param rsp
+ *
+ * @return
+ *
+ * @throws SolrException
+ */
+ protected boolean handlePersistAction(SolrQueryRequest req, SolrQueryResponse rsp)
+ throws SolrException {
+ SolrParams params = req.getParams();
+ boolean doPersist = false;
+ String fileName = params.get(CoreAdminParams.FILE);
+ if (fileName != null) {
+ File file = new File(coreContainer.getConfigFile().getParentFile(), fileName);
+ coreContainer.persistFile(file);
+ rsp.add("saved", file.getAbsolutePath());
+ doPersist = false;
+ } else if (!coreContainer.isPersistent()) {
+ throw new SolrException(SolrException.ErrorCode.FORBIDDEN, "Persistence is not enabled");
+ } else
+ doPersist = true;
+
+ return doPersist;
+ }
+
+ /**
+ * Handler "RELOAD" action
+ *
+ * @param req
+ * @param rsp
+ *
+ * @return
+ */
+ protected boolean handleReloadAction(SolrQueryRequest req, SolrQueryResponse rsp) {
+ SolrParams params = req.getParams();
+ String cname = params.get(CoreAdminParams.CORE);
+ try {
+ coreContainer.reload(cname);
+ return false; // no change on reload
+ } catch (Exception ex) {
+ throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Error handling 'reload' action", ex);
+ }
+ }
+
+ /**
+ * Handle "SWAP" action
+ *
+ * @param req
+ * @param rsp
+ *
+ * @return
+ */
+ protected boolean handleSwapAction(SolrQueryRequest req, SolrQueryResponse rsp) {
+ final SolrParams params = req.getParams();
+ final SolrParams required = params.required();
+
+ final String cname = params.get(CoreAdminParams.CORE);
+ boolean doPersist = params.getBool(CoreAdminParams.PERSISTENT, coreContainer.isPersistent());
+ String other = required.get(CoreAdminParams.OTHER);
+ coreContainer.swap(cname, other);
+ return doPersist;
+
+ }
+
+ protected static NamedList<Object> getCoreStatus(CoreContainer cores, String cname) throws IOException {
NamedList<Object> info = new SimpleOrderedMap<Object>();
SolrCore core = cores.getCore(cname);
if (core != null) {
@@ -227,15 +395,15 @@
return info;
}
- private static String normalizePath(String path) {
+ protected static String normalizePath(String path) {
if (path == null)
return null;
path = path.replace('/', File.separatorChar);
path = path.replace('\\', File.separatorChar);
return path;
}
-
-
+
+
//////////////////////// SolrInfoMBeans methods //////////////////////
@Override