/* * Copyright 2010-2012 Capgemini * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package net.sf.appstatus.web.pages; import static java.util.Collections.sort; import static net.sf.appstatus.web.HtmlUtils.applyLayout; import static net.sf.appstatus.web.HtmlUtils.generateBeginTable; import static net.sf.appstatus.web.HtmlUtils.generateEndTable; import static net.sf.appstatus.web.HtmlUtils.generateHeaders; import static net.sf.appstatus.web.HtmlUtils.generateRow; import static net.sf.appstatus.web.HtmlUtils.json; import static org.apache.commons.lang3.StringUtils.join; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.text.StrBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import net.sf.appstatus.core.AppStatus; import net.sf.appstatus.core.check.ICheckResult; import net.sf.appstatus.web.StatusWebHandler; public class StatusPage extends AbstractPage { private static final String ENCODING = "UTF-8"; private static Logger LOGGER = LoggerFactory.getLogger(StatusPage.class); private static final String PAGECONTENTLAYOUT = "statusContentLayout.html"; /** * Returns status icon id. * * @param result * @return */ private static String getStatus(final ICheckResult result) { if (result.getCode() == ICheckResult.OK) { return Resources.STATUS_OK; } if (result.isFatal()) { return Resources.STATUS_ERROR; } return Resources.STATUS_WARN; } @Override public void doGet(final StatusWebHandler webHandler, final HttpServletRequest req, final HttpServletResponse resp) throws UnsupportedEncodingException, IOException { if (req.getParameter("json") != null) { doGetJSON(webHandler, req, resp); } else { doGetHTML(webHandler, req, resp); } } public void doGetHTML(final StatusWebHandler webHandler, final HttpServletRequest req, final HttpServletResponse resp) throws UnsupportedEncodingException, IOException { setup(resp, "text/html"); final ServletOutputStream os = resp.getOutputStream(); final AppStatus appStatus = webHandler.getAppStatus(); final Map<String, String> valuesMap = new HashMap<String, String>(); final List<ICheckResult> results = appStatus.checkAll(req.getLocale()); sort(results); boolean statusOk = true; int statusCode = 200; for (final ICheckResult r : results) { if (r.getCode() != ICheckResult.OK && r.isFatal()) { statusCode = 500; statusOk = false; break; } } if (statusOk && appStatus.isMaintenance()) { statusCode = 503; } valuesMap.put("maintenanceModeActive", appStatus.isMaintenance() ? "on" : "off"); valuesMap.put("nextMode", appStatus.isMaintenance() ? "available" : "maintenance"); valuesMap.put("statusOk", String.valueOf(statusOk)); valuesMap.put("statusCode", String.valueOf(statusCode)); resp.setStatus(statusCode); // STATUS TABLE final StrBuilder sbStatusTable = new StrBuilder(); if (generateBeginTable(sbStatusTable, results.size())) { generateHeaders(sbStatusTable, "", "Group", "Name", "Description", "Code", "Resolution"); for (final ICheckResult r : results) { generateRow(sbStatusTable, getStatus(r), r.getGroup(), r.getProbeName(), r.getDescription(), String.valueOf(r.getCode()), r.getResolutionSteps()); } generateEndTable(sbStatusTable, results.size()); } valuesMap.put("statusTable", sbStatusTable.toString()); // PROPERTIES TABLE final StrBuilder sbPropertiesTable = new StrBuilder(); final Map<String, Map<String, String>> properties = appStatus.getProperties(); if (generateBeginTable(sbPropertiesTable, properties.size())) { generateHeaders(sbPropertiesTable, "", "Group", "Name", "Value"); for (final Entry<String, Map<String, String>> cat : properties.entrySet()) { final String category = cat.getKey(); for (final Entry<String, String> r : cat.getValue().entrySet()) { generateRow(sbPropertiesTable, Resources.STATUS_PROP, category, r.getKey(), r.getValue()); } } generateEndTable(sbPropertiesTable, properties.size()); } valuesMap.put("propertiesTable", sbPropertiesTable.toString()); final String content = applyLayout(valuesMap, PAGECONTENTLAYOUT); valuesMap.clear(); valuesMap.put("content", content); os.write(getPage(webHandler, valuesMap).getBytes(ENCODING)); } public void doGetJSON(final StatusWebHandler webHandler, final HttpServletRequest req, final HttpServletResponse resp) throws UnsupportedEncodingException, IOException { setup(resp, "application/json"); final AppStatus appStatus = webHandler.getAppStatus(); final ServletOutputStream os = resp.getOutputStream(); int statusCode = 200; final List<ICheckResult> results = appStatus.checkAll(req.getLocale()); for (final ICheckResult r : results) { if (r.isFatal()) { resp.setStatus(500); statusCode = 500; break; } } if (appStatus.isMaintenance()) { resp.setStatus(503); statusCode = 503; } os.write("{".getBytes(ENCODING)); os.write((json("code", statusCode) + ",").getBytes(ENCODING)); os.write(("\"status\" : [").getBytes(ENCODING)); boolean first = true; for (final ICheckResult r : results) { if (!first) { os.write((",").getBytes(ENCODING)); } os.write(("{" + join(new String[] { json("name", r.getProbeName()), json("group", r.getGroup()), json("description", r.getDescription()), json("resolution", r.getResolutionSteps()), json("code", r.getCode()) }, ",") + "}").getBytes(ENCODING)); if (first) { first = false; } } os.write("]".getBytes(ENCODING)); final Map<String, Map<String, String>> properties = appStatus.getProperties(); os.write((", \"properties\" : [").getBytes(ENCODING)); first = true; for (Entry<String, Map<String, String>> cat : properties.entrySet()) { for (final Entry<String, String> r : cat.getValue().entrySet()) { if (!first) { os.write((",").getBytes(ENCODING)); } os.write(("{" + join(new String[] { json("group", cat.getKey()), json("name", r.getKey()), json("value", r.getValue()) }, ",") + "}").getBytes(ENCODING)); if (first) { first = false; } } } os.write("]".getBytes(ENCODING)); os.write("}".getBytes(ENCODING)); } @Override public void doPost(final StatusWebHandler webHandler, final HttpServletRequest req, final HttpServletResponse resp) { updateMode(webHandler, req.getParameter("mode")); try { resp.sendRedirect(req.getRequestURI()); } catch (final IOException ex) { LOGGER.warn("Unable to redirect to main status page after updating mode", ex); } } @Override public String getId() { return "status"; } @Override public String getName() { return "Status"; } private void updateMode(final StatusWebHandler webHandler, final String mode) { if (null != mode) { try { webHandler.getAppStatus().setMaintenance("maintenance".equalsIgnoreCase(mode)); } catch (final IOException ex) { throw new RuntimeException("Error while updating maintenance status", ex); } } } }