Skip to content

Commit fa91910

Browse files
Gytis Triklerisiocanel
Gytis Trikleris
authored andcommitted
LeaderContext
1 parent 7f6627e commit fa91910

File tree

4 files changed

+156
-8
lines changed

4 files changed

+156
-8
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright 2018 Red Hat, Inc, and individual contributors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.kubernetes.leader;
18+
19+
import org.springframework.integration.leader.Candidate;
20+
import org.springframework.integration.leader.Context;
21+
22+
/**
23+
* @author <a href="mailto:[email protected]">Gytis Trikleris</a>
24+
*/
25+
public class LeaderContext implements Context {
26+
27+
private final Candidate candidate;
28+
29+
private final LeadershipController leadershipController;
30+
31+
public LeaderContext(Candidate candidate, LeadershipController leadershipController) {
32+
this.candidate = candidate;
33+
this.leadershipController = leadershipController;
34+
}
35+
36+
@Override
37+
public boolean isLeader() {
38+
Leader leader = leadershipController.getLeader(candidate.getRole());
39+
if (leader == null) {
40+
return false;
41+
}
42+
43+
return candidate.getId().equals(leader.getId());
44+
}
45+
46+
@Override
47+
public void yield() {
48+
leadershipController.revoke(candidate);
49+
}
50+
}

spring-cloud-kubernetes-leader/src/main/java/org/springframework/cloud/kubernetes/leader/LeadershipController.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.slf4j.Logger;
2525
import org.slf4j.LoggerFactory;
2626
import org.springframework.integration.leader.Candidate;
27+
import org.springframework.integration.leader.Context;
2728
import org.springframework.integration.leader.event.LeaderEventPublisher;
2829

2930
/**
@@ -123,17 +124,19 @@ private void updateLeaderConfigMap(Candidate candidate, ConfigMap configMap) {
123124
}
124125

125126
private void handleOnGranted(Candidate candidate) {
126-
leaderEventPublisher.publishOnGranted(this, null, candidate.getRole());
127+
Context context = new LeaderContext(candidate, this);
128+
leaderEventPublisher.publishOnGranted(this, context, candidate.getRole());
127129
try {
128-
candidate.onGranted(null); // TODO context
130+
candidate.onGranted(context);
129131
} catch (InterruptedException e) {
130132
LOGGER.warn(e.getMessage());
131133
Thread.currentThread().interrupt();
132134
}
133135
}
134136

135137
private void handleOnFailed(Candidate candidate) {
136-
leaderEventPublisher.publishOnFailedToAcquire(this, null, candidate.getRole()); // TODO context
138+
Context context = new LeaderContext(candidate, this);
139+
leaderEventPublisher.publishOnFailedToAcquire(this, context, candidate.getRole());
137140
}
138141

139142
private Map<String, String> getLeaderData(Candidate candidate) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package org.springframework.cloud.kubernetes.leader;
2+
3+
import org.junit.Before;
4+
import org.junit.Test;
5+
import org.junit.runner.RunWith;
6+
import org.mockito.Mock;
7+
import org.mockito.junit.MockitoJUnitRunner;
8+
import org.springframework.integration.leader.Candidate;
9+
10+
import static org.assertj.core.api.Assertions.assertThat;
11+
import static org.mockito.BDDMockito.given;
12+
import static org.mockito.Mockito.verify;
13+
14+
/**
15+
* @author <a href="mailto:[email protected]">Gytis Trikleris</a>
16+
*/
17+
@RunWith(MockitoJUnitRunner.class)
18+
public class LeaderContextTest {
19+
20+
private static final String ROLE = "test-role";
21+
22+
private static final String ID = "test-id";
23+
24+
@Mock
25+
private Candidate mockCandidate;
26+
27+
@Mock
28+
private LeadershipController mockLeadershipController;
29+
30+
@Mock
31+
private Leader mockLeader;
32+
33+
private LeaderContext leaderContext;
34+
35+
@Before
36+
public void before() {
37+
given(mockCandidate.getRole()).willReturn(ROLE);
38+
given(mockCandidate.getId()).willReturn(ID);
39+
40+
leaderContext = new LeaderContext(mockCandidate, mockLeadershipController);
41+
}
42+
43+
@Test
44+
public void testIsLeaderWithoutLeader() {
45+
boolean result = leaderContext.isLeader();
46+
47+
assertThat(result).isFalse();
48+
}
49+
50+
@Test
51+
public void testIsLeaderWithAnotherLeader() {
52+
given(mockLeadershipController.getLeader(ROLE)).willReturn(mockLeader);
53+
given(mockLeader.getId()).willReturn("another-test-id");
54+
55+
boolean result = leaderContext.isLeader();
56+
57+
assertThat(result).isFalse();
58+
}
59+
60+
@Test
61+
public void testIsLeaderWhenLeader() {
62+
given(mockLeadershipController.getLeader(ROLE)).willReturn(mockLeader);
63+
given(mockLeader.getId()).willReturn(ID);
64+
65+
boolean result = leaderContext.isLeader();
66+
67+
assertThat(result).isTrue();
68+
}
69+
70+
@Test
71+
public void shouldYieldLeadership() {
72+
leaderContext.yield();
73+
74+
verify(mockLeadershipController).revoke(mockCandidate);
75+
}
76+
77+
}

