@Override public InetAddress resolve(String hostName) throws UnknownHostException { // Get ALL IP addresses associated with the requested host. InetAddress[] ipAddresses = getAllAddressesForHost(hostName); // Get-and-increment the atomic int associated with this host, then mod it against the number of instances // available. This effectively round robins the use of all the instances associated with the host. AtomicInteger roundRobinCounter = HOST_ROUND_ROBIN_COUNTER_MAP.computeIfAbsent(hostName, host -> new AtomicInteger(0)); int instanceIndexToUse = roundRobinCounter.getAndIncrement() % ipAddresses.length; if (instanceIndexToUse < 0) { // The counter went high enough to do an integer overflow. Fix the index so we don't blow up this call, // and reset the counter to 0. instanceIndexToUse = Math.abs(instanceIndexToUse); roundRobinCounter.set(0); } return ipAddresses[instanceIndexToUse]; }
throws UnknownHostException { MultiIpAwareNameResolver resolver = spy(new MultiIpAwareNameResolver()); InetAddress[] ipAddresses = new InetAddress[]{ mock(InetAddress.class), mock(InetAddress.class), mock(InetAddress.class) }; String host = UUID.randomUUID().toString(); doReturn(ipAddresses).when(resolver).getAllAddressesForHost(host); resolver.resolve(host); resolver.resolve(host); resolver.resolve(host);
@Test public void multiIpAwareNameResolver_resolve_works_as_expected() throws UnknownHostException { // given MultiIpAwareNameResolver resolver = spy(new MultiIpAwareNameResolver()); InetAddress[] ipAddresses = new InetAddress[]{ mock(InetAddress.class), mock(InetAddress.class), mock(InetAddress.class) }; String host = UUID.randomUUID().toString(); doReturn(ipAddresses).when(resolver).getAllAddressesForHost(host); for (int i = 0; i < (ipAddresses.length * 10); i++) { InetAddress expectedAddress = ipAddresses[i % ipAddresses.length]; // when InetAddress actualAddress = resolver.resolve(host); // then assertThat(actualAddress).isSameAs(expectedAddress); } }