1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.appstatus.web.pages;
17
18 import static java.util.Collections.sort;
19 import static net.sf.appstatus.web.HtmlUtils.applyLayout;
20 import static net.sf.appstatus.web.HtmlUtils.generateBeginTable;
21 import static net.sf.appstatus.web.HtmlUtils.generateEndTable;
22 import static net.sf.appstatus.web.HtmlUtils.generateHeaders;
23 import static net.sf.appstatus.web.HtmlUtils.generateRow;
24 import static net.sf.appstatus.web.HtmlUtils.json;
25 import static org.apache.commons.lang3.StringUtils.join;
26
27 import java.io.IOException;
28 import java.io.UnsupportedEncodingException;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Map.Entry;
33
34 import javax.servlet.ServletOutputStream;
35 import javax.servlet.http.HttpServletRequest;
36 import javax.servlet.http.HttpServletResponse;
37
38 import org.apache.commons.lang3.text.StrBuilder;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42 import net.sf.appstatus.core.AppStatus;
43 import net.sf.appstatus.core.check.ICheckResult;
44 import net.sf.appstatus.web.StatusWebHandler;
45
46 public class StatusPage extends AbstractPage {
47
48 private static final String ENCODING = "UTF-8";
49
50 private static Logger LOGGER = LoggerFactory.getLogger(StatusPage.class);
51
52 private static final String PAGECONTENTLAYOUT = "statusContentLayout.html";
53
54
55
56
57
58
59
60 private static String getStatus(final ICheckResult result) {
61
62 if (result.getCode() == ICheckResult.OK) {
63 return Resources.STATUS_OK;
64 }
65
66 if (result.isFatal()) {
67 return Resources.STATUS_ERROR;
68 }
69
70 return Resources.STATUS_WARN;
71 }
72
73 @Override
74 public void doGet(final StatusWebHandler webHandler, final HttpServletRequest req, final HttpServletResponse resp)
75 throws UnsupportedEncodingException, IOException {
76
77 if (req.getParameter("json") != null) {
78 doGetJSON(webHandler, req, resp);
79 } else {
80 doGetHTML(webHandler, req, resp);
81 }
82
83 }
84
85 public void doGetHTML(final StatusWebHandler webHandler, final HttpServletRequest req,
86 final HttpServletResponse resp) throws UnsupportedEncodingException, IOException {
87
88 setup(resp, "text/html");
89 final ServletOutputStream os = resp.getOutputStream();
90
91 final AppStatus appStatus = webHandler.getAppStatus();
92
93 final Map<String, String> valuesMap = new HashMap<String, String>();
94 final List<ICheckResult> results = appStatus.checkAll(req.getLocale());
95 sort(results);
96 boolean statusOk = true;
97 int statusCode = 200;
98 for (final ICheckResult r : results) {
99 if (r.getCode() != ICheckResult.OK && r.isFatal()) {
100 statusCode = 500;
101 statusOk = false;
102 break;
103 }
104 }
105
106 if (statusOk && appStatus.isMaintenance()) {
107 statusCode = 503;
108 }
109
110 valuesMap.put("maintenanceModeActive", appStatus.isMaintenance() ? "on" : "off");
111 valuesMap.put("nextMode", appStatus.isMaintenance() ? "available" : "maintenance");
112
113 valuesMap.put("statusOk", String.valueOf(statusOk));
114 valuesMap.put("statusCode", String.valueOf(statusCode));
115
116 resp.setStatus(statusCode);
117
118
119 final StrBuilder sbStatusTable = new StrBuilder();
120 if (generateBeginTable(sbStatusTable, results.size())) {
121
122 generateHeaders(sbStatusTable, "", "Group", "Name", "Description", "Code", "Resolution");
123
124 for (final ICheckResult r : results) {
125 generateRow(sbStatusTable, getStatus(r), r.getGroup(), r.getProbeName(), r.getDescription(),
126 String.valueOf(r.getCode()), r.getResolutionSteps());
127 }
128 generateEndTable(sbStatusTable, results.size());
129 }
130 valuesMap.put("statusTable", sbStatusTable.toString());
131
132
133 final StrBuilder sbPropertiesTable = new StrBuilder();
134 final Map<String, Map<String, String>> properties = appStatus.getProperties();
135 if (generateBeginTable(sbPropertiesTable, properties.size())) {
136
137 generateHeaders(sbPropertiesTable, "", "Group", "Name", "Value");
138
139 for (final Entry<String, Map<String, String>> cat : properties.entrySet()) {
140 final String category = cat.getKey();
141
142 for (final Entry<String, String> r : cat.getValue().entrySet()) {
143 generateRow(sbPropertiesTable, Resources.STATUS_PROP, category, r.getKey(), r.getValue());
144 }
145
146 }
147 generateEndTable(sbPropertiesTable, properties.size());
148 }
149 valuesMap.put("propertiesTable", sbPropertiesTable.toString());
150 final String content = applyLayout(valuesMap, PAGECONTENTLAYOUT);
151
152 valuesMap.clear();
153 valuesMap.put("content", content);
154 os.write(getPage(webHandler, valuesMap).getBytes(ENCODING));
155 }
156
157 public void doGetJSON(final StatusWebHandler webHandler, final HttpServletRequest req,
158 final HttpServletResponse resp) throws UnsupportedEncodingException, IOException {
159
160 setup(resp, "application/json");
161
162 final AppStatus appStatus = webHandler.getAppStatus();
163
164 final ServletOutputStream os = resp.getOutputStream();
165 int statusCode = 200;
166 final List<ICheckResult> results = appStatus.checkAll(req.getLocale());
167 for (final ICheckResult r : results) {
168 if (r.isFatal()) {
169 resp.setStatus(500);
170 statusCode = 500;
171 break;
172 }
173 }
174
175 if (appStatus.isMaintenance()) {
176 resp.setStatus(503);
177 statusCode = 503;
178 }
179
180 os.write("{".getBytes(ENCODING));
181
182 os.write((json("code", statusCode) + ",").getBytes(ENCODING));
183 os.write(("\"status\" : [").getBytes(ENCODING));
184
185 boolean first = true;
186 for (final ICheckResult r : results) {
187 if (!first) {
188 os.write((",").getBytes(ENCODING));
189 }
190
191 os.write(("{" + join(new String[] { json("name", r.getProbeName()), json("group", r.getGroup()),
192 json("description", r.getDescription()), json("resolution", r.getResolutionSteps()),
193 json("code", r.getCode()) }, ",") + "}").getBytes(ENCODING));
194
195 if (first) {
196 first = false;
197 }
198 }
199
200 os.write("]".getBytes(ENCODING));
201
202 final Map<String, Map<String, String>> properties = appStatus.getProperties();
203
204 os.write((", \"properties\" : [").getBytes(ENCODING));
205
206 first = true;
207 for (Entry<String, Map<String, String>> cat : properties.entrySet()) {
208
209 for (final Entry<String, String> r : cat.getValue().entrySet()) {
210 if (!first) {
211 os.write((",").getBytes(ENCODING));
212 }
213
214 os.write(("{" + join(new String[] { json("group", cat.getKey()), json("name", r.getKey()),
215 json("value", r.getValue()) }, ",") + "}").getBytes(ENCODING));
216
217 if (first) {
218 first = false;
219 }
220 }
221 }
222
223 os.write("]".getBytes(ENCODING));
224
225 os.write("}".getBytes(ENCODING));
226
227 }
228
229 @Override
230 public void doPost(final StatusWebHandler webHandler, final HttpServletRequest req,
231 final HttpServletResponse resp) {
232 updateMode(webHandler, req.getParameter("mode"));
233 try {
234 resp.sendRedirect(req.getRequestURI());
235 } catch (final IOException ex) {
236 LOGGER.warn("Unable to redirect to main status page after updating mode", ex);
237 }
238 }
239
240 @Override
241 public String getId() {
242 return "status";
243 }
244
245 @Override
246 public String getName() {
247 return "Status";
248 }
249
250 private void updateMode(final StatusWebHandler webHandler, final String mode) {
251 if (null != mode) {
252 try {
253 webHandler.getAppStatus().setMaintenance("maintenance".equalsIgnoreCase(mode));
254 } catch (final IOException ex) {
255 throw new RuntimeException("Error while updating maintenance status", ex);
256 }
257 }
258 }
259 }