public synchronized DataSet registerAINode(TAINodeRegisterReq req) {

    if (!nodeInfo.getRegisteredAINodes().isEmpty()) {
      AINodeRegisterResp dataSet = new AINodeRegisterResp();
      dataSet.setConfigNodeList(Collections.emptyList());
      dataSet.setStatus(
          new TSStatus(TSStatusCode.REGISTER_AI_NODE_ERROR.getStatusCode())
              .setMessage("There is already one AINode in the cluster."));
      return dataSet;
    }

    int aiNodeId = nodeInfo.generateNextNodeId();
    getLoadManager().getLoadCache().createNodeHeartbeatCache(NodeType.AINode, aiNodeId);
    RegisterAINodePlan registerAINodePlan = new RegisterAINodePlan(req.getAiNodeConfiguration());
    // Register new DataNode
    registerAINodePlan.getAINodeConfiguration().getLocation().setAiNodeId(aiNodeId);
    try {
      getConsensusManager().write(registerAINodePlan);
    } catch (ConsensusException e) {
      LOGGER.warn(CONSENSUS_WRITE_ERROR, e);
    }

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

    AINodeRegisterResp resp = new AINodeRegisterResp();
    resp.setStatus(ClusterNodeStartUtils.ACCEPT_NODE_REGISTRATION);
    resp.setConfigNodeList(getRegisteredConfigNodes());
    resp.setAINodeId(registerAINodePlan.getAINodeConfiguration().getLocation().getAiNodeId());
    return resp;
  }
Register AINode. Use synchronized to make sure

@param req TAINodeRegisterReq
@return AINodeConfigurationDataSet. 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