2023-01-26 18:24:18 +01:00
|
|
|
package org.gcube.smartgears.extensions.resource;
|
|
|
|
|
|
|
|
import static org.gcube.smartgears.Constants.application_json;
|
|
|
|
import static org.gcube.smartgears.extensions.HttpExtension.Method.GET;
|
|
|
|
|
|
|
|
import java.io.IOException;
|
2023-02-01 14:40:31 +01:00
|
|
|
import java.io.PrintWriter;
|
|
|
|
import java.util.Set;
|
|
|
|
import java.util.Timer;
|
|
|
|
import java.util.stream.Collectors;
|
2023-01-26 18:24:18 +01:00
|
|
|
|
|
|
|
import javax.servlet.ServletException;
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
2023-02-01 14:40:31 +01:00
|
|
|
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
import org.gcube.common.health.api.HealthCheck;
|
|
|
|
import org.gcube.common.health.api.ReadinessChecker;
|
|
|
|
import org.gcube.smartgears.context.application.ApplicationContext;
|
2023-01-26 18:24:18 +01:00
|
|
|
import org.gcube.smartgears.extensions.ApiResource;
|
|
|
|
import org.gcube.smartgears.extensions.ApiSignature;
|
2023-02-01 14:40:31 +01:00
|
|
|
import org.gcube.smartgears.handlers.application.request.RequestError;
|
|
|
|
import org.gcube.smartgears.health.HealthManager;
|
|
|
|
import org.gcube.smartgears.health.HealthResponse;
|
|
|
|
import org.gcube.smartgears.health.HealthTask;
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
import io.github.classgraph.ClassGraph;
|
|
|
|
import io.github.classgraph.ClassInfo;
|
|
|
|
import io.github.classgraph.ClassInfoList;
|
|
|
|
import io.github.classgraph.ScanResult;
|
2023-01-26 18:24:18 +01:00
|
|
|
|
|
|
|
public class HealthResource extends ApiResource {
|
|
|
|
|
|
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
|
2023-02-01 14:40:31 +01:00
|
|
|
private static Logger log = LoggerFactory.getLogger(HealthResource.class);
|
|
|
|
|
2023-01-26 18:24:18 +01:00
|
|
|
public static final String mapping = "/health";
|
|
|
|
|
2023-02-01 14:56:57 +01:00
|
|
|
public static final String readiness_mapping = "/readiness";
|
|
|
|
|
2023-01-26 18:24:18 +01:00
|
|
|
private static final ApiSignature signature = handles(mapping).with(method(GET).produces(application_json));
|
2023-02-01 14:40:31 +01:00
|
|
|
|
|
|
|
private HealthManager manager;
|
|
|
|
|
|
|
|
private HealthTask task;
|
|
|
|
|
|
|
|
private Timer timer;
|
2023-01-26 18:24:18 +01:00
|
|
|
|
|
|
|
HealthResource() {
|
|
|
|
super(signature);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2023-02-01 14:40:31 +01:00
|
|
|
public void init(ApplicationContext context) throws Exception {
|
|
|
|
Set<Class<?>> annotatedReadiness;
|
|
|
|
|
|
|
|
try (ScanResult result = new ClassGraph().enableClassInfo().enableAnnotationInfo().scan()) {
|
|
|
|
|
|
|
|
ClassInfoList classInfos = result.getClassesWithAnnotation(ReadinessChecker.class.getName());
|
|
|
|
|
|
|
|
annotatedReadiness = classInfos.stream().map(ClassInfo::loadClass)
|
|
|
|
.filter(c -> HealthCheck.class.isAssignableFrom(c)).collect(Collectors.toSet());
|
|
|
|
}
|
2023-01-26 18:24:18 +01:00
|
|
|
|
2023-02-01 14:40:31 +01:00
|
|
|
manager = new HealthManager();
|
|
|
|
for (Class<?> readnessClass : annotatedReadiness)
|
|
|
|
try {
|
|
|
|
manager.register((HealthCheck) readnessClass.getDeclaredConstructor().newInstance());
|
|
|
|
log.info("added class {} to health manager", readnessClass.getCanonicalName());
|
|
|
|
} catch (Throwable e) {
|
|
|
|
log.error("healthChecher class {} cannot be instantiated", readnessClass.getCanonicalName(), e);
|
|
|
|
}
|
|
|
|
|
|
|
|
task = new HealthTask(manager);
|
|
|
|
|
|
|
|
timer = new Timer(true);
|
|
|
|
|
|
|
|
timer.scheduleAtFixedRate(task, 0, 10000);
|
|
|
|
|
|
|
|
super.init(context);
|
2023-01-26 18:24:18 +01:00
|
|
|
}
|
|
|
|
|
2023-02-01 14:40:31 +01:00
|
|
|
public void stop() {
|
2023-02-01 14:55:11 +01:00
|
|
|
if (timer!=null)
|
|
|
|
timer.cancel();
|
2023-02-01 14:40:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
|
|
|
PrintWriter out = resp.getWriter();
|
|
|
|
resp.setContentType("application/json");
|
|
|
|
resp.setCharacterEncoding("UTF-8");
|
|
|
|
Object response = null;
|
|
|
|
|
|
|
|
String contextpath = req.getContextPath();
|
|
|
|
log.info("context path is {}", req.getContextPath());
|
2023-02-01 14:56:57 +01:00
|
|
|
if (contextpath.endsWith(readiness_mapping))
|
2023-02-01 14:40:31 +01:00
|
|
|
response = readiness();
|
|
|
|
else
|
|
|
|
RequestError.resource_notfound_error.fire();
|
|
|
|
|
|
|
|
new ObjectMapper().writeValue(out, response);
|
|
|
|
|
|
|
|
out.flush();
|
2023-01-26 18:24:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public HealthResponse readiness() {
|
2023-02-01 14:40:31 +01:00
|
|
|
return task.getResponse();
|
2023-01-26 18:24:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|