0e4ed7920048b7ac1dffde7745df3e4669b04731
[policy/drools-pdp.git] / feature-healthcheck / src / main / java / org / onap / policy / drools / healthcheck / HealthCheck.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * feature-healthcheck
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.onap.policy.drools.healthcheck;
22
23 import java.util.ArrayList;
24 import java.util.Properties;
25
26 import javax.ws.rs.core.Response;
27
28 import org.onap.policy.drools.http.client.HttpClient;
29 import org.onap.policy.drools.http.server.HttpServletServer;
30 import org.onap.policy.drools.persistence.SystemPersistence;
31 import org.onap.policy.drools.properties.Startable;
32 import org.onap.policy.drools.system.PolicyEngine;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 /**
37  * Healthcheck
38  */
39 public interface HealthCheck extends Startable {
40         
41         /**
42          * Healthcheck Report
43          */
44         public static class Report {
45                 /**
46                  * Named Entity in the report
47                  */
48                 public String name;
49                 
50                 /**
51                  * URL queried
52                  */
53                 public String url;
54                 
55                 /**
56                  * healthy?
57                  */
58                 public boolean healthy;
59                 
60                 /**
61                  * return code
62                  */
63                 public int code;
64                 
65                 /**
66                  * Message from remote entity
67                  */
68                 public String message;
69                 
70                 @Override
71                 public String toString() {
72                         StringBuilder builder = new StringBuilder();
73                         builder.append("Report [name=");
74                         builder.append(name);
75                         builder.append(", url=");
76                         builder.append(url);
77                         builder.append(", healthy=");
78                         builder.append(healthy);
79                         builder.append(", code=");
80                         builder.append(code);
81                         builder.append(", message=");
82                         builder.append(message);
83                         builder.append("]");
84                         return builder.toString();
85                 }
86         }
87         
88         /**
89          * Report aggregation
90          */
91         public static class Reports {
92                 public boolean healthy;
93                 public ArrayList<Report> details = new ArrayList<>();
94                 
95                 @Override
96                 public String toString() {
97                         StringBuilder builder = new StringBuilder();
98                         builder.append("Reports [healthy=");
99                         builder.append(healthy);
100                         builder.append(", details=");
101                         builder.append(details);
102                         builder.append("]");
103                         return builder.toString();
104                 }
105         }
106         
107         /**
108          * perform a healthcheck
109          * @return a report
110          */
111         public Reports healthCheck();
112
113         /**
114          * Healthcheck Monitor
115          */
116         public static final HealthCheck monitor = new HealthCheckMonitor();
117 }
118
119 /**
120  * Healthcheck Monitor
121  */
122 class HealthCheckMonitor implements HealthCheck {
123
124         /**
125          * Logger
126          */
127         private static Logger logger = LoggerFactory.getLogger(HealthCheckMonitor.class);
128         
129         /**
130          * attached http servers
131          */
132         protected volatile ArrayList<HttpServletServer> servers = new ArrayList<>();
133         
134         /**
135          * attached http clients
136          */
137         protected volatile ArrayList<HttpClient> clients = new ArrayList<>();
138         
139         /**
140          * healthcheck configuration
141          */
142         protected volatile Properties healthCheckProperties = null; 
143         
144         /**
145          * {@inheritDoc}
146          */
147         public Reports healthCheck() {  
148                 Reports reports = new Reports();
149                 reports.healthy = PolicyEngine.manager.isAlive();
150                 
151                 HealthCheck.Report engineReport = new Report();
152                 engineReport.healthy = PolicyEngine.manager.isAlive();
153                 engineReport.name = "PDP-D";
154                 engineReport.url = "self";
155                 engineReport.code = (PolicyEngine.manager.isAlive()) ? 200 : 500;
156                 engineReport.message = (PolicyEngine.manager.isAlive()) ? "alive" : "not alive";
157                 reports.details.add(engineReport);
158                 
159                 for (HttpClient client : clients) {
160                         HealthCheck.Report report = new Report();
161                         report.name = client.getName();
162                         report.url = client.getBaseUrl();
163                         report.healthy = true;
164                         try {
165                                 Response response = client.get();
166                                 report.code = response.getStatus();
167                                 if (report.code != 200) {
168                                         report.healthy = false;
169                                         reports.healthy = false;
170                                 }
171                                         
172                                 try {
173                                         report.message = HttpClient.getBody(response, String.class);
174                                 } catch (Exception e) {
175                                         logger.warn("{}: cannot get body from http-client {}", this, client, e);
176                                 }
177                         } catch (Exception e) {
178                                 report.healthy = false;
179                                 reports.healthy = false;
180                         }
181                         reports.details.add(report);
182                 }
183                 return reports;
184         }
185         
186         /**
187          * {@inheritDoc}
188          */
189         @Override
190         public boolean start() throws IllegalStateException {
191                 
192                 try {
193                         this.healthCheckProperties = SystemPersistence.manager.getProperties(HealthCheckFeature.CONFIGURATION_PROPERTIES_NAME);
194                         this.servers = HttpServletServer.factory.build(healthCheckProperties);
195                         this.clients = HttpClient.factory.build(healthCheckProperties);
196                         
197                         for (HttpServletServer server : servers) {
198                                 try {
199                                         server.start();
200                                 } catch (Exception e) {
201                                         logger.warn("{}: cannot start http-server {}", this, server, e);
202                                 }
203                         }
204                 } catch (Exception e) {
205                         return false;
206                 }
207                 
208                 return true;
209         }
210
211         /**
212          * {@inheritDoc}
213          */
214         @Override
215         public boolean stop() throws IllegalStateException {
216                 
217                 for (HttpServletServer server : servers) {
218                         try {
219                                 server.stop();
220                         } catch (Exception e) {
221                                 logger.warn("{}: cannot stop http-server {}", this, server, e);
222                         }
223                 }
224                 
225                 for (HttpClient client : clients) {
226                         try {
227                                 client.stop();
228                         } catch (Exception e) {
229                                 logger.warn("{}: cannot stop http-client {}", this, client, e);
230                         }
231                 }
232                 
233                 return true;
234         }
235
236         /**
237          * {@inheritDoc}
238          */
239         @Override
240         public void shutdown() throws IllegalStateException {
241                 this.stop();
242         }
243
244         /**
245          * {@inheritDoc}
246          */
247         @Override
248         public synchronized boolean isAlive() {
249                 return this.healthCheckProperties != null;
250         }
251         
252         /**
253          * @return list of attached Http Servers
254          */
255         public ArrayList<HttpServletServer> getServers() {
256                 return this.servers;
257         }
258         
259         /**
260          * @return list of attached Http Clients
261          */
262         public ArrayList<HttpClient> getClients() {
263                 return this.clients;
264         }
265
266         @Override
267         public String toString() {
268                 StringBuilder builder = new StringBuilder();
269                 builder.append("HealthCheckMonitor [servers=");
270                 builder.append(servers);
271                 builder.append(", clients=");
272                 builder.append(clients);
273                 builder.append("]");
274                 return builder.toString();
275         }
276         
277 }