0379ae3578d95d7ecd5921252aac299fbca13554
[so.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
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
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
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=========================================================
21  */
22
23 package org.onap.so.apihandlerinfra;
24
25
26 import java.net.URI;
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;
58
59
60 @Component
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 = "";
76
77     // e.g. /manage
78     private String actuatorContextPath;
79
80     @Autowired
81     private Environment env;
82
83     @Autowired
84     private RestTemplate restTemplate;
85
86     @Autowired
87     private HealthCheckConfig config;
88
89     private static final String HEALTH = "/health";
90
91     private String msoAuth;
92
93     @PostConstruct
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);
97     }
98
99     @GET
100     @Produces("application/json")
101     @ApiOperation(value = "Performing global health check", response = Response.class)
102     @Transactional
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();
108
109         try {
110             // Generated RequestId
111             String requestId = requestContext.getProperty("requestId").toString();
112             logger.info(LoggingAnchor.TWO, MessageEnum.APIH_GENERATED_REQUEST_ID.toString(), requestId);
113
114             List<Endpoint> endpoints = config.getEndpoints().stream().filter(item -> {
115                 if (!enableBpmn && SoSubsystems.BPMN.equals(item.getSubsystem())) {
116                     return false;
117                 } else {
118                     return true;
119                 }
120             }).collect(Collectors.toList());
121
122             for (Endpoint endpoint : endpoints) {
123                 rsp.getSubsystems().add(querySubsystemHealth(endpoint));
124             }
125
126             // set Message
127             rsp.setMessage(String.format("HttpStatus: %s", HttpStatus.SC_OK));
128             logger.info(rsp.toString());
129
130             HEALTH_CHECK_RESPONSE = Response.status(HttpStatus.SC_OK).entity(rsp).build();
131
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();
136         }
137
138         return HEALTH_CHECK_RESPONSE;
139     }
140
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);
147         return entity;
148     }
149
150     protected HealthCheckSubsystem querySubsystemHealth(Endpoint subsystem) {
151         HealthCheckStatus status = HealthCheckStatus.DOWN;
152         URI uri = subsystem.getUri();
153         try {
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);
158
159             ResponseEntity<SubsystemHealthcheckResponse> result = restTemplate.exchange(uri, HttpMethod.GET,
160                     buildHttpEntityForRequest(), SubsystemHealthcheckResponse.class);
161
162             status = processResponseFromSubsystem(result, subsystem);
163
164
165         } catch (Exception ex) {
166             logger.error("Exception occured in GlobalHealthcheckHandler.querySubsystemHealth() ", ex);
167         }
168
169         return new HealthCheckSubsystem(subsystem.getSubsystem(), uri, status);
170     }
171
172     protected HealthCheckStatus processResponseFromSubsystem(ResponseEntity<SubsystemHealthcheckResponse> result,
173             Endpoint endpoint) {
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;
178         }
179
180         SubsystemHealthcheckResponse body = result.getBody();
181
182         String status = body.getStatus();
183         if ("UP".equalsIgnoreCase(status)) {
184             return HealthCheckStatus.UP;
185         } else {
186             logger.error("{}, query health endpoint did not return UP status!", endpoint.getSubsystem());
187             return HealthCheckStatus.DOWN;
188         }
189     }
190
191 }