/** * Handle 'CREATE' action. * * @param req * @param rsp * @return true if a modification has resulted that requires persistance of the CoreContainer * configuration. * @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); // Process all property.name=value parameters and set them as name=value core properties Properties coreProperties = new Properties(); Iterator<String> parameterNamesIterator = params.getParameterNamesIterator(); while (parameterNamesIterator.hasNext()) { String parameterName = parameterNamesIterator.next(); if (parameterName.startsWith(CoreAdminParams.PROPERTY_PREFIX)) { String parameterValue = params.get(parameterName); String propertyName = parameterName.substring(CoreAdminParams.PROPERTY_PREFIX.length()); // skip prefix coreProperties.put(propertyName, parameterValue); } } dcore.setCoreProperties(coreProperties); 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); } }
public DistributedUpdateProcessor( SolrQueryRequest req, SolrQueryResponse rsp, UpdateRequestProcessor next) { super(next); this.rsp = rsp; this.next = next; this.idField = req.getSchema().getUniqueKeyField(); // version init this.updateHandler = req.getCore().getUpdateHandler(); this.ulog = updateHandler.getUpdateLog(); this.vinfo = ulog == null ? null : ulog.getVersionInfo(); versionsStored = this.vinfo != null && this.vinfo.getVersionField() != null; returnVersions = req.getParams().getBool(UpdateParams.VERSIONS, false); // TODO: better way to get the response, or pass back info to it? SolrRequestInfo reqInfo = returnVersions ? SolrRequestInfo.getRequestInfo() : null; this.req = req; CoreDescriptor coreDesc = req.getCore().getCoreDescriptor(); this.zkEnabled = coreDesc.getCoreContainer().isZooKeeperAware(); zkController = req.getCore().getCoreDescriptor().getCoreContainer().getZkController(); if (zkEnabled) { numNodes = zkController.getZkStateReader().getClusterState().getLiveNodes().size(); cmdDistrib = new SolrCmdDistributor( numNodes, coreDesc.getCoreContainer().getZkController().getCmdDistribExecutor()); } // this.rsp = reqInfo != null ? reqInfo.getRsp() : null; cloudDesc = coreDesc.getCloudDescriptor(); if (cloudDesc != null) { collection = cloudDesc.getCollectionName(); } }
@Test public void testCoreAdminHandler() throws Exception { final File workDir = createTempDir().toFile(); final CoreContainer cores = h.getCoreContainer(); final CoreAdminHandler admin = new CoreAdminHandler(cores); Path instDir; try (SolrCore template = cores.getCore("collection1")) { assertNotNull(template); instDir = template.getCoreDescriptor().getInstanceDir(); } assertTrue("instDir doesn't exist: " + instDir, Files.exists(instDir)); final File instPropFile = new File(workDir, "instProp"); FileUtils.copyDirectory(instDir.toFile(), instPropFile); SolrQueryResponse resp = new SolrQueryResponse(); // Sneaking in a test for using a bad core name try { admin.handleRequestBody( req( CoreAdminParams.ACTION, CoreAdminParams.CoreAdminAction.CREATE.toString(), CoreAdminParams.INSTANCE_DIR, instPropFile.getAbsolutePath(), CoreAdminParams.NAME, "ugly$core=name"), resp); } catch (SolrException se) { assertTrue( "Expected error message for bad core name.", se.toString().contains("Invalid core")); } CoreDescriptor cd = cores.getCoreDescriptor("ugly$core=name"); assertNull("Should NOT have added this core!", cd); // create a new core (using CoreAdminHandler) w/ properties admin.handleRequestBody( req( CoreAdminParams.ACTION, CoreAdminParams.CoreAdminAction.CREATE.toString(), CoreAdminParams.INSTANCE_DIR, instPropFile.getAbsolutePath(), CoreAdminParams.NAME, "props", CoreAdminParams.PROPERTY_PREFIX + "hoss", "man", CoreAdminParams.PROPERTY_PREFIX + "foo", "baz"), resp); assertNull("Exception on create", resp.getException()); cd = cores.getCoreDescriptor("props"); assertNotNull("Core not added!", cd); assertEquals(cd.getCoreProperty("hoss", null), "man"); assertEquals(cd.getCoreProperty("foo", null), "baz"); // attempt to create a bogus core and confirm failure ignoreException("Could not load config"); try { resp = new SolrQueryResponse(); admin.handleRequestBody( req( CoreAdminParams.ACTION, CoreAdminParams.CoreAdminAction.CREATE.toString(), CoreAdminParams.NAME, "bogus_dir_core", CoreAdminParams.INSTANCE_DIR, "dir_does_not_exist_127896"), resp); fail("bogus collection created ok"); } catch (SolrException e) { // :NOOP: // :TODO: CoreAdminHandler's exception messages are terrible, otherwise we could assert // something useful here } unIgnoreException("Could not load config"); // check specifically for status of the failed core name resp = new SolrQueryResponse(); admin.handleRequestBody( req( CoreAdminParams.ACTION, CoreAdminParams.CoreAdminAction.STATUS.toString(), CoreAdminParams.CORE, "bogus_dir_core"), resp); Map<String, Exception> failures = (Map<String, Exception>) resp.getValues().get("initFailures"); assertNotNull("core failures is null", failures); NamedList<Object> status = (NamedList<Object>) resp.getValues().get("status"); assertNotNull("core status is null", status); assertEquals("wrong number of core failures", 1, failures.size()); Exception fail = failures.get("bogus_dir_core"); assertNotNull("null failure for test core", fail); assertTrue( "init failure doesn't mention problem: " + fail.getCause().getMessage(), 0 < fail.getCause().getMessage().indexOf("dir_does_not_exist")); assertEquals( "bogus_dir_core status isn't empty", 0, ((NamedList) status.get("bogus_dir_core")).size()); // Try renaming the core, we should fail // First assert that the props core exists cd = cores.getCoreDescriptor("props"); assertNotNull("Core disappeared!", cd); // now rename it something else just for kicks since we don't actually test this that I could // find. admin.handleRequestBody( req( CoreAdminParams.ACTION, CoreAdminParams.CoreAdminAction.RENAME.toString(), CoreAdminParams.CORE, "props", CoreAdminParams.OTHER, "rename_me"), resp); cd = cores.getCoreDescriptor("rename_me"); assertNotNull("Core should have been renamed!", cd); // Rename it something bogus and see if you get an exception, the old core is still there and // the bogus one isn't try { admin.handleRequestBody( req( CoreAdminParams.ACTION, CoreAdminParams.CoreAdminAction.RENAME.toString(), CoreAdminParams.CORE, "rename_me", CoreAdminParams.OTHER, "bad$name"), resp); } catch ( SolrException e) { // why the heck does create return a SolrException (admittedly wrapping an IAE) assertTrue( "Expected error message for bad core name.", e.getMessage().contains("Invalid core")); } cd = cores.getCoreDescriptor("bad$name"); assertNull("Core should NOT exist!", cd); cd = cores.getCoreDescriptor("rename_me"); assertNotNull("Core should have been renamed!", cd); // :TODO: because of SOLR-3665 we can't ask for status from all cores }
private void syncToMe( ZkController zkController, String collection, String shardId, ZkNodeProps leaderProps, CoreDescriptor cd) { // sync everyone else // TODO: we should do this in parallel at least List<ZkCoreNodeProps> nodes = zkController .getZkStateReader() .getReplicaProps(collection, shardId, cd.getCloudDescriptor().getCoreNodeName()); if (nodes == null) { log.info(ZkCoreNodeProps.getCoreUrl(leaderProps) + " has no replicas"); return; } ZkCoreNodeProps zkLeader = new ZkCoreNodeProps(leaderProps); for (ZkCoreNodeProps node : nodes) { try { log.info( ZkCoreNodeProps.getCoreUrl(leaderProps) + ": try and ask " + node.getCoreUrl() + " to sync"); requestSync( node.getBaseUrl(), node.getCoreUrl(), zkLeader.getCoreUrl(), node.getCoreName()); } catch (Exception e) { SolrException.log(log, "Error syncing replica to leader", e); } } for (; ; ) { ShardResponse srsp = shardHandler.takeCompletedOrError(); if (srsp == null) break; boolean success = handleResponse(srsp); if (srsp.getException() != null) { SolrException.log(log, "Sync request error: " + srsp.getException()); } if (!success) { try { log.info( ZkCoreNodeProps.getCoreUrl(leaderProps) + ": Sync failed - asking replica (" + srsp.getShardAddress() + ") to recover."); if (isClosed) { log.info("We have been closed, don't request that a replica recover"); } else { requestRecovery( leaderProps, ((ShardCoreRequest) srsp.getShardRequest()).baseUrl, ((ShardCoreRequest) srsp.getShardRequest()).coreName); } } catch (Exception e) { SolrException.log( log, ZkCoreNodeProps.getCoreUrl(leaderProps) + ": Could not tell a replica to recover", e); } } else { log.info( ZkCoreNodeProps.getCoreUrl(leaderProps) + ": " + " sync completed with " + srsp.getShardAddress()); } } }