1 package org.onap.so.adapters.cnf.service.healthcheck;
3 import com.google.common.util.concurrent.ThreadFactoryBuilder;
4 import org.onap.so.adapters.cnf.client.MulticloudClient;
5 import org.onap.so.adapters.cnf.model.CheckInstanceRequest;
6 import org.onap.so.adapters.cnf.model.InstanceRequest;
7 import org.onap.so.adapters.cnf.model.healthcheck.HealthCheckInstance;
8 import org.onap.so.adapters.cnf.model.healthcheck.HealthCheckInstanceResponse;
9 import org.onap.so.adapters.cnf.model.healthcheck.HealthCheckResponse;
10 import org.onap.so.adapters.cnf.model.healthcheck.K8sRbInstanceHealthCheck;
11 import org.onap.so.adapters.cnf.model.healthcheck.K8sRbInstanceHealthCheckSimple;
12 import org.onap.so.adapters.cnf.service.CnfAdapterService;
13 import org.onap.so.client.exception.BadResponseException;
14 import org.slf4j.Logger;
15 import org.slf4j.LoggerFactory;
16 import org.springframework.beans.factory.annotation.Autowired;
17 import org.springframework.stereotype.Service;
19 import java.util.ArrayList;
20 import java.util.List;
21 import java.util.concurrent.Callable;
22 import java.util.concurrent.ExecutorService;
23 import java.util.concurrent.ThreadFactory;
24 import java.util.stream.Collectors;
26 import static java.lang.Thread.sleep;
27 import static java.util.concurrent.Executors.newFixedThreadPool;
30 public class HealthCheckService {
32 private static final Logger log = LoggerFactory.getLogger(CnfAdapterService.class);
34 private final MulticloudClient instanceApi;
37 public HealthCheckService(MulticloudClient multicloudClient) {
38 this.instanceApi = multicloudClient;
41 public HealthCheckResponse healthCheck(CheckInstanceRequest healthCheckRequest) throws Exception {
42 log.info("Health check - START");
43 List<HealthCheckInstance> instanceHealthCheckList = startInstanceHealthCheck(healthCheckRequest);
44 HealthCheckResponse statuses = getStatuses(instanceHealthCheckList);
45 log.info("Health check - END");
50 private List<HealthCheckInstance> startInstanceHealthCheck(CheckInstanceRequest healthCheckRequest) throws Exception {
51 log.debug("startInstanceHealthCheck - START");
52 List<HealthCheckInstance> healthCheckInstanceList = new ArrayList<>();
54 for (InstanceRequest instance : healthCheckRequest.getInstances()) {
55 String instanceId = instance.getInstanceId();
56 K8sRbInstanceHealthCheckSimple response = instanceApi.startInstanceHealthCheck(instanceId);
57 log.info("K8sRbInstanceHealthCheckSimple: {}", response);
58 healthCheckInstanceList.add(new HealthCheckInstance(instanceId, response.getId()));
61 log.info("healthCheckInstanceList: {}", healthCheckInstanceList);
62 log.debug("startInstanceHealthCheck - END");
63 return healthCheckInstanceList;
66 private HealthCheckResponse getStatuses(List<HealthCheckInstance> instanceHealthCheckList) throws Exception {
67 log.debug("getStatuses - START");
68 List<HealthCheckThread> threads = instanceHealthCheckList.stream()
69 .map(HealthCheckThread::new)
70 .collect(Collectors.toList());
72 int processors = Runtime.getRuntime().availableProcessors();
73 ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("Health-check-thread-%d").build();
74 ExecutorService executorService = newFixedThreadPool(processors, threadFactory);
75 HealthCheckResponse response = new HealthCheckResponse();
76 List<HealthCheckInstanceResponse> healthCheckInstance = null;
77 healthCheckInstance = executorService.invokeAll(threads).stream()
80 InstanceStatusTuple instanceStatusTuple = future.get();
81 String instanceId = instanceStatusTuple.getInstanceId();
82 String status = instanceStatusTuple.getStatus();
84 return new HealthCheckInstanceResponse(instanceId, reason, status);
85 } catch (Exception e) {
86 throw new RuntimeException(e);
89 .collect(Collectors.toList());
90 response.setInstanceResponse(healthCheckInstance);
91 log.info("Get statuses response: \n {}", response);
92 log.debug("getStatuses - END");
96 private class HealthCheckThread implements Callable<InstanceStatusTuple> {
98 private final HealthCheckInstance healthCheckInstance;
100 HealthCheckThread(HealthCheckInstance healthCheckInstance) {
101 this.healthCheckInstance = healthCheckInstance;
105 * Approx 5 minutes thread
106 * If timeout method returns tuple with HeatStackId => Timeout
107 * @return InstanceStatusTuple
108 * @throws InterruptedException
109 * @throws BadResponseException
112 public InstanceStatusTuple call() throws InterruptedException, BadResponseException {
113 log.info("{} started for: {}", Thread.currentThread().getName(), healthCheckInstance);
114 for (int retry = 0; retry < 30; retry++) {
115 K8sRbInstanceHealthCheck response = instanceApi.getInstanceHealthCheck(healthCheckInstance.getInstanceId(), healthCheckInstance.getHealthCheckInstance());
116 log.debug("Response for instanceId={}: {}", healthCheckInstance, response);
117 String status = response.getStatus();
118 if (!"RUNNING".equals(status.toUpperCase())) {
119 log.info("Poll status: {} for {}", status, healthCheckInstance);
120 instanceApi.deleteInstanceHealthCheck(healthCheckInstance.getInstanceId(), healthCheckInstance.getHealthCheckInstance());
121 return new InstanceStatusTuple(healthCheckInstance.getInstanceId(), status);
125 return new InstanceStatusTuple(healthCheckInstance.getInstanceId(), "Timeout");
129 private class InstanceStatusTuple {
130 private final String instanceId;
131 private final String status;
133 InstanceStatusTuple(String instanceId, String status) {
134 this.instanceId = instanceId;
135 this.status = status;
138 String getInstanceId() {