incubator-blur-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cr...@apache.org
Subject [2/2] git commit: Finished Server side of the console
Date Fri, 23 May 2014 03:57:16 GMT
Finished Server side of the console


Project: http://git-wip-us.apache.org/repos/asf/incubator-blur/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-blur/commit/6cdce8ec
Tree: http://git-wip-us.apache.org/repos/asf/incubator-blur/tree/6cdce8ec
Diff: http://git-wip-us.apache.org/repos/asf/incubator-blur/diff/6cdce8ec

Branch: refs/heads/console-v2
Commit: 6cdce8ec6446a705fc79c087b202bdbf78c6cfab
Parents: 0dc64c6
Author: Chris Rohr <crohr@nearinfinity.com>
Authored: Thu May 22 23:57:08 2014 -0400
Committer: Chris Rohr <crohr@nearinfinity.com>
Committed: Thu May 22 23:57:08 2014 -0400

----------------------------------------------------------------------
 .../org/apache/blur/console/JettyServer.java    |  19 ++-
 .../main/java/org/apache/blur/console/Main.java |  10 +-
 .../org/apache/blur/console/model/Column.java   |  63 ---------
 .../org/apache/blur/console/model/Family.java   |  42 ------
 .../console/servlets/BaseConsoleServlet.java    |  45 ++++++
 .../blur/console/servlets/DashboardServlet.java | 108 --------------
 .../blur/console/servlets/NodesServlet.java     |  63 +++++++++
 .../blur/console/servlets/QueriesServlet.java   |  62 +++++----
 .../blur/console/servlets/SearchServlet.java    |  61 ++++++++
 .../blur/console/servlets/TablesServlet.java    |  44 ++----
 .../org/apache/blur/console/util/Config.java    |  54 ++++++-
 .../org/apache/blur/console/util/HttpUtil.java  |   1 +
 .../org/apache/blur/console/util/NodeUtil.java  |  13 +-
 .../org/apache/blur/console/util/QueryUtil.java | 138 ++++++------------
 .../apache/blur/console/util/SearchUtil.java    | 129 +++++++++++++++++
 .../org/apache/blur/console/util/TableUtil.java | 106 ++++----------
 .../src/main/webapp/js/blurconsole.data.js      |  86 ++++++++++++
 .../src/main/webapp/js/blurconsole.fake.js      |  54 ++++---
 .../src/main/webapp/js/blurconsole.model.js     |  41 ++++--
 .../src/main/webapp/js/blurconsole.queries.js   |  23 ++-
 .../src/main/webapp/js/blurconsole.schema.js    |  11 +-
 .../src/main/webapp/js/blurconsole.search.js    |   8 +-
 .../src/main/webapp/sass/blurconsole.scss       |   2 +-
 .../apache/blur/console/ConsoleTestBase.java    |  14 +-
 .../apache/blur/console/util/HttpUtilTest.java  | 139 -------------------
 .../apache/blur/console/util/NodeUtilTest.java  |  19 +--
 .../apache/blur/console/util/QueryUtilTest.java |  77 +++++-----
 .../apache/blur/console/util/TableUtilTest.java |  28 ++--
 28 files changed, 729 insertions(+), 731 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/java/org/apache/blur/console/JettyServer.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/java/org/apache/blur/console/JettyServer.java b/contrib/blur-console/src/main/java/org/apache/blur/console/JettyServer.java
index 2a7436d..07fccff 100644
--- a/contrib/blur-console/src/main/java/org/apache/blur/console/JettyServer.java
+++ b/contrib/blur-console/src/main/java/org/apache/blur/console/JettyServer.java
@@ -17,10 +17,9 @@ package org.apache.blur.console;
  * limitations under the License.
  */
 
-import java.net.URL;
-
-import org.apache.blur.console.servlets.DashboardServlet;
+import org.apache.blur.console.servlets.NodesServlet;
 import org.apache.blur.console.servlets.QueriesServlet;
+import org.apache.blur.console.servlets.SearchServlet;
 import org.apache.blur.console.servlets.TablesServlet;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -29,16 +28,21 @@ import org.mortbay.jetty.servlet.Context;
 import org.mortbay.jetty.servlet.ServletHolder;
 import org.mortbay.jetty.webapp.WebAppContext;
 
