@Override
  public Response replaceLabelsOnNode(Set<String> newNodeLabelsName,
      HttpServletRequest hsr, String nodeId) throws Exception {

    // Step1. Check the parameters to ensure that the parameters are not empty.
    if (StringUtils.isBlank(nodeId)) {
      routerMetrics.incrReplaceLabelsOnNodeFailedRetrieved();
      RouterAuditLogger.logFailure(getUser().getShortUserName(), REPLACE_LABELSONNODE, UNKNOWN,
          TARGET_WEB_SERVICE, "Parameter error, nodeId must not be null or empty.");
      throw new IllegalArgumentException("Parameter error, nodeId must not be null or empty.");
    }
    if (CollectionUtils.isEmpty(newNodeLabelsName)) {
      routerMetrics.incrReplaceLabelsOnNodeFailedRetrieved();
      RouterAuditLogger.logFailure(getUser().getShortUserName(), REPLACE_LABELSONNODE, UNKNOWN,
          TARGET_WEB_SERVICE, "Parameter error, newNodeLabelsName must not be empty.");
      throw new IllegalArgumentException("Parameter error, newNodeLabelsName must not be empty.");
    }

    try {
      // Step2. We find the subCluster according to the nodeId,
      // and then call the replaceLabelsOnNode of the subCluster.
      long startTime = clock.getTime();
      SubClusterInfo subClusterInfo = getNodeSubcluster(nodeId);
      DefaultRequestInterceptorREST interceptor = getOrCreateInterceptorByNodeId(nodeId);
      final HttpServletRequest hsrCopy = clone(hsr);
      interceptor.replaceLabelsOnNode(newNodeLabelsName, hsrCopy, nodeId);

      // Step3. Return the response result.
      long stopTime = clock.getTime();
      RouterAuditLogger.logSuccess(getUser().getShortUserName(), REPLACE_LABELSONNODE,
          TARGET_WEB_SERVICE);
      routerMetrics.succeededReplaceLabelsOnNodeRetrieved(stopTime - startTime);
      String msg = "subCluster#" + subClusterInfo.getSubClusterId().getId() + ":Success;";
      return Response.status(Status.OK).entity(msg).build();
    } catch (Exception e) {
      routerMetrics.incrReplaceLabelsOnNodeFailedRetrieved();
      RouterAuditLogger.logFailure(getUser().getShortUserName(), REPLACE_LABELSONNODE, UNKNOWN,
          TARGET_WEB_SERVICE, e.getLocalizedMessage());
      throw e;
    }
  }
@Test
  public void testReplaceLabelsOnNodeError() throws Exception {
    // newNodeToLabels is null
    String nodeId = "node3:3";
    Set<String> labels = Collections.singleton("NodeLabel3");
    Set<String> labelsEmpty = new HashSet<>();

    // nodeId is null
    LambdaTestUtils.intercept(IllegalArgumentException.class,
        "Parameter error, nodeId must not be null or empty.",
        () -> interceptor.replaceLabelsOnNode(labels, null, null));

    // labels is null
    LambdaTestUtils.intercept(IllegalArgumentException.class,
        "Parameter error, newNodeLabelsName must not be empty.",
        () -> interceptor.replaceLabelsOnNode(null, null, nodeId));

    // labels is empty
    LambdaTestUtils.intercept(IllegalArgumentException.class,
        "Parameter error, newNodeLabelsName must not be empty.",
        () -> interceptor.replaceLabelsOnNode(labelsEmpty, null, nodeId));
  }