1 package org.openecomp.sdc.be.components.distribution.engine;
3 import org.apache.commons.validator.routines.UrlValidator;
4 import org.apache.http.client.utils.URIUtils;
5 import org.openecomp.sdc.be.config.BeEcompErrorManager;
6 import org.openecomp.sdc.be.config.ConfigurationManager;
7 import org.openecomp.sdc.be.config.DmaapConsumerConfiguration;
8 import org.openecomp.sdc.common.api.HealthCheckInfo;
9 import org.openecomp.sdc.common.log.wrappers.Logger;
10 import org.springframework.stereotype.Component;
12 import javax.annotation.PostConstruct;
13 import javax.annotation.PreDestroy;
14 import java.io.IOException;
15 import java.net.InetAddress;
17 import java.net.URISyntaxException;
18 import java.util.concurrent.Executors;
19 import java.util.concurrent.ScheduledExecutorService;
20 import java.util.concurrent.ScheduledFuture;
21 import java.util.concurrent.TimeUnit;
22 import java.util.concurrent.atomic.AtomicBoolean;
24 import static org.apache.commons.lang3.StringUtils.countMatches;
25 import static org.apache.commons.lang3.StringUtils.isNotBlank;
26 import static org.openecomp.sdc.common.api.Constants.HC_COMPONENT_DMAAP_ENGINE;
28 @Component("dmaapHealth")
29 public class DmaapHealth {
32 private static final String DMAAP_HEALTH_LOG_CONTEXT = "dmaap.healthcheck";
33 private static final String DMAAP_HEALTH_CHECK_STR = "dmaapHealthCheck";
34 private static final Logger log = Logger.getLogger(DmaapHealth.class.getName());
35 private static final Logger logHealth = Logger.getLogger(DMAAP_HEALTH_LOG_CONTEXT);
36 private HealthCheckInfo healthCheckInfo = DmaapHealth.HealthCheckInfoResult.UNAVAILABLE.getHealthCheckInfo();
37 private long healthCheckReadTimeout = 20;
38 private long reconnectInterval = 5;
39 private HealthCheckScheduledTask healthCheckScheduledTask = null ;
40 private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
41 private ScheduledFuture<?> scheduledFuture = null;
42 private DmaapConsumerConfiguration configuration = null ;
44 private volatile AtomicBoolean lastHealthState = new AtomicBoolean(false);
45 private volatile AtomicBoolean reportedHealthState = null;
47 public enum HealthCheckInfoResult {
48 OK(new HealthCheckInfo(HC_COMPONENT_DMAAP_ENGINE, HealthCheckInfo.HealthCheckStatus.UP, null, DmaapStatusDescription.OK.getDescription())),
49 UNAVAILABLE(new HealthCheckInfo(HC_COMPONENT_DMAAP_ENGINE, HealthCheckInfo.HealthCheckStatus.DOWN, null, DmaapStatusDescription.UNAVAILABLE.getDescription())),
50 DOWN(new HealthCheckInfo(HC_COMPONENT_DMAAP_ENGINE, HealthCheckInfo.HealthCheckStatus.DOWN, null, DmaapStatusDescription.DOWN.getDescription()));
52 private HealthCheckInfo healthCheckInfo;
53 HealthCheckInfoResult(HealthCheckInfo healthCheckInfo) {
54 this.healthCheckInfo = healthCheckInfo;
56 public HealthCheckInfo getHealthCheckInfo() {
57 return healthCheckInfo;
61 public enum DmaapStatusDescription {
62 OK("OK"), UNAVAILABLE("Dmaap is not available"),DOWN("DOWN"), NOT_CONFIGURED("Dmaap configuration is missing/wrong ");
65 DmaapStatusDescription(String desc) {
68 public String getDescription() {
75 public DmaapHealth init() {
76 log.trace("Enter init method of Dmaap health");
77 synchronized (DmaapHealth.class){
78 this.configuration = ConfigurationManager.getConfigurationManager().getConfiguration().getDmaapConsumerConfiguration();
80 Integer pollingInterval = configuration.getPollingInterval();
81 if (pollingInterval != null && pollingInterval!=0) {
82 reconnectInterval = pollingInterval;
84 Integer healthCheckReadTimeoutConfig = configuration.getTimeoutMs();
85 if (healthCheckReadTimeoutConfig != null) {
86 this.healthCheckReadTimeout = healthCheckReadTimeoutConfig;
88 this.healthCheckScheduledTask = new HealthCheckScheduledTask( configuration ); //what is the representation? csv? delimiter? json or other
89 startHealthCheckTask(true);
91 log.trace("Exit init method of DistributionEngineClusterHealth");
96 protected void destroy() {
97 if (scheduledFuture != null) {
98 scheduledFuture.cancel(true);
99 scheduledFuture = null;
101 if (scheduler != null) {
102 scheduler.shutdown();
107 * Start health check task.
111 private void startHealthCheckTask(boolean startTask) {
112 synchronized (DmaapHealth.class){
113 if (startTask && this.scheduledFuture == null) {
114 this.scheduledFuture = this.scheduler.scheduleAtFixedRate(this.healthCheckScheduledTask , 0, reconnectInterval, TimeUnit.SECONDS);
119 void report(Boolean isUp){
120 if (reportedHealthState == null)
121 reportedHealthState = new AtomicBoolean(isUp);
122 reportedHealthState.set(isUp);
126 public HealthCheckInfo getHealthCheckInfo() {
127 return healthCheckInfo;
131 * Health Check Task Scheduler - infinite check.
133 public class HealthCheckScheduledTask implements Runnable {
134 private final DmaapConsumerConfiguration config;
135 private static final int TIMEOUT = 8192;
137 HealthCheckScheduledTask(final DmaapConsumerConfiguration config){
138 this.config = config;
142 logHealth.trace("Executing Dmaap Health Check Task - Start");
143 boolean prevIsReachable;
145 //first try simple ping
147 if ( reportedHealthState != null ){
148 reachable = reportedHealthState.get();
153 prevIsReachable = lastHealthState.getAndSet( reachable );
154 healthCheckInfo = reachable ? HealthCheckInfoResult.OK.healthCheckInfo : HealthCheckInfoResult.DOWN.healthCheckInfo;
156 catch( Exception e ){
157 log.debug("{} | cannot check connectivity -> {}",DMAAP_HEALTH_CHECK_STR, e );
158 prevIsReachable = lastHealthState.getAndSet(false);
159 healthCheckInfo = HealthCheckInfoResult.UNAVAILABLE.healthCheckInfo;
161 if (prevIsReachable != lastHealthState.get())
162 logAlarm( lastHealthState.get() );
167 * @deprecated (health is reported outside from EnvironmentEngine consumer fetch)
170 public boolean isICMPReachable( ) throws IOException{
172 String hostname = getUrlHost(config.getHosts());
173 return InetAddress.getByName( hostname ).isReachable(TIMEOUT);
174 }catch( URISyntaxException e ){
175 log.debug("{} | malformed host configuration -> ",DMAAP_HEALTH_CHECK_STR , e);
180 private void logAlarm(boolean lastHealthState) {
182 if ( lastHealthState ) {
183 BeEcompErrorManager.getInstance().logDmaapHealthCheckRecovery( DMAAP_HEALTH_CHECK_STR );
185 BeEcompErrorManager.getInstance().logDmaapHealthCheckError( DMAAP_HEALTH_CHECK_STR );
187 }catch( Exception e ){
188 log.debug("cannot logAlarm -> {}" ,e );
194 public static String getUrlHost(String qualifiedHost) throws URISyntaxException{
195 //region - parse complex format ex. <http://URL:PORT>
197 UrlValidator validator = new UrlValidator();
198 if (validator.isValid(qualifiedHost)){
199 return URIUtils.extractHost(new URI(qualifiedHost)).getHostName();
201 log.debug("{} | invalid url format, continuing ", DMAAP_HEALTH_CHECK_STR );
203 }catch(URISyntaxException e){
204 log.debug("{} | invalid url format, continuing {} ", DMAAP_HEALTH_CHECK_STR , e);
208 //region - try shortcut format <URL> or <URL:PORT>
209 if ( countMatches( qualifiedHost , ":") <= 1){
210 String[] address = qualifiedHost.split(":");
211 if ( address.length>0 && isNotBlank(address[0]) ){
216 throw new URISyntaxException( qualifiedHost , "invalid hostname, expecting a single <host:port> , (valid ex. www.google.com:80 | www.google.com | http:\\\\www.google.com:8181)");