This is an automated email from the ASF dual-hosted git repository.
rongr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push:
new 2f0eee9f12 Add health/readiness and health/liveness endpoint (#9031)
2f0eee9f12 is described below
commit 2f0eee9f1205f5119c940e1cd33bf31e8093347a
Author: Rong Rong <[email protected]>
AuthorDate: Mon Jul 25 07:33:39 2022 -0700
Add health/readiness and health/liveness endpoint (#9031)
* add liveness and readiness endpoint
Co-authored-by: Rong Rong <[email protected]>
Co-authored-by: Xiaotian (Jackie) Jiang
<[email protected]>
---
.../server/api/resources/HealthCheckResource.java | 31 +++++++++++-
.../apache/pinot/server/api/BaseResourceTest.java | 5 +-
.../pinot/server/api/HealthCheckResourceTest.java | 57 ++++++++++++++++++++++
3 files changed, 90 insertions(+), 3 deletions(-)
diff --git
a/pinot-server/src/main/java/org/apache/pinot/server/api/resources/HealthCheckResource.java
b/pinot-server/src/main/java/org/apache/pinot/server/api/resources/HealthCheckResource.java
index 921117382a..3157e7e456 100644
---
a/pinot-server/src/main/java/org/apache/pinot/server/api/resources/HealthCheckResource.java
+++
b/pinot-server/src/main/java/org/apache/pinot/server/api/resources/HealthCheckResource.java
@@ -55,7 +55,36 @@ public class HealthCheckResource {
@ApiResponse(code = 503, message = "Server is not healthy")
})
public String checkHealth() {
- Status status = ServiceStatus.getServiceStatus(_instanceId);
+ return getReadinessStatus(_instanceId);
+ }
+
+ @GET
+ @Path("/health/liveness")
+ @Produces(MediaType.TEXT_PLAIN)
+ @ApiOperation(value = "Checking server liveness status.")
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "Server is live"),
+ @ApiResponse(code = 503, message = "Server is not live")
+ })
+ public String checkLiveness() {
+ // Returns OK since if we reached here, the admin application is running.
+ return "OK";
+ }
+
+ @GET
+ @Path("/health/readiness")
+ @Produces(MediaType.TEXT_PLAIN)
+ @ApiOperation(value = "Checking server readiness status")
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "Server is ready to serve queries"),
+ @ApiResponse(code = 503, message = "Server is not ready to serve
queries")
+ })
+ public String checkReadiness() {
+ return getReadinessStatus(_instanceId);
+ }
+
+ private static String getReadinessStatus(String instanceId) throws
WebApplicationException {
+ Status status = ServiceStatus.getServiceStatus(instanceId);
if (status == Status.GOOD) {
return "OK";
}
diff --git
a/pinot-server/src/test/java/org/apache/pinot/server/api/BaseResourceTest.java
b/pinot-server/src/test/java/org/apache/pinot/server/api/BaseResourceTest.java
index d9a88d504f..c0ad22a2dc 100644
---
a/pinot-server/src/test/java/org/apache/pinot/server/api/BaseResourceTest.java
+++
b/pinot-server/src/test/java/org/apache/pinot/server/api/BaseResourceTest.java
@@ -87,6 +87,7 @@ public abstract class BaseResourceTest {
private File _avroFile;
private AdminApiApplication _adminApiApplication;
protected WebTarget _webTarget;
+ protected String _instanceId;
@SuppressWarnings("SuspiciousMethodCalls")
@BeforeClass
@@ -133,8 +134,8 @@ public abstract class BaseResourceTest {
? NetUtils.getHostnameOrAddress() : NetUtils.getHostAddress());
int port =
serverConf.getProperty(CommonConstants.Helix.KEY_OF_SERVER_NETTY_PORT,
CommonConstants.Helix.DEFAULT_SERVER_NETTY_PORT);
- serverConf.setProperty(CommonConstants.Server.CONFIG_OF_INSTANCE_ID,
- CommonConstants.Helix.PREFIX_OF_SERVER_INSTANCE + hostname + "_" +
port);
+ _instanceId = CommonConstants.Helix.PREFIX_OF_SERVER_INSTANCE + hostname +
"_" + port;
+ serverConf.setProperty(CommonConstants.Server.CONFIG_OF_INSTANCE_ID,
_instanceId);
_adminApiApplication = new AdminApiApplication(serverInstance, new
AllowAllAccessFactory(), serverConf);
_adminApiApplication.start(Collections.singletonList(
new ListenerConfig(CommonConstants.HTTP_PROTOCOL, "0.0.0.0",
CommonConstants.Server.DEFAULT_ADMIN_API_PORT,
diff --git
a/pinot-server/src/test/java/org/apache/pinot/server/api/HealthCheckResourceTest.java
b/pinot-server/src/test/java/org/apache/pinot/server/api/HealthCheckResourceTest.java
new file mode 100644
index 0000000000..8d8e1b6b46
--- /dev/null
+++
b/pinot-server/src/test/java/org/apache/pinot/server/api/HealthCheckResourceTest.java
@@ -0,0 +1,57 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.server.api;
+
+import javax.ws.rs.core.Response;
+import org.apache.pinot.common.utils.ServiceStatus;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+
+public class HealthCheckResourceTest extends BaseResourceTest {
+ @Test
+ public void checkHealthProbes()
+ throws Exception {
+ String healthPath = "/health";
+ String livenessPath = "/health/liveness";
+ String readinessPath = "/health/readiness";
+
+ ServiceStatus.ServiceStatusCallback mockSuccessCallback =
mock(ServiceStatus.ServiceStatusCallback.class);
+ ServiceStatus.ServiceStatusCallback mockFailureCallback =
mock(ServiceStatus.ServiceStatusCallback.class);
+
when(mockSuccessCallback.getServiceStatus()).thenReturn(ServiceStatus.Status.GOOD);
+
when(mockFailureCallback.getServiceStatus()).thenReturn(ServiceStatus.Status.BAD);
+
+
Assert.assertEquals(_webTarget.path(livenessPath).request().get(Response.class).getStatus(),
200);
+
Assert.assertEquals(_webTarget.path(healthPath).request().get(Response.class).getStatus(),
503);
+
Assert.assertEquals(_webTarget.path(readinessPath).request().get(Response.class).getStatus(),
503);
+
+ ServiceStatus.setServiceStatusCallback(_instanceId, mockSuccessCallback);
+
Assert.assertEquals(_webTarget.path(livenessPath).request().get(Response.class).getStatus(),
200);
+
Assert.assertEquals(_webTarget.path(healthPath).request().get(Response.class).getStatus(),
200);
+
Assert.assertEquals(_webTarget.path(readinessPath).request().get(Response.class).getStatus(),
200);
+
+ ServiceStatus.setServiceStatusCallback(_instanceId, mockFailureCallback);
+
Assert.assertEquals(_webTarget.path(livenessPath).request().get(Response.class).getStatus(),
200);
+
Assert.assertEquals(_webTarget.path(healthPath).request().get(Response.class).getStatus(),
503);
+
Assert.assertEquals(_webTarget.path(readinessPath).request().get(Response.class).getStatus(),
503);
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]