package ru.vyarus.dropwizard.orient.support; import com.google.common.base.MoreObjects; import com.orientechnologies.orient.core.OConstants; import com.orientechnologies.orient.core.config.OContextConfiguration; import com.orientechnologies.orient.server.OServerMain; import com.orientechnologies.orient.server.plugin.OServerPluginInfo; import ru.vyarus.dropwizard.orient.internal.EmbeddedOrientServer; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.text.MessageFormat; import java.util.Collection; /** * Embedded orient server info servlet. Deployed on '/orient' path in admin context * (by default 'http://localhost:8081/orient'). * <p>Special url '/orient/studio' leads to embedded studio (no matter what port was configured * it will redirect properly).</p> * <p>Servlet is installed only when embedded server is started. Servlet deployment could be disabled * in configuration ('admin-servlet' option).</p> * * @author Vyacheslav Rusakov * @since 25.08.2015 */ public class OrientServlet extends HttpServlet { public static final String STUDIO_URI = "/studio"; private static final long serialVersionUID = -2850794040708785320L; private static final String DISABLED = "disabled"; private static final String CONF_DYNAMIC_PLUGIN = "plugin.dynamic"; private static final String CONF_PLUGIN_RELOAD = "plugin.hotReload"; private static final String CONF_PROFILER = "profiler.enabled"; //CHECKSTYLE:OFF private static final String TEMPLATE = String.format( "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"%n" + " \"http://www.w3.org/TR/html4/loose.dtd\">%n" + "<html>%n" + "<head>%n" + " <title>OrientDB</title>%n" + "</head>%n" + "<body>%n" + " <h1>Embedded OrientDB server</h1>%n" + " <ul>%n" + " <li>Version: {0}</li>%n" + " <li>Binary port: {1}</li>%n" + " <li>Http port: {2}</li>%n" + " <li>Studio installed: {3}</li>%n" + " <li>Plugins: {4}</li>%n" + " <li>Dynamic plugins: {5} (hot reload: {6})</li>%n" + " <li>Profiler: {7}</li>%n" + " </ul>%n" + " {8}%n" + "</body>%n" + "</html>" ); private static final String LINKS_TEMPLATE = String.format( " <h2>Links</h2>%n" + " <ul>%n" + " <li><a href=\"{0}/studio\">Embedded studio</a></li>%n" + " </ul>%n" + " <ul>%n" + " <li><a href=\"{1}\" {2}>Documentation</a>%n" + " <ul>%n" + " <li><a href=\"{1}DB-Server.html#configuration\" {2}>Server</a></li>%n" + " <li><a href=\"{1}Commands.html\" {2}>Sql commands</a></li>%n" + " <li><a href=\"{1}SQL-Functions.html#bundled-functions\" {2}>Sql functions</a></li>%n" + " <li><a href=\"{1}SQL-Methods.html\" {2}>Sql methods</a></li>%n" + " <li><a href=\"{1}Query-Examples.html\" {2}>Query examples</a></li>%n" + " <li><a href=\"{1}Console-Commands.html#console-commands\" {2}>Console commands</a></li>%n" + " <li><a href=\"{1}OrientDB-REST.html\" {2}>Rest api</a></li>%n" + " </ul></li>%n" + " </ul>" ); //CHECKSTYLE:ON private final transient EmbeddedOrientServer.Info info; public OrientServlet(final EmbeddedOrientServer.Info info) { this.info = info; } @Override protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { final String uri = req.getPathInfo(); // if webjar is not used, studio could still be installed as dynamic plugin (in db files folder) if (STUDIO_URI.equals(uri)) { resp.sendRedirect(String.format("http://%s:%s/studio/", req.getServerName(), info.httpPort)); } else { super.service(req, resp); } } @Override protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { final String path = req.getContextPath() + req.getServletPath(); resp.setStatus(HttpServletResponse.SC_OK); resp.setHeader("Cache-Control", "must-revalidate,no-cache,no-store"); resp.setContentType("text/html"); try (PrintWriter writer = resp.getWriter()) { final OContextConfiguration config = OServerMain.server().getContextConfiguration(); writer.println(MessageFormat.format(TEMPLATE, OConstants.ORIENT_VERSION, MoreObjects.firstNonNull(info.binaryPort, DISABLED), MoreObjects.firstNonNull(info.httpPort, DISABLED), info.studioInstalled, renderPlugins(config), config.getValueAsString(CONF_DYNAMIC_PLUGIN, null), config.getValueAsString(CONF_PLUGIN_RELOAD, null), config.getValueAsString(CONF_PROFILER, null), renderLinks(path))); } } private String renderLinks(final String path) { return MessageFormat.format(LINKS_TEMPLATE, path, "http://orientdb.com/docs/last/", "target=\"_blank\""); } private String renderPlugins(final OContextConfiguration config) { final String pluginsEnabled = config.getValueAsString(CONF_DYNAMIC_PLUGIN, null); final StringBuilder installedPlugins = new StringBuilder(); if (pluginsEnabled != null) { final Collection<OServerPluginInfo> plugins = OServerMain.server().getPlugins(); if (!plugins.isEmpty()) { installedPlugins.append("<ul>"); for (OServerPluginInfo plugin : plugins) { installedPlugins.append(String.format("<li>%s</li>", plugin.getName())); } installedPlugins.append("</ul>"); } else { installedPlugins.append("none"); } } return installedPlugins.toString(); } }