spring-cloud-kubernetes-leader/src/test/java/org/springframework/cloud/kubernetes/leader/LeadershipControllerTest.java

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
import org.junit.Before;
99
import org.junit.Test;
1010
import org.junit.runner.RunWith;
11+
import org.mockito.ArgumentCaptor;
1112
import org.mockito.Mock;
1213
import org.mockito.junit.MockitoJUnitRunner;
1314
import org.springframework.integration.leader.Candidate;
1415
import org.springframework.integration.leader.event.LeaderEventPublisher;
1516

1617
import static org.assertj.core.api.Assertions.assertThat;
1718
import static org.mockito.ArgumentMatchers.any;
19+
import static org.mockito.ArgumentMatchers.eq;
1820
import static org.mockito.BDDMockito.given;
1921
import static org.mockito.Mockito.doThrow;
2022
import static org.mockito.Mockito.times;
@@ -67,7 +69,7 @@ public void shouldAcquireWithoutExistingConfigMap() {
6769

6870
assertThat(result).isTrue();
6971
verify(mockKubernetesHelper).createConfigMap(Collections.singletonMap(PREFIX + ROLE, ID));
70-
verify(mockLeaderEventPublisher).publishOnGranted(leadershipController, null, ROLE);
72+
verifyPublishOnGranted();
7173
}
7274

7375
@Test
@@ -78,7 +80,7 @@ public void shouldAcquireWithExistingConfigMap() {
7880

7981
assertThat(result).isTrue();
8082
verify(mockKubernetesHelper).updateConfigMap(mockConfigMap, leaderData);
81-
verify(mockLeaderEventPublisher).publishOnGranted(leadershipController, null, ROLE);
83+
verifyPublishOnGranted();
8284
}
8385

8486
@Test
@@ -109,7 +111,7 @@ public void shouldTakeOverLeadershipFromInvalidLeader() {
109111

110112
assertThat(result).isTrue();
111113
verify(mockKubernetesHelper).updateConfigMap(mockConfigMap, Collections.singletonMap(PREFIX + ROLE, anotherId));
112-
verify(mockLeaderEventPublisher).publishOnGranted(leadershipController, null, ROLE);
114+
verifyPublishOnGranted();
113115
}
114116

115117
@Test
@@ -124,7 +126,7 @@ public void shouldFailToAcquireBecauseOfExistingLeader() {
124126
assertThat(result).isFalse();
125127
verify(mockKubernetesHelper, times(0)).createConfigMap(any());
126128
verify(mockKubernetesHelper, times(0)).updateConfigMap(any(), any());
127-
verify(mockLeaderEventPublisher).publishOnFailedToAcquire(leadershipController, null, ROLE);
129+
verifyPublishOnFailedToAcquire();
128130
}
129131

130132
@Test
@@ -134,7 +136,7 @@ public void shouldFailToAcquireBecauseOfException() {
134136
boolean result = leadershipController.acquire(mockCandidate);
135137

136138
assertThat(result).isFalse();
137-
verify(mockLeaderEventPublisher).publishOnFailedToAcquire(leadershipController, null, ROLE);
139+
verifyPublishOnFailedToAcquire();
138140
}
139141

140142
@Test
@@ -182,4 +184,20 @@ public void shouldHandleFailureWhenGettingLeader() {
182184
assertThat(leader).isNull();
183185
}
184186

187+
private void verifyPublishOnGranted() {
188+
ArgumentCaptor<LeaderContext> leaderContextCaptor = ArgumentCaptor.forClass(LeaderContext.class);
189+
verify(mockLeaderEventPublisher).publishOnGranted(eq(leadershipController),
190+
leaderContextCaptor.capture(), eq(ROLE));
191+
LeaderContext expectedLeaderContext = new LeaderContext(mockCandidate, leadershipController);
192+
assertThat(leaderContextCaptor.getValue()).isEqualToComparingFieldByField(expectedLeaderContext);
193+
}
194+
195+
public void verifyPublishOnFailedToAcquire() {
196+
ArgumentCaptor<LeaderContext> leaderContextCaptor = ArgumentCaptor.forClass(LeaderContext.class);
197+
verify(mockLeaderEventPublisher).publishOnFailedToAcquire(eq(leadershipController),
198+
leaderContextCaptor.capture(), eq(ROLE));
199+
LeaderContext expectedLeaderContext = new LeaderContext(mockCandidate, leadershipController);
200+
assertThat(leaderContextCaptor.getValue()).isEqualToComparingFieldByField(expectedLeaderContext);
201+
}
202+
185203
}

0 commit comments

Comments
 (0)