2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.fe.servlets;
23 import java.io.IOException;
24 import java.lang.reflect.Type;
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.concurrent.Executors;
28 import java.util.concurrent.ScheduledExecutorService;
29 import java.util.concurrent.ThreadFactory;
30 import java.util.concurrent.TimeUnit;
32 import javax.servlet.ServletContext;
33 import javax.ws.rs.core.Response;
35 import org.apache.http.client.config.RequestConfig;
36 import org.apache.http.client.methods.CloseableHttpResponse;
37 import org.apache.http.client.methods.HttpGet;
38 import org.apache.http.impl.client.CloseableHttpClient;
39 import org.apache.http.impl.client.HttpClientBuilder;
40 import org.apache.http.util.EntityUtils;
41 import org.openecomp.sdc.common.api.Constants;
42 import org.openecomp.sdc.common.api.HealthCheckInfo;
43 import org.openecomp.sdc.common.api.HealthCheckWrapper;
44 import org.openecomp.sdc.common.api.HealthCheckInfo.HealthCheckComponent;
45 import org.openecomp.sdc.common.api.HealthCheckInfo.HealthCheckStatus;
46 import org.openecomp.sdc.common.config.EcompErrorName;
47 import org.openecomp.sdc.common.impl.ExternalConfiguration;
48 import org.openecomp.sdc.fe.config.Configuration;
49 import org.openecomp.sdc.fe.config.ConfigurationManager;
50 import org.openecomp.sdc.fe.config.FeEcompErrorManager;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
54 import com.google.gson.Gson;
55 import com.google.gson.GsonBuilder;
56 import com.google.gson.reflect.TypeToken;
58 public class HealthCheckService {
60 private class HealthStatus {
62 public int statusCode;
64 public HealthStatus(int code, String body) {
66 this.statusCode = code;
70 private static final String URL = "%s://%s:%s/sdc2/rest/healthCheck";
71 private static Logger healthLogger = LoggerFactory.getLogger("asdc.fe.healthcheck");
72 private static Logger log = LoggerFactory.getLogger(HealthCheckService.class.getName());
74 private HealthStatus lastHealthStatus = new HealthStatus(500, "{}");
76 private class HealthCheckScheduledTask implements Runnable {
79 healthLogger.trace("Executing FE Health Check Task - Start");
80 HealthStatus currentHealth = checkHealth();
81 int currentHealthStatus = currentHealth.statusCode;
82 healthLogger.trace("Executing FE Health Check Task - Status = {}", currentHealthStatus);
84 // In case health status was changed, issue alarm/recovery
85 if (currentHealthStatus != lastHealthStatus.statusCode) {
86 log.trace("FE Health State Changed to {}. Issuing alarm / recovery alarm...", currentHealthStatus);
87 logFeAlarm(currentHealthStatus);
90 // Anyway, update latest response
91 lastHealthStatus = currentHealth;
96 * This executor will execute the health check task.
98 ScheduledExecutorService healthCheckExecutor = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
100 public Thread newThread(Runnable r) {
101 return new Thread(r, "FE-Health-Check-Thread");
104 private ServletContext context;
106 public HealthCheckService(ServletContext context) {
107 this.context = context;
110 public void start(int interval) {
111 this.healthCheckExecutor.scheduleAtFixedRate(new HealthCheckScheduledTask(), 0, interval, TimeUnit.SECONDS);
115 * To be used by the HealthCheckServlet
119 public Response getFeHealth() {
120 return this.buildResponse(lastHealthStatus.statusCode, lastHealthStatus.body);
123 private HealthStatus checkHealth() {
124 CloseableHttpClient httpClient = null;
126 Gson gson = new GsonBuilder().setPrettyPrinting().create();
127 Configuration config = ((ConfigurationManager) context.getAttribute(Constants.CONFIGURATION_MANAGER_ATTR))
129 String redirectedUrl = String.format(URL, config.getBeProtocol(), config.getBeHost(),
130 config.getBeHttpPort());
131 httpClient = getHttpClient(config);
132 HttpGet httpGet = new HttpGet(redirectedUrl);
133 CloseableHttpResponse beResponse;
135 String feAggHealthCheck;
137 beResponse = httpClient.execute(httpGet);
138 beStatus = beResponse.getStatusLine().getStatusCode();
139 String beJsonResponse = EntityUtils.toString(beResponse.getEntity());
140 feAggHealthCheck = getFeHealthCheckInfos(gson, beJsonResponse);
141 } catch (Exception e) {
142 log.error("Health Check error when trying to connect to BE", e);
143 String beDowneResponse = gson.toJson(getBeDownCheckInfos());
144 return new HealthStatus(500, beDowneResponse);
146 return new HealthStatus(beStatus, feAggHealthCheck);
147 } catch (Exception e) {
148 FeEcompErrorManager.getInstance().processEcompError(EcompErrorName.FeHealthCheckGeneralError, "Unexpected FE Health check error");
149 FeEcompErrorManager.getInstance().logFeHealthCheckGeneralError("Unexpected FE Health check error");
150 log.error("Unexpected FE health check error {}", e.getMessage());
151 return new HealthStatus(500, e.getMessage());
153 if (httpClient != null) {
156 } catch (IOException e) {
162 private Response buildResponse(int status, String jsonResponse) {
163 healthLogger.trace("FE and BE health check status: {}", jsonResponse);
164 return Response.status(status).entity(jsonResponse).build();
167 private void logFeAlarm(int lastFeStatus) {
169 switch (lastFeStatus) {
171 FeEcompErrorManager.getInstance().processEcompError(EcompErrorName.FeHealthCheckRecovery,
172 "FE Health Recovered");
173 FeEcompErrorManager.getInstance().logFeHealthCheckRecovery("FE Health Recovered");
176 FeEcompErrorManager.getInstance().processEcompError(EcompErrorName.FeHealthCheckConnectionError,
177 "Connection with ASDC-BE is probably down");
178 FeEcompErrorManager.getInstance().logFeHealthCheckError("Connection with ASDC-BE is probably down");
186 private String getFeHealthCheckInfos(Gson gson, String responseString) {
187 Type wrapperType = new TypeToken<HealthCheckWrapper>() {
189 HealthCheckWrapper healthCheckWrapper = gson.fromJson(responseString, wrapperType);
190 String appVersion = ExternalConfiguration.getAppVersion();
191 String description = "OK";
192 healthCheckWrapper.getComponentsInfo()
193 .add(new HealthCheckInfo(HealthCheckComponent.FE, HealthCheckStatus.UP, appVersion, description));
194 return gson.toJson(healthCheckWrapper);
197 private HealthCheckWrapper getBeDownCheckInfos() {
198 List<HealthCheckInfo> healthCheckInfos = new ArrayList<HealthCheckInfo>();
199 healthCheckInfos.add(new HealthCheckInfo(HealthCheckComponent.FE, HealthCheckStatus.UP,
200 ExternalConfiguration.getAppVersion(), "OK"));
201 healthCheckInfos.add(new HealthCheckInfo(HealthCheckComponent.BE, HealthCheckStatus.DOWN, null, null));
202 healthCheckInfos.add(new HealthCheckInfo(HealthCheckComponent.TITAN, HealthCheckStatus.UNKNOWN, null, null));
203 healthCheckInfos.add(new HealthCheckInfo(HealthCheckComponent.CASSANDRA, HealthCheckStatus.UNKNOWN, null, null));
204 healthCheckInfos.add(new HealthCheckInfo(HealthCheckComponent.DE, HealthCheckStatus.UNKNOWN, null, null));
205 healthCheckInfos.add(new HealthCheckInfo(HealthCheckComponent.ON_BOARDING, HealthCheckStatus.UNKNOWN, null, null));
206 HealthCheckWrapper hcWrapper = new HealthCheckWrapper(healthCheckInfos, "UNKNOWN", "UNKNOWN");
210 private CloseableHttpClient getHttpClient(Configuration config) {
212 int socketTimeout = config.getHealthCheckSocketTimeoutInMs(5000);
213 RequestConfig.Builder requestBuilder = RequestConfig.custom();
214 requestBuilder.setConnectTimeout(timeout).setConnectionRequestTimeout(timeout).setSocketTimeout(socketTimeout);
216 HttpClientBuilder builder = HttpClientBuilder.create();
217 builder.setDefaultRequestConfig(requestBuilder.build());
218 return builder.build();