public void testFromHost() { HostAndPort hp = HostAndPort.fromHost("gmail.com"); assertEquals("gmail.com", hp.getHost()); assertFalse(hp.hasPort()); hp = HostAndPort.fromHost("[::1]"); assertEquals("::1", hp.getHost()); assertFalse(hp.hasPort()); try { HostAndPort.fromHost("gmail.com:80"); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException expected) { } try { HostAndPort.fromHost("[gmail.com]"); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException expected) { } }
public void testHashCodeAndEquals() { HostAndPort hpNoPort1 = HostAndPort.fromString("foo::123"); HostAndPort hpNoPort2 = HostAndPort.fromString("foo::123"); HostAndPort hpNoPort3 = HostAndPort.fromString("[foo::123]"); HostAndPort hpNoPort4 = HostAndPort.fromHost("[foo::123]"); HostAndPort hpNoPort5 = HostAndPort.fromHost("foo::123"); HostAndPort hpWithPort1 = HostAndPort.fromParts("[foo::123]", 80); HostAndPort hpWithPort2 = HostAndPort.fromParts("foo::123", 80); HostAndPort hpWithPort3 = HostAndPort.fromString("[foo::123]:80"); new EqualsTester() .addEqualityGroup(hpNoPort1, hpNoPort2, hpNoPort3, hpNoPort4, hpNoPort5) .addEqualityGroup(hpWithPort1, hpWithPort2, hpWithPort3) .testEquals(); }
/** * Removes a port from a host+port if the string contains the specified port. If the host+port does not contain * a port, or contains another port, the string is returned unaltered. For example, if hostWithPort is the * string {@code www.website.com:443}, this method will return {@code www.website.com}. * * <b>Note:</b> The hostWithPort string is not a URI and should not contain a scheme or resource. This method does * not attempt to validate the specified host; it <i>might</i> throw IllegalArgumentException if there was a problem * parsing the hostname, but makes no guarantees. In general, it should be validated externally, if necessary. * * @param hostWithPort string containing a hostname and optional port * @param portNumber port to remove from the string * @return string with the specified port removed, or the original string if it did not contain the portNumber */ public static String removeMatchingPort(String hostWithPort, int portNumber) { HostAndPort parsedHostAndPort = HostAndPort.fromString(hostWithPort); if (parsedHostAndPort.hasPort() && parsedHostAndPort.getPort() == portNumber) { // HostAndPort.getHostText() strips brackets from ipv6 addresses, so reparse using fromHost return HostAndPort.fromHost(parsedHostAndPort.getHost()).toString(); } else { return hostWithPort; } }
@Test public void shouldRedirectToOtherHosts() { HostAndPort otherHost = HostAndPort.fromHost("otherhost"); AtomicReference<LeaderElectionService.LeadershipToken> reference = new AtomicReference<>(); when(mockLeader.getSuspectedLeaderInMemory()).thenReturn(Optional.of(otherHost)); AwaitingLeadershipProxy<Runnable> proxy = AwaitingLeadershipProxy.proxyForTest(delegateSupplier, mockLeader, Runnable.class, reference); assertThatThrownBy(proxy::getLeadershipToken).isInstanceOf(NotCurrentLeaderException.class) .hasMessageContaining("hinting suspected leader host otherhost"); }
@Test public void shouldNotRedirectToItself() { HostAndPort localHost = HostAndPort.fromHost("localhost"); AtomicReference<LeaderElectionService.LeadershipToken> reference = new AtomicReference<>(); // This is a hacky way to "gain leadership" whilst checking the leader in memory. Answer<Optional<HostAndPort>> answer = invocation -> { reference.set(leadershipToken); return Optional.of(localHost); }; when(mockLeader.getSuspectedLeaderInMemory()).then(answer); AwaitingLeadershipProxy<Runnable> proxy = AwaitingLeadershipProxy.proxyForTest(delegateSupplier, mockLeader, Runnable.class, reference); LeaderElectionService.LeadershipToken token = proxy.getLeadershipToken(); assertEquals(token, leadershipToken); }
@Test public void weAreOneOfThePotentialLeaders() throws Exception { PingableLeader other = mock(PingableLeader.class); PaxosLeaderElectionService service = new PaxosLeaderElectionServiceBuilder() .proposer(mock(PaxosProposer.class)) .knowledge(mock(PaxosLearner.class)) .potentialLeadersToHosts(ImmutableMap.of(other, HostAndPort.fromHost("other"))) .acceptors(ImmutableList.of()) .learners(ImmutableList.of()) .executor(Executors.newSingleThreadExecutor()) .pingRateMs(0L) .randomWaitBeforeProposingLeadershipMs(0L) .leaderPingResponseWaitMs(0L) .eventRecorder(mock(PaxosLeadershipEventRecorder.class)) .onlyLogOnQuorumFailure(() -> true) .build(); assertThat(service.getPotentialLeaders()).containsExactlyInAnyOrder(other, service); }
/** * Removes a port from a host+port if the string contains the specified port. If the host+port does not contain * a port, or contains another port, the string is returned unaltered. For example, if hostWithPort is the * string {@code www.website.com:443}, this method will return {@code www.website.com}. * * <b>Note:</b> The hostWithPort string is not a URI and should not contain a scheme or resource. This method does * not attempt to validate the specified host; it <i>might</i> throw IllegalArgumentException if there was a problem * parsing the hostname, but makes no guarantees. In general, it should be validated externally, if necessary. * * @param hostWithPort string containing a hostname and optional port * @param portNumber port to remove from the string * @return string with the specified port removed, or the original string if it did not contain the portNumber */ public static String removeMatchingPort(String hostWithPort, int portNumber) { HostAndPort parsedHostAndPort = HostAndPort.fromString(hostWithPort); if (parsedHostAndPort.hasPort() && parsedHostAndPort.getPort() == portNumber) { // HostAndPort.getHostText() strips brackets from ipv6 addresses, so reparse using fromHost return HostAndPort.fromHost(parsedHostAndPort.getHostText()).toString(); } else { return hostWithPort; } }
/** * Removes a port from a host+port if the string contains the specified port. If the host+port does not contain * a port, or contains another port, the string is returned unaltered. For example, if hostWithPort is the * string {@code www.website.com:443}, this method will return {@code www.website.com}. * * <b>Note:</b> The hostWithPort string is not a URI and should not contain a scheme or resource. This method does * not attempt to validate the specified host; it <i>might</i> throw IllegalArgumentException if there was a problem * parsing the hostname, but makes no guarantees. In general, it should be validated externally, if necessary. * * @param hostWithPort string containing a hostname and optional port * @param portNumber port to remove from the string * @return string with the specified port removed, or the original string if it did not contain the portNumber */ public static String removeMatchingPort(String hostWithPort, int portNumber) { HostAndPort parsedHostAndPort = HostAndPort.fromString(hostWithPort); if (parsedHostAndPort.hasPort() && parsedHostAndPort.getPort() == portNumber) { // HostAndPort.getHostText() strips brackets from ipv6 addresses, so reparse using fromHost return HostAndPort.fromHost(parsedHostAndPort.getHost()).toString(); } else { return hostWithPort; } }
public void testFromHost() { HostAndPort hp = HostAndPort.fromHost("gmail.com"); assertEquals("gmail.com", hp.getHost()); assertFalse(hp.hasPort()); hp = HostAndPort.fromHost("[::1]"); assertEquals("::1", hp.getHost()); assertFalse(hp.hasPort()); try { HostAndPort.fromHost("gmail.com:80"); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException expected) { } try { HostAndPort.fromHost("[gmail.com]"); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException expected) { } }