public DataSet registerDataNode(TDataNodeRegisterReq req) {
    DataNodeRegisterResp resp = new DataNodeRegisterResp();
    resp.setConfigNodeList(getRegisteredConfigNodes());

    // Create a new DataNodeHeartbeatCache and force update NodeStatus
    int dataNodeId = nodeInfo.generateNextNodeId();
    getLoadManager().getLoadCache().createNodeHeartbeatCache(NodeType.DataNode, dataNodeId);
    // TODO: invoke a force heartbeat to update new DataNode's status immediately

    RegisterDataNodePlan registerDataNodePlan =
        new RegisterDataNodePlan(req.getDataNodeConfiguration());
    // Register new DataNode
    registerDataNodePlan.getDataNodeConfiguration().getLocation().setDataNodeId(dataNodeId);
    try {
      getConsensusManager().write(registerDataNodePlan);
    } catch (ConsensusException e) {
      LOGGER.warn(CONSENSUS_WRITE_ERROR, e);
    }

    // update datanode's versionInfo
    UpdateVersionInfoPlan updateVersionInfoPlan =
        new UpdateVersionInfoPlan(req.getVersionInfo(), dataNodeId);
    try {
      getConsensusManager().write(updateVersionInfoPlan);
    } catch (ConsensusException e) {
      LOGGER.warn(CONSENSUS_WRITE_ERROR, e);
    }

    // Bind DataNode metrics
    PartitionMetrics.bindDataNodePartitionMetricsWhenUpdate(
        MetricService.getInstance(), configManager, dataNodeId);

    // Adjust the maximum RegionGroup number of each Database
    getClusterSchemaManager().adjustMaxRegionGroupNum();

    resp.setStatus(ClusterNodeStartUtils.ACCEPT_NODE_REGISTRATION);
    resp.setDataNodeId(
        registerDataNodePlan.getDataNodeConfiguration().getLocation().getDataNodeId());
    resp.setRuntimeConfiguration(getRuntimeConfiguration());
    return resp;
  }
Register DataNode.

@param req TDataNodeRegisterReq
@return DataNodeConfigurationDataSet. The {@link TSStatus} will be set to {@link
    TSStatusCode#SUCCESS_STATUS} when register success.
iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/node/NodeManager.java