/**
   * 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

  }
Example #4
0
  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());
      }
    }
  }