package bdv.server; import mpicbg.spim.data.SpimDataException; import org.antlr.stringtemplate.StringTemplate; import org.antlr.stringtemplate.StringTemplateGroup; import org.eclipse.jetty.server.ConnectorStatistics; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.StatisticsHandler; import org.eclipse.jetty.util.log.Log; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.net.URISyntaxException; import java.text.DecimalFormat; /** * @author HongKee Moon <moon@mpi-cbg.quantization.de> * @author Tobias Pietzsch <tobias.pietzsch@gmail.com> */ public class ManagerHandler extends ContextHandler { private static final org.eclipse.jetty.util.log.Logger LOG = Log.getLogger(ManagerHandler.class); private final String baseURL; private final Server server; private final ContextHandlerCollection handlers; private final StatisticsHandler statHandler; private final ConnectorStatistics connectorStats; private String contexts = null; private int noDataSets = 0; private long sizeDataSets = 0; private final String thumbnailsDirectoryName; public ManagerHandler( final String baseURL, final Server server, final ConnectorStatistics connectorStats, final StatisticsHandler statHandler, final ContextHandlerCollection handlers, final String thumbnailsDirectoryName) throws IOException, URISyntaxException { this.baseURL = baseURL; this.server = server; this.handlers = handlers; this.statHandler = statHandler; this.connectorStats = connectorStats; this.thumbnailsDirectoryName = thumbnailsDirectoryName; setContextPath("/" + Constants.MANAGER_CONTEXT_NAME); } @Override public void doHandle(final String target, final Request baseRequest, final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException { final String op = request.getParameter("op"); if (op == null) { list(baseRequest, response); } else if (op.equals("deploy")) { final String ds = request.getParameter("ds"); final String file = request.getParameter("file"); deploy(ds, file, baseRequest, response); } else if (op.equals("undeploy")) { final String ds = request.getParameter("ds"); undeploy(ds, baseRequest, response); } } public String getByteSizeString(final long size) { if (size <= 0) return "0"; final String[] units = new String[]{"B", "kB", "MB", "GB", "TB"}; final int digitGroups = (int) (Math.log10(size) / Math.log10(1024)); return new DecimalFormat("#,##0.#").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups]; } private void list(final Request baseRequest, final HttpServletResponse response) throws IOException { response.setContentType("text/html"); response.setStatus(HttpServletResponse.SC_OK); baseRequest.setHandled(true); final PrintWriter ow = response.getWriter(); ow.write(getHtml()); ow.close(); } private String getHtml() { final StringTemplateGroup templates = new StringTemplateGroup("manager"); final StringTemplate t = templates.getInstanceOf("templates/manager"); t.setAttribute("bytesSent", getByteSizeString(statHandler.getResponsesBytesTotal())); t.setAttribute("msgPerSec", connectorStats.getMessagesOutPerSecond()); t.setAttribute("openConnections", connectorStats.getConnectionsOpen()); t.setAttribute("maxOpenConnections", connectorStats.getConnectionsOpenMax()); getContexts(); t.setAttribute("contexts", contexts); t.setAttribute("noDataSets", noDataSets); t.setAttribute("sizeDataSets", getByteSizeString(sizeDataSets)); t.setAttribute("statHtml", statHandler.toStatsHTML()); return t.toString(); } private void getContexts() { if (contexts == null) { noDataSets = 0; sizeDataSets = 0; final StringBuilder sb = new StringBuilder(); for (final Handler handler : server.getChildHandlersByClass(CellHandler.class)) { sb.append("<tr>\n<th>"); final CellHandler contextHandler = (CellHandler) handler; sb.append(contextHandler.getContextPath() + "</th>\n<td>"); sb.append(contextHandler.getXmlFile() + "</td>\n</tr>\n"); noDataSets++; sizeDataSets += new File(contextHandler.getXmlFile().replace(".xml", ".h5")).length(); } contexts = sb.toString(); } } private void deploy(final String datasetName, final String fileLocation, final Request baseRequest, final HttpServletResponse response) throws IOException { LOG.info("Add new context: " + datasetName); final String context = "/" + datasetName; boolean alreadyExists = false; for (final Handler handler : server.getChildHandlersByClass(CellHandler.class)) { final CellHandler contextHandler = (CellHandler) handler; if (context.equals(contextHandler.getContextPath())) { LOG.info("Context " + datasetName + " already exists."); alreadyExists = true; break; } } if (!alreadyExists) { CellHandler ctx = null; try { LOG.warn("We are creating CellHandler without compression params!"); ctx = new CellHandler(baseURL + context + "/", fileLocation, datasetName, thumbnailsDirectoryName, null); } catch (final SpimDataException e) { LOG.warn("Failed to create a CellHandler", e); e.printStackTrace(); } ctx.setContextPath(context); handlers.addHandler(ctx); } response.setContentType("text/html"); response.setStatus(HttpServletResponse.SC_OK); baseRequest.setHandled(true); final PrintWriter ow = response.getWriter(); if (alreadyExists) ow.write(datasetName + " already exists. Not registered."); else ow.write(datasetName + " registered."); ow.close(); } private void undeploy(final String datasetName, final Request baseRequest, final HttpServletResponse response) throws IOException { LOG.info("Remove the context: " + datasetName); boolean ret = false; final String context = "/" + datasetName; for (final Handler handler : server.getChildHandlersByClass(CellHandler.class)) { final CellHandler contextHandler = (CellHandler) handler; if (context.equals(contextHandler.getContextPath())) { try { contextHandler.stop(); } catch (final Exception e) { e.printStackTrace(); } contextHandler.destroy(); handlers.removeHandler(contextHandler); ret = true; break; } } if (ret) { response.setContentType("text/html"); response.setStatus(HttpServletResponse.SC_OK); baseRequest.setHandled(true); final PrintWriter ow = response.getWriter(); ow.write(datasetName + " removed."); ow.close(); } } }