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.be.components.distribution.engine;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.List;
27 import java.util.concurrent.ExecutorService;
28 import java.util.concurrent.Executors;
29 import java.util.concurrent.Future;
30 import java.util.concurrent.ScheduledExecutorService;
31 import java.util.concurrent.ScheduledFuture;
32 import java.util.concurrent.ThreadFactory;
33 import java.util.concurrent.TimeUnit;
34 import java.util.concurrent.atomic.AtomicBoolean;
36 import javax.annotation.PostConstruct;
37 import javax.annotation.PreDestroy;
39 import org.openecomp.sdc.be.config.BeEcompErrorManager;
40 import org.openecomp.sdc.be.config.ConfigurationManager;
41 import org.openecomp.sdc.be.config.DistributionEngineConfiguration;
42 import org.openecomp.sdc.common.api.Constants;
43 import org.openecomp.sdc.common.api.HealthCheckInfo;
44 import org.openecomp.sdc.common.api.HealthCheckInfo.HealthCheckStatus;
45 import org.openecomp.sdc.common.config.EcompErrorName;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48 import org.springframework.stereotype.Component;
50 @Component("distribution-engine-cluster-health")
51 public class DistributionEngineClusterHealth {
53 protected static String UEB_HEALTH_LOG_CONTEXT = "ueb.healthcheck";
55 private static Logger healthLogger = LoggerFactory.getLogger(UEB_HEALTH_LOG_CONTEXT);
57 private static final String UEB_HEALTH_CHECK_STR = "uebHealthCheck";
59 boolean lastHealthState = false;
61 Object lockOject = new Object();
63 private long reconnectInterval = 5;
65 private long healthCheckReadTimeout = 20;
67 private static Logger logger = LoggerFactory.getLogger(DistributionEngineClusterHealth.class.getName());
69 private List<String> uebServers = null;
71 private String publicApiKey = null;
73 public enum HealthCheckInfoResult {
75 OK(new HealthCheckInfo(Constants.HC_COMPONENT_DISTRIBUTION_ENGINE, HealthCheckStatus.UP, null, ClusterStatusDescription.OK.getDescription())),
76 UNAVAILABLE(new HealthCheckInfo(Constants.HC_COMPONENT_DISTRIBUTION_ENGINE, HealthCheckStatus.DOWN, null, ClusterStatusDescription.UNAVAILABLE.getDescription())),
77 NOT_CONFIGURED(new HealthCheckInfo(Constants.HC_COMPONENT_DISTRIBUTION_ENGINE, HealthCheckStatus.DOWN, null, ClusterStatusDescription.NOT_CONFIGURED.getDescription())),
78 DISABLED(new HealthCheckInfo(Constants.HC_COMPONENT_DISTRIBUTION_ENGINE, HealthCheckStatus.DOWN, null, ClusterStatusDescription.DISABLED.getDescription()));
80 private HealthCheckInfo healthCheckInfo;
82 HealthCheckInfoResult(HealthCheckInfo healthCheckInfo) {
83 this.healthCheckInfo = healthCheckInfo;
86 public HealthCheckInfo getHealthCheckInfo() {
87 return healthCheckInfo;
92 private HealthCheckInfo healthCheckInfo = HealthCheckInfoResult.UNAVAILABLE.getHealthCheckInfo();
94 private Map<String, AtomicBoolean> envNamePerStatus = null;
96 private ScheduledFuture<?> scheduledFuture = null;
98 ScheduledExecutorService healthCheckScheduler = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
100 public Thread newThread(Runnable r) {
101 return new Thread(r, "UEB-Health-Check-Task");
105 HealthCheckScheduledTask healthCheckScheduledTask = null;
107 public enum ClusterStatusDescription {
109 OK("OK"), UNAVAILABLE("U-EB cluster is not available"), NOT_CONFIGURED("U-EB cluster is not configured"), DISABLED("DE is disabled in configuration");
113 ClusterStatusDescription(String desc) {
117 public String getDescription() {
124 * Health Check Task Scheduler.
126 * It schedules a task which send a apiKey get query towards the UEB servers. In case a query to the first UEB server is failed, then a second query is sent to the next UEB server.
132 public class HealthCheckScheduledTask implements Runnable {
134 List<UebHealthCheckCall> healthCheckCalls = new ArrayList<>();
136 public HealthCheckScheduledTask(List<String> uebServers) {
138 logger.debug("Create health check calls for servers {}", uebServers);
139 if (uebServers != null) {
140 for (String server : uebServers) {
141 healthCheckCalls.add(new UebHealthCheckCall(server, publicApiKey));
149 healthLogger.trace("Executing UEB Health Check Task - Start");
151 boolean healthStatus = verifyAtLeastOneEnvIsUp();
153 if (true == healthStatus) {
154 boolean queryUebStatus = queryUeb();
155 if (queryUebStatus == lastHealthState) {
159 synchronized (lockOject) {
160 if (queryUebStatus != lastHealthState) {
161 logger.trace("UEB Health State Changed to {}. Issuing alarm / recovery alarm...", healthStatus);
162 lastHealthState = queryUebStatus;
163 logAlarm(lastHealthState);
164 if (true == queryUebStatus) {
165 healthCheckInfo = HealthCheckInfoResult.OK.getHealthCheckInfo();
167 healthCheckInfo = HealthCheckInfoResult.UNAVAILABLE.getHealthCheckInfo();
172 healthLogger.trace("Not all UEB Environments are up");
178 * verify that at least one environment is up.
181 private boolean verifyAtLeastOneEnvIsUp() {
183 boolean healthStatus = false;
185 if (envNamePerStatus != null) {
186 Collection<AtomicBoolean> values = envNamePerStatus.values();
187 if (values != null) {
188 for (AtomicBoolean status : values) {
189 if (true == status.get()) {
201 * executor for the query itself
203 ExecutorService healthCheckExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
205 public Thread newThread(Runnable r) {
206 return new Thread(r, "UEB-Health-Check-Thread");
211 * go all UEB servers and send a get apiKeys query. In case a query is succeed, no query is sent to the rest of UEB servers.
216 private boolean queryUeb() {
218 Boolean result = false;
220 for (UebHealthCheckCall healthCheckCall : healthCheckCalls) {
223 healthLogger.debug("Before running Health Check retry query number {} towards UEB server {}", retryNumber, healthCheckCall.getServer());
225 Future<Boolean> future = healthCheckExecutor.submit(healthCheckCall);
226 result = future.get(healthCheckReadTimeout, TimeUnit.SECONDS);
228 healthLogger.debug("After running Health Check retry query number {} towards UEB server {}. Result is {}", retryNumber, healthCheckCall.getServer(), result);
230 if (result != null && true == result.booleanValue()) {
234 } catch (Exception e) {
235 String message = e.getMessage();
236 if (message == null) {
237 message = e.getClass().getName();
239 healthLogger.debug("Error occured during running Health Check retry query towards UEB server {}. Result is {}", healthCheckCall.getServer(), message);
240 healthLogger.trace("Error occured during running Health Check retry query towards UEB server {}. Result is {}", healthCheckCall.getServer(), message, e);
250 public List<UebHealthCheckCall> getHealthCheckCalls() {
251 return healthCheckCalls;
257 private void init() {
259 logger.trace("Enter init method of DistributionEngineClusterHealth");
261 Long reconnectIntervalConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getUebHealthCheckReconnectIntervalInSeconds();
262 if (reconnectIntervalConfig != null) {
263 reconnectInterval = reconnectIntervalConfig.longValue();
265 Long healthCheckReadTimeoutConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getUebHealthCheckReadTimeout();
266 if (healthCheckReadTimeoutConfig != null) {
267 healthCheckReadTimeout = healthCheckReadTimeoutConfig.longValue();
270 DistributionEngineConfiguration distributionEngineConfiguration = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration();
272 this.uebServers = distributionEngineConfiguration.getUebServers();
273 this.publicApiKey = distributionEngineConfiguration.getUebPublicKey();
275 this.healthCheckScheduledTask = new HealthCheckScheduledTask(this.uebServers);
277 logger.trace("Exit init method of DistributionEngineClusterHealth");
282 private void destroy() {
284 if (scheduledFuture != null) {
285 scheduledFuture.cancel(true);
286 scheduledFuture = null;
289 if (healthCheckScheduler != null) {
290 healthCheckScheduler.shutdown();
296 * Start health check task.
298 * @param envNamePerStatus
301 public void startHealthCheckTask(Map<String, AtomicBoolean> envNamePerStatus, boolean startTask) {
302 this.envNamePerStatus = envNamePerStatus;
304 if (startTask == true && this.scheduledFuture == null) {
305 this.scheduledFuture = this.healthCheckScheduler.scheduleAtFixedRate(healthCheckScheduledTask, 0, reconnectInterval, TimeUnit.SECONDS);
309 public void startHealthCheckTask(Map<String, AtomicBoolean> envNamePerStatus) {
310 startHealthCheckTask(envNamePerStatus, true);
313 private void logAlarm(boolean lastHealthState) {
314 if (lastHealthState == true) {
315 BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeHealthCheckRecovery, UEB_HEALTH_CHECK_STR);
316 BeEcompErrorManager.getInstance().logBeHealthCheckUebClusterRecovery(UEB_HEALTH_CHECK_STR);
318 BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeHealthCheckError, UEB_HEALTH_CHECK_STR);
319 BeEcompErrorManager.getInstance().logBeHealthCheckUebClusterError(UEB_HEALTH_CHECK_STR);
323 public HealthCheckInfo getHealthCheckInfo() {
324 return healthCheckInfo;
328 * change the health check to DISABLE
330 public void setHealthCheckUebIsDisabled() {
331 healthCheckInfo = HealthCheckInfoResult.DISABLED.getHealthCheckInfo();
335 * change the health check to NOT CONFGIURED
337 public void setHealthCheckUebConfigurationError() {
338 healthCheckInfo = HealthCheckInfoResult.NOT_CONFIGURED.getHealthCheckInfo();
341 public void setHealthCheckOkAndReportInCaseLastStateIsDown() {
343 if (lastHealthState == true) {
346 synchronized (lockOject) {
347 if (lastHealthState == false) {
348 logger.debug("Going to update health check state to available");
349 lastHealthState = true;
350 healthCheckInfo = HealthCheckInfoResult.OK.getHealthCheckInfo();
351 logAlarm(lastHealthState);