@Override public Optional<HostAndPort> getSuspectedLeaderInMemory() { return delegate.getSuspectedLeaderInMemory(); }
private NotCurrentLeaderException notCurrentLeaderException(String message, @Nullable Throwable cause) { Optional<HostAndPort> maybeLeader = leaderElectionService.getSuspectedLeaderInMemory(); if (maybeLeader.isPresent()) { HostAndPort leaderHint = maybeLeader.get(); return new NotCurrentLeaderException(message + "; hinting suspected leader host " + leaderHint, cause, leaderHint); } else { return new NotCurrentLeaderException(message, cause); } }
@Test public void canSerializeSuspectedLeader() throws JsonProcessingException { Optional<HostAndPort> suspectedLeader = Optional.of(HostAndPort.fromParts("foo", 123)); LeaderElectionService leaderElectionService = mock(LeaderElectionService.class); when(leaderElectionService.getSuspectedLeaderInMemory()).thenReturn(suspectedLeader); // Be very careful about changing the following! Doing so would be a wire break. assertThat(MAPPER.writeValueAsString(leaderElectionService.getSuspectedLeaderInMemory())) .isEqualTo("\"foo:123\""); } }
@Test public void canSerializeNoSuspectedLeader() throws JsonProcessingException { LeaderElectionService leaderElectionService = mock(LeaderElectionService.class); when(leaderElectionService.getSuspectedLeaderInMemory()).thenReturn(Optional.empty()); // Be very careful about changing the following! Doing so would be a wire break. assertThat(MAPPER.writeValueAsString(leaderElectionService.getSuspectedLeaderInMemory())).isEqualTo("null"); }
@Before public void before() throws InterruptedException { when(leaderElectionService.blockOnBecomingLeader()).thenReturn(leadershipToken); when(leaderElectionService.getCurrentTokenIfLeading()).thenReturn(Optional.empty()); when(leaderElectionService.getSuspectedLeaderInMemory()).thenReturn(Optional.empty()); when(leaderElectionService.isStillLeading(leadershipToken)).thenReturn( LeaderElectionService.StillLeadingStatus.LEADING); }
@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 @SuppressWarnings("SelfEquals") // We're asserting that calling .equals on a proxy does not redirect // the .equals call to the instance its being proxied. public void shouldAllowObjectMethodsWhenLeading() { when(mockLeader.getSuspectedLeaderInMemory()).thenReturn(Optional.empty()); when(mockLeader.getCurrentTokenIfLeading()).thenReturn(Optional.empty()); when(mockLeader.isStillLeading(any(LeaderElectionService.LeadershipToken.class))) .thenReturn(LeaderElectionService.StillLeadingStatus.LEADING); Runnable proxy = AwaitingLeadershipProxy.newProxyInstance(Runnable.class, delegateSupplier, mockLeader); assertThat(proxy.hashCode()).isNotNull(); assertThat(proxy.equals(proxy)).isTrue(); assertThat(proxy.equals(null)).isFalse(); assertThat(proxy.toString()).startsWith("com.palantir.leader.proxy.AwaitingLeadershipProxy@"); }
@Test @SuppressWarnings("SelfEquals") // We're asserting that calling .equals on a proxy does not redirect // the .equals call to the instance its being proxied. public void shouldAllowObjectMethodsWhenNotLeading() { when(mockLeader.getSuspectedLeaderInMemory()).thenReturn(Optional.empty()); when(mockLeader.getCurrentTokenIfLeading()).thenReturn(Optional.empty()); when(mockLeader.isStillLeading(any(LeaderElectionService.LeadershipToken.class))) .thenReturn(LeaderElectionService.StillLeadingStatus.NOT_LEADING); Runnable proxy = AwaitingLeadershipProxy.newProxyInstance(Runnable.class, delegateSupplier, mockLeader); assertThat(proxy.hashCode()).isNotNull(); assertThat(proxy.equals(proxy)).isTrue(); assertThat(proxy.equals(null)).isFalse(); assertThat(proxy.toString()).startsWith("com.palantir.leader.proxy.AwaitingLeadershipProxy@"); }
@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); }
@Override public Optional<HostAndPort> getSuspectedLeaderInMemory() { return delegate.getSuspectedLeaderInMemory(); }
private NotCurrentLeaderException notCurrentLeaderException(String message, @Nullable Throwable cause) { Optional<HostAndPort> maybeLeader = leaderElectionService.getSuspectedLeaderInMemory(); if (maybeLeader.isPresent()) { HostAndPort leaderHint = maybeLeader.get(); return new NotCurrentLeaderException(message + "; hinting suspected leader host " + leaderHint, cause, leaderHint); } else { return new NotCurrentLeaderException(message, cause); } }