private DistributedLock getDistributedLockWithDedicatedZkClient(String resource, String userId, String reason,
      String zkConnectionStr) throws Exception {
    LockScope distributedLockScope =
        new HelixLockScope(HelixLockScope.LockScopeProperty.RESOURCE, Arrays.asList(clusterName, resource));
    String scopePath = distributedLockScope.getPath();
    long leaseTimeout = clusterMapConfig.clustermapDistributedLockLeaseTimeoutInMs;
    int priority = 0;
    int waitingTimeout = Integer.MAX_VALUE;
    int cleanupTimeout = 0;
    boolean isForceful = false;

    Constructor<ZKDistributedNonblockingLock> constructor = getConstructorForZkDistributedLock();
    assertNotNull(constructor);
    ZKDistributedNonblockingLock zkLock =
        constructor.newInstance(scopePath, leaseTimeout, reason, userId, priority, waitingTimeout, cleanupTimeout,
            isForceful, null,
            new ZkBaseDataAccessor<ZNRecord>(zkConnectionStr, ZkBaseDataAccessor.ZkClientType.DEDICATED));

    return new HelixParticipant.DistributedLockImpl(zkLock);
  }
This is a hacky way to create distributed lock with different zookeeper connection.
@param resource The resource to lock
@param userId The user id for the lock
@param reason The reason to acquire the lock
@param zkConnectionStr The zookeeper server
@return A {@link DistributedLock}.
@throws Exception
ambry-clustermap/src/test/java/com/github/ambry/clustermap/HelixParticipantTest.java