mirror of https://github.com/apache/lucene.git
506 lines
10 KiB
Plaintext
506 lines
10 KiB
Plaintext
|
<%@ page contentType="application/json; charset=utf-8" pageEncoding="UTF-8" %>
|
||
|
<%@ page trimDirectiveWhitespaces="true" %>
|
||
|
|
||
|
<%@ page import="javax.servlet.jsp.JspWriter" %>
|
||
|
<%@ page import="java.io.IOException" %>
|
||
|
<%@ page import="org.apache.zookeeper.*" %>
|
||
|
<%@ page import="org.apache.zookeeper.data.Stat" %>
|
||
|
<%@ page import="org.apache.solr.core.*" %>
|
||
|
<%@ page import="org.apache.solr.cloud.*" %>
|
||
|
<%@ page import="org.apache.solr.common.cloud.*" %>
|
||
|
<%@ page import="org.apache.solr.common.util.*" %>
|
||
|
<%@ page import="java.util.concurrent.TimeoutException" %>
|
||
|
<%@ page import="java.io.*" %>
|
||
|
<%@ page import="java.util.*" %>
|
||
|
<%@ page import="java.net.URLEncoder" %>
|
||
|
|
||
|
<% SolrCore core = (SolrCore)request.getAttribute( "org.apache.solr.SolrCore" ); %>
|
||
|
|
||
|
<%!
|
||
|
|
||
|
static class ZKPrinter
|
||
|
{
|
||
|
|
||
|
static boolean FULLPATH_DEFAULT = false;
|
||
|
|
||
|
boolean indent = true;
|
||
|
boolean fullpath = FULLPATH_DEFAULT;
|
||
|
boolean detail = false;
|
||
|
|
||
|
String addr; // the address passed to us
|
||
|
String keeperAddr; // the address we're connected to
|
||
|
|
||
|
boolean doClose; // close the client after done if we opened it
|
||
|
|
||
|
HttpServletResponse response;
|
||
|
JspWriter out;
|
||
|
SolrZkClient zkClient;
|
||
|
|
||
|
private boolean levelchange;
|
||
|
int level;
|
||
|
int maxData = 95;
|
||
|
|
||
|
public ZKPrinter(HttpServletResponse response, JspWriter out, SolrCore core, String addr)
|
||
|
throws IOException
|
||
|
{
|
||
|
this.response = response;
|
||
|
this.out = out;
|
||
|
this.addr = addr;
|
||
|
|
||
|
if (addr == null)
|
||
|
{
|
||
|
ZkController controller = core.getCoreDescriptor().getCoreContainer().getZkController();
|
||
|
if (controller != null)
|
||
|
{
|
||
|
// this core is zk enabled
|
||
|
keeperAddr = controller.getZkServerAddress();
|
||
|
zkClient = controller.getZkClient();
|
||
|
if (zkClient != null && zkClient.isConnected())
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// try a different client with this address
|
||
|
addr = keeperAddr;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
keeperAddr = addr;
|
||
|
if (addr == null)
|
||
|
{
|
||
|
response.setStatus(404);
|
||
|
out.println
|
||
|
(
|
||
|
"{" +
|
||
|
"\"status\": 404" +
|
||
|
", \"error\" : \"Zookeeper is not configured for this Solr Core. Please try connecting to an alternate zookeeper address.\"" +
|
||
|
"}"
|
||
|
);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
try
|
||
|
{
|
||
|
zkClient = new SolrZkClient(addr, 10000);
|
||
|
doClose = true;
|
||
|
}
|
||
|
catch (TimeoutException e)
|
||
|
{
|
||
|
response.setStatus(503);
|
||
|
out.println
|
||
|
(
|
||
|
"{" +
|
||
|
"\"status\": 503" +
|
||
|
", \"error\" : \"Could not connect to zookeeper at '" + addr + "'\"" +
|
||
|
"}"
|
||
|
);
|
||
|
zkClient = null;
|
||
|
return;
|
||
|
}
|
||
|
catch (InterruptedException e)
|
||
|
{
|
||
|
// Restore the interrupted status
|
||
|
Thread.currentThread().interrupt();
|
||
|
response.setStatus(503);
|
||
|
out.println
|
||
|
(
|
||
|
"{" +
|
||
|
"\"status\": 503" +
|
||
|
", \"error\" : \"Could not connect to zookeeper at '" + addr + "'\"" +
|
||
|
"}"
|
||
|
);
|
||
|
zkClient = null;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
public void close()
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
if (doClose)
|
||
|
{
|
||
|
zkClient.close();
|
||
|
}
|
||
|
} catch (InterruptedException e)
|
||
|
{
|
||
|
// ignore exception on close
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// main entry point
|
||
|
void print(String path) throws IOException
|
||
|
{
|
||
|
if (zkClient == null)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// normalize path
|
||
|
if (path == null)
|
||
|
{
|
||
|
path = "/";
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
path.trim();
|
||
|
if (path.length() == 0)
|
||
|
{
|
||
|
path = "/";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (path.endsWith("/") && path.length() > 1)
|
||
|
{
|
||
|
path = path.substring(0, path.length() - 1);
|
||
|
}
|
||
|
|
||
|
int idx = path.lastIndexOf('/');
|
||
|
String parent = idx >= 0 ? path.substring(0, idx) : path;
|
||
|
if (parent.length() == 0)
|
||
|
{
|
||
|
parent = "/";
|
||
|
}
|
||
|
|
||
|
out.println("{");
|
||
|
|
||
|
if (detail)
|
||
|
{
|
||
|
printZnode(path);
|
||
|
out.println(", ");
|
||
|
}
|
||
|
|
||
|
out.println("\"tree\" : [");
|
||
|
printTree(path);
|
||
|
out.println("]");
|
||
|
|
||
|
out.println("}");
|
||
|
}
|
||
|
|
||
|
void exception(Exception e)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
response.setStatus(500);
|
||
|
out.println
|
||
|
(
|
||
|
"{" +
|
||
|
"\"status\": 500" +
|
||
|
", \"error\" : \"" + e.toString() + "\"" +
|
||
|
"}"
|
||
|
);
|
||
|
}
|
||
|
catch (IOException e1)
|
||
|
{
|
||
|
// nothing we can do
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void xmlescape(String s)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
XML.escapeCharData(s, out);
|
||
|
}
|
||
|
catch (IOException e)
|
||
|
{
|
||
|
throw new RuntimeException(e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// collapse all whitespace to a single space or escaped newline
|
||
|
String compress(String str) {
|
||
|
StringBuilder sb = new StringBuilder();
|
||
|
for (int i = 0; i < str.length(); i++) {
|
||
|
char ch = str.charAt(i);
|
||
|
boolean whitespace = false;
|
||
|
boolean newline = false;
|
||
|
while (Character.isWhitespace(ch)) {
|
||
|
whitespace = true;
|
||
|
if (ch == '\n')
|
||
|
newline = true;
|
||
|
if (++i >= str.length())
|
||
|
return sb.toString();
|
||
|
ch = str.charAt(i);
|
||
|
}
|
||
|
|
||
|
if (newline) {
|
||
|
// sb.append("\\n");
|
||
|
sb.append(" "); // collapse newline to two spaces
|
||
|
} else if (whitespace) {
|
||
|
sb.append(' ');
|
||
|
}
|
||
|
|
||
|
// TODO: handle non-printable chars
|
||
|
sb.append(ch);
|
||
|
|
||
|
if (sb.length() >= maxData)
|
||
|
return sb.toString() + " ...";
|
||
|
}
|
||
|
return sb.toString();
|
||
|
}
|
||
|
|
||
|
void url(String label, String path, boolean detail) throws IOException {
|
||
|
try {
|
||
|
out.print("<a href=\"zookeeper.jsp?");
|
||
|
if (path != null) {
|
||
|
out.print("path=");
|
||
|
out.print(URLEncoder.encode(path, "UTF-8"));
|
||
|
}
|
||
|
if (detail) {
|
||
|
out.print("&detail=" + detail);
|
||
|
}
|
||
|
if (fullpath != FULLPATH_DEFAULT) {
|
||
|
out.print("&fullpath=" + fullpath);
|
||
|
}
|
||
|
if (addr != null) {
|
||
|
out.print("&addr=");
|
||
|
out.print(URLEncoder.encode(addr, "UTF-8"));
|
||
|
}
|
||
|
|
||
|
out.print("\">");
|
||
|
xmlescape(label);
|
||
|
out.print("</a>");
|
||
|
|
||
|
} catch (UnsupportedEncodingException e) {
|
||
|
exception(e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void printTree(String path) throws IOException
|
||
|
{
|
||
|
String label = path;
|
||
|
if (!fullpath)
|
||
|
{
|
||
|
int idx = path.lastIndexOf('/');
|
||
|
label = idx > 0 ? path.substring(idx + 1) : path;
|
||
|
}
|
||
|
|
||
|
//url(label, path, true);
|
||
|
out.println("{");
|
||
|
out.println("\"data\" : \"" + label + "\"");
|
||
|
|
||
|
Stat stat = new Stat();
|
||
|
try
|
||
|
{
|
||
|
byte[] data = zkClient.getData(path, null, stat);
|
||
|
|
||
|
if( stat.getEphemeralOwner() != 0 )
|
||
|
{
|
||
|
out.println(", \"ephemeral\" : true");
|
||
|
out.println(", \"version\" : \"" + stat.getVersion() + "\"");
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
if (stat.getNumChildren() != 0)
|
||
|
{
|
||
|
out.println(", \"children_count\" : \"" + stat.getNumChildren() + "\"");
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
//if (data != null)
|
||
|
if( stat.getDataLength() != 0 )
|
||
|
{
|
||
|
|
||
|
String str;
|
||
|
try
|
||
|
{
|
||
|
str = new String(data, "UTF-8");
|
||
|
str = str.replaceAll("\\\"", "\\\\\"");
|
||
|
|
||
|
out.print(", \"content\" : \"");
|
||
|
//xmlescape(compress(str));
|
||
|
out.print(compress(str));
|
||
|
out.println("\"");
|
||
|
}
|
||
|
catch (UnsupportedEncodingException e)
|
||
|
{
|
||
|
// not UTF8
|
||
|
StringBuilder sb = new StringBuilder("BIN(");
|
||
|
sb.append("len=" + data.length);
|
||
|
sb.append("hex=");
|
||
|
int limit = Math.min(data.length, maxData / 2);
|
||
|
for (int i = 0; i < limit; i++)
|
||
|
{
|
||
|
byte b = data[i];
|
||
|
sb.append(StrUtils.HEX_DIGITS[(b >> 4) & 0xf]);
|
||
|
sb.append(StrUtils.HEX_DIGITS[b & 0xf]);
|
||
|
}
|
||
|
if (limit != data.length)
|
||
|
{
|
||
|
sb.append("...");
|
||
|
}
|
||
|
sb.append(")");
|
||
|
str = sb.toString();
|
||
|
//out.print(str);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
catch (IllegalArgumentException e)
|
||
|
{
|
||
|
// path doesn't exist (must have been removed)
|
||
|
out.println("(path gone)");
|
||
|
}
|
||
|
catch (KeeperException e)
|
||
|
{
|
||
|
e.printStackTrace();
|
||
|
}
|
||
|
catch (InterruptedException e)
|
||
|
{
|
||
|
e.printStackTrace();
|
||
|
}
|
||
|
|
||
|
if( stat.getNumChildren() > 0 )
|
||
|
{
|
||
|
out.print(", \"children\" : [");
|
||
|
|
||
|
List<String> children = null;
|
||
|
try
|
||
|
{
|
||
|
children = zkClient.getChildren(path, null);
|
||
|
}
|
||
|
catch (KeeperException e)
|
||
|
{
|
||
|
exception(e);
|
||
|
return;
|
||
|
}
|
||
|
catch (InterruptedException e)
|
||
|
{
|
||
|
exception(e);
|
||
|
}
|
||
|
catch (IllegalArgumentException e)
|
||
|
{
|
||
|
// path doesn't exist (must have been removed)
|
||
|
out.println("(children gone)");
|
||
|
}
|
||
|
|
||
|
Integer i = 0;
|
||
|
for( String child : children )
|
||
|
{
|
||
|
if( 0 != i )
|
||
|
{
|
||
|
out.print(", ");
|
||
|
}
|
||
|
|
||
|
String childPath = path + (path.endsWith("/") ? "" : "/") + child;
|
||
|
printTree( childPath );
|
||
|
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
out.println("]");
|
||
|
}
|
||
|
|
||
|
out.println("}");
|
||
|
}
|
||
|
|
||
|
String time(long ms) {
|
||
|
return (new Date(ms)).toString() + " (" + ms + ")";
|
||
|
}
|
||
|
|
||
|
void printZnode(String path) throws IOException
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
Stat stat = new Stat();
|
||
|
byte[] data = zkClient.getData(path, null, stat);
|
||
|
|
||
|
out.println("\"znode\" : {");
|
||
|
|
||
|
out.print("\"path\" : \"");
|
||
|
xmlescape(path);
|
||
|
out.println("\"");
|
||
|
|
||
|
out.println(", \"version\" : \"" + stat.getVersion() + "\"");
|
||
|
out.println(", \"aversion\" : \"" + stat.getAversion() + "\"");
|
||
|
out.println(", \"cversion\" : \"" + stat.getCversion() + "\"");
|
||
|
out.println(", \"ctime\" : \"" + time(stat.getCtime()) + "\"");
|
||
|
out.println(", \"mtime\" : \"" + time(stat.getMtime()) + "\"");
|
||
|
out.println(", \"czxid\" : \"" + stat.getCzxid() + "\"");
|
||
|
out.println(", \"mzxid\" : \"" + stat.getMzxid() + "\"");
|
||
|
out.println(", \"pzxid\" : \"" + stat.getPzxid() + "\"");
|
||
|
out.println(", \"children_count\" : \"" + stat.getNumChildren() + "\"");
|
||
|
out.println(", \"ephemeralOwner\" : \"" + stat.getEphemeralOwner() + "\"");
|
||
|
out.println(", \"dataLength\" : \"" + stat.getDataLength() + "\"");
|
||
|
|
||
|
if( stat.getDataLength() != 0 )
|
||
|
{
|
||
|
boolean isBinary = false;
|
||
|
String str;
|
||
|
try
|
||
|
{
|
||
|
str = new String(data, "UTF-8");
|
||
|
}
|
||
|
catch (UnsupportedEncodingException e)
|
||
|
{
|
||
|
// The results are unspecified
|
||
|
// when the bytes are not properly encoded.
|
||
|
|
||
|
// not UTF8
|
||
|
StringBuilder sb = new StringBuilder(data.length * 2);
|
||
|
for (int i = 0; i < data.length; i++)
|
||
|
{
|
||
|
byte b = data[i];
|
||
|
sb.append(StrUtils.HEX_DIGITS[(b >> 4) & 0xf]);
|
||
|
sb.append(StrUtils.HEX_DIGITS[b & 0xf]);
|
||
|
if ((i & 0x3f) == 0x3f)
|
||
|
{
|
||
|
sb.append("\n");
|
||
|
}
|
||
|
}
|
||
|
str = sb.toString();
|
||
|
}
|
||
|
str = str.replaceAll("\\\"", "\\\\\"");
|
||
|
|
||
|
out.print(", \"data\" : \"");
|
||
|
//xmlescape(str);
|
||
|
out.print(str);
|
||
|
out.println("\"");
|
||
|
}
|
||
|
|
||
|
out.println("}");
|
||
|
|
||
|
}
|
||
|
catch (KeeperException e)
|
||
|
{
|
||
|
exception(e);
|
||
|
return;
|
||
|
}
|
||
|
catch (InterruptedException e)
|
||
|
{
|
||
|
exception(e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
%>
|
||
|
|
||
|
<%
|
||
|
|
||
|
String path = request.getParameter("path");
|
||
|
String addr = request.getParameter("addr");
|
||
|
|
||
|
if (addr != null && addr.length() == 0)
|
||
|
{
|
||
|
addr = null;
|
||
|
}
|
||
|
|
||
|
String detailS = request.getParameter("detail");
|
||
|
boolean detail = detailS != null && detailS.equals("true");
|
||
|
|
||
|
ZKPrinter printer = new ZKPrinter(response, out, core, addr);
|
||
|
printer.detail = detail;
|
||
|
String tryAddr = printer.keeperAddr != null ? printer.keeperAddr : "localhost:2181";
|
||
|
|
||
|
try {
|
||
|
printer.print(path);
|
||
|
} finally {
|
||
|
printer.close();
|
||
|
}
|
||
|
|
||
|
%>
|