Skip to content

Commit 2214df8

Browse files
committed
Add a new check to the /readiness, verify that the node has bootstrapped before indicating we are ready to serve requests
1 parent fa64362 commit 2214df8

File tree

2 files changed

+101
-1
lines changed

2 files changed

+101
-1
lines changed

management-api-server/src/main/java/com/datastax/mgmtapi/resources/K8OperatorResources.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ public class K8OperatorResources extends BaseResources {
4242

4343
private static final ObjectMapper jsonMapper = new ObjectMapper();
4444

45+
private boolean bootStrapped = false;
46+
4547
public K8OperatorResources(ManagementApplication application) {
4648
super(application);
4749
}
@@ -93,11 +95,22 @@ public Response checkLiveness() {
9395
public Response checkReadiness() {
9496
return handle(
9597
() -> {
98+
99+
if(!bootStrapped) {
100+
ResultSet bootstrapped = app.cqlService.executeCql(app.dbUnixSocketFile, "SELECT bootstrapped FROM system.local WHERE key = 'local'");
101+
Row resultBootstrap = bootstrapped.one();
102+
if(resultBootstrap != null) {
103+
if ("COMPLETED".equalsIgnoreCase(resultBootstrap.getString("bootstrapped"))) {
104+
bootStrapped = true;
105+
}
106+
}
107+
}
108+
96109
ResultSet resultSet =
97110
app.cqlService.executeCql(app.dbUnixSocketFile, "SELECT * from system.local");
98111
Row result = resultSet.one();
99112

100-
if (result != null) {
113+
if (result != null && bootStrapped) {
101114
return Response.ok("OK").build();
102115
} else {
103116
Response.ResponseBuilder rb = Response.status(Response.Status.INTERNAL_SERVER_ERROR);

management-api-server/src/test/java/com/datastax/mgmtapi/K8OperatorResourcesTest.java

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,93 @@ public void testLiveness() throws Exception {
133133
Assert.assertTrue(response.getContentAsString().contains("OK"));
134134
}
135135

136+
@Test
137+
public void testReadinessFailsWhenNotBootstrapped() throws Exception {
138+
Context context = setup();
139+
140+
ResultSet bootstrapResultSet = mock(ResultSet.class);
141+
Row bootstrapRow = mock(Row.class);
142+
ResultSet localResultSet = mock(ResultSet.class);
143+
Row localRow = mock(Row.class);
144+
145+
when(context.cqlService.executeCql(
146+
any(), eq("SELECT bootstrapped FROM system.local WHERE key = 'local'")))
147+
.thenReturn(bootstrapResultSet);
148+
when(bootstrapResultSet.one()).thenReturn(bootstrapRow);
149+
when(bootstrapRow.getString("bootstrapped")).thenReturn("IN_PROGRESS");
150+
151+
when(context.cqlService.executeCql(any(), eq("SELECT * from system.local")))
152+
.thenReturn(localResultSet);
153+
when(localResultSet.one()).thenReturn(localRow);
154+
155+
MockHttpRequest request = MockHttpRequest.get(ROOT_PATH + "/probes/readiness");
156+
MockHttpResponse response = context.invoke(request);
157+
158+
Assert.assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, response.getStatus());
159+
160+
verify(context.cqlService)
161+
.executeCql(any(), eq("SELECT bootstrapped FROM system.local WHERE key = 'local'"));
162+
verify(context.cqlService).executeCql(any(), eq("SELECT * from system.local"));
163+
}
164+
165+
@Test
166+
public void testReadinessFailsWhenSystemLocalRowMissing() throws Exception {
167+
Context context = setup();
168+
169+
ResultSet bootstrapResultSet = mock(ResultSet.class);
170+
Row bootstrapRow = mock(Row.class);
171+
ResultSet localResultSet = mock(ResultSet.class);
172+
173+
when(context.cqlService.executeCql(
174+
any(), eq("SELECT bootstrapped FROM system.local WHERE key = 'local'")))
175+
.thenReturn(bootstrapResultSet);
176+
when(bootstrapResultSet.one()).thenReturn(bootstrapRow);
177+
when(bootstrapRow.getString("bootstrapped")).thenReturn("COMPLETED");
178+
179+
when(context.cqlService.executeCql(any(), eq("SELECT * from system.local")))
180+
.thenReturn(localResultSet);
181+
when(localResultSet.one()).thenReturn(null);
182+
183+
MockHttpRequest request = MockHttpRequest.get(ROOT_PATH + "/probes/readiness");
184+
MockHttpResponse response = context.invoke(request);
185+
186+
Assert.assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, response.getStatus());
187+
188+
verify(context.cqlService)
189+
.executeCql(any(), eq("SELECT bootstrapped FROM system.local WHERE key = 'local'"));
190+
verify(context.cqlService).executeCql(any(), eq("SELECT * from system.local"));
191+
}
192+
193+
@Test
194+
public void testReadinessSucceedsWhenBootstrappedAndSystemLocalPresent() throws Exception {
195+
Context context = setup();
196+
197+
ResultSet bootstrapResultSet = mock(ResultSet.class);
198+
Row bootstrapRow = mock(Row.class);
199+
ResultSet localResultSet = mock(ResultSet.class);
200+
Row localRow = mock(Row.class);
201+
202+
when(context.cqlService.executeCql(
203+
any(), eq("SELECT bootstrapped FROM system.local WHERE key = 'local'")))
204+
.thenReturn(bootstrapResultSet);
205+
when(bootstrapResultSet.one()).thenReturn(bootstrapRow);
206+
when(bootstrapRow.getString("bootstrapped")).thenReturn("COMPLETED");
207+
208+
when(context.cqlService.executeCql(any(), eq("SELECT * from system.local")))
209+
.thenReturn(localResultSet);
210+
when(localResultSet.one()).thenReturn(localRow);
211+
212+
MockHttpRequest request = MockHttpRequest.get(ROOT_PATH + "/probes/readiness");
213+
MockHttpResponse response = context.invoke(request);
214+
215+
Assert.assertEquals(HttpStatus.SC_OK, response.getStatus());
216+
Assert.assertEquals("OK", response.getContentAsString());
217+
218+
verify(context.cqlService)
219+
.executeCql(any(), eq("SELECT bootstrapped FROM system.local WHERE key = 'local'"));
220+
verify(context.cqlService).executeCql(any(), eq("SELECT * from system.local"));
221+
}
222+
136223
@Test
137224
public void testSeedReload() throws Exception {
138225
Context context = setup();

0 commit comments

Comments
 (0)