public static void updateHelixInstanceConfig(InstanceConfig instanceConfig, Instance instance) {
    ZNRecord znRecord = instanceConfig.getRecord();

    Map<String, String> simpleFields = znRecord.getSimpleFields();
    simpleFields.put(InstanceConfig.InstanceConfigProperty.HELIX_HOST.name(), instance.getHost());
    simpleFields.put(InstanceConfig.InstanceConfigProperty.HELIX_PORT.name(), Integer.toString(instance.getPort()));
    int grpcPort = instance.getGrpcPort();
    if (grpcPort > 0) {
      simpleFields.put(Helix.Instance.GRPC_PORT_KEY, Integer.toString(grpcPort));
    } else {
      simpleFields.remove(Helix.Instance.GRPC_PORT_KEY);
    }
    int adminPort = instance.getAdminPort();
    if (adminPort > 0) {
      simpleFields.put(Helix.Instance.ADMIN_PORT_KEY, Integer.toString(adminPort));
    } else {
      simpleFields.remove(Helix.Instance.ADMIN_PORT_KEY);
    }
    int queryServicePort = instance.getQueryServicePort();
    if (queryServicePort > 0) {
      simpleFields.put(Helix.Instance.MULTI_STAGE_QUERY_ENGINE_SERVICE_PORT_KEY, Integer.toString(queryServicePort));
    } else {
      simpleFields.remove(Helix.Instance.MULTI_STAGE_QUERY_ENGINE_SERVICE_PORT_KEY);
    }
    int queryMailboxPort = instance.getQueryMailboxPort();
    if (queryMailboxPort > 0) {
      simpleFields.put(Helix.Instance.MULTI_STAGE_QUERY_ENGINE_MAILBOX_PORT_KEY, Integer.toString(queryMailboxPort));
    } else {
      simpleFields.remove(Helix.Instance.MULTI_STAGE_QUERY_ENGINE_MAILBOX_PORT_KEY);
    }
    boolean queriesDisabled = instance.isQueriesDisabled();
    if (queriesDisabled) {
      simpleFields.put(Helix.QUERIES_DISABLED, Boolean.toString(true));
    } else {
      simpleFields.remove(Helix.QUERIES_DISABLED);
    }

    Map<String, List<String>> listFields = znRecord.getListFields();
    List<String> tags = instance.getTags();
    String tagsKey = InstanceConfig.InstanceConfigProperty.TAG_LIST.name();
    if (CollectionUtils.isNotEmpty(tags)) {
      listFields.put(tagsKey, tags);
    } else {
      listFields.remove(tagsKey);
    }

    Map<String, Map<String, String>> mapFields = znRecord.getMapFields();
    Map<String, Integer> pools = instance.getPools();
    if (MapUtils.isNotEmpty(pools)) {
      Map<String, String> mapValue = new TreeMap<>();
      for (Map.Entry<String, Integer> entry : pools.entrySet()) {
        mapValue.put(entry.getKey(), entry.getValue().toString());
      }
      mapFields.put(POOL_KEY, mapValue);
    } else {
      mapFields.remove(POOL_KEY);
    }
  }
@Test
  public void testUpdateHelixInstanceConfig() {
    Instance instance =
        new Instance("localhost", 1234, InstanceType.SERVER, Collections.singletonList("DefaultTenant_OFFLINE"), null,
            0, 123, 234, 345, false);
    InstanceConfig instanceConfig = InstanceUtils.toHelixInstanceConfig(instance);

    // Put some custom fields, which should not be updated
    ZNRecord znRecord = instanceConfig.getRecord();
    znRecord.setSimpleField("customSimple", "potato");
    List<String> customList = Arrays.asList("foo", "bar");
    znRecord.setListField("customList", customList);
    Map<String, String> customMap = Collections.singletonMap("foo", "bar");
    znRecord.setMapField("customMap", customMap);

    List<String> tags = Arrays.asList("T1_OFFLINE", "T2_REALTIME");
    Map<String, Integer> poolMap = new TreeMap<>();
    poolMap.put("T1_OFFLINE", 0);
    poolMap.put("T2_REALTIME", 1);
    instance = new Instance("myHost", 2345, InstanceType.SERVER, tags, poolMap, 123, 234, 345, 456, true);
    InstanceUtils.updateHelixInstanceConfig(instanceConfig, instance);

    // Instance name should not change
    assertEquals(instanceConfig.getInstanceName(), "Server_localhost_1234");
    assertTrue(instanceConfig.getInstanceEnabled());
    assertEquals(instanceConfig.getHostName(), "myHost");
    assertEquals(instanceConfig.getPort(), "2345");
    assertEquals(instanceConfig.getTags(), tags);
    znRecord = instanceConfig.getRecord();
    Map<String, String> expectedPoolMap = new TreeMap<>();
    expectedPoolMap.put("T1_OFFLINE", "0");
    expectedPoolMap.put("T2_REALTIME", "1");
    assertEquals(znRecord.getMapField(InstanceUtils.POOL_KEY), expectedPoolMap);
    assertEquals(znRecord.getSimpleField(CommonConstants.Helix.Instance.GRPC_PORT_KEY), "123");
    assertEquals(znRecord.getSimpleField(CommonConstants.Helix.Instance.ADMIN_PORT_KEY), "234");
    assertEquals(znRecord.getSimpleField(CommonConstants.Helix.Instance.MULTI_STAGE_QUERY_ENGINE_SERVICE_PORT_KEY),
        "345");
    assertEquals(znRecord.getSimpleField(CommonConstants.Helix.Instance.MULTI_STAGE_QUERY_ENGINE_MAILBOX_PORT_KEY),
        "456");
    assertEquals(znRecord.getSimpleField(CommonConstants.Helix.QUERIES_DISABLED), "true");

    // Custom fields should be preserved
    assertEquals(znRecord.getSimpleField("customSimple"), "potato");
    assertEquals(znRecord.getListField("customList"), customList);
    assertEquals(znRecord.getMapField("customMap"), customMap);
  }