要完成solr的索引動態配置,須要solr提供動態新建、修改配置等的接口。solr雖提供core的添加刪除,但不提供schema.xml修改新建接口,而且若是添加一個新core,也要將另外一個core的conf配置文件複製一份到新的core文件夾下,而後管理頁載入新的core。所以須要二次開發。
查看solr的web.xml,能夠發現請求連接都進入org.apache.solr.servlet.SolrDispatchFilter。查看SolrDispatchFilter源碼,能夠在doFilter方式裏看到,若是是adminPath的連接,則SolrRequestHandler的實現是cores.getMultiCoreHandler()。 java
進入getMultiCoreHandler()方法,能夠得知是org.apache.solr.handler.admin.CoreAdminHandler。此類則是solr管理界面的Core Admin的接口處理類。所以,能夠繼承CoreAdminHandler,重載handleRequestBody方法來給solr增長所需的處理接口。web
進一步查看源碼,能夠發現solr.xml裏能夠用adminHandler標籤替換CoreAdminHandler。solr.xml:apache
<?xml version="1.0" encoding="UTF-8" ?> <solr persistent="true"> <cores defaultCoreName="default" adminHandler="org.apache.solr.handler.admin.EdenCoreAdminHandler" adminPath="/admin/cores" zkClientTimeout="${zkClientTimeout:15000}" hostPort="8080" hostContext="solr"> <core instanceDir="core0\" name="core0"/> <core instanceDir="default\" name="default"/> <core instanceDir="periodical\" name="periodical"/> </cores> </solr>
EdenCoreAdminHandler:ide
public class EdenCoreAdminHandler extends CoreAdminHandler { public EdenCoreAdminHandler() { } public EdenCoreAdminHandler(final CoreContainer coreContainer) { super(coreContainer); } public CoreContainer getCoreContainer() { return this.coreContainer; } @Override public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception { CoreContainer cores = getCoreContainer(); if (cores == null) { throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Core container instance missing"); } String action = req.getParams().get(CoreAdminParams.ACTION); //String newCoreName=req.getParams().get("newCoreName"); if (action!=null&&action.equals("ADDNEWCORE")) { doAddCore( req, rsp); }else if (action!=null&&action.equals("CHANGESCHEMA")) { changeSchemaXml(req, rsp); }else if (action!=null&&action.equals("DELCORE")) { delCore(req, rsp); }else{ super.handleRequestBody( req, rsp); } } /** * 添加core *將默認core下conf裏的solrconfig.xml和schema.xml拷貝到新core的conf下。這步是必須的 *由於新建的core solr會去其conf文件夾下找這兩個文件,若是沒有就會報錯,新core則不會建立成功 * @param req * @param rsp * @throws Exception */ public void doAddCore(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception { CoreContainer cores = getCoreContainer(); String defaultCoreName= cores.getDefaultCoreName(); SolrCore core=cores.getCore(defaultCoreName); final SolrResourceLoader loader = core.getResourceLoader(); File srcCoredir = new File(loader.getInstanceDir()); if (!srcCoredir.exists()) { throw new SolrException(ErrorCode.FORBIDDEN, "當前core不存在!"); } String newCoreName=req.getParams().get(CoreAdminParams.NAME); if (newCoreName==null||newCoreName.equals("")) { throw new SolrException(ErrorCode.FORBIDDEN, "name不能爲空!"); } if (coreContainer.getCore(newCoreName) != null) { throw new SolrException(ErrorCode.FORBIDDEN, "已經建立了"+newCoreName+"的core!"); } String solrHome=srcCoredir.getParent(); String srcConfPath= solrHome+File.separator+"default"+ File.separator+"conf"; //複製default文件夾 String fromCoreName=req.getParams().get(CoreAdminParams.OTHER); if(fromCoreName!=null&&!fromCoreName.equals("")) //若是有參數,則用這個的配置 { SolrCore fromcore=cores.getCore(fromCoreName); SolrResourceLoader fromcoreLoader = fromcore.getResourceLoader(); srcConfPath=fromcoreLoader.getConfigDir(); } // 創建新core所在文件夾 File newCorePath = new File(solrHome + File.separator + newCoreName); if (!newCorePath.exists()) { newCorePath.mkdir(); } // 創建新core下的conf文件夾 File newConfPath = new File(newCorePath.getAbsolutePath() + File.separator + "conf/"); if (!newConfPath.exists()) { newConfPath.mkdir(); } boolean doPersist=this.handleCreateAction(req, rsp); if (doPersist) { cores.persist(); rsp.add("saved", cores.getConfigFile().getAbsolutePath()); } rsp.setHttpCaching(false); } ....... @Override public String getDescription() { return "add new core"; } @Override public String getSource() { return null; } }
同時solrj也要擴展新接口的請求方法。按照solrj源碼裏的請求方式。post
EdenCoreAdminParams:this
public class EdenCoreAdminParams implements CoreAdminParams{ public enum EdenCoreAdminAction { CORESINFO, ADDNEWCORE, CHANGESCHEMA, DELCORE; public static CoreAdminAction get( String p ) { if( p != null ) { try { return CoreAdminAction.valueOf( p.toUpperCase(Locale.ROOT) ); } catch( Exception ex ) {} } return null; } } }
EdenSchemaUpdateRequest(動態修改schema.xml):spa
public class EdenSchemaUpdateRequest extends AbstractUpdateRequest{ private String xmlContent=null; public EdenSchemaUpdateRequest( String path) { super(METHOD.POST, path); } @Override public Collection<ContentStream> getContentStreams() throws IOException { return ClientUtils.toContentStreams(getXmlContent(), ClientUtils.TEXT_XML); } public String getXmlContent() { return xmlContent; } public void setXmlContent(String xmlContent) { this.xmlContent = xmlContent; } }
EdenCoreAdminRequest:code
/** * solrj CoreAdminRequest擴展 * @author hanxuetong * */ @SuppressWarnings("serial") public class EdenCoreAdminRequest extends CoreAdminRequest{ protected ModifiableSolrParams params; protected EdenCoreAdminAction edenAction; @Override public SolrParams getParams() { if(params==null) { params = new ModifiableSolrParams(); } if( edenAction == null&¶ms==null ) { //使用原來的 return super.getParams(); } if(edenAction==null||edenAction.equals(EdenCoreAdminAction.CORESINFO) ) //直接查詢全部信息 { return params; } params.set( EdenCoreAdminParams.ACTION, edenAction.toString() ); params.set( EdenCoreAdminParams.NAME, core ); if(other!=null) { params.set( EdenCoreAdminParams.OTHER, other ); } return params; } public void setParams(ModifiableSolrParams params) { this.params = params; } public void setEdenAction(EdenCoreAdminAction edenAction) { this.edenAction = edenAction; } public static class DelCore extends EdenCoreAdminRequest { protected String deleteDir; public DelCore(String deleteDir) { edenAction=EdenCoreAdminAction.DELCORE; this.deleteDir = deleteDir; } public String isDeleteDir() { return deleteDir; } public void setDeleteDir(String deleteDir) { this.deleteDir = deleteDir; } @Override public SolrParams getParams() { ModifiableSolrParams params = new ModifiableSolrParams(); params.set( EdenCoreAdminParams.ACTION, edenAction.toString()); params.set( EdenCoreAdminParams.CORE, core ); if(deleteDir!=null) { params.set("deleteDir", deleteDir); } return params; } } public static CoreAdminResponse delCore( String name, String deleteDir, SolrServer server ) throws SolrServerException, IOException { DelCore req = new DelCore(deleteDir); req.setCoreName( name ); return req.process( server ); } }
EdenSolrCoresRequest:server
/** * solr控制檯管理交互類 * @author hanxuetong * */ public class EdenSolrCoresRequest { /** * 得到全部core信息 * @return * @throws IOException * @throws SolrServerException */ public static NamedList<NamedList<Object>> getSolrCoresInfo(HttpSolrServer rootServer) throws SolrServerException, IOException { EdenCoreAdminRequest req = new EdenCoreAdminRequest(); req.setEdenAction( EdenCoreAdminAction.CORESINFO ); CoreAdminResponse list = req.process( rootServer ); NamedList<NamedList<Object>> coresInfoList=list.getCoreStatus(); return coresInfoList; } /** * 獲取某一core信息 * @param coreName * @param rootServer * @return * @throws SolrServerException * @throws IOException */ public static NamedList<Object> getSolrOneCoreInfo(String coreName,HttpSolrServer rootServer) throws SolrServerException, IOException { NamedList<Object> list = EdenCoreAdminRequest .getStatus(coreName, rootServer) .getCoreStatus() .get(coreName); return list; } /** * 添加core,默認 * @param newCoreName * @param rootServer * @throws SolrServerException * @throws IOException */ public static void addCore(String newCoreName,HttpSolrServer rootServer) throws SolrServerException, IOException { EdenCoreAdminRequest req = new EdenCoreAdminRequest(); req.setCoreName(newCoreName); req.setEdenAction(EdenCoreAdminAction.ADDNEWCORE); CoreAdminResponse list = req.process(rootServer); int state = list.getStatus(); if (state != 0) { throw new SolrServerException("添加core失敗!"); } } /** * 添加core * @param newCoreName * @param from 複製的core配置 * @throws SolrServerException * @throws IOException */ public static void addCore(String newCoreName,String from,HttpSolrServer rootServer) throws SolrServerException, IOException { EdenCoreAdminRequest req = new EdenCoreAdminRequest(); req.setCoreName(newCoreName); req.setEdenAction(EdenCoreAdminAction.ADDNEWCORE); req.setOtherCoreName(from); CoreAdminResponse list = req.process(rootServer); int state = list.getStatus(); if (state != 0) { throw new SolrServerException("添加core失敗!"); } } /** * 獲取schema.xml內容 * @param coreName * @param rootServer * @return * @throws SolrServerException * @throws IOException */ public static String getSchemaXmlContent(String coreName,HttpSolrServer rootServer) throws SolrServerException, IOException { ModifiableSolrParams params = new ModifiableSolrParams(); params.set("file", "schema.xml"); params.set("contentType", "text/xml;charset=utf-8"); EdenCoreAdminRequest req = new EdenCoreAdminRequest(); req.setPath("/" + coreName + "/admin/file"); req.setParams(params); NamedList<Object> ob = rootServer.request(req, null); InputStream respBody = (InputStream) ob.get("stream"); String con=StringStreamUtil.convertStreamToString(respBody); return con; } /** * 遠程修改schema.xml的內容 * @param coreName * @param xmlContent * @param rootServer * @throws SolrServerException * @throws IOException */ public static void postSchemaXmlContent(String coreName,String xmlContent,HttpSolrServer rootServer) throws SolrServerException, IOException { EdenSchemaUpdateRequest edenSchemaUpdateRequest=new EdenSchemaUpdateRequest("/admin/cores"); edenSchemaUpdateRequest.setParam("name", coreName); edenSchemaUpdateRequest.setParam("action", "CHANGESCHEMA"); edenSchemaUpdateRequest.setXmlContent(xmlContent); UpdateResponse rep=edenSchemaUpdateRequest.process(rootServer); int state = rep.getStatus(); if (state != 0) { throw new SolrServerException("postSchemaXml失敗!"); } } /** * 從新加載core * @param coreName * @param rootServer * @throws SolrServerException * @throws IOException */ public static void reloadCore(String coreName,HttpSolrServer rootServer) throws SolrServerException, IOException { CoreAdminRequest req = new CoreAdminRequest(); req.setAction(CoreAdminAction.RELOAD); req.setCoreName(coreName); CoreAdminResponse list = req.process(rootServer); int state = list.getStatus(); if (state != 0) { throw new SolrServerException("reload失敗!"); } } /*** * 加載core * @param coreName * @param rootServer * @throws SolrServerException * @throws IOException */ public static void loadCore(String coreName,HttpSolrServer rootServer) throws SolrServerException, IOException { CoreAdminRequest req = new CoreAdminRequest(); req.setAction(CoreAdminAction.LOAD); req.setCoreName(coreName); CoreAdminResponse list = req.process(rootServer); int state = list.getStatus(); if (state != 0) { throw new SolrServerException("load失敗!"); } } /** * 刪除core * @param coreName * @param isDeleteDir 是否刪除文件夾 * @param rootServer * @throws SolrServerException * @throws IOException */ public static void delCore(String coreName,boolean isDeleteDir,HttpSolrServer rootServer) throws SolrServerException, IOException { String instanceDir=null; if(isDeleteDir) { NamedList<Object> list = EdenCoreAdminRequest .getStatus(coreName, rootServer) .getCoreStatus() .get(coreName); instanceDir=(String) list.get("instanceDir"); } int state= EdenCoreAdminRequest .delCore(coreName, instanceDir, rootServer) .getStatus(); if (state != 0) { throw new SolrServerException("delCore失敗!"); } } /** * 兩個core交換 * @param coreName * @param otherCore * @param rootServer * @throws SolrServerException * @throws IOException */ public static void swap(String coreName,String otherCore,HttpSolrServer rootServer) throws SolrServerException, IOException { CoreAdminRequest req = new CoreAdminRequest(); req.setAction(CoreAdminAction.SWAP); req.setCoreName(coreName); req.setOtherCoreName(otherCore); CoreAdminResponse list = req.process(rootServer); int state = list.getStatus(); if (state != 0) { throw new SolrServerException("swap失敗!"); } } public static void main(String[] args) { HttpSolrServer server = new HttpSolrServer("http://localhost:8082/solr"); /*try { swap("newsss","dddsdd",server); } catch (SolrServerException e) { e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } */ try { delCore( "oa_car5", false, server); } catch (SolrServerException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }