Update vulnerable package dependencies
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / health / PortalHealthCheckBuilder.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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=========================================================
19  */
20 package org.openecomp.sdc.be.components.health;
21
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;
27
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;
58
59 @Component("portalHealthCheckBusinessLogic")
60 public class PortalHealthCheckBuilder {
61
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);
76
77     @VisibleForTesting
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;
87                 }
88                 Integer healthCheckReadTimeoutConfig = configuration.getTimeoutMs();
89                 if (healthCheckReadTimeoutConfig != null) {
90                     this.healthCheckReadTimeout = healthCheckReadTimeoutConfig;
91                 }
92                 this.healthCheckScheduledTask = new HealthCheckScheduledTask(configuration);
93                 startHealthCheckTask(true);
94             } else {
95                 log.error("ECOMP Portal health check configuration is missing.");
96             }
97         }
98         log.trace("Exit init method of Portal healthcheck");
99         return this;
100     }
101
102     @PostConstruct
103     public PortalHealthCheckBuilder init() throws CipherUtilException {
104         return init(ConfigurationManager.getConfigurationManager().getConfiguration().getEcompPortal());
105     }
106
107     @PreDestroy
108     protected void destroy() {
109         if (scheduledFuture != null) {
110             scheduledFuture.cancel(true);
111             scheduledFuture = null;
112         }
113         if (scheduler != null) {
114             scheduler.shutdown();
115         }
116     }
117
118     /**
119      * Start health check task.
120      *
121      * @param startTask
122      */
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);
127             }
128         }
129     }
130
131     @VisibleForTesting
132     void runTask() {
133         healthCheckScheduledTask.run();
134     }
135
136     public HealthCheckInfo getHealthCheckInfo() {
137         return healthCheckInfo;
138     }
139
140     /**
141      * Health Check Task Scheduler - infinite check.
142      */
143     public class HealthCheckScheduledTask implements Runnable {
144
145         private final EcompPortalConfig config;
146         String healthCheckUrl = buildPortalHealthCheckUrl();
147         HealthCheckStatus healthCheckStatus = DOWN;
148         String componentName = HC_COMPONENT_ECOMP_PORTAL;
149         String description;
150         final int timeout = 3000;
151
152         HealthCheckScheduledTask(final EcompPortalConfig config) {
153             this.config = config;
154         }
155
156         @Override
157         public void run() {
158             if (healthCheckUrl != null) {
159                 try {
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);
164                     } else {
165                         healthCheckStatus = UP;
166                         description = "OK";
167                     }
168                 } catch (Exception e) {
169                     log.error("{} is not available: ", componentName, e.getMessage());
170                     description = PORTAL_NOT_AVAILABLE;
171                 }
172             } else {
173                 description = CONFIG_IS_MISSING;
174             }
175             healthCheckInfo.setHealthCheckStatus(healthCheckStatus);
176             healthCheckInfo.setDescription(description);
177         }
178     }
179
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));
184         }
185         return value;
186     }
187
188     String buildPortalHealthCheckUrl() {
189         final String hcUrl = "%s://%s:%s%s";
190         Configuration.EcompPortalConfig configuration = ConfigurationManager.getConfigurationManager().getConfiguration().getEcompPortal();
191         if (configuration != null) {
192             return String
193                 .format(hcUrl, configuration.getProtocol(), configuration.getHost(), configuration.getPort(), configuration.getHealthCheckUri());
194         }
195         log.error("ECOMP Portal health check configuration is missing.");
196         return null;
197     }
198
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"));
208         return headers;
209     }
210
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();
214     }
215
216     @VisibleForTesting
217     public EcompPortalConfig getConfiguration() {
218         return ConfigurationManager.getConfigurationManager().getConfiguration().getEcompPortal();
219     }
220 }