Initial OpenECOMP MSO commit
[so.git] / bpmn / MSOCoreBPMN / src / main / java / org / openecomp / mso / bpmn / core / HealthCheckHandler.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * OPENECOMP - MSO
4  * ================================================================================
5  * Copyright (C) 2017 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
21 package org.openecomp.mso.bpmn.core;
22
23 import org.apache.http.client.config.RequestConfig;
24 import org.apache.http.impl.client.CloseableHttpClient;
25 import org.apache.http.impl.client.HttpClientBuilder;
26 import org.apache.http.HttpResponse;
27 import org.apache.http.HttpStatus;
28 import org.apache.http.HttpEntity;
29 import org.apache.http.client.methods.HttpPost;
30 import org.apache.http.entity.StringEntity;
31
32 import java.io.BufferedReader;
33 import java.io.InputStreamReader;
34 import java.util.Map;
35 import java.util.UUID;
36
37 import org.openecomp.mso.logger.MsoLogger;
38 import org.openecomp.mso.logger.MessageEnum;
39 import javax.ws.rs.GET;
40 import javax.ws.rs.HEAD;
41 import javax.ws.rs.Path;
42 import javax.ws.rs.Produces;
43 import javax.ws.rs.QueryParam;
44 import javax.ws.rs.core.Response;
45
46 import org.camunda.bpm.engine.ProcessEngines;
47
48 @Path("/")
49 public class HealthCheckHandler  {
50
51         private static MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL);
52     private static final String SITENAME = "mso.sitename";
53     private static final String ADPTER_ENDPOINT = "mso.adapters.db.endpoint";
54     private static final String CONFIG = "mso.bpmn.urn.properties";
55
56     private static final String CHECK_HTML = "<!DOCTYPE html><html><head><meta charset=\"ISO-8859-1\"><title>Health Check</title></head><body>Application ready</body></html>";
57     private static final String NOT_FOUND = "<!DOCTYPE html><html><head><meta charset=\"ISO-8859-1\"><title>Application Not Started</title></head><body>Application not started. Properties file missing or invalid or database Connection failed</body></html>";
58     private static final String NOT_HEALTHY = "<!DOCTYPE html><html><head><meta charset=\"ISO-8859-1\"><title>Application Not Started</title></head><body>Application not available or at least one of the sub-modules is not available.</body></html>";
59     public static final Response HEALTH_CHECK_RESPONSE = Response.status (HttpStatus.SC_OK)
60             .entity (CHECK_HTML)
61             .build ();
62     public static final Response HEALTH_CHECK_NOK_RESPONSE = Response.status (HttpStatus.SC_SERVICE_UNAVAILABLE)
63             .entity (NOT_HEALTHY)
64             .  build ();
65     public static final Response NOT_STARTED_RESPONSE = Response.status (HttpStatus.SC_SERVICE_UNAVAILABLE)
66             .entity (NOT_FOUND)
67             .build ();
68
69     @HEAD
70     @GET
71     @Path("/healthcheck")
72     @Produces("text/html")
73     public Response healthcheck (@QueryParam("requestId") String requestId) {
74         MsoLogger.setServiceName ("Healthcheck");
75         verifyOldUUID(requestId);
76
77         PropertyConfiguration propertyConfiguration = PropertyConfiguration.getInstance();
78         Map<String,String> props = propertyConfiguration.getProperties(CONFIG);
79
80         if (props == null) {
81
82             msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION, "BPMN", MsoLogger.getServiceName(),  MsoLogger.ErrorCode.AvailabilityError, "Unable to load " + CONFIG);
83
84             return NOT_STARTED_RESPONSE;
85         }
86
87         String siteName = props.get(SITENAME);
88         String endpoint = props.get(ADPTER_ENDPOINT);
89
90         if (null == siteName || siteName.length () == 0 || null == endpoint || endpoint.length () == 0) {
91
92             msoLogger.error(MessageEnum.BPMN_GENERAL_EXCEPTION, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.DataError, "Unable to load key attributes (" + SITENAME + " or " + ADPTER_ENDPOINT + ") from the config file:" + CONFIG);
93
94             return NOT_STARTED_RESPONSE;
95         }
96
97         try {
98             if (!this.getSiteStatus (endpoint, siteName)) {
99                 msoLogger.debug("This site is currently disabled for maintenance.");
100                 return HEALTH_CHECK_NOK_RESPONSE;
101             }
102         } catch (Exception e) {
103
104             msoLogger.error(MessageEnum.GENERAL_EXCEPTION_ARG, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception while getting SiteStatus", e);
105
106             msoLogger.debug("Exception while getting SiteStatus");
107             return NOT_STARTED_RESPONSE;
108         }
109
110         try {
111             ProcessEngines.getDefaultProcessEngine().getIdentityService().createGroupQuery().list();
112         } catch (final Exception e) {
113
114             msoLogger.error(MessageEnum.GENERAL_EXCEPTION_ARG, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.UnknownError, "Exception while verifying Camunda engine", e);
115
116             msoLogger.debug("Exception while verifying Camunda engine");
117             return NOT_STARTED_RESPONSE;
118         }
119
120         return HEALTH_CHECK_RESPONSE;
121     }
122
123
124     private String verifyOldUUID (String oldId) {
125         if (!isValidUUID(oldId)) {
126             String newId = UUID.randomUUID().toString();
127             MsoLogger.setLogContext(newId, null);
128             return newId;
129         }
130         MsoLogger.setLogContext(oldId, null);
131         return oldId;
132     }
133
134
135     private boolean isValidUUID (String id) {
136         try {
137             if (null == id) {
138                 return false;
139             }
140             UUID uuid = UUID.fromString(id);
141             return uuid.toString().equalsIgnoreCase(id);
142         } catch (IllegalArgumentException iae) {
143             return false;
144         }
145     }
146
147     private boolean getSiteStatus (String url, String site) throws Exception {
148         HttpResponse response;
149         // set the connection timeout value to 30 seconds (30000 milliseconds)
150         RequestConfig.Builder requestBuilder = RequestConfig.custom();
151         requestBuilder = requestBuilder.setConnectTimeout(30000);
152         requestBuilder = requestBuilder.setConnectionRequestTimeout(30000);
153         HttpClientBuilder builder = HttpClientBuilder.create ();
154         builder.setDefaultRequestConfig (requestBuilder.build ());
155
156         HttpPost post = new HttpPost(url);
157         msoLogger.debug("Post url is: " + url);
158
159         //now create a soap request message as follows:
160         final StringBuffer payload = new StringBuffer();
161         payload.append("\n");
162         payload.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:req=\"http://com.att.mso/requestsdb\">\n");
163         payload.append("<soapenv:Header/>\n");
164         payload.append("<soapenv:Body>\n");
165         payload.append("<req:getSiteStatus>\n");
166         payload.append("<siteName>" + site + "</siteName>\n");
167         payload.append("</req:getSiteStatus>\n");
168         payload.append("</soapenv:Body>\n");
169         payload.append("</soapenv:Envelope>\n");
170
171         msoLogger.debug ("Initialize SOAP request to url:" + url);
172         msoLogger.debug ("The payload of the request is:" + payload);
173         HttpEntity entity = new StringEntity(payload.toString(),"UTF-8");
174         post.setEntity(entity);
175
176         try (CloseableHttpClient client = builder.build()) {
177             response = client.execute(post);
178             msoLogger.debug("Response received is:" + response);
179
180             int statusCode = response.getStatusLine().getStatusCode();
181             if (statusCode != 200) {
182
183                 msoLogger.error(MessageEnum.GENERAL_EXCEPTION_ARG, "BPMN", MsoLogger.getServiceName(), MsoLogger.ErrorCode.DataError,
184                         "Communication with DB Adapter failed, The response received from DB Adapter is with failed status code:" + statusCode);
185
186                 Exception e = new Exception("Communication with DB Adapter failed");
187                 throw e;
188             }
189             BufferedReader rd = new BufferedReader(
190                     new InputStreamReader(response.getEntity().getContent()));
191
192             StringBuffer result = new StringBuffer();
193             String line = "";
194             while ((line = rd.readLine()) != null) {
195                 result.append(line);
196             }
197             msoLogger.debug("Content of the response is:" + result);
198             String status = result.substring(result.indexOf("<return>") + 8, result.indexOf("</return>"));
199
200             return Boolean.valueOf(status);
201         }
202     }
203 }