2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Modifications Copyright (c) 2019 Samsung
8 * ================================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 * ============LICENSE_END=========================================================
23 package org.onap.so.apihandlerinfra;
27 import java.util.Collections;
28 import java.util.List;
29 import java.util.stream.Collectors;
30 import javax.annotation.PostConstruct;
31 import javax.transaction.Transactional;
32 import javax.ws.rs.DefaultValue;
33 import javax.ws.rs.GET;
34 import javax.ws.rs.Path;
35 import javax.ws.rs.Produces;
36 import javax.ws.rs.QueryParam;
37 import javax.ws.rs.container.ContainerRequestContext;
38 import javax.ws.rs.core.Context;
39 import javax.ws.rs.core.Response;
40 import javax.ws.rs.core.UriBuilder;
41 import org.apache.http.HttpStatus;
42 import org.onap.so.apihandlerinfra.HealthCheckConfig.Endpoint;
43 import org.onap.so.logger.LoggingAnchor;
44 import org.onap.so.logger.MessageEnum;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47 import org.springframework.beans.factory.annotation.Autowired;
48 import org.springframework.core.env.Environment;
49 import org.springframework.http.HttpEntity;
50 import org.springframework.http.HttpHeaders;
51 import org.springframework.http.HttpMethod;
52 import org.springframework.http.MediaType;
53 import org.springframework.http.ResponseEntity;
54 import org.springframework.stereotype.Component;
55 import org.springframework.web.client.RestTemplate;
56 import io.swagger.annotations.Api;
57 import io.swagger.annotations.ApiOperation;
61 @Path("/globalhealthcheck")
62 @Api(value = "/globalhealthcheck", description = "APIH Infra Global Health Check")
63 public class GlobalHealthcheckHandler {
64 private static Logger logger = LoggerFactory.getLogger(GlobalHealthcheckHandler.class);
65 protected static final String CONTEXTPATH_PROPERTY = "management.endpoints.web.base-path";
66 protected static final String PROPERTY_DOMAIN = "mso.health";
67 protected static final String CATALOGDB_PROPERTY = PROPERTY_DOMAIN + ".endpoints.catalogdb";
68 protected static final String REQUESTDB_PROPERTY = PROPERTY_DOMAIN + ".endpoints.requestdb";
69 protected static final String SDNC_PROPERTY = PROPERTY_DOMAIN + ".endpoints.sdnc";
70 protected static final String OPENSTACK_PROPERTY = PROPERTY_DOMAIN + ".endpoints.openstack";
71 protected static final String BPMN_PROPERTY = PROPERTY_DOMAIN + ".endpoints.bpmn";
72 protected static final String ASDC_PROPERTY = PROPERTY_DOMAIN + ".endpoints.asdc";
73 protected static final String REQUESTDBATTSVC_PROPERTY = PROPERTY_DOMAIN + ".endpoints.requestdbattsvc";
74 protected static final String MSO_AUTH_PROPERTY = PROPERTY_DOMAIN + ".auth";
75 protected static final String DEFAULT_PROPERTY_VALUE = "";
78 private String actuatorContextPath;
81 private Environment env;
84 private RestTemplate restTemplate;
87 private HealthCheckConfig config;
89 private static final String HEALTH = "/health";
91 private String msoAuth;
94 protected void init() {
95 actuatorContextPath = env.getProperty(CONTEXTPATH_PROPERTY, String.class, DEFAULT_PROPERTY_VALUE);
96 msoAuth = env.getProperty(MSO_AUTH_PROPERTY, String.class, DEFAULT_PROPERTY_VALUE);
100 @Produces("application/json")
101 @ApiOperation(value = "Performing global health check", response = Response.class)
103 public Response globalHealthcheck(@DefaultValue("true") @QueryParam("enableBpmn") boolean enableBpmn,
104 @Context ContainerRequestContext requestContext) {
105 Response HEALTH_CHECK_RESPONSE = null;
106 // Build internal response object
107 HealthCheckResponse rsp = new HealthCheckResponse();
110 // Generated RequestId
111 String requestId = requestContext.getProperty("requestId").toString();
112 logger.info(LoggingAnchor.TWO, MessageEnum.APIH_GENERATED_REQUEST_ID.toString(), requestId);
114 List<Endpoint> endpoints = config.getEndpoints().stream().filter(item -> {
115 if (!enableBpmn && SoSubsystems.BPMN.equals(item.getSubsystem())) {
120 }).collect(Collectors.toList());
122 for (Endpoint endpoint : endpoints) {
123 rsp.getSubsystems().add(querySubsystemHealth(endpoint));
127 rsp.setMessage(String.format("HttpStatus: %s", HttpStatus.SC_OK));
128 logger.info(rsp.toString());
130 HEALTH_CHECK_RESPONSE = Response.status(HttpStatus.SC_OK).entity(rsp).build();
132 } catch (Exception ex) {
133 logger.error("Exception occurred", ex);
134 rsp.setMessage(ex.getMessage());
135 HEALTH_CHECK_RESPONSE = Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).entity(rsp).build();
138 return HEALTH_CHECK_RESPONSE;
141 protected HttpEntity<String> buildHttpEntityForRequest() {
142 HttpHeaders headers = new HttpHeaders();
143 headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
144 headers.set(HttpHeaders.CONTENT_TYPE, "application/json");
145 headers.set(HttpHeaders.AUTHORIZATION, msoAuth);
146 HttpEntity<String> entity = new HttpEntity<>("parameters", headers);
150 protected HealthCheckSubsystem querySubsystemHealth(Endpoint subsystem) {
151 HealthCheckStatus status = HealthCheckStatus.DOWN;
152 URI uri = subsystem.getUri();
154 // get port number for the subsystem
155 // build final endpoint url
156 uri = UriBuilder.fromUri(subsystem.getUri()).path(actuatorContextPath).path(HEALTH).build();
157 logger.info("Calculated URL: {}", uri);
159 ResponseEntity<SubsystemHealthcheckResponse> result = restTemplate.exchange(uri, HttpMethod.GET,
160 buildHttpEntityForRequest(), SubsystemHealthcheckResponse.class);
162 status = processResponseFromSubsystem(result, subsystem);
165 } catch (Exception ex) {
166 logger.error("Exception occured in GlobalHealthcheckHandler.querySubsystemHealth() ", ex);
169 return new HealthCheckSubsystem(subsystem.getSubsystem(), uri, status);
172 protected HealthCheckStatus processResponseFromSubsystem(ResponseEntity<SubsystemHealthcheckResponse> result,
174 if (result == null || result.getStatusCodeValue() != HttpStatus.SC_OK) {
175 logger.error(String.format("Globalhealthcheck: checking subsystem: %s failed ! result object is: %s",
176 endpoint.getSubsystem(), result == null ? "NULL" : result));
177 return HealthCheckStatus.DOWN;
180 SubsystemHealthcheckResponse body = result.getBody();
182 String status = body.getStatus();
183 if ("UP".equalsIgnoreCase(status)) {
184 return HealthCheckStatus.UP;
186 logger.error("{}, query health endpoint did not return UP status!", endpoint.getSubsystem());
187 return HealthCheckStatus.DOWN;