要完成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(); } } }