+import java.net.URL;
+
 public class JettyServer {
-	private final static String WEBAPPDIR = "org/apache/blur/console/webapp";
+	private final static String DEV_WEBAPPDIR = "../classes/";
+	private final static String PROD_WEBAPPDIR = "webapp/";
 	private final static String CONTEXTPATH = "/console";
 	private final Log log = LogFactory.getLog(JettyServer.class);
 		
 	private int port;
 	private Server server;
+	private boolean devMode;
 	
-	public JettyServer(int port) {
+	public JettyServer(int port, boolean devMode) {
 		this.port = port;
+		this.devMode = devMode;
 	}
 	
 	public JettyServer start() {
@@ -58,15 +62,16 @@ public class JettyServer {
 		server = new Server(port);
 		
 		// for localhost:port/console/index.html and whatever else is in the webapp directory
-	    final URL warUrl = this.getClass().getClassLoader().getResource(WEBAPPDIR);
+	    final URL warUrl = devMode ? this.getClass().getClassLoader().getResource(DEV_WEBAPPDIR) : this.getClass().getClassLoader().getResource(PROD_WEBAPPDIR);
 	    final String warUrlString = warUrl.toExternalForm();
 	    server.setHandler(new WebAppContext(warUrlString, CONTEXTPATH));
 
 	    // for localhost:port/service/dashboard, etc.
 	    final Context context = new Context(server, "/service", Context.SESSIONS);
-	    context.addServlet(new ServletHolder(new DashboardServlet()), "/dashboard/*");
+	    context.addServlet(new ServletHolder(new NodesServlet()), "/nodes/*");
 	    context.addServlet(new ServletHolder(new TablesServlet()), "/tables/*");
 	    context.addServlet(new ServletHolder(new QueriesServlet()), "/queries/*");
+	    context.addServlet(new ServletHolder(new SearchServlet()), "/search/*");
 
 	    try {
 			server.start();

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/java/org/apache/blur/console/Main.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/java/org/apache/blur/console/Main.java b/contrib/blur-console/src/main/java/org/apache/blur/console/Main.java
index fb61fde..2df9783 100644
--- a/contrib/blur-console/src/main/java/org/apache/blur/console/Main.java
+++ b/contrib/blur-console/src/main/java/org/apache/blur/console/Main.java
@@ -18,11 +18,19 @@ package org.apache.blur.console;
  */
 
 import org.apache.blur.console.util.Config;
+import org.apache.commons.lang.ArrayUtils;
 
 public class Main {
 	public static void main(String[] args) throws Exception {
+		boolean devMode = ArrayUtils.contains(args, "--dev");
+		if (devMode) {
+			Config.setupMiniCluster();
+		}
 		Config.setupConfig();
-		JettyServer server = new JettyServer(Config.getConsolePort()).start();
+		JettyServer server = new JettyServer(Config.getConsolePort(), devMode).start();
 		server.join();
+		if (devMode) {
+			Config.shutdownMiniCluster();
+		}
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/java/org/apache/blur/console/model/Column.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/java/org/apache/blur/console/model/Column.java b/contrib/blur-console/src/main/java/org/apache/blur/console/model/Column.java
deleted file mode 100644
index 3c61ad7..0000000
--- a/contrib/blur-console/src/main/java/org/apache/blur/console/model/Column.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.apache.blur.console.model;
-
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-import java.util.Map;
-
-public class Column {
-	private String name;
-	private boolean fullTextIndexed;
-	private String subColumn;
-	private String type;
-	private Map<String, String> props;
-	
-	public Column(String name) {
-		this.name = name;
-	}
-	
-	public String getName() {
-		return name;
-	}
-	public void setName(String name) {
-		this.name = name;
-	}
-	public boolean isFullTextIndexed() {
-		return fullTextIndexed;
-	}
-	public void setFullTextIndexed(boolean fullTextIndexed) {
-		this.fullTextIndexed = fullTextIndexed;
-	}
-	public String getSubColumn() {
-		return subColumn;
-	}
-	public void setSubColumn(String subColumn) {
-		this.subColumn = subColumn;
-	}
-	public String getType() {
-		return type;
-	}
-	public void setType(String type) {
-		this.type = type;
-	}
-	public Map<String, String> getProps() {
-		return props;
-	}
-	public void setProps(Map<String, String> props) {
-		this.props = props;
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/java/org/apache/blur/console/model/Family.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/java/org/apache/blur/console/model/Family.java b/contrib/blur-console/src/main/java/org/apache/blur/console/model/Family.java
deleted file mode 100644
index 4f4015b..0000000
--- a/contrib/blur-console/src/main/java/org/apache/blur/console/model/Family.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package org.apache.blur.console.model;
-
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-import java.util.List;
-
-public class Family {
-	private String name;
-	private List<Column> columns;
-	
-	public Family(String name) {
-		this.name = name;
-	}
-	
-	public String getName() {
-		return name;
-	}
-	public void setName(String name) {
-		this.name = name;
-	}
-	public List<Column> getColumns() {
-		return columns;
-	}
-	public void setColumns(List<Column> columns) {
-		this.columns = columns;
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/BaseConsoleServlet.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/BaseConsoleServlet.java b/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/BaseConsoleServlet.java
new file mode 100644
index 0000000..4f74966
--- /dev/null
+++ b/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/BaseConsoleServlet.java
@@ -0,0 +1,45 @@
+package org.apache.blur.console.servlets;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.IOUtils;
+
+public abstract class BaseConsoleServlet extends HttpServlet {
+	private static final long serialVersionUID = -5156028303476799953L;
+
+	protected void sendError(HttpServletResponse response, Exception e) throws IOException {
+		e.printStackTrace();
+		String body = e.getMessage();
+		response.setContentType("application/json");
+		response.setContentLength(body.getBytes().length);
+		response.setStatus(500);
+		IOUtils.write(body, response.getOutputStream());
+	}
+	
+	protected void sendGenericOk(HttpServletResponse response) throws IOException {
+		response.setContentType("text/plain");
+		response.setContentLength(6);
+		response.setStatus(200);
+		IOUtils.write("success", response.getOutputStream());
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/DashboardServlet.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/DashboardServlet.java b/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/DashboardServlet.java
deleted file mode 100644
index 562bfce..0000000
--- a/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/DashboardServlet.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package org.apache.blur.console.servlets;
-
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.blur.console.util.HttpUtil;
-import org.apache.blur.console.util.NodeUtil;
-import org.apache.blur.console.util.QueryUtil;
-import org.apache.blur.console.util.TableUtil;
-import org.apache.commons.io.IOUtils;
-import org.codehaus.jackson.map.ObjectMapper;
-
-public class DashboardServlet extends HttpServlet {
-	private static final long serialVersionUID = 6522056391102413432L;
-
-	@Override
-	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-		String path = request.getPathInfo();
-		if ("/node/status".equalsIgnoreCase(path)) {
-			sendNodeStatus(response);
-		} else if ("/table/status".equalsIgnoreCase(path)) {
-			sendTableStatus(response);
-		} else if ("/query/status".equalsIgnoreCase(path)) {
-			sendQueryStatus(response);
-		} else {
-			response.setStatus(404);
-			IOUtils.write("Route [" + path + "] doesn't exist", response.getOutputStream());
-		}
-	}
-	
-	private void sendError(HttpServletResponse response, Exception e) throws IOException {
-		String body = e.getMessage();
-		response.setContentType("application/json");
-		response.setContentLength(body.getBytes().length);
-		response.setStatus(500);
-		IOUtils.write(body, response.getOutputStream());
-	}
-
-	private void sendNodeStatus(HttpServletResponse response) throws IOException {
-		Map<String, Object> nodeData = new HashMap<String, Object>();
-
-		try {
-			nodeData.put("zookeepers", NodeUtil.getZookeeperStatus());
-			nodeData.put("controllers", NodeUtil.getControllerStatus());
-			nodeData.put("clusters", NodeUtil.getClusterStatus());
-		} catch (IOException e) {
-			throw new IOException(e);
-		} catch (Exception e) {
-			sendError(response, e);
-			return;
-		}
-
-		HttpUtil.sendResponse(response, new ObjectMapper().writeValueAsString(nodeData), HttpUtil.JSON);
-	}
-	
-	private void sendTableStatus(HttpServletResponse response) throws IOException {
-		Map<String, Object> tableData = new HashMap<String, Object>();
-
-		try {
-			tableData = TableUtil.getTableStatus();
-		} catch (IOException e) {
-			throw new IOException(e);
-		} catch (Exception e) {
-			sendError(response, e);
-			return;
-		}
-
-		HttpUtil.sendResponse(response, new ObjectMapper().writeValueAsString(tableData), HttpUtil.JSON);
-	}
-	
-	private void sendQueryStatus(HttpServletResponse response) throws IOException {
-		Map<String, Object> queryData = new HashMap<String, Object>();
-
-		try {
-			queryData = QueryUtil.getQueryStatus();
-		} catch (IOException e) {
-			throw new IOException(e);
-		} catch (Exception e) {
-			sendError(response, e);
-			return;
-		}
-
-		HttpUtil.sendResponse(response, new ObjectMapper().writeValueAsString(queryData), HttpUtil.JSON);
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/NodesServlet.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/NodesServlet.java b/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/NodesServlet.java
new file mode 100644
index 0000000..31b77f2
--- /dev/null
+++ b/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/NodesServlet.java
@@ -0,0 +1,63 @@
+package org.apache.blur.console.servlets;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.blur.console.util.HttpUtil;
+import org.apache.blur.console.util.NodeUtil;
+import org.apache.commons.io.IOUtils;
+import org.codehaus.jackson.map.ObjectMapper;
+
+public class NodesServlet extends BaseConsoleServlet {
+	private static final long serialVersionUID = 6522056391102413432L;
+
+	@Override
+	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+		String path = request.getPathInfo();
+		if (path == null) {
+			sendNodeStatus(response);
+		} else {
+			response.setStatus(404);
+			IOUtils.write("Route [" + path + "] doesn't exist", response.getOutputStream());
+		}
+	}
+
+	private void sendNodeStatus(HttpServletResponse response) throws IOException {
+		Map<String, Object> nodeData = new HashMap<String, Object>();
+
+		try {
+			nodeData.put("zookeepers", NodeUtil.getZookeeperStatus());
+			nodeData.put("controllers", NodeUtil.getControllerStatus());
+			nodeData.put("clusters", NodeUtil.getClusterStatus());
+		} catch (IOException e) {
+			throw new IOException(e);
+		} catch (Exception e) {
+			sendError(response, e);
+			return;
+		}
+
+		HttpUtil.sendResponse(response, new ObjectMapper().writeValueAsString(nodeData), HttpUtil.JSON);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/QueriesServlet.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/QueriesServlet.java b/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/QueriesServlet.java
index 533a3fe..8a9a30c 100644
--- a/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/QueriesServlet.java
+++ b/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/QueriesServlet.java
@@ -19,60 +19,57 @@ package org.apache.blur.console.servlets;
 
 import java.io.IOException;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.blur.console.util.HttpUtil;
-import org.apache.blur.console.util.NodeUtil;
 import org.apache.blur.console.util.QueryUtil;
-import org.apache.blur.console.util.TableUtil;
-import org.apache.blur.thirdparty.thrift_0_9_0.TException;
-import org.apache.blur.thrift.generated.BlurException;
 import org.apache.commons.io.IOUtils;
 import org.codehaus.jackson.map.ObjectMapper;
 
-public class QueriesServlet extends HttpServlet {
+public class QueriesServlet extends BaseConsoleServlet {
 	private static final long serialVersionUID = -5725846390100596115L;
-//	private static Pattern tableTermsPattern = Pattern.compile("/(.*)/(.*)/terms");
+	private static Pattern queryCancelPattern = Pattern.compile("/(.*)/cancel");
 
 	@Override
 	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 		String path = request.getPathInfo();
 		Matcher m;
-		if ("/status".equalsIgnoreCase(path)) {
-			sendQueryStatus(response);
-		}
-//		else if ((m = tableTermsPattern.matcher(path)).matches()) {
-////			sendTerms(response, m.group(1), m.group(2));
-//		} 
-//		else if ("/query/status".equalsIgnoreCase(path)) {
-//			sendQueryStatus(response);
-//		} 
-		else {
+		if (path == null) {
+			sendQueries(response);
+		} else if ("/performance".equalsIgnoreCase(path)) {
+			sendCurrentQueryCount(response);
+		} else if ((m = queryCancelPattern.matcher(path)).matches()) {
+			cancelQuery(response, m.group(1), request.getParameter("table"));
+		} else {
 			response.setStatus(404);
 			IOUtils.write("Route [" + path + "] doesn't exist", response.getOutputStream());
 		}
 	}
 	
-	private void sendError(HttpServletResponse response, Exception e) throws IOException {
-		String body = e.getMessage();
-		response.setContentType("application/json");
-		response.setContentLength(body.getBytes().length);
-		response.setStatus(500);
-		IOUtils.write(body, response.getOutputStream());
+	private void sendCurrentQueryCount(HttpServletResponse response) throws IOException {
+		int count;
+		try {
+			count = QueryUtil.getCurrentQueryCount();
+		} catch (IOException e) {
+			throw new IOException(e);
+		} catch (Exception e) {
+			sendError(response, e);
+			return;
+		}
+		
+		HttpUtil.sendResponse(response, new ObjectMapper().writeValueAsString(count), HttpUtil.JSON);
 	}
 	
-	private void sendQueryStatus(HttpServletResponse response) throws IOException {
+	private void sendQueries(HttpServletResponse response) throws IOException {
 		Map<String, Object> queries = new HashMap<String, Object>();
 		try {
-			queries = QueryUtil.getQueryStatus();
+			queries = QueryUtil.getQueries();
 		} catch (IOException e) {
 			throw new IOException(e);
 		} catch (Exception e) {
@@ -82,4 +79,17 @@ public class QueriesServlet extends HttpServlet {
 		
 		HttpUtil.sendResponse(response, new ObjectMapper().writeValueAsString(queries), HttpUtil.JSON);
 	}
+	
+	private void cancelQuery(HttpServletResponse response, String uuid, String table) throws IOException {
+		try {
+			QueryUtil.cancelQuery(table, uuid);
+		} catch (IOException e) {
+			throw new IOException(e);
+		} catch (Exception e) {
+			sendError(response, e);
+			return;
+		}
+		
+		sendGenericOk(response);
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/SearchServlet.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/SearchServlet.java b/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/SearchServlet.java
new file mode 100644
index 0000000..1697d59
--- /dev/null
+++ b/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/SearchServlet.java
@@ -0,0 +1,61 @@
+package org.apache.blur.console.servlets;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.blur.console.util.HttpUtil;
+import org.apache.blur.console.util.SearchUtil;
+import org.apache.commons.io.IOUtils;
+import org.codehaus.jackson.map.ObjectMapper;
+
+
+public class SearchServlet extends BaseConsoleServlet {
+	private static final long serialVersionUID = 8236015799570635548L;
+
+	@Override
+	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+		String path = request.getPathInfo();
+		if (path == null) {
+			sendSearch(response, request.getParameterMap());
+		} else {
+			response.setStatus(404);
+			IOUtils.write("Route [" + path + "] doesn't exist", response.getOutputStream());
+		}
+	}
+	
+	private void sendSearch(HttpServletResponse response, Map<String, String[]> params) throws IOException {
+		Map<String, Object> results = new HashMap<String, Object>();
+		try {
+			results = SearchUtil.search(params);
+		} catch (IOException e) {
+			throw new IOException(e);
+		} catch (Exception e) {
+			sendError(response, e);
+			return;
+		}
+		
+		HttpUtil.sendResponse(response, new ObjectMapper().writeValueAsString(results), HttpUtil.JSON);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/TablesServlet.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/TablesServlet.java b/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/TablesServlet.java
index 32ca756..8f9321e 100644
--- a/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/TablesServlet.java
+++ b/contrib/blur-console/src/main/java/org/apache/blur/console/servlets/TablesServlet.java
@@ -19,14 +19,12 @@ package org.apache.blur.console.servlets;
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
@@ -35,7 +33,7 @@ import org.apache.blur.console.util.TableUtil;
 import org.apache.commons.io.IOUtils;
 import org.codehaus.jackson.map.ObjectMapper;
 
-public class TablesServlet extends HttpServlet {
+public class TablesServlet extends BaseConsoleServlet {
 	private static final long serialVersionUID = -5725846390100596115L;
 	private static Pattern tableSchemaPattern = Pattern.compile("/(.*)/schema");
 	private static Pattern tableEnablePattern = Pattern.compile("/(.*)/enable");
@@ -43,46 +41,30 @@ public class TablesServlet extends HttpServlet {
 	private static Pattern tableDeletePattern = Pattern.compile("/(.*)/delete");
 	private static Pattern tableTermsPattern = Pattern.compile("/(.*)/(.*)/(.*)/terms");
 
-	@SuppressWarnings("unchecked")
 	@Override
 	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 		String path = request.getPathInfo();
 		Matcher m;
-		if ("/summaries".equalsIgnoreCase(path)) {
+		if (path == null) {
 			sendSummaries(response);
 		} else if ((m = tableSchemaPattern.matcher(path)).matches()) {
 			sendSchema(response, m.group(1));
 		} else if ((m = tableTermsPattern.matcher(path)).matches()) {
-			sendTerms(response, m.group(1), m.group(2), m.group(3), request.getParameterMap());
+			sendTerms(response, m.group(1), m.group(2), m.group(3), request.getParameter("startsWith"));
 		} else if ((m = tableEnablePattern.matcher(path)).matches()) {
 			enableTable(response, m.group(1));
 		} else if ((m = tableDisablePattern.matcher(path)).matches()) {
 			disableTable(response, m.group(1));
 		} else if ((m = tableDeletePattern.matcher(path)).matches()) {
-			deleteTable(response, m.group(1), request.getParameterMap());
+			deleteTable(response, m.group(1), request.getParameter("includeFiles"));
 		} else {
 			response.setStatus(404);
 			IOUtils.write("Route [" + path + "] doesn't exist", response.getOutputStream());
 		}
 	}
 	
-	private void sendError(HttpServletResponse response, Exception e) throws IOException {
-		String body = e.getMessage();
-		response.setContentType("application/json");
-		response.setContentLength(body.getBytes().length);
-		response.setStatus(500);
-		IOUtils.write(body, response.getOutputStream());
-	}
-	
-	private void sendGenericOk(HttpServletResponse response) throws IOException {
-		response.setContentType("text/plain");
-		response.setContentLength(6);
-		response.setStatus(200);
-		IOUtils.write("success", response.getOutputStream());
-	}
-	
 	private void sendSummaries(HttpServletResponse response) throws IOException {
-		Map<String, Object> tableSummaries = new HashMap<String, Object>();
+		List<Map<String, Object>> tableSummaries = new ArrayList<Map<String,Object>>();
 		try {
 			tableSummaries = TableUtil.getTableSummaries();
 		} catch (IOException e) {
@@ -109,15 +91,10 @@ public class TablesServlet extends HttpServlet {
 		HttpUtil.sendResponse(response, new ObjectMapper().writeValueAsString(schema), HttpUtil.JSON);
 	}
 	
-	private void sendTerms(HttpServletResponse response, String table, String family, String column, Map<String, String[]> params) throws IOException {
+	private void sendTerms(HttpServletResponse response, String table, String family, String column, String startsWith) throws IOException {
 		List<String> terms = new ArrayList<String>();
 		try {
-			String startWith = null;
-			if (params.containsKey("startWith")) {
-				startWith = params.get("startWith")[0];
-			}
-			
-			terms = TableUtil.getTerms(table, family, column, startWith);
+			terms = TableUtil.getTerms(table, family, column, startsWith);
 		} catch (IOException e) {
 			throw new IOException(e);
 		} catch (Exception e) {
@@ -152,13 +129,8 @@ public class TablesServlet extends HttpServlet {
 		sendGenericOk(response);
 	}
 	
-	private void deleteTable(HttpServletResponse response, String table, Map<String, String[]> params) throws IOException {
+	private void deleteTable(HttpServletResponse response, String table, String includeFiles) throws IOException {
 		try {
-			String includeFiles = null;
-			if (params.containsKey("includeFiles")) {
-				includeFiles = params.get("includeFiles")[0];
-			}
-			
 			TableUtil.deleteTable(table, Boolean.parseBoolean(includeFiles));
 		} catch (IOException e) {
 			throw new IOException(e);

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/java/org/apache/blur/console/util/Config.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/java/org/apache/blur/console/util/Config.java b/contrib/blur-console/src/main/java/org/apache/blur/console/util/Config.java
index b732004..fc75989 100644
--- a/contrib/blur-console/src/main/java/org/apache/blur/console/util/Config.java
+++ b/contrib/blur-console/src/main/java/org/apache/blur/console/util/Config.java
@@ -17,19 +17,32 @@ package org.apache.blur.console.util;
  * limitations under the License.
  */
 
+import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.blur.BlurConfiguration;
+import org.apache.blur.MiniCluster;
 import org.apache.blur.manager.clusterstatus.ZookeeperClusterStatus;
+import org.apache.blur.utils.GCWatcher;
+import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.StringUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.LocalFileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.permission.FsAction;
+import org.apache.hadoop.fs.permission.FsPermission;
 
 public class Config {
+	private static final File TMPDIR = new File(System.getProperty("blur.tmp.dir", "./target/mini-cluster"));
+	
 	private static int port = 8080;
 	private static BlurConfiguration blurConfig;
 	private static ZookeeperClusterStatus zk;
 	private static String blurConnection;
+	private static MiniCluster cluster;
 
 	public static int getConsolePort() {
 		return port;
@@ -39,7 +52,12 @@ public class Config {
 	}
 	
 	public static void setupConfig() throws IOException {
-		blurConfig = new BlurConfiguration();
+		if (cluster == null) {
+			blurConfig = new BlurConfiguration();
+		} else {
+			blurConfig = new BlurConfiguration(false);
+			blurConfig.set("blur.zookeeper.connection", cluster.getZkConnectionString());
+		}
 		zk = new ZookeeperClusterStatus(blurConfig.get("blur.zookeeper.connection"), blurConfig);
 		blurConnection = buildConnectionString();
 	}
@@ -57,4 +75,38 @@ public class Config {
 		allControllers = zk.getControllerServerList();
 		return StringUtils.join(allControllers, ",");
 	}
+	
+	public static void shutdownMiniCluster() throws IOException {
+		if (cluster != null) {
+			cluster.shutdownBlurCluster();
+			File file = new File(TMPDIR, "blur-cluster-test");
+			if (file.exists()) {
+				FileUtils.deleteDirectory(file);
+			}
+		}
+	}
+	
+	
+	public static void setupMiniCluster() throws IOException {
+		GCWatcher.init(0.60);
+	    LocalFileSystem localFS = FileSystem.getLocal(new Configuration());
+	    File testDirectory = new File(TMPDIR, "blur-cluster-test").getAbsoluteFile();
+	    testDirectory.mkdirs();
+
+	    Path directory = new Path(testDirectory.getPath());
+	    FsPermission dirPermissions = localFS.getFileStatus(directory).getPermission();
+	    FsAction userAction = dirPermissions.getUserAction();
+	    FsAction groupAction = dirPermissions.getGroupAction();
+	    FsAction otherAction = dirPermissions.getOtherAction();
+
+	    StringBuilder builder = new StringBuilder();
+	    builder.append(userAction.ordinal());
+	    builder.append(groupAction.ordinal());
+	    builder.append(otherAction.ordinal());
+	    String dirPermissionNum = builder.toString();
+	    System.setProperty("dfs.datanode.data.dir.perm", dirPermissionNum);
+	    testDirectory.delete();
+	    cluster = new MiniCluster();
+	    cluster.startBlurCluster(new File(testDirectory, "cluster").getAbsolutePath(), 2, 3, true);
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/java/org/apache/blur/console/util/HttpUtil.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/java/org/apache/blur/console/util/HttpUtil.java b/contrib/blur-console/src/main/java/org/apache/blur/console/util/HttpUtil.java
index 6b502b5..cdc8c41 100644
--- a/contrib/blur-console/src/main/java/org/apache/blur/console/util/HttpUtil.java
+++ b/contrib/blur-console/src/main/java/org/apache/blur/console/util/HttpUtil.java
@@ -25,6 +25,7 @@ import org.apache.commons.io.IOUtils;
 
 public class HttpUtil {
 	public static String JSON = "application/json";
+	public static String TEXT = "plain/text";
 	
 	public static void sendResponse(HttpServletResponse response, String body, String contentType) throws IOException {
 		response.setContentType(contentType);

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/java/org/apache/blur/console/util/NodeUtil.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/java/org/apache/blur/console/util/NodeUtil.java b/contrib/blur-console/src/main/java/org/apache/blur/console/util/NodeUtil.java
index f2b3b9b..8c20d42 100644
--- a/contrib/blur-console/src/main/java/org/apache/blur/console/util/NodeUtil.java
+++ b/contrib/blur-console/src/main/java/org/apache/blur/console/util/NodeUtil.java
@@ -36,6 +36,7 @@ import org.apache.blur.manager.clusterstatus.ZookeeperClusterStatus;
 import org.apache.commons.collections.CollectionUtils;
 
 public class NodeUtil {
+	
 	@SuppressWarnings("unchecked")
 	public static Map<String, Object> getControllerStatus() throws IOException {
 		ZookeeperClusterStatus zk = Config.getZookeeper();
@@ -53,10 +54,6 @@ public class NodeUtil {
 		data.put("online", onlineControllers);
 		data.put("offline", offlineControllers);
 		
-		if (allControllers.isEmpty()) {
-			data.put("errmsg", "Unable to find any nodes");
-		}
-		
 		return data;
 	}
 
@@ -76,10 +73,6 @@ public class NodeUtil {
 			clusterObj.put("online", onlineShardServers);
 			clusterObj.put("offline", offlineShardServers);
 
-			if (offlineShardServers.isEmpty() && onlineShardServers.isEmpty()) {
-				clusterObj.put("errmsg", "Unable to find any nodes for cluster [" + cluster + "]");
-			}
-
 			data.add(clusterObj);
 		}
 
@@ -145,10 +138,6 @@ public class NodeUtil {
 		data.put("online", onlineZookeepers);
 		data.put("offline", offlineZookeepers);
 		
-		if (onlineZookeepers.isEmpty() && offlineZookeepers.isEmpty()) {
-			data.put("errmsg", "Unable to find any nodes");
-		}
-		
 		return data;
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/java/org/apache/blur/console/util/QueryUtil.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/java/org/apache/blur/console/util/QueryUtil.java b/contrib/blur-console/src/main/java/org/apache/blur/console/util/QueryUtil.java
index 44ec68d..a6c2041 100644
--- a/contrib/blur-console/src/main/java/org/apache/blur/console/util/QueryUtil.java
+++ b/contrib/blur-console/src/main/java/org/apache/blur/console/util/QueryUtil.java
@@ -19,129 +19,77 @@ package org.apache.blur.console.util;
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.TreeMap;
 
 import org.apache.blur.thirdparty.thrift_0_9_0.TException;
 import org.apache.blur.thrift.BlurClient;
 import org.apache.blur.thrift.generated.Blur.Iface;
 import org.apache.blur.thrift.generated.BlurException;
 import org.apache.blur.thrift.generated.BlurQueryStatus;
-import org.apache.blur.thrift.generated.CpuTime;
-import org.apache.blur.thrift.generated.QueryState;
+import org.apache.blur.thrift.generated.Status;
 
 public class QueryUtil {
 	
-	/**
-	 * {
-	 * 	clusters: ['prodA', 'prodB'],
-	 * 	counts: {
-	 * 		'prodA':{
-	 * 			timeToTheMinute: count
-	 *  	}
-	 *  },
-	 *  performance: {
-	 *  	'prodA':{
-	 *  		timeToTheMinute: avgCpuTime
-	 *  	}
-	 *  },
-	 *  slowQueries: count
-	 * }
-	 */
-	public static Map<String, Object> getQueryStatus() throws IOException, BlurException, TException {
+	public static int getCurrentQueryCount() throws IOException, BlurException, TException {
 		Iface client = BlurClient.getClient(Config.getConnectionString());
 		
-		Map<String, Object> queryStatus = new HashMap<String, Object>();
+		int count = 0;
+		List<String> tableList = client.tableList();
+		for (String table : tableList) {
+			List<String> queries = client.queryStatusIdList(table);
+			count += queries.size();
+		}
 		
-		List<String> clusters = client.shardClusterList();
-		queryStatus.put("clusters", clusters);
+		return count;
+	}
+	
+	public static Map<String, Object> getQueries() throws BlurException, TException, IOException {
+		Map<String, Object> queriesInfo = new HashMap<String, Object>();
 		
-		Integer slowQueries = 0;
+		int slow = 0;
 		
-		Calendar slowThreshold = Calendar.getInstance();
-		slowThreshold.add(Calendar.MINUTE, -1);
+		List<Map<String, Object>> queries = new ArrayList<Map<String,Object>>();
 		
-		Map<String, Map<Long, Long>> queryCounts = new HashMap<String, Map<Long, Long>>();
-		Map<String, Map<Long, Double>> queryPerformances = new HashMap<String, Map<Long, Double>>();
+		Iface client = BlurClient.getClient(Config.getConnectionString());
+		List<String> tableList = client.tableList();
 		
-		for (String cluster : clusters) {
-			List<String> tables = client.tableListByCluster(cluster);
-
-			Map<Long, List<Double>> queryPerfs = new TreeMap<Long, List<Double>>();
-			Map<Long, Long> clusterQueries = new TreeMap<Long,Long>();
-			
-			for (String table : tables) {
-				if (client.describe(table).isEnabled()) {
-					List<String> queryIds = client.queryStatusIdList(table);				
+		for (String table : tableList) {
+			List<String> queriesForTable = client.queryStatusIdList(table);
+			for (String id : queriesForTable) {
+				BlurQueryStatus status = client.queryStatusById(table, id);
+				
+				if (Status.FOUND.equals(status.getStatus())) {
+					Map<String, Object> info = new HashMap<String, Object>();
+					info.put("uuid", id);
+					info.put("user", status.getQuery().getUserContext());
+					info.put("query", status.getQuery().getQuery().getQuery());
+					info.put("table", table);
+					info.put("state", status.getState().getValue());
+					info.put("percent", ((double)status.getCompleteShards())/((double)status.getTotalShards())*100);
+					
 					
-					if (queryIds.isEmpty()) {
-						Calendar cal = Calendar.getInstance();
-						cal.set(Calendar.SECOND, 0);
-						cal.set(Calendar.MILLISECOND, 0);
-						clusterQueries.put(cal.getTimeInMillis(), 0L);
-						queryPerfs.put(cal.getTimeInMillis(), new ArrayList<Double>(Arrays.asList(new Double[]{0.0})));
-					} else {
-						for (String queryId : queryIds) {
-							BlurQueryStatus status = client.queryStatusById(table, queryId);
-							
-							Calendar cal = Calendar.getInstance();
-							cal.setTimeInMillis(status.getQuery().getStartTime());
-							cal.set(Calendar.SECOND, 0);
-							cal.set(Calendar.MILLISECOND, 0);
-							
-							if (QueryState.RUNNING.equals(status.getState()) && cal.getTimeInMillis() < slowThreshold.getTimeInMillis()) {
-								slowQueries++;
-							}
-							
-							incrementQueryCount(clusterQueries, cal);
-							collectQueryPerformance(queryPerfs, cal, status);
-						}
+					long startTime = status.getQuery().getStartTime();
+					info.put("startTime", startTime);
+					queries.add(info);
+					
+					if (System.currentTimeMillis() - startTime > 60000) {
+						slow++;
 					}
 				}
 			}
-			Map<Long, Double> clusterQueryPerfs = new TreeMap<Long,Double>();
-			for (Map.Entry<Long, List<Double>> perfEntry : queryPerfs.entrySet()) {
-				double sum = 0.0;
-				for (Double perf : perfEntry.getValue()) {
-					sum += perf;
-				}
-				clusterQueryPerfs.put(perfEntry.getKey(), (sum/perfEntry.getValue().size()));
-			}
-			
-			queryCounts.put(cluster, clusterQueries);
-			queryPerformances.put(cluster, clusterQueryPerfs);
 		}
 		
-		queryStatus.put("counts", queryCounts);
-		queryStatus.put("performance", queryPerformances);
-		queryStatus.put("slowQueries", slowQueries);
-		
-		return queryStatus;
-	}
-	
-	private static void incrementQueryCount(Map<Long, Long> queries, Calendar cal) {
-		Long previousCount = queries.get(cal.getTimeInMillis());
-		if (previousCount == null) {
-			previousCount = 0L;
-		}
+		queriesInfo.put("slowQueries", slow);
+		queriesInfo.put("queries", queries);
 		
-		queries.put(cal.getTimeInMillis(), previousCount + 1);
+		return queriesInfo;
 	}
 	
-	private static void collectQueryPerformance(Map<Long, List<Double>> queries, Calendar cal, BlurQueryStatus status) {
-		List<Double> perfs = queries.get(cal.getTimeInMillis());
-		if (perfs == null) {
-			perfs = new ArrayList<Double>();
-			queries.put(cal.getTimeInMillis(), perfs);
-		}
+	public static void cancelQuery(String table, String uuid) throws IOException, BlurException, TException {
+		Iface client = BlurClient.getClient(Config.getConnectionString());
 		
-		Map<String, CpuTime> cpuTimes = status.getCpuTimes();
-		for (CpuTime cpu : cpuTimes.values()) {
-			perfs.add(cpu.getRealTime()/1000000.0);
-		}
+		client.cancelQuery(table, uuid);
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/java/org/apache/blur/console/util/SearchUtil.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/java/org/apache/blur/console/util/SearchUtil.java b/contrib/blur-console/src/main/java/org/apache/blur/console/util/SearchUtil.java
new file mode 100644
index 0000000..23eecd3
--- /dev/null
+++ b/contrib/blur-console/src/main/java/org/apache/blur/console/util/SearchUtil.java
@@ -0,0 +1,129 @@
+package org.apache.blur.console.util;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.blur.thirdparty.thrift_0_9_0.TException;
+import org.apache.blur.thrift.BlurClient;
+import org.apache.blur.thrift.generated.Blur.Iface;
+import org.apache.blur.thrift.generated.BlurException;
+import org.apache.blur.thrift.generated.BlurQuery;
+import org.apache.blur.thrift.generated.BlurResult;
+import org.apache.blur.thrift.generated.BlurResults;
+import org.apache.blur.thrift.generated.Column;
+import org.apache.blur.thrift.generated.FetchRecordResult;
+import org.apache.blur.thrift.generated.FetchResult;
+import org.apache.blur.thrift.generated.FetchRowResult;
+import org.apache.blur.thrift.generated.Query;
+import org.apache.blur.thrift.generated.Record;
+import org.apache.blur.thrift.generated.Row;
+import org.apache.blur.thrift.generated.ScoreType;
+import org.apache.blur.thrift.generated.Selector;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+public class SearchUtil {
+	public static Map<String, Object> search(Map<String, String[]> params) throws IOException, BlurException, TException {
+		Iface client = BlurClient.getClient(Config.getConnectionString());
+		
+		String table = params.get("table")[0];
+		String query = params.get("query")[0];
+		String rowQuery = params.get("rowRecordOption")[0];
+		String start = params.get("start")[0];
+		String fetch = params.get("fetch")[0];
+		String[] families = params.get("families[]");
+		
+		BlurQuery blurQuery = new BlurQuery();
+		
+		Query q = new Query(query, "rowrow".equalsIgnoreCase(rowQuery), ScoreType.SUPER, null, null);
+		blurQuery.setQuery(q);
+		blurQuery.setStart(Long.parseLong(start));
+		blurQuery.setFetch(Integer.parseInt(fetch));
+		
+		Selector s = new Selector();
+		s.setRecordOnly("recordrecord".equalsIgnoreCase(rowQuery));
+		s.setColumnFamiliesToFetch(new HashSet<String>(Arrays.asList(families)));
+		blurQuery.setSelector(s);
+		
+		BlurResults blurResults = client.query(table, blurQuery);
+		
+		Map<String, Object> results = new HashMap<String, Object>();
+		results.put("total", blurResults.getTotalResults());
+		
+		Set<String> fams = new HashSet<String>();
+		Map<String, List<Map<String, Object>>> rows = new HashMap<String, List<Map<String, Object>>>();
+		for (BlurResult result : blurResults.getResults()) {
+			FetchResult fetchResult = result.getFetchResult();
+			
+			if ("recordrecord".equalsIgnoreCase(rowQuery)) {
+				// Record Result
+				FetchRecordResult recordResult = fetchResult.getRecordResult();
+				Record record = recordResult.getRecord();
+				
+				String family = record.getFamily();
+				fams.add(family);
+				
+				addRowToFam(family, columnsToMap(record.getColumns(), null, record.getRecordId()), rows);
+			} else {
+				// Row Result
+				FetchRowResult rowResult = fetchResult.getRowResult();
+				Row row = rowResult.getRow();
+				for (Record record : row.getRecords()) {
+					String family = record.getFamily();
+					fams.add(family);
+					
+					addRowToFam(family, columnsToMap(record.getColumns(), row.getId(), record.getRecordId()), rows);
+				}
+			}
+		}
+		
+		results.put("families", fams);
+		results.put("results", rows);
+		
+		return results;
+	}
+	
+	private static void addRowToFam(String fam, Map<String, Object> row, Map<String, List<Map<String, Object>>> results) {
+		List<Map<String, Object>> famResults = results.get(fam);
+		
+		if (famResults == null) {
+			famResults = new ArrayList<Map<String,Object>>();
+			results.put(fam, famResults);
+		}
+		
+		famResults.add(row);
+	}
+	
+	private static Map<String, Object> columnsToMap(List<Column> columns, String rowid, String recordid) {
+		Map<String, Object> map = new HashMap<String, Object>();
+		map.put("rowid", rowid);
+		map.put("recordid", recordid);
+		
+		for (Column column : columns) {
+			map.put(column.getName(), column.getValue());
+		}
+		
+		return map;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/java/org/apache/blur/console/util/TableUtil.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/java/org/apache/blur/console/util/TableUtil.java b/contrib/blur-console/src/main/java/org/apache/blur/console/util/TableUtil.java
index 67bd1fd..3aad7f1 100644
--- a/contrib/blur-console/src/main/java/org/apache/blur/console/util/TableUtil.java
+++ b/contrib/blur-console/src/main/java/org/apache/blur/console/util/TableUtil.java
@@ -22,9 +22,8 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.TreeMap;
 
-import org.apache.blur.console.model.Column;
-import org.apache.blur.console.model.Family;
 import org.apache.blur.thirdparty.thrift_0_9_0.TException;
 import org.apache.blur.thrift.BlurClient;
 import org.apache.blur.thrift.generated.Blur.Iface;
@@ -35,119 +34,64 @@ import org.apache.blur.thrift.generated.TableDescriptor;
 import org.apache.blur.thrift.generated.TableStats;
 
 public class TableUtil {
-	public static Map<String, Object> getTableStatus() throws IOException, BlurException, TException {
-		Iface client = BlurClient.getClient(Config.getConnectionString());
-		
-		List<String> clusters = client.shardClusterList();
-
-		Map<String, Object> data = new HashMap<String, Object>();
-		List<Map<String, Object>> clusterInfo = new ArrayList<Map<String,Object>>();
-		
-		int clusterCount = 0;
-		for (String cluster : clusters) {
-			Map<String, Object> clusterObj = new HashMap<String, Object>();
-			clusterObj.put("name", cluster);
-
-			List<String> tables = client.tableListByCluster(cluster);
-			
-			List<String> enabledTables = new ArrayList<String>();
-			List<String> disabledTables = new ArrayList<String>();
-			int enabledCount = 0;
-			int disabledCount = 0;
-			
-			for (String table : tables) {
-				boolean enabled = client.describe(table).isEnabled();
-				
-				if (enabled) {
-					enabledTables.add(table);
-					enabledCount++;
-				} else {
-					disabledTables.add(table);
-					disabledCount++;
-				}
-			}
-			
-			clusterObj.put("enabled", enabledTables);
-			clusterObj.put("disabled", disabledTables);
-			
-			List<Object> e = new ArrayList<Object>();
-			e.add(clusterCount);
-			e.add(enabledCount);
-			
-			List<Object> d = new ArrayList<Object>();
-			d.add(clusterCount);
-			d.add(disabledCount);
-
-			clusterInfo.add(clusterObj);
-			clusterCount++;
-		}
-		
-		data.put("tables", clusterInfo);
-		
-		return data;
-	}
 	
-	public static Map<String, Object> getTableSummaries() throws IOException, BlurException, TException {
+	public static List<Map<String, Object>> getTableSummaries() throws IOException, BlurException, TException {
 		Iface client = BlurClient.getClient(Config.getConnectionString());
 		
-		Map<String, List<Map<String, Object>>> tablesByCluster = new HashMap<String, List<Map<String,Object>>>();
+		List<Map<String, Object>> summaries = new ArrayList<Map<String, Object>>();
 		
 		List<String> clusters = client.shardClusterList();
 		
 		for (String cluster : clusters) {
 			List<String> tables = client.tableListByCluster(cluster);
-			List<Map<String, Object>> tableList = new ArrayList<Map<String,Object>>();
 			for (String table : tables) {
 				Map<String, Object> tableInfo = new HashMap<String, Object>();
-				
 				TableDescriptor descriptor = client.describe(table);
 				
+				tableInfo.put("cluster", cluster);
 				tableInfo.put("name", table);
 				tableInfo.put("enabled", descriptor.isEnabled());
 				
 				if (descriptor.isEnabled()) {
 					TableStats stats = client.tableStats(table);
-					tableInfo.put("rowCount", stats.getRowCount());
-					tableInfo.put("recordCount", stats.getRecordCount());
+					tableInfo.put("rows", stats.getRowCount());
+					tableInfo.put("records", stats.getRecordCount());
+					
+					Schema schema = client.schema(table);
+					tableInfo.put("families", new ArrayList<String>(schema.getFamilies().keySet()));
+				} else {
+					tableInfo.put("rows", "?");
+					tableInfo.put("records", "?");
+					tableInfo.put("families", new ArrayList<String>());
 				}
 				
-				tableList.add(tableInfo);
+				summaries.add(tableInfo);
 			}
-			tablesByCluster.put(cluster, tableList);
 		}
 		
-		Map<String, Object> data = new HashMap<String, Object>();
-		
-		data.put("clusters", clusters);
-		data.put("tables", tablesByCluster);
-		
-		return data;
+		return summaries;
 	}
 	
-	public static Object getSchema(String table) throws IOException, BlurException, TException {
+	public static Map<String, Map<String, Map<String, Object>>> getSchema(String table) throws IOException, BlurException, TException {
 		Iface client = BlurClient.getClient(Config.getConnectionString());
 		
 		Schema schema = client.schema(table);
 		
-		List<Family> schemaList = new ArrayList<Family>();
+		Map<String, Map<String, Map<String, Object>>> schemaInfo = new TreeMap<String, Map<String,Map<String, Object>>>();
 		for (Map.Entry<String, Map<String, ColumnDefinition>> famEntry : schema.getFamilies().entrySet()) {
-			Family family = new Family(famEntry.getKey());
-			List<Column> columns = new ArrayList<Column>();
-			family.setColumns(columns);
+			Map<String, Map<String, Object>> columns = new TreeMap<String, Map<String, Object>>();
 			for(Map.Entry<String, ColumnDefinition> colEntry : famEntry.getValue().entrySet()) {
+				Map<String, Object> info = new HashMap<String, Object>();
 				ColumnDefinition def = colEntry.getValue();
-				
-				Column column = new Column(colEntry.getKey());
-				column.setFullTextIndexed(def.isFieldLessIndexed());
-				column.setSubColumn(def.getSubColumnName());
-				column.setType(def.getFieldType());
-				column.setProps(def.getProperties());
-				columns.add(column);
+				info.put("fieldLess", def.isFieldLessIndexed());
+				info.put("type", def.getFieldType());
+				info.put("extra", def.getProperties());
+				columns.put(colEntry.getKey(), info);
 			}
-			schemaList.add(family);
+			schemaInfo.put(famEntry.getKey(), columns);
 		}
 		
-		return schemaList;
+		return schemaInfo;
 	}
 	
 	public static List<String> getTerms(String table, String family, String column, String startWith) throws IOException, BlurException, TException {

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/webapp/js/blurconsole.data.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/webapp/js/blurconsole.data.js b/contrib/blur-console/src/main/webapp/js/blurconsole.data.js
index 441fb43..003e791 100644
--- a/contrib/blur-console/src/main/webapp/js/blurconsole.data.js
+++ b/contrib/blur-console/src/main/webapp/js/blurconsole.data.js
@@ -20,4 +20,90 @@ under the License.
 /*global blurconsole:false */
 blurconsole.data = (function() {
 	'use strict';
+	var getTableList, getNodeList, getQueryPerformance, getQueries, cancelQuery, disableTable, enableTable, deleteTable, getSchema, findTerms, sendSearch;
+
+	getTableList = function(callback) {
+		$.getJSON('/service/tables', callback);
+	};
+
+	getNodeList = function(callback) {
+		$.getJSON('/service/nodes', callback);
+	};
+
+	getQueryPerformance = function(callback) {
+		$.getJSON('/service/queries/performance', callback);
+	};
+
+	getQueries = function(callback) {
+		$.getJSON('/service/queries', callback);
+	};
+
+	cancelQuery = function(table, uuid) {
+		$.ajax('/service/queries/' + uuid + '/cancel', {
+			data: {
+				table: table
+			},
+			error: function(xhr, msg) {
+				$.gevent.publish('query-cancel-error', uuid, msg);
+			}
+		});
+	};
+
+	disableTable = function(table) {
+		$.ajax('/service/tables/' + table + '/disable', {
+			error: function(xhr, msg) {
+				$.gevent.publish('table-disable-error', table, msg);
+			}
+		});
+	};
+
+	enableTable = function(table) {
+		$.ajax('/service/tables/' + table + '/enable', {
+			error: function(xhr, msg) {
+				$.gevent.publish('table-enable-error', table, msg);
+			}
+		});
+	};
+
+	deleteTable = function(table, includeFiles) {
+		$.ajax('/service/tables/' + table + '/delete', {
+			data: {
+				includeFiles: includeFiles
+			},
+			error: function(xhr, msg) {
+				$.gevent.publish('table-delete-error', table, msg);
+			}
+		});
+	};
+
+	getSchema = function(table, callback) {
+		$.getJSON('/service/tables/' + table + '/schema', callback);
+	};
+
+	findTerms = function(table, family, column, startsWith, callback) {
+		$.getJSON('/service/tables/' + table + '/' + family + '/' + column + '/terms', {startsWith: startsWith}, callback);
+	};
+
+	sendSearch = function(query, table, args, callback) {
+		var params = $.extend({table:table, query:query}, args);
+		$.ajax('/service/search', {
+			'type': 'POST',
+			'data': params,
+			'success': callback
+		});
+	};
+
+	return {
+		getTableList : getTableList,
+		getNodeList : getNodeList,
+		getQueryPerformance : getQueryPerformance,
+		getQueries : getQueries,
+		cancelQuery : cancelQuery,
+		disableTable : disableTable,
+		enableTable : enableTable,
+		deleteTable : deleteTable,
+		getSchema : getSchema,
+		findTerms : findTerms,
+		sendSearch : sendSearch
+	};
 }());
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/webapp/js/blurconsole.fake.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/webapp/js/blurconsole.fake.js b/contrib/blur-console/src/main/webapp/js/blurconsole.fake.js
index aa85975..64f2587 100644
--- a/contrib/blur-console/src/main/webapp/js/blurconsole.fake.js
+++ b/contrib/blur-console/src/main/webapp/js/blurconsole.fake.js
@@ -21,9 +21,9 @@ under the License.
 blurconsole.fake = (function() {
 	'use strict';
 	var getTableList, getNodeList, getQueryPerformance, getQueries, cancelQuery, disableTable, enableTable, deleteTable, getSchema, findTerms, sendSearch,
-		randomNumber, randomBoolean, randomString;
+		buildSchema, randomNumber, randomBoolean, randomString;
 
-	getTableList = function() {
+	getTableList = function(callback) {
 		console.log('getting fake table list');
 		var clusters = ['prodA', 'prodB'], data = [], i, cluster, rows, records, enabled;
 
@@ -33,13 +33,16 @@ blurconsole.fake = (function() {
 			records = randomNumber(10000)+1000;
 			enabled = randomBoolean();
 
-			data.push({cluster:cluster, name:'testtable'+i, enabled:enabled, rows:rows, records:records, families: blurconsole.utils.keys(getSchema('testtable'+i))});
+			data.push({cluster:cluster, name:'testtable'+i, enabled:enabled, rows:rows, records:records, families: blurconsole.utils.keys(buildSchema())});
 
 		}
-		return data;
+
+		setTimeout(function() {
+			callback(data);
+		}, randomNumber(1000));
 	};
 
-	getNodeList = function() {
+	getNodeList = function(callback) {
 		console.log('getting fake node list');
 		var controllers = {online:[], offline:[]},
 			clusters = [{name:'prodA', online:[], offline:[]}, {name:'prodB', online:[], offline:[]}],
@@ -60,15 +63,21 @@ blurconsole.fake = (function() {
 				zookeepers.offline.push('zookeeper' + i + '.localhost');
 			}
 		}
-		return {controllers: controllers, clusters: clusters, zookeepers: zookeepers};
+
+		setTimeout(function(){
+			callback({controllers: controllers, clusters: clusters, zookeepers: zookeepers});
+		}, randomNumber(1000));
 	};
 
-	getQueryPerformance = function() {
+	getQueryPerformance = function(callback) {
 		console.log('getting fake query performance');
-		return randomNumber(1000);
+
+		setTimeout(function(){
+			callback(randomNumber(1000));
+		}, randomNumber(1000));
 	};
 
-	getQueries = function() {
+	getQueries = function(callback) {
 		console.log('getting fake queries');
 		var queries = [];
 
@@ -80,18 +89,20 @@ blurconsole.fake = (function() {
 				table: 'testtable' + randomNumber(5, true),
 				state: randomNumber(3, true),
 				percent: randomNumber(100, true),
-				startTime: new Date()
+				startTime: new Date().getTime()
 			});
 		}
 
-		return {
-			slowQueries : randomNumber(100) % 10 === 0,
-			queries : queries
-		};
+		setTimeout(function(){
+			callback({
+				slowQueries : randomNumber(100) % 10 === 0,
+				queries : queries
+			});
+		}, randomNumber(1000));
 	};
 
-	cancelQuery = function(uuid) {
-		console.log('Fake sending request to cancel query [' + uuid + ']');
+	cancelQuery = function(table, uuid) {
+		console.log('Fake sending request to cancel query [' + uuid + '] on table [' + table + ']');
 	};
 
 	disableTable = function(table) {
@@ -106,8 +117,14 @@ blurconsole.fake = (function() {
 		console.log('Fake sending request to delete table [' + table + '] with files [' + includeFiles + ']');
 	};
 
-	getSchema = function(table) {
+	getSchema = function(table, callback) {
 		console.log('getting fake schema for table [' + table + ']');
+		setTimeout(function() {
+			callback(buildSchema());
+		}, randomNumber(1000));
+	};
+
+	buildSchema = function() {
 		var f, schema = {}, familyCount = randomNumber(20), types = ['string', 'long', 'int', 'date', 'stored', 'customType'];
 
 		for(f=0; f < familyCount; f++) {
@@ -129,7 +146,6 @@ blurconsole.fake = (function() {
 			}
 			schema['fam'+f] = fam;
 		}
-
 		return schema;
 	};
 
@@ -174,7 +190,7 @@ blurconsole.fake = (function() {
 		});
 
 		callback({
-			families: args.families,
+			families: fams,
 			results: results,
 			total: total
 		});

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/webapp/js/blurconsole.model.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/webapp/js/blurconsole.model.js b/contrib/blur-console/src/main/webapp/js/blurconsole.model.js
index 8eefec3..146c548 100644
--- a/contrib/blur-console/src/main/webapp/js/blurconsole.model.js
+++ b/contrib/blur-console/src/main/webapp/js/blurconsole.model.js
@@ -30,7 +30,7 @@ blurconsole.model = (function() {
 			queryPerformance : [],
 			queries : {}
 		},
-		tables, metrics, nodes, queries, search, initModule, nodePoller, tablePoller, queryPerformancePoller, queryPoller;
+		tables, metrics, nodes, queries, search, initModule, nodePoller, updateNodes, tablePoller, updateTables, queryPerformancePoller, updateQueryPerformance, queryPoller, updateQueries;
 
 	tables = (function() {
 		var getClusters, getEnabledTables, getDisabledTables, isDataLoaded, disableTable, enableTable, deleteTable, getSchema, findTerms, getAllEnabledTables, getFamilies;
@@ -95,8 +95,8 @@ blurconsole.model = (function() {
 			configMap.poller.deleteTable(tableName, includeFiles);
 		};
 
-		getSchema = function(tableName) {
-			return configMap.poller.getSchema(tableName);
+		getSchema = function(tableName, callback) {
+			configMap.poller.getSchema(tableName, callback);
 		};
 
 		getFamilies = function(tableName) {
@@ -330,7 +330,7 @@ blurconsole.model = (function() {
 			return queries;
 		};
 
-		cancelQuery = function(uuid) {
+		cancelQuery = function(table, uuid) {
 			configMap.poller.cancelQuery(uuid);
 		};
 
@@ -427,37 +427,50 @@ blurconsole.model = (function() {
 	}());
 
 	nodePoller = function() {
-		var tmpNodeMap = configMap.poller.getNodeList();
-		if (!blurconsole.utils.equals(tmpNodeMap, stateMap.nodeMap)) {
-			stateMap.nodeMap = tmpNodeMap;
+		configMap.poller.getNodeList(updateNodes);
+	};
+
+	updateNodes = function(nodes) {
+		if (!blurconsole.utils.equals(nodes, stateMap.nodeMap)) {
+			stateMap.nodeMap = nodes;
 			$.gevent.publish('node-status-updated');
 		}
 		setTimeout(nodePoller, 5000);
 	};
 
 	tablePoller = function() {
-		var tmpTableMap = configMap.poller.getTableList();
-		if (!blurconsole.utils.equals(tmpTableMap, stateMap.tableNameMap)) {
-			stateMap.tableNameMap = tmpTableMap;
+		configMap.poller.getTableList(updateTables);
+	};
+
+	updateTables = function(tables) {
+		if (!blurconsole.utils.equals(tables, stateMap.tableNameMap)) {
+			stateMap.tableNameMap = tables;
 			$.gevent.publish('tables-updated');
 		}
 		setTimeout(tablePoller, 5000);
 	};
 
 	queryPerformancePoller = function() {
+		configMap.poller.getQueryPerformance(updateQueryPerformance);
+	};
+
+	updateQueryPerformance = function(performanceMetric) {
 		if (stateMap.queryPerformance.length === 100) {
 			stateMap.queryPerformance.shift();
 		}
 
-		stateMap.queryPerformance.push(configMap.poller.getQueryPerformance());
+		stateMap.queryPerformance.push(performanceMetric);
 		$.gevent.publish('query-perf-updated');
 		setTimeout(queryPerformancePoller, 5000);
 	};
 
 	queryPoller = function() {
-		var tmpQueries = configMap.poller.getQueries();
-		if (!blurconsole.utils.equals(tmpQueries, stateMap.queries)) {
-			stateMap.queries = tmpQueries;
+		configMap.poller.getQueries(updateQueries);
+	};
+
+	updateQueries = function(queries) {
+		if (!blurconsole.utils.equals(queries, stateMap.queries)) {
+			stateMap.queries = queries;
 			$.gevent.publish('queries-updated');
 		}
 		setTimeout(queryPoller, 5000);

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/webapp/js/blurconsole.queries.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/webapp/js/blurconsole.queries.js b/contrib/blur-console/src/main/webapp/js/blurconsole.queries.js
index ce0298c..256abaf 100644
--- a/contrib/blur-console/src/main/webapp/js/blurconsole.queries.js
+++ b/contrib/blur-console/src/main/webapp/js/blurconsole.queries.js
@@ -26,7 +26,10 @@ blurconsole.queries = (function () {
 		queryDef : [
 			{label:'User', key:'user'},
 			{label:'Query', key: 'query'},
-			{label:'Time Started', key: 'startTime'},
+			{label:'Time Started', key: function(row){
+				var start = new Date(row.startTime);
+				return start.toTimeString(); //start.getHours() + ':' + start.getMinutes() + ':' + start.getSeconds();
+			}},
 			{label:'State', key: function(row) {
 				var stateInfo = configMap.states[row.state];
 
@@ -38,7 +41,7 @@ blurconsole.queries = (function () {
 			{label:'Actions', key: function(row) {
 				var actions = '';
 				if (row.state === 0) {
-					actions += '<a href="#" class="cancelTrigger btn btn-danger" data-uuid="' + row.uuid + '" data-query="' + row.query + '"><i class="glyphicon glyphicon-ban-circle"></i> Cancel</a> ';
+					actions += '<a href="#" class="cancelTrigger btn btn-danger" data-uuid="' + row.uuid + '" data-query="' + row.query + '" data-table="' + row.table + '"><i class="glyphicon glyphicon-ban-circle"></i> Cancel</a> ';
 				}
 				return actions;
 			}}
@@ -51,7 +54,7 @@ blurconsole.queries = (function () {
 		currentSort : null
 	},
 	jqueryMap = {},
-	setJqueryMap, initModule, unloadModule, drawTableList, drawQueries, registerPageEvents, unregisterPageEvents;
+	setJqueryMap, initModule, unloadModule, drawTableList, drawQueries, registerPageEvents, unregisterPageEvents, waitForData;
 
 	setJqueryMap = function() {
 		var $container = stateMap.$container;
@@ -74,7 +77,7 @@ blurconsole.queries = (function () {
 			return false;
 		});
 		jqueryMap.$queryHolder.on('click', 'a.cancelTrigger', function(){
-			var uuid = $(this).data('uuid'), query = $(this).data('query');
+			var uuid = $(this).data('uuid'), query = $(this).data('query'), table = $(this).data('table');
 			var modalContent = blurconsole.browserUtils.modal('confirmDelete', 'Confirm Query Cancel', 'You are about to cancel the query [' + query + '].  Are you sure you want to do this?', [
 				{classes: 'btn-primary killQuery', label: 'Stop Query'},
 				{classes: 'btn-default cancel', label: 'Cancel', data: {dismiss:'modal'}}
@@ -82,7 +85,7 @@ blurconsole.queries = (function () {
 
 			var modal = $(modalContent).modal().on('shown.bs.modal', function(e){
 				$(e.currentTarget).on('click', '.killQuery', function() {
-					blurconsole.model.queries.cancelQuery(uuid);
+					blurconsole.model.queries.cancelQuery(table, uuid);
 					modal.modal('hide');
 				});
 			}).on('hidden.bs.modal', function(e) {
@@ -153,6 +156,15 @@ blurconsole.queries = (function () {
 		}
 	};
 
+	waitForData = function() {
+		var clusters = blurconsole.model.tables.getClusters();
+		if (clusters && clusters.length > 0) {
+			drawTableList();
+		} else {
+			setTimeout(waitForData, 100);
+		}
+	};
+
 	initModule = function($container) {
 		$container.load(configMap.view, function() {
 			stateMap.$container = $container;
@@ -160,6 +172,7 @@ blurconsole.queries = (function () {
 			$.gevent.subscribe(jqueryMap.$container, 'queries-updated', drawQueries);
 			$.gevent.subscribe(jqueryMap.$container, 'tables-updated', drawTableList);
 			registerPageEvents();
+			waitForData();
 		});
 		return true;
 	};

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/webapp/js/blurconsole.schema.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/webapp/js/blurconsole.schema.js b/contrib/blur-console/src/main/webapp/js/blurconsole.schema.js
index 9f29f4f..6f2728d 100644
--- a/contrib/blur-console/src/main/webapp/js/blurconsole.schema.js
+++ b/contrib/blur-console/src/main/webapp/js/blurconsole.schema.js
@@ -55,13 +55,16 @@ blurconsole.schema = (function () {
 		},
 		stateMap = {},
 		jqueryMap = {},
-		initModule, showSchema, buildTreeSection, buildInfoSection, viewTerms, findTerms, loadTerms, switchToSearch;
+		initModule, showSchema, popupSchemaView, buildTreeSection, buildInfoSection, viewTerms, findTerms, loadTerms, switchToSearch;
 
 	showSchema = function(event, table) {
 		stateMap.table = table;
 		stateMap.modalId = stateMap.table + '_modal';
-		stateMap.schema = blurconsole.model.tables.getSchema(stateMap.table);
+		blurconsole.model.tables.getSchema(stateMap.table, popupSchemaView);
+	};
 
+	popupSchemaView = function(schema) {
+		stateMap.schema = schema;
 		jqueryMap.contentHolder = $(configMap.mainHtml);
 		jqueryMap.contentHolder.find('.schemaList').html(buildTreeSection());
 		jqueryMap.contentHolder.find('.schemaColumnInfo').append(buildInfoSection());
@@ -120,6 +123,7 @@ blurconsole.schema = (function () {
 			$.each(cols, function(col, def){
 				var colId = blurconsole.browserUtils.cleanId(col);
 				info += '<div class="schemaColumnDef" id="' + famId + '_' + colId + '"><ul class="list-group">';
+				info += '<li class="list-group-item"><strong>Field Name:</strong> ' + col + '</li>';
 				info += '<li class="list-group-item"><strong>Fieldless Searching:</strong> ' + blurconsole.browserUtils.booleanImg(def.fieldLess) + '</li>';
 				info += '<li class="list-group-item"><strong>Field Type:</strong> ' + def.type + '</li>';
 				if (def.extra) {
@@ -165,7 +169,8 @@ blurconsole.schema = (function () {
 			tab: 'search',
 			_tab: {
 				query: encodeURIComponent(stateMap.termFamily + '.' + stateMap.termColumn + ':' + $(this).data('value')),
-				table: $(this).data('table')
+				table: $(this).data('table'),
+				rr: 'rowrow'
 			}
 		});
 		jqueryMap.modal.modal('hide');

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/webapp/js/blurconsole.search.js
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/webapp/js/blurconsole.search.js b/contrib/blur-console/src/main/webapp/js/blurconsole.search.js
index 5035ac0..023d64f 100644
--- a/contrib/blur-console/src/main/webapp/js/blurconsole.search.js
+++ b/contrib/blur-console/src/main/webapp/js/blurconsole.search.js
@@ -134,7 +134,7 @@ blurconsole.search = (function () {
 
 		drawResultHolders();
 
-		blurconsole.model.search.runSearch(stateMap.$currentQuery, stateMap.$currentTable, {start: 0, fetch: 10});
+		blurconsole.model.search.runSearch(stateMap.$currentQuery, stateMap.$currentTable, {start: 0, fetch: 10, rowRecord: stateMap.$rowRecordOption});
 	};
 
 	getMoreData = function() {
@@ -213,9 +213,13 @@ blurconsole.search = (function () {
 				famId = '#' + blurconsole.browserUtils.cleanId(fam),
 				famHolder = $(famId + ' .panel-body'), table = '', cols;
 
-			cols = blurconsole.utils.keys(famResults[0]);
+			cols = blurconsole.utils.reject(blurconsole.utils.keys(famResults[0]), function(i) {
+				return i === 'rowid' || i === 'recordid';
+			});
 			cols.sort();
 
+			cols = ['rowid', 'recordid'].concat(cols);
+
 			table += '<table class="table table-condensed table-hover table-bordered"><thead><tr>';
 			$.each(cols, function(i, col) {
 				table += '<th>' + col + '</th>';

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/main/webapp/sass/blurconsole.scss
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/main/webapp/sass/blurconsole.scss b/contrib/blur-console/src/main/webapp/sass/blurconsole.scss
index 70fa5d7..b7db31b 100644
--- a/contrib/blur-console/src/main/webapp/sass/blurconsole.scss
+++ b/contrib/blur-console/src/main/webapp/sass/blurconsole.scss
@@ -18,7 +18,7 @@ specific language governing permissions and limitations
 under the License.
  */
 
-$icon-font-path: "/libs/twbs-bootstrap-sass/vendor/assets/fonts/bootstrap/";
+$icon-font-path: "../libs/twbs-bootstrap-sass/vendor/assets/fonts/bootstrap/";
 
 @import 'twbs-bootstrap-sass/vendor/assets/stylesheets/bootstrap';
 @import 'colors';

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/test/java/org/apache/blur/console/ConsoleTestBase.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/test/java/org/apache/blur/console/ConsoleTestBase.java b/contrib/blur-console/src/test/java/org/apache/blur/console/ConsoleTestBase.java
index 813df6c..0aeebaf 100644
--- a/contrib/blur-console/src/test/java/org/apache/blur/console/ConsoleTestBase.java
+++ b/contrib/blur-console/src/test/java/org/apache/blur/console/ConsoleTestBase.java
@@ -20,29 +20,21 @@ package org.apache.blur.console;
 import java.io.File;
 import java.io.IOException;
 
-import org.apache.blur.MiniCluster;
 import org.apache.blur.console.util.Config;
-import org.apache.commons.io.FileUtils;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 
 public class ConsoleTestBase {
-	protected static MiniCluster cluster;
 	protected static String TABLE_PATH = new File("./test-data/test-tables").getAbsolutePath();
 
 	@BeforeClass
-	public static void startup() {
-		cluster = new MiniCluster();
-		cluster.startBlurCluster(new File("./test-data").getAbsolutePath(), 1, 1);
+	public static void startup() throws IOException {
+		Config.setupMiniCluster();
 	}
 
 	@AfterClass
 	public static void shutdown() throws IOException {
-		cluster.shutdownBlurCluster();
-		File file = new File("./test-data");
-		if (file.exists()) {
-			FileUtils.deleteDirectory(file);
-		}
+		Config.shutdownMiniCluster();
 	}
 
 	protected void setupConfigIfNeeded() throws IOException {

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/test/java/org/apache/blur/console/util/HttpUtilTest.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/test/java/org/apache/blur/console/util/HttpUtilTest.java b/contrib/blur-console/src/test/java/org/apache/blur/console/util/HttpUtilTest.java
deleted file mode 100644
index 6985e80..0000000
--- a/contrib/blur-console/src/test/java/org/apache/blur/console/util/HttpUtilTest.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.blur.console.util;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.Collection;
-import java.util.Locale;
-
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletResponse;
-
-import org.junit.Test;
-
-public class HttpUtilTest {
-
-	@Test
-	public void testSendResponse() throws IOException {
-		MockHttpServletResponse mockResponse = new MockHttpServletResponse();
-		
-		HttpUtil.sendResponse(mockResponse, "Test content", "text/plain");
-		
-		assertEquals("text/plain", mockResponse.getContentType());
-		assertEquals(200, mockResponse.status);
-		assertEquals("Test content".getBytes().length, mockResponse.contentLength);
-		assertEquals("Test content", mockResponse.out.toString());
-	}
-	
-	private class MockHttpServletResponse implements HttpServletResponse {
-		public String contentType;
-		public int contentLength;
-		public int status;
-		public ByteArrayOutputStream out;
-		
-		@Override
-		public void setContentType(String type) {
-			contentType = type;
-		}
-		
-		@Override
-		public void setContentLength(int len) {
-			contentLength = len;
-		}
-		
-		@Override
-		public ServletOutputStream getOutputStream() throws IOException {
-			out = new ByteArrayOutputStream();
-			return new ServletOutputStream() {
-				@Override
-				public void write(int b) throws IOException {
-					out.write(b);
-				}
-			};
-		}
-		
-		@Override
-		public String getContentType() {
-			return contentType;
-		}
-		
-		@Override
-		public void setStatus(int sc) {
-			status = sc;
-		}
-		
-		@Override
-		public void setLocale(Locale loc) {}
-		@Override
-		public void setCharacterEncoding(String charset) {}
-		@Override
-		public void setBufferSize(int size) {}
-		@Override
-		public void resetBuffer() {}
-		@Override
-		public void reset() {}
-		@Override
-		public boolean isCommitted() { return false; }
-		@Override
-		public PrintWriter getWriter() throws IOException { return null; }
-		@Override
-		public Locale getLocale() { return null; }
-		@Override
-		public String getCharacterEncoding() { return null; }
-		@Override
-		public int getBufferSize() { return 0; }
-		@Override
-		public void flushBuffer() throws IOException {}
-		@Override
-		public void setStatus(int sc, String sm) {}
-        @Override
-		public void setIntHeader(String name, int value) {}
-		@Override
-		public void setHeader(String name, String value) {}
-		@Override
-		public void setDateHeader(String name, long date) {}
-		@Override
-		public void sendRedirect(String location) throws IOException {}
-		@Override
-		public void sendError(int sc, String msg) throws IOException {}
-		@Override
-		public void sendError(int sc) throws IOException {}
-		@Override
-		public String encodeUrl(String url) { return null; }
-		@Override
-		public String encodeURL(String url) { return null; }
-		@Override
-		public String encodeRedirectUrl(String url) { return null; }
-		@Override
-		public String encodeRedirectURL(String url) { return null; }
-		@Override
-		public boolean containsHeader(String name) { return false; }
-		@Override
-		public void addIntHeader(String name, int value) {}
-		@Override
-		public void addHeader(String name, String value) {}
-		@Override
-		public void addDateHeader(String name, long date) {}
-		@Override
-		public void addCookie(Cookie cookie) {}
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/6cdce8ec/contrib/blur-console/src/test/java/org/apache/blur/console/util/NodeUtilTest.java
----------------------------------------------------------------------
diff --git a/contrib/blur-console/src/test/java/org/apache/blur/console/util/NodeUtilTest.java b/contrib/blur-console/src/test/java/org/apache/blur/console/util/NodeUtilTest.java
index e122f07..1d56b92 100644
--- a/contrib/blur-console/src/test/java/org/apache/blur/console/util/NodeUtilTest.java
+++ b/contrib/blur-console/src/test/java/org/apache/blur/console/util/NodeUtilTest.java
@@ -19,6 +19,7 @@ package org.apache.blur.console.util;
 import static org.junit.Assert.assertEquals;
 
 import java.io.IOException;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 
@@ -39,10 +40,8 @@ public class NodeUtilTest extends ConsoleTestBase {
 	public void testGetControllerStatus() throws BlurException, IOException, TException {
 		Map<String, Object> nodeStatus = NodeUtil.getControllerStatus();
 		
-		List<Map<String, int[][]>> chartData = (List<Map<String, int[][]>>) nodeStatus.get("chart");
-		
-		assertEquals(1, chartData.get(0).get("data")[0][1]);
-		assertEquals(0, chartData.get(1).get("data")[0][1]);
+		assertEquals(2, ((List<String>) nodeStatus.get("online")).size());
+		assertEquals(0, ((List<String>) nodeStatus.get("offline")).size());
 	}
 	
 	@SuppressWarnings("unchecked")
@@ -50,10 +49,8 @@ public class NodeUtilTest extends ConsoleTestBase {
 	public void testGetZookeeperStatus() throws BlurException, IOException, TException {
 		Map<String, Object> nodeStatus = NodeUtil.getZookeeperStatus();
 		
-		List<Map<String, int[][]>> chartData = (List<Map<String, int[][]>>) nodeStatus.get("chart");
-		
-		assertEquals(1, chartData.get(0).get("data")[0][1]);
-		assertEquals(0, chartData.get(1).get("data")[0][1]);
+		assertEquals(0, ((HashSet<String>) nodeStatus.get("online")).size());
+		assertEquals(1, ((HashSet<String>) nodeStatus.get("offline")).size());
 	}
 	
 	@SuppressWarnings("unchecked")
@@ -61,9 +58,7 @@ public class NodeUtilTest extends ConsoleTestBase {
 	public void testGetClusterStatus() throws BlurException, IOException, TException {
 		List<Map<String, Object>> nodeStatus = NodeUtil.getClusterStatus();
 		
-		List<Map<String, int[][]>> chartData = (List<Map<String, int[][]>>) nodeStatus.get(0).get("chart");
-		
-		assertEquals(0, chartData.get(0).get("data")[0][1]);
-		assertEquals(2, chartData.get(1).get("data")[0][1]);
+		assertEquals(3, ((List<String>) nodeStatus.get(0).get("online")).size());
+		assertEquals(0, ((List<String>) nodeStatus.get(0).get("offline")).size());
 	}
 }


Mime
View raw message