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=========================================================
20 package org.openecomp.sdc.be.components.distribution.engine;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.List;
26 import java.util.concurrent.ExecutorService;
27 import java.util.concurrent.Executors;
28 import java.util.concurrent.Future;
29 import java.util.concurrent.ScheduledExecutorService;
30 import java.util.concurrent.ScheduledFuture;
31 import java.util.concurrent.ThreadFactory;
32 import java.util.concurrent.TimeUnit;
33 import java.util.concurrent.atomic.AtomicBoolean;
34 import javax.annotation.PostConstruct;
35 import javax.annotation.PreDestroy;
36 import org.openecomp.sdc.be.config.BeEcompErrorManager;
37 import org.openecomp.sdc.be.config.ConfigurationManager;
38 import org.openecomp.sdc.be.config.DistributionEngineConfiguration;
39 import org.openecomp.sdc.common.api.Constants;
40 import org.openecomp.sdc.common.api.HealthCheckInfo;
41 import org.openecomp.sdc.common.api.HealthCheckInfo.HealthCheckStatus;
42 import org.openecomp.sdc.common.log.wrappers.Logger;
43 import org.springframework.stereotype.Component;
45 @Component("distribution-engine-cluster-health")
46 public class DistributionEngineClusterHealth {
48 private static final String UEB_HEALTH_CHECK_STR = "uebHealthCheck";
49 private static final Logger logger = Logger.getLogger(DistributionEngineClusterHealth.class.getName());
50 protected static String UEB_HEALTH_LOG_CONTEXT = "ueb.healthcheck";
51 //TODO use LoggerMetric instead
52 private static final Logger healthLogger = Logger.getLogger(UEB_HEALTH_LOG_CONTEXT);
53 boolean lastHealthState = false;
54 Object lockOject = new Object();
55 ScheduledExecutorService healthCheckScheduler = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
57 public Thread newThread(Runnable r) {
58 return new Thread(r, "UEB-Health-Check-Task");
61 HealthCheckScheduledTask healthCheckScheduledTask = null;
62 private long reconnectInterval = 5;
63 private long healthCheckReadTimeout = 20;
64 private List<String> uebServers = null;
65 private String publicApiKey = null;
66 private HealthCheckInfo healthCheckInfo = HealthCheckInfoResult.UNKNOWN.getHealthCheckInfo();
67 private Map<String, AtomicBoolean> envNamePerStatus = null;
68 private ScheduledFuture<?> scheduledFuture = null;
71 protected void init() {
72 logger.trace("Enter init method of DistributionEngineClusterHealth");
73 Long reconnectIntervalConfig = ConfigurationManager.getConfigurationManager().getConfiguration()
74 .getUebHealthCheckReconnectIntervalInSeconds();
75 if (reconnectIntervalConfig != null) {
76 reconnectInterval = reconnectIntervalConfig.longValue();
78 Long healthCheckReadTimeoutConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getUebHealthCheckReadTimeout();
79 if (healthCheckReadTimeoutConfig != null) {
80 healthCheckReadTimeout = healthCheckReadTimeoutConfig.longValue();
82 DistributionEngineConfiguration distributionEngineConfiguration = ConfigurationManager.getConfigurationManager()
83 .getDistributionEngineConfiguration();
84 this.uebServers = distributionEngineConfiguration.getUebServers();
85 this.publicApiKey = distributionEngineConfiguration.getUebPublicKey();
86 this.healthCheckScheduledTask = new HealthCheckScheduledTask(this.uebServers);
87 logger.trace("Exit init method of DistributionEngineClusterHealth");
91 protected void destroy() {
92 if (scheduledFuture != null) {
93 scheduledFuture.cancel(true);
94 scheduledFuture = null;
96 if (healthCheckScheduler != null) {
97 healthCheckScheduler.shutdown();
102 * Start health check task.
104 * @param envNamePerStatus
107 public void startHealthCheckTask(Map<String, AtomicBoolean> envNamePerStatus, boolean startTask) {
108 this.envNamePerStatus = envNamePerStatus;
109 if (startTask && this.scheduledFuture == null) {
110 this.scheduledFuture = this.healthCheckScheduler.scheduleAtFixedRate(healthCheckScheduledTask, 0, reconnectInterval, TimeUnit.SECONDS);
114 public void startHealthCheckTask(Map<String, AtomicBoolean> envNamePerStatus) {
115 startHealthCheckTask(envNamePerStatus, true);
118 private void logAlarm(boolean lastHealthState) {
119 if (lastHealthState) {
120 BeEcompErrorManager.getInstance().logBeHealthCheckUebClusterRecovery(UEB_HEALTH_CHECK_STR);
122 BeEcompErrorManager.getInstance().logBeHealthCheckUebClusterError(UEB_HEALTH_CHECK_STR);
126 public HealthCheckInfo getHealthCheckInfo() {
127 return healthCheckInfo;
131 * change the health check to DISABLE
133 public void setHealthCheckUebIsDisabled() {
134 healthCheckInfo = HealthCheckInfoResult.DISABLED.getHealthCheckInfo();
138 * change the health check to NOT CONFGIURED
140 public void setHealthCheckUebConfigurationError() {
141 healthCheckInfo = HealthCheckInfoResult.NOT_CONFIGURED.getHealthCheckInfo();
144 public void setHealthCheckOkAndReportInCaseLastStateIsDown() {
145 if (lastHealthState) {
148 synchronized (lockOject) {
149 if (!lastHealthState) {
150 logger.debug("Going to update health check state to available");
151 lastHealthState = true;
152 healthCheckInfo = HealthCheckInfoResult.OK.getHealthCheckInfo();
153 logAlarm(lastHealthState);
158 public enum HealthCheckInfoResult {
159 OK(new HealthCheckInfo(Constants.HC_COMPONENT_DISTRIBUTION_ENGINE, HealthCheckStatus.UP, null,
160 ClusterStatusDescription.OK.getDescription())), UNAVAILABLE(
161 new HealthCheckInfo(Constants.HC_COMPONENT_DISTRIBUTION_ENGINE, HealthCheckStatus.DOWN, null,
162 ClusterStatusDescription.UNAVAILABLE.getDescription())), NOT_CONFIGURED(
163 new HealthCheckInfo(Constants.HC_COMPONENT_DISTRIBUTION_ENGINE, HealthCheckStatus.DOWN, null,
164 ClusterStatusDescription.NOT_CONFIGURED.getDescription())), DISABLED(
165 new HealthCheckInfo(Constants.HC_COMPONENT_DISTRIBUTION_ENGINE, HealthCheckStatus.DOWN, null,
166 ClusterStatusDescription.DISABLED.getDescription())), UNKNOWN(
167 new HealthCheckInfo(Constants.HC_COMPONENT_DISTRIBUTION_ENGINE, HealthCheckStatus.UNKNOWN, null,
168 ClusterStatusDescription.UNKNOWN.getDescription()));
169 private HealthCheckInfo healthCheckInfo;
171 HealthCheckInfoResult(HealthCheckInfo healthCheckInfo) {
172 this.healthCheckInfo = healthCheckInfo;
175 public HealthCheckInfo getHealthCheckInfo() {
176 return healthCheckInfo;
180 public enum ClusterStatusDescription {
181 OK("OK"), UNAVAILABLE("U-EB cluster is not available"), NOT_CONFIGURED("U-EB cluster is not configured"), DISABLED(
182 "DE is disabled in configuration"), UNKNOWN("U-EB cluster is currently unknown (try again in few minutes)");
185 ClusterStatusDescription(String desc) {
189 public String getDescription() {
195 * Health Check Task Scheduler.
197 * 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
198 * query is sent to the next UEB server.
202 public class HealthCheckScheduledTask implements Runnable {
204 List<UebHealthCheckCall> healthCheckCalls = new ArrayList<>();
206 * executor for the query itself
208 ExecutorService healthCheckExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
210 public Thread newThread(Runnable r) {
211 return new Thread(r, "UEB-Health-Check-Thread");
215 public HealthCheckScheduledTask(List<String> uebServers) {
216 logger.debug("Create health check calls for servers {}", uebServers);
217 if (uebServers != null) {
218 for (String server : uebServers) {
219 healthCheckCalls.add(new UebHealthCheckCall(server, publicApiKey));
226 healthLogger.trace("Executing UEB Health Check Task - Start");
227 boolean healthStatus = verifyAtLeastOneEnvIsUp();
229 boolean queryUebStatus = queryUeb();
230 if (queryUebStatus == lastHealthState) {
233 synchronized (lockOject) {
234 if (queryUebStatus != lastHealthState) {
235 logger.trace("UEB Health State Changed to {}. Issuing alarm / recovery alarm...", healthStatus);
236 lastHealthState = queryUebStatus;
237 logAlarm(lastHealthState);
238 if (queryUebStatus) {
239 healthCheckInfo = HealthCheckInfoResult.OK.getHealthCheckInfo();
241 healthCheckInfo = HealthCheckInfoResult.UNAVAILABLE.getHealthCheckInfo();
246 healthLogger.trace("Not all UEB Environments are up");
251 * verify that at least one environment is up.
253 private boolean verifyAtLeastOneEnvIsUp() {
254 boolean healthStatus = false;
255 if (envNamePerStatus != null) {
256 Collection<AtomicBoolean> values = envNamePerStatus.values();
257 if (values != null) {
258 for (AtomicBoolean status : values) {
270 * 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.
274 private boolean queryUeb() {
275 Boolean result = false;
277 for (UebHealthCheckCall healthCheckCall : healthCheckCalls) {
280 .debug("Before running Health Check retry query number {} towards UEB server {}", retryNumber, healthCheckCall.getServer());
281 Future<Boolean> future = healthCheckExecutor.submit(healthCheckCall);
282 result = future.get(healthCheckReadTimeout, TimeUnit.SECONDS);
283 healthLogger.debug("After running Health Check retry query number {} towards UEB server {}. Result is {}", retryNumber,
284 healthCheckCall.getServer(), result);
285 if (result != null && result.booleanValue()) {
288 } catch (Exception e) {
289 String message = e.getMessage();
290 if (message == null) {
291 message = e.getClass().getName();
293 healthLogger.debug("Error occured during running Health Check retry query towards UEB server {}. Result is {}",
294 healthCheckCall.getServer(), message);
295 healthLogger.trace("Error occured during running Health Check retry query towards UEB server {}. Result is {}",
296 healthCheckCall.getServer(), message, e);
303 public List<UebHealthCheckCall> getHealthCheckCalls() {
304 return healthCheckCalls;