2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2020 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.health;
22 import static org.apache.http.HttpStatus.SC_OK;
23 import static org.onap.portalsdk.core.onboarding.util.CipherUtil.decryptPKC;
24 import static org.openecomp.sdc.common.api.Constants.HC_COMPONENT_ECOMP_PORTAL;
25 import static org.openecomp.sdc.common.api.HealthCheckInfo.HealthCheckStatus.DOWN;
26 import static org.openecomp.sdc.common.api.HealthCheckInfo.HealthCheckStatus.UP;
28 import com.google.common.annotations.VisibleForTesting;
29 import java.security.InvalidParameterException;
30 import java.util.Base64;
31 import java.util.Properties;
32 import java.util.UUID;
33 import java.util.concurrent.Executors;
34 import java.util.concurrent.ScheduledExecutorService;
35 import java.util.concurrent.ScheduledFuture;
36 import java.util.concurrent.TimeUnit;
37 import javax.annotation.PostConstruct;
38 import javax.annotation.PreDestroy;
39 import javax.ws.rs.core.HttpHeaders;
40 import javax.ws.rs.core.MediaType;
41 import org.apache.commons.lang3.StringUtils;
42 import org.onap.portalsdk.core.onboarding.exception.CipherUtilException;
43 import org.onap.portalsdk.core.onboarding.util.PortalApiProperties;
44 import org.openecomp.sdc.be.config.Configuration;
45 import org.openecomp.sdc.be.config.Configuration.EcompPortalConfig;
46 import org.openecomp.sdc.be.config.ConfigurationManager;
47 import org.openecomp.sdc.be.ecomp.PortalPropertiesEnum;
48 import org.openecomp.sdc.common.api.Constants;
49 import org.openecomp.sdc.common.api.HealthCheckInfo;
50 import org.openecomp.sdc.common.api.HealthCheckInfo.HealthCheckStatus;
51 import org.openecomp.sdc.common.http.client.api.HttpExecuteException;
52 import org.openecomp.sdc.common.http.client.api.HttpRequest;
53 import org.openecomp.sdc.common.http.client.api.HttpResponse;
54 import org.openecomp.sdc.common.http.config.HttpClientConfig;
55 import org.openecomp.sdc.common.http.config.Timeouts;
56 import org.openecomp.sdc.common.log.wrappers.Logger;
57 import org.springframework.stereotype.Component;
59 @Component("portalHealthCheckBusinessLogic")
60 public class PortalHealthCheckBuilder {
62 private static final Logger log = Logger.getLogger(HealthCheckBusinessLogic.class.getName());
63 private static final String PORTAL_NOT_AVAILABLE = HC_COMPONENT_ECOMP_PORTAL + " is not available";
64 private static final String PROPERTY_NOT_SET = "Property is not found %s";
65 private static final String CONFIG_IS_MISSING = HC_COMPONENT_ECOMP_PORTAL + " health check configuration is missing";
66 private static final String PORTAL_ERROR = HC_COMPONENT_ECOMP_PORTAL + " responded with %s status code";
67 private String decryptedPortalUser;
68 private String decryptedPortalPass;
69 private EcompPortalConfig configuration = null;
70 private long healthCheckReadTimeout = 20;
71 private long reconnectInterval = 5;
72 private HealthCheckScheduledTask healthCheckScheduledTask = null;
73 private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
74 private ScheduledFuture<?> scheduledFuture = null;
75 private HealthCheckInfo healthCheckInfo = new HealthCheckInfo(HC_COMPONENT_ECOMP_PORTAL, HealthCheckStatus.DOWN, null, CONFIG_IS_MISSING, null);
78 PortalHealthCheckBuilder init(EcompPortalConfig configuration) throws CipherUtilException {
79 log.trace("Enter init method of Portal healthcheck");
80 decryptedPortalUser = decryptPKC(getPortalProperty(PortalPropertiesEnum.USER.value()));
81 decryptedPortalPass = decryptPKC(getPortalProperty(PortalPropertiesEnum.PASSWORD.value()));
82 synchronized (PortalHealthCheckBuilder.class) {
83 if (configuration != null) {
84 Integer pollingInterval = configuration.getPollingInterval();
85 if (pollingInterval != null && pollingInterval != 0) {
86 reconnectInterval = pollingInterval;
88 Integer healthCheckReadTimeoutConfig = configuration.getTimeoutMs();
89 if (healthCheckReadTimeoutConfig != null) {
90 this.healthCheckReadTimeout = healthCheckReadTimeoutConfig;
92 this.healthCheckScheduledTask = new HealthCheckScheduledTask(configuration);
93 startHealthCheckTask(true);
95 log.error("ECOMP Portal health check configuration is missing.");
98 log.trace("Exit init method of Portal healthcheck");
103 public PortalHealthCheckBuilder init() throws CipherUtilException {
104 return init(ConfigurationManager.getConfigurationManager().getConfiguration().getEcompPortal());
108 protected void destroy() {
109 if (scheduledFuture != null) {
110 scheduledFuture.cancel(true);
111 scheduledFuture = null;
113 if (scheduler != null) {
114 scheduler.shutdown();
119 * Start health check task.
123 private void startHealthCheckTask(boolean startTask) {
124 synchronized (PortalHealthCheckBuilder.class) {
125 if (startTask && this.scheduledFuture == null) {
126 this.scheduledFuture = this.scheduler.scheduleAtFixedRate(this.healthCheckScheduledTask, 0, reconnectInterval, TimeUnit.SECONDS);
133 healthCheckScheduledTask.run();
136 public HealthCheckInfo getHealthCheckInfo() {
137 return healthCheckInfo;
141 * Health Check Task Scheduler - infinite check.
143 public class HealthCheckScheduledTask implements Runnable {
145 private final EcompPortalConfig config;
146 String healthCheckUrl = buildPortalHealthCheckUrl();
147 HealthCheckStatus healthCheckStatus = DOWN;
148 String componentName = HC_COMPONENT_ECOMP_PORTAL;
150 final int timeout = 3000;
152 HealthCheckScheduledTask(final EcompPortalConfig config) {
153 this.config = config;
158 if (healthCheckUrl != null) {
160 int statusCode = getStatusCode(healthCheckUrl, timeout);
161 log.trace("{} Health Check response code: {}", componentName, statusCode);
162 if (statusCode != SC_OK) {
163 description = String.format(PORTAL_ERROR, statusCode);
165 healthCheckStatus = UP;
168 } catch (Exception e) {
169 log.error("{} is not available: ", componentName, e.getMessage());
170 description = PORTAL_NOT_AVAILABLE;
173 description = CONFIG_IS_MISSING;
175 healthCheckInfo.setHealthCheckStatus(healthCheckStatus);
176 healthCheckInfo.setDescription(description);
180 private static String getPortalProperty(String key) {
181 String value = PortalApiProperties.getProperty(key);
182 if (StringUtils.isEmpty(value)) {
183 throw new InvalidParameterException(String.format(PROPERTY_NOT_SET, key));
188 String buildPortalHealthCheckUrl() {
189 final String hcUrl = "%s://%s:%s%s";
190 Configuration.EcompPortalConfig configuration = ConfigurationManager.getConfigurationManager().getConfiguration().getEcompPortal();
191 if (configuration != null) {
193 .format(hcUrl, configuration.getProtocol(), configuration.getHost(), configuration.getPort(), configuration.getHealthCheckUri());
195 log.error("ECOMP Portal health check configuration is missing.");
199 private Properties createHeaders() {
200 Properties headers = new Properties();
201 String encodedBasicAuthCred = Base64.getEncoder().encodeToString((decryptedPortalUser + ":" + decryptedPortalPass).getBytes());
202 headers.put(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON);
203 headers.put(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
204 headers.put(Constants.X_TRANSACTION_ID_HEADER, UUID.randomUUID().toString());
205 headers.put("Authorization", "Basic " + encodedBasicAuthCred);
206 headers.put("cache-control", "no-cache");
207 headers.put("uebkey", PortalApiProperties.getProperty("ueb_app_key"));
211 int getStatusCode(String healthCheckUrl, int timeout) throws HttpExecuteException {
212 HttpResponse<String> httpResponse = HttpRequest.get(healthCheckUrl, createHeaders(), new HttpClientConfig(new Timeouts(timeout, timeout)));
213 return httpResponse.getStatusCode();
217 public EcompPortalConfig getConfiguration() {
218 return ConfigurationManager.getConfigurationManager().getConfiguration().getEcompPortal();