You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tajo.apache.org by hy...@apache.org on 2014/04/18 11:19:33 UTC
[11/51] [partial] TAJO-752: Escalate sub modules in tajo-core into
the top-level modules. (hyunsik)
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/static/queryplan.css
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/static/queryplan.css b/tajo-core/src/main/resources/webapps/static/queryplan.css
new file mode 100644
index 0000000..b1b7dd4
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/static/queryplan.css
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+.window {
+ border:3px solid;
+ width:15em;
+ height:1.5em;
+ z-index:20;
+ position:absolute;
+}
+
+.component {
+ opacity:0.8;
+ filter:alpha(opacity=80);
+ background-color:white;
+ color:black;
+ font-family:helvetica;
+ padding:0.5em;
+}
+
+.label {
+ border:1px solid #346789;
+ padding:4px;
+ padding:4px;
+ font-size: 0.8em;
+}
+
+.label:hover {
+ border-color:#5d94a6;
+}
+
+.textborder {
+ border: 1px solid;
+ padding: 2px;
+}
+
+.component a:link {text-decoration:none;}
+.component a:visited {text-decoration:none;}
+.component a:hover {text-decoration:underline;}
+.component a:active {text-decoration:underline;}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/static/style.css
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/static/style.css b/tajo-core/src/main/resources/webapps/static/style.css
new file mode 100644
index 0000000..2af350e
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/static/style.css
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+html{
+ font:12px Arial, Helvetica, sans-serif; /* Sets the font size and type for the whole html page */
+ color:#333;} /* Sets the font color for the whole html page */
+
+body {margin:0;padding:0}
+
+.menu{
+ width: 100%; /* The menu should be the entire width of it's surrounding object, in this case the whole page */
+ background-color: #333;} /* dark grey bg */
+
+.menu ul{
+ margin: 0;
+ padding: 0;
+ float: left;}
+
+.menu ul li{
+ display: inline;} /* Makes the link all appear in one line, rather than on top of each other */
+
+.menu ul li a{
+ float: left;
+ text-decoration: none; /* removes the underline from the menu text */
+ color: #fff; /* text color of the menu */
+ padding: 10.5px 11px; /* 10.5px of padding to the right and left of the link and 11px to the top and bottom */
+ margin-right: 20px;
+ background-color: #333;}
+
+.menu ul li a:visited{ /* This bit just makes sure the text color doesn't change once you've visited a link */
+ color: #fff;
+ text-decoration: none;}
+
+.menu ul li a:hover, .menu ul li .current{
+ color: #fff;
+ background-color:#0b75b2;} /* change the background color of the list item when you hover over it */
+
+.page_title {
+ padding: 0px 0px 0px 10px
+}
+
+.contents {
+ padding: 0px 10px 0px 10px;
+ font-size:14px;
+}
+
+.border_table {
+ border-collapse:collapse;
+ border:1px gray solid;
+}
+
+.border_table td {
+ border:1px gray solid;
+ padding: 2px 5px 2px 5px
+}
+
+.border_table th {
+ border:1px gray solid;
+ padding: 2px 5px 2px 5px
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/worker/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/worker/WEB-INF/web.xml b/tajo-core/src/main/resources/webapps/worker/WEB-INF/web.xml
new file mode 100644
index 0000000..0ff8db6
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/worker/WEB-INF/web.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ version="2.5">
+ <display-name>Tajo Worker</display-name>
+ <welcome-file-list>
+ <welcome-file>index.jsp</welcome-file>
+ </welcome-file-list>
+</web-app>
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/worker/conf.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/worker/conf.jsp b/tajo-core/src/main/resources/webapps/worker/conf.jsp
new file mode 100644
index 0000000..571461b
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/worker/conf.jsp
@@ -0,0 +1,55 @@
+<%
+ /*
+ * 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.
+ */
+%>
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+
+<%@ page import="org.apache.tajo.webapp.StaticHttpServer" %>
+<%@ page import="org.apache.tajo.worker.*" %>
+<%@ page import="java.util.Map" %>
+<%@ page import="org.apache.hadoop.conf.Configuration" %>
+
+<%
+ TajoWorker tajoWorker = (TajoWorker) StaticHttpServer.getInstance().getAttribute("tajo.info.server.object");
+ Configuration tajoConf = tajoWorker.getConfig();
+%>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <link rel="stylesheet" type = "text/css" href = "/static/style.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <title>Tajo</title>
+</head>
+<body>
+<%@ include file="header.jsp"%>
+<div class='contents'>
+ <h2>Tajo Worker: <a href='index.jsp'><%=tajoWorker.getWorkerContext().getWorkerName()%></a></h2>
+ <hr/>
+ <table width="100%" border="1" class="border_table">
+<%
+ for(Map.Entry<String,String> entry: tajoConf) {
+%>
+ <tr><td width="200"><%=entry.getKey()%></td><td><%=entry.getValue()%></td>
+<%
+ }
+%>
+ </table>
+</div>
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/worker/env.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/worker/env.jsp b/tajo-core/src/main/resources/webapps/worker/env.jsp
new file mode 100644
index 0000000..b84f6b7
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/worker/env.jsp
@@ -0,0 +1,69 @@
+<%
+ /*
+ * 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.
+ */
+%>
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+
+<%@ page import="org.apache.tajo.webapp.StaticHttpServer" %>
+<%@ page import="java.util.Map" %>
+<%@ page import="org.apache.tajo.worker.*" %>
+<%@ page import="org.apache.hadoop.conf.Configuration" %>
+
+<%
+ TajoWorker tajoWorker = (TajoWorker) StaticHttpServer.getInstance().getAttribute("tajo.info.server.object");
+ Configuration tajoConf = tajoWorker.getConfig();
+%>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <link rel="stylesheet" type = "text/css" href = "/static/style.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <title>Tajo</title>
+</head>
+<body>
+<%@ include file="header.jsp"%>
+<div class='contents'>
+ <h2>Tajo Worker: <a href='index.jsp'><%=tajoWorker.getWorkerContext().getWorkerName()%></a></h2>
+ <hr/>
+ <h3>System Environment</h3>
+ <table width="100%" class="border_table">
+<%
+ for(Map.Entry<String, String> entry: System.getenv().entrySet()) {
+%>
+ <tr><td width="200"><%=entry.getKey()%></td><td><%=entry.getValue()%></td>
+<%
+ }
+%>
+ </table>
+
+ <h3>Properties</h3>
+ <hr/>
+
+ <table width="100%" class="border_table">
+<%
+ for(Map.Entry<Object, Object> entry: System.getProperties().entrySet()) {
+%>
+ <tr><td width="200"><%=entry.getKey()%></td><td><%=entry.getValue()%></td>
+<%
+ }
+%>
+ </table>
+</div>
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/worker/header.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/worker/header.jsp b/tajo-core/src/main/resources/webapps/worker/header.jsp
new file mode 100644
index 0000000..f20eaf0
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/worker/header.jsp
@@ -0,0 +1,37 @@
+<%
+ /*
+ * 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.
+ */
+%>
+<%@ page import="org.apache.tajo.util.JSPUtil" %>
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+<%
+ TajoWorker tmpTajoWorker = (TajoWorker) StaticHttpServer.getInstance().getAttribute("tajo.info.server.object");
+ String tajoMasterHttp = "http://" + JSPUtil.getTajoMasterHttpAddr(tmpTajoWorker.getConfig());
+%>
+<div class="menu">
+ <div style='float:left; margin-left:12px; margin-top:6px;'><a href='<%=tajoMasterHttp%>/index.jsp'><img src='/static/img/logo_tajo.gif' border='0'/></a></div>
+ <ul>
+ <li><a class='top_menu_item' style='margin-left:10px;' href='<%=tajoMasterHttp%>/index.jsp'>Home</a></li>
+ <li><a class='top_menu_item' href='<%=tajoMasterHttp%>/cluster.jsp'>Cluster</a></li>
+ <li><a class='top_menu_item' href='<%=tajoMasterHttp%>/query.jsp'>Query</a></li>
+ <li><a class='top_menu_item' href='<%=tajoMasterHttp%>/catalogview.jsp'>Catalog</a></li>
+ <li><a class='top_menu_item' href='<%=tajoMasterHttp%>/query_executor.jsp'>Execute Query</a></li>
+ </ul>
+ <br style="clear: left" />
+</div>
+
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/worker/index.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/worker/index.jsp b/tajo-core/src/main/resources/webapps/worker/index.jsp
new file mode 100644
index 0000000..c30a72d
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/worker/index.jsp
@@ -0,0 +1,150 @@
+<%
+ /*
+ * 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.
+ */
+%>
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+
+<%@ page import="java.util.*" %>
+<%@ page import="org.apache.tajo.webapp.StaticHttpServer" %>
+<%@ page import="org.apache.tajo.worker.*" %>
+<%@ page import="java.text.SimpleDateFormat" %>
+<%@ page import="org.apache.tajo.master.querymaster.QueryMasterTask" %>
+<%@ page import="org.apache.tajo.master.querymaster.Query" %>
+
+<%
+ TajoWorker tajoWorker = (TajoWorker) StaticHttpServer.getInstance().getAttribute("tajo.info.server.object");
+
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+%>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+<head>
+ <link rel="stylesheet" type = "text/css" href = "/static/style.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <title>tajo worker</title>
+</head>
+<body>
+<%@ include file="header.jsp"%>
+<div class='contents'>
+ <h2>Tajo Worker: <%=tajoWorker.getWorkerContext().getWorkerName()%></h2>
+ <hr/>
+ <table border=0>
+ <tr><td width='100'>MaxHeap: </td><td><%=Runtime.getRuntime().maxMemory()/1024/1024%> MB</td>
+ <tr><td width='100'>TotalHeap: </td><td><%=Runtime.getRuntime().totalMemory()/1024/1024%> MB</td>
+ <tr><td width='100'>FreeHeap: </td><td><%=Runtime.getRuntime().freeMemory()/1024/1024%> MB</td>
+ <tr><td width="100">Configuration:</td><td><a href='conf.jsp'>detail...</a></td></tr>
+ <tr><td width="100">Environment:</td><td><a href='env.jsp'>detail...</a></td></tr>
+ <tr><td width="100">Threads:</td><td><a href='thread.jsp'>thread dump...</a></tr>
+ </table>
+ <hr/>
+
+<%
+if(tajoWorker.getWorkerContext().isQueryMasterMode()) {
+ List<QueryMasterTask> queryMasterTasks = JSPUtil.sortQueryMasterTask(tajoWorker.getWorkerContext()
+ .getQueryMasterManagerService().getQueryMaster().getQueryMasterTasks(), true);
+
+ List<QueryMasterTask> finishedQueryMasterTasks = JSPUtil.sortQueryMasterTask(tajoWorker.getWorkerContext()
+ .getQueryMasterManagerService().getQueryMaster().getFinishedQueryMasterTasks(), true);
+%>
+ <h3>Running Query</h3>
+ <%
+ if(queryMasterTasks.isEmpty()) {
+ out.write("No running query master");
+ } else {
+ %>
+ <table width="100%" border="1" class="border_table">
+ <tr><th>QueryId</th><th>Status</th><th>StartTime</th><th>FinishTime</th><th>Progress</th><th>RunTime</th></tr>
+ <%
+ for(QueryMasterTask eachQueryMasterTask: queryMasterTasks) {
+ Query query = eachQueryMasterTask.getQuery();
+ %>
+ <tr>
+ <td align='center'><a href='querydetail.jsp?queryId=<%=query.getId()%>'><%=query.getId()%></a></td>
+ <td align='center'><%=eachQueryMasterTask.getState()%></td>
+ <td align='center'><%=df.format(query.getStartTime())%></td>
+ <td align='center'><%=query.getFinishTime() == 0 ? "-" : df.format(query.getFinishTime())%></td>
+ <td align='center'><%=(int)(query.getProgress()*100.0f)%>%</td>
+ <td align='right'><%=JSPUtil.getElapsedTime(query.getStartTime(), query.getFinishTime())%></td>
+ </tr>
+ <%
+ } //end of for
+ } //end of if
+ %>
+ </table>
+ <p/>
+ <hr/>
+ <h3>Finished Query</h3>
+ <%
+ if(finishedQueryMasterTasks.isEmpty()) {
+ out.write("No finished query master");
+ } else {
+ %>
+ <table width="100%" border="1" class="border_table">
+ <tr><th>QueryId</th><th>Status</th><th>StartTime</th><th>FinishTime</th><th>Progress</th><th>RunTime</th></tr>
+ <%
+ for(QueryMasterTask eachQueryMasterTask: finishedQueryMasterTasks) {
+ Query query = eachQueryMasterTask.getQuery();
+ long startTime = query != null ? query.getStartTime() : eachQueryMasterTask.getQuerySubmitTime();
+ %>
+ <tr>
+ <td align='center'><a href='querydetail.jsp?queryId=<%=eachQueryMasterTask.getQueryId()%>'><%=eachQueryMasterTask.getQueryId()%></a></td>
+ <td align='center'><%=eachQueryMasterTask.getState()%></td>
+ <td align='center'><%=df.format(startTime)%></td>
+ <td align='center'><%=(query == null || query.getFinishTime() == 0) ? "-" : df.format(query.getFinishTime())%></td>
+ <td align='center'><%=(query == null) ? "-" : (int)(query.getProgress()*100.0f)%>%</td>
+ <td align='right'><%=(query == null) ? "-" : JSPUtil.getElapsedTime(query.getStartTime(), query.getFinishTime())%></td>
+ </tr>
+ <%
+ } //end of for
+ } //end of if
+ %>
+ </table>
+ <p/>
+ <hr/>
+<%
+} // end of QueryMaster
+if(tajoWorker.getWorkerContext().isTaskRunnerMode()) {
+ List<TaskRunner> taskRunners = new ArrayList<TaskRunner>(tajoWorker.getWorkerContext().getTaskRunnerManager().getTaskRunners());
+ JSPUtil.sortTaskRunner(taskRunners);
+%>
+ <h3>Running Task Containers</h3>
+ <a href='taskcontainers.jsp'>[All Task Containers]</a>
+ <br/>
+ <table width="100%" border="1" class="border_table">
+ <tr><th>ContainerId</th><th>StartTime</th><th>FinishTime</th><th>RunTime</th><th>Status</th></tr>
+ <%
+ for(TaskRunner eachTaskRunner: taskRunners) {
+ %>
+ <tr>
+ <td><a href="tasks.jsp?containerId=<%=eachTaskRunner.getId()%>"><%=eachTaskRunner.getId()%></a></td>
+ <td><%=df.format(eachTaskRunner.getStartTime())%></td>
+ <td><%=eachTaskRunner.getFinishTime() == 0 ? "-" : df.format(eachTaskRunner.getFinishTime())%></td>
+ <td><%=JSPUtil.getElapsedTime(eachTaskRunner.getStartTime(), eachTaskRunner.getFinishTime())%></td>
+ <td><%=eachTaskRunner.getServiceState()%></td>
+<%
+ } //end of for
+%>
+ </table>
+<%
+} //end of if
+%>
+</div>
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/worker/querydetail.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/worker/querydetail.jsp b/tajo-core/src/main/resources/webapps/worker/querydetail.jsp
new file mode 100644
index 0000000..3de20fe
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/worker/querydetail.jsp
@@ -0,0 +1,105 @@
+<%
+ /*
+ * 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.
+ */
+%>
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+
+<%@ page import="org.apache.tajo.master.querymaster.*" %>
+<%@ page import="java.util.*" %>
+<%@ page import="org.apache.tajo.webapp.StaticHttpServer" %>
+<%@ page import="org.apache.tajo.worker.*" %>
+<%@ page import="java.text.SimpleDateFormat" %>
+<%@ page import="org.apache.tajo.QueryId" %>
+<%@ page import="org.apache.tajo.util.TajoIdUtils" %>
+
+<%
+ QueryId queryId = TajoIdUtils.parseQueryId(request.getParameter("queryId"));
+
+ TajoWorker tajoWorker = (TajoWorker) StaticHttpServer.getInstance().getAttribute("tajo.info.server.object");
+ QueryMasterTask queryMasterTask = tajoWorker.getWorkerContext()
+ .getQueryMasterManagerService().getQueryMaster().getQueryMasterTask(queryId, true);
+
+ if (queryMasterTask == null) {
+ out.write("<script type='text/javascript'>alert('no query'); history.back(0); </script>");
+ return;
+ }
+ Query query = queryMasterTask.getQuery();
+ List<SubQuery> subQueries = null;
+ if (query != null) {
+ subQueries = JSPUtil.sortSubQuery(query.getSubQueries());
+ }
+
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+%>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <link rel="stylesheet" type="text/css" href="/static/style.css"/>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <title>Query Detail Info</title>
+</head>
+<body>
+<%@ include file="header.jsp"%>
+<div class='contents'>
+ <h2>Tajo Worker: <a href='index.jsp'><%=tajoWorker.getWorkerContext().getWorkerName()%></a></h2>
+ <hr/>
+<%
+if (query == null) {
+ String errorMessage = queryMasterTask.getErrorMessage();
+ out.write("Query Status: " + queryMasterTask.getState());
+ if (errorMessage != null && !errorMessage.isEmpty()) {
+ out.write("<p/>Message:<p/><pre>" + errorMessage + "</pre>");
+ }
+} else {
+%>
+ <h3><%=queryId.toString()%> <a href='queryplan.jsp?queryId=<%=queryId%>'>[Query Plan]</a></h3>
+ <table width="100%" border="1" class="border_table">
+ <tr><th>ID</th><th>State</th><th>Started</th><th>Finished</th><th>Running time</th><th>Progress</th><th>Tasks</th></tr>
+<%
+for(SubQuery eachSubQuery: subQueries) {
+ eachSubQuery.getSucceededObjectCount();
+ String detailLink = "querytasks.jsp?queryId=" + queryId + "&ebid=" + eachSubQuery.getId();
+%>
+ <tr>
+ <td><a href='<%=detailLink%>'><%=eachSubQuery.getId()%></a></td>
+ <td><%=eachSubQuery.getState()%></td>
+ <td><%=df.format(eachSubQuery.getStartTime())%></td>
+ <td><%=eachSubQuery.getFinishTime() == 0 ? "-" : df.format(eachSubQuery.getFinishTime())%></td>
+ <td><%=JSPUtil.getElapsedTime(eachSubQuery.getStartTime(), eachSubQuery.getFinishTime())%></td>
+ <td align='center'><%=JSPUtil.percentFormat(eachSubQuery.getProgress())%>%</td>
+ <td align='center'><a href='<%=detailLink%>&status=SUCCEEDED'><%=eachSubQuery.getSucceededObjectCount()%></a>/<a href='<%=detailLink%>&status=ALL'><%=eachSubQuery.getTotalScheduledObjectsCount()%></a></td>
+ </tr>
+ <%
+} //end of for
+ %>
+ </table>
+ <p/>
+ <hr/>
+ <h3>Logical Plan</h3>
+ <pre style="white-space:pre-wrap;"><%=query.getPlan().getLogicalPlan().toString()%></pre>
+ <hr/>
+ <h3>Distributed Query Plan</h3>
+ <pre style="white-space:pre-wrap;"><%=query.getPlan().toString()%></pre>
+ <hr/>
+<%
+} //end of else [if (query == null)]
+%>
+</div>
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/worker/queryplan.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/worker/queryplan.jsp b/tajo-core/src/main/resources/webapps/worker/queryplan.jsp
new file mode 100644
index 0000000..ec860b9
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/worker/queryplan.jsp
@@ -0,0 +1,237 @@
+<%
+ /*
+ * 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.
+ */
+%>
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+
+<%@ page import="org.apache.tajo.webapp.StaticHttpServer" %>
+<%@ page import="org.apache.tajo.worker.*" %>
+<%@ page import="org.apache.tajo.master.querymaster.Query" %>
+<%@ page import="org.apache.tajo.QueryId" %>
+<%@ page import="org.apache.tajo.util.TajoIdUtils" %>
+<%@ page import="org.apache.tajo.master.querymaster.QueryMasterTask" %>
+<%@ page import="org.apache.tajo.master.querymaster.SubQuery" %>
+<%@ page import="org.apache.tajo.engine.planner.global.ExecutionBlock" %>
+<%@ page import="java.util.*" %>
+<%@ page import="org.apache.tajo.ExecutionBlockId" %>
+<%@ page import="org.apache.tajo.engine.planner.global.MasterPlan" %>
+<%@ page import="org.apache.tajo.engine.planner.global.DataChannel" %>
+
+<%
+ QueryId queryId = TajoIdUtils.parseQueryId(request.getParameter("queryId"));
+
+ TajoWorker tajoWorker = (TajoWorker) StaticHttpServer.getInstance().getAttribute("tajo.info.server.object");
+ QueryMasterTask queryMasterTask = tajoWorker.getWorkerContext()
+ .getQueryMasterManagerService().getQueryMaster().getQueryMasterTask(queryId, true);
+
+ if(queryMasterTask == null) {
+ out.write("<script type='text/javascript'>alert('no query'); history.back(0); </script>");
+ return;
+ }
+
+ Query query = queryMasterTask.getQuery();
+
+ Map<ExecutionBlockId, SubQuery> subQueryMap = new HashMap<ExecutionBlockId, SubQuery>();
+
+ for(SubQuery eachSubQuery: query.getSubQueries()) {
+ subQueryMap.put(eachSubQuery.getId(), eachSubQuery);
+ }
+
+ class SubQueryInfo {
+ ExecutionBlock executionBlock;
+ SubQuery subQuery;
+ ExecutionBlockId parentId;
+ int px;
+ int py;
+ int pos; // 0: mid 1: left 2: right
+ public SubQueryInfo(ExecutionBlock executionBlock, SubQuery subQuery, ExecutionBlockId parentId, int px, int py, int pos) {
+ this.executionBlock = executionBlock;
+ this.subQuery = subQuery;
+ this.parentId = parentId;
+ this.px = px;
+ this.py = py;
+ this.pos = pos;
+ }
+ }
+%>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <link rel="stylesheet" type = "text/css" href = "/static/style.css" />
+ <link rel="stylesheet" type = "text/css" href = "/static/queryplan.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <title>Tajo</title>
+ <script type='text/javascript' src='/static/js/jquery.js'></script>
+ <script type='text/javascript' src='/static/js/jquery-ui.min.js'></script>
+ <script type='text/javascript' src='/static/js/jquery.jsPlumb-1.3.16-all.js'></script>
+</head>
+<body>
+<%@ include file="header.jsp"%>
+<div class='contents'>
+ <h2>Tajo Worker: <a href='index.jsp'><%=tajoWorker.getWorkerContext().getWorkerName()%></a></h2>
+ <hr/>
+ <div>
+ <h3>Distributed Query Execution Plan</h3>
+ <div style='float:left'><span class="textborder" style="color:black;font-size:9px">NEW</span></div>
+ <div style='float:left;margin-left:5px;'><span class="textborder" style="color:gray;font-size:9px">ALLOCATED</span></div>
+ <div style='float:left;margin-left:5px;'><span class="textborder" style="color:skyblue;font-size:9px">INIT</span></div>
+ <div style='float:left;margin-left:5px;'><span class="textborder" style="color:blue;font-size:9px">RUNNING</span></div>
+ <div style='float:left;margin-left:5px;'><span class="textborder" style="color:green;font-size:9px">SUCCEEDED</span></div>
+ <div style='float:left;margin-left:5px;'><span class="textborder" style="color:red;font-size:9px">FAILED</span></div>
+ </div>
+
+<!-- draw the query plan -->
+<%
+ MasterPlan masterPlan = query.getPlan();
+ String curIdStr = null;
+ int x=35, y=1;
+ int pos;
+ List<SubQueryInfo> subQueryInfos = new ArrayList<SubQueryInfo>();
+
+ subQueryInfos.add(new SubQueryInfo(masterPlan.getRoot(), null, null, x, y, 0));
+
+ while (!subQueryInfos.isEmpty()) {
+ SubQueryInfo eachSubQueryInfo = subQueryInfos.remove(0);
+ curIdStr = eachSubQueryInfo.executionBlock.getId().toString();
+
+ y = eachSubQueryInfo.py + 13;
+ if (eachSubQueryInfo.pos == 0) {
+ x = eachSubQueryInfo.px;
+ } else if (eachSubQueryInfo.pos == 1) {
+ x = eachSubQueryInfo.px - 20;
+ } else if (eachSubQueryInfo.pos == 2) {
+ x = eachSubQueryInfo.px + 20;
+ }
+%>
+ <script type='text/javascript'>
+ jsPlumb.setRenderMode(jsPlumb.CANVAS);
+ </script>
+
+ <div class="component window" id="<%=curIdStr%>" style="left:<%=x%>em;top:<%=y%>em;">
+ <a style="font-size:0.9em;" href="./querytasks.jsp?queryId=<%=queryId%>&ebid=<%=curIdStr%>"><%=curIdStr%></a></p>
+ </div>
+
+<%
+ if (eachSubQueryInfo.parentId != null) {
+ String outgoing = "";
+ String prefix = "";
+ for (DataChannel channel : masterPlan.getOutgoingChannels(eachSubQueryInfo.executionBlock.getId())) {
+ outgoing += prefix + channel.getShuffleType();
+ prefix = "; ";
+ }
+%>
+ <script type="text/javascript">
+ var srcId = "<%=curIdStr%>";
+ var destId = "<%=eachSubQueryInfo.parentId.toString()%>";
+ var src = window.jsPlumb.addEndpoint(srcId, {
+ anchor:"AutoDefault",
+ paintStyle:{
+ fillStyle:"CornflowerBlue "
+ },
+ hoverPaintStyle:{
+ fillStyle:"red"
+ }
+ }
+ );
+
+ var dst = jsPlumb.addEndpoint(destId, {
+ anchor:"AutoDefault",
+ paintStyle:{
+ fillStyle:"CornflowerBlue "
+ },
+ hoverPaintStyle:{
+ fillStyle:"red"
+ }
+ }
+ );
+
+ var con = jsPlumb.connect({
+ source:src,
+ target:dst,
+ paintStyle:{ strokeStyle:"CornflowerBlue ", lineWidth:3 },
+ hoverPaintStyle:{ strokeStyle:"red", lineWidth:4 },
+ overlays : [ <!-- overlays start -->
+ [ "Arrow", { location:1 } ],
+ ["Label", {
+ cssClass:"l1 component label",
+ label : "<%=outgoing%>",
+ location:0.5,
+ id:"label",
+ events:{
+ "click":function(label, evt) {
+ }
+ }
+ }] <!-- label end -->
+ ] <!-- overlays end -->
+ });
+ </script>
+<%
+ } //end of if
+%>
+
+ <script type='text/javascript'>
+ var e = document.getElementById("<%=curIdStr%>");
+ var state = "<%=eachSubQueryInfo.subQuery != null ? eachSubQueryInfo.subQuery.getState().name(): ""%>";
+ switch (state) {
+ case 'NEW':
+ e.style.borderColor = "black";
+ e.style.color = "black";
+ break;
+ case 'CONTAINER_ALLOCATED':
+ e.style.borderColor = "gray";
+ e.style.color = "gray";
+ break;
+ case 'INIT':
+ e.style.borderColor = "skyblue";
+ e.style.color = "skyblue";
+ break;
+ case 'RUNNING':
+ e.style.borderColor = "blue";
+ e.style.color = "blue";
+ break;
+ case 'SUCCEEDED':
+ e.style.borderColor = "green";
+ e.style.color = "green";
+ break;
+ case 'FAILED':
+ e.style.borderColor = "red";
+ e.style.color = "red";
+ break;
+ default:
+ break;
+ }
+ </script>
+
+<%
+ List<ExecutionBlock> children = masterPlan.getChilds(eachSubQueryInfo.executionBlock.getId());
+
+ if (children.size() == 1) {
+ pos = 0;
+ } else {
+ pos = 1;
+ }
+ for (ExecutionBlock child : children) {
+ subQueryInfos.add(new SubQueryInfo(child, subQueryMap.get(child.getId()), eachSubQueryInfo.executionBlock.getId(), x, y, pos++));
+ }
+ } //end of while
+%>
+
+</div>
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/worker/querytasks.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/worker/querytasks.jsp b/tajo-core/src/main/resources/webapps/worker/querytasks.jsp
new file mode 100644
index 0000000..ab6ff26
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/worker/querytasks.jsp
@@ -0,0 +1,232 @@
+<%
+ /*
+ * 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.
+ */
+%>
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+
+<%@ page import="org.apache.tajo.master.querymaster.*" %>
+<%@ page import="org.apache.tajo.webapp.StaticHttpServer" %>
+<%@ page import="org.apache.tajo.worker.*" %>
+<%@ page import="java.text.SimpleDateFormat" %>
+<%@ page import="org.apache.tajo.QueryId" %>
+<%@ page import="org.apache.tajo.util.TajoIdUtils" %>
+<%@ page import="org.apache.tajo.ExecutionBlockId" %>
+<%@ page import="org.apache.tajo.ipc.TajoMasterProtocol" %>
+<%@ page import="java.util.List" %>
+<%@ page import="java.util.Map" %>
+<%@ page import="java.util.HashMap" %>
+<%@ page import="org.apache.tajo.QueryUnitAttemptId" %>
+<%@ page import="org.apache.tajo.catalog.statistics.TableStats" %>
+<%@ page import="java.util.Locale" %>
+<%@ page import="java.text.NumberFormat" %>
+<%@ page import="org.apache.tajo.engine.planner.PlannerUtil" %>
+<%@ page import="org.apache.tajo.util.FileUtil" %>
+
+<%
+ String paramQueryId = request.getParameter("queryId");
+ String paramEbId = request.getParameter("ebid");
+
+ QueryId queryId = TajoIdUtils.parseQueryId(paramQueryId);
+ ExecutionBlockId ebid = TajoIdUtils.createExecutionBlockId(paramEbId);
+ String sort = request.getParameter("sort");
+ if(sort == null) {
+ sort = "id";
+ }
+ String sortOrder = request.getParameter("sortOrder");
+ if(sortOrder == null) {
+ sortOrder = "asc";
+ }
+
+ String nextSortOrder = "asc";
+ if("asc".equals(sortOrder)) {
+ nextSortOrder = "desc";
+ }
+
+ String status = request.getParameter("status");
+ if(status == null || status.isEmpty() || "null".equals(status)) {
+ status = "ALL";
+ }
+ TajoWorker tajoWorker = (TajoWorker) StaticHttpServer.getInstance().getAttribute("tajo.info.server.object");
+
+ List<TajoMasterProtocol.WorkerResourceProto> allWorkers = tajoWorker.getWorkerContext()
+ .getQueryMasterManagerService().getQueryMaster().getAllWorker();
+
+ Map<String, TajoMasterProtocol.WorkerResourceProto> workerMap = new HashMap<String, TajoMasterProtocol.WorkerResourceProto>();
+ if(allWorkers != null) {
+ for(TajoMasterProtocol.WorkerResourceProto eachWorker: allWorkers) {
+ workerMap.put(eachWorker.getHost(), eachWorker);
+ }
+ }
+ QueryMasterTask queryMasterTask = tajoWorker.getWorkerContext()
+ .getQueryMasterManagerService().getQueryMaster().getQueryMasterTask(queryId, true);
+
+ if(queryMasterTask == null) {
+ out.write("<script type='text/javascript'>alert('no query'); history.back(0); </script>");
+ return;
+ }
+
+ Query query = queryMasterTask.getQuery();
+ SubQuery subQuery = query.getSubQuery(ebid);
+
+ if(subQuery == null) {
+ out.write("<script type='text/javascript'>alert('no sub-query'); history.back(0); </script>");
+ return;
+ }
+
+ if(subQuery == null) {
+%>
+<script type="text/javascript">
+ alert("No Execution Block for" + ebid);
+ document.history.back();
+</script>
+<%
+ return;
+ }
+
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+ String url = "querytasks.jsp?queryId=" + queryId + "&ebid=" + ebid + "&status=" + status + "&sortOrder=" + nextSortOrder + "&sort=";
+ QueryUnit[] queryUnits = subQuery.getQueryUnits();
+
+
+ long totalInputBytes = 0;
+ long totalReadBytes = 0;
+ long totalReadRows = 0;
+ long totalWriteBytes = 0;
+ long totalWriteRows = 0;
+ int numTasks = queryUnits.length;
+// int numSucceededTasks = 0;
+// int localReadTasks = subQuery.;
+ int numShuffles = 0;
+
+ float totalProgress = 0.0f;
+ for(QueryUnit eachQueryUnit: queryUnits) {
+ totalProgress += eachQueryUnit.getLastAttempt() != null ? eachQueryUnit.getLastAttempt().getProgress(): 0.0f;
+ numShuffles = eachQueryUnit.getShuffleOutpuNum();
+ if (eachQueryUnit.getLastAttempt() != null) {
+ TableStats inputStats = eachQueryUnit.getLastAttempt().getInputStats();
+ if (inputStats != null) {
+ totalInputBytes += inputStats.getNumBytes();
+ totalReadBytes += inputStats.getReadBytes();
+ totalReadRows += inputStats.getNumRows();
+ }
+ TableStats outputStats = eachQueryUnit.getLastAttempt().getResultStats();
+ if (outputStats != null) {
+ totalWriteBytes += outputStats.getNumBytes();
+ totalWriteRows += outputStats.getNumRows();
+ }
+ }
+ }
+
+ NumberFormat nf = NumberFormat.getInstance(Locale.US);
+%>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <link rel="stylesheet" type="text/css" href="/static/style.css"/>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <title>Query Detail Info</title>
+</head>
+<body>
+<%@ include file="header.jsp"%>
+<div class='contents'>
+ <h2>Tajo Worker: <a href='index.jsp'><%=tajoWorker.getWorkerContext().getWorkerName()%></a></h2>
+ <hr/>
+ <h3><a href='querydetail.jsp?queryId=<%=paramQueryId%>'><%=ebid.toString()%></a></h3>
+ <hr/>
+ <p/>
+ <pre style="white-space:pre-wrap;"><%=PlannerUtil.buildExplainString(subQuery.getBlock().getPlan())%></pre>
+ <p/>
+ <table border="1" width="100%" class="border_table">
+ <tr><td align='right' width='180px'>Status:</td><td><%=subQuery.getState()%></td></tr>
+ <tr><td align='right'>Started:</td><td><%=df.format(subQuery.getStartTime())%> ~ <%=subQuery.getFinishTime() == 0 ? "-" : df.format(subQuery.getFinishTime())%></td></tr>
+ <tr><td align='right'># Tasks:</td><td><%=numTasks%> (Local Tasks: <%=subQuery.getTaskScheduler().getHostLocalAssigned()%>, Rack Local Tasks: <%=subQuery.getTaskScheduler().getRackLocalAssigned()%>)</td></tr>
+ <tr><td align='right'>Progress:</td><td><%=JSPUtil.percentFormat((float)(totalProgress/numTasks))%>%</td></tr>
+ <tr><td align='right'># Shuffles:</td><td><%=numShuffles%></td></tr>
+ <tr><td align='right'>Input Bytes:</td><td><%=FileUtil.humanReadableByteCount(totalInputBytes, false) + " (" + nf.format(totalInputBytes) + " B)"%></td></tr>
+ <tr><td align='right'>Actual Processed Bytes:</td><td><%=totalReadBytes == 0 ? "-" : FileUtil.humanReadableByteCount(totalReadBytes, false) + " (" + nf.format(totalReadBytes) + " B)"%></td></tr>
+ <tr><td align='right'>Input Rows:</td><td><%=nf.format(totalReadRows)%></td></tr>
+ <tr><td align='right'>Output Bytes:</td><td><%=FileUtil.humanReadableByteCount(totalWriteBytes, false) + " (" + nf.format(totalWriteBytes) + " B)"%></td></tr>
+ <tr><td align='right'>Output Rows:</td><td><%=nf.format(totalWriteRows)%></td></tr>
+ </table>
+ <hr/>
+
+
+ <form action='querytasks.jsp' method='GET'>
+ Status:
+ <select name="status" onchange="this.form.submit()">
+ <option value="ALL" <%="ALL".equals(status) ? "selected" : ""%>>ALL</option>
+ <option value="SCHEDULED" <%="SCHEDULED".equals(status) ? "selected" : ""%>>SCHEDULED</option>
+ <option value="RUNNING" <%="RUNNING".equals(status) ? "selected" : ""%>>RUNNING</option>
+ <option value="SUCCEEDED" <%="SUCCEEDED".equals(status) ? "selected" : ""%>>SUCCEEDED</option>
+ </select>
+
+ <input type="submit" value="Filter">
+ <input type="hidden" name="queryId" value="<%=paramQueryId%>"/>
+ <input type="hidden" name="ebid" value="<%=paramEbId%>"/>
+ <input type="hidden" name="sort" value="<%=sort%>"/>
+ <input type="hidden" name="sortOrder" value="<%=sortOrder%>"/>
+ </form>
+ <table border="1" width="100%" class="border_table">
+ <tr><th>No</th><th><a href='<%=url%>id'>Id</a></th><th>Status</th><th>Progress</th><th><a href='<%=url%>startTime'>Started</a></th><th><a href='<%=url%>runTime'>Running Time</a></th><th><a href='<%=url%>host'>Host</a></th></tr>
+ <%
+ JSPUtil.sortQueryUnit(queryUnits, sort, sortOrder);
+ int rowNo = 1;
+ for(QueryUnit eachQueryUnit: queryUnits) {
+ if(!"ALL".equals(status)) {
+ if(!status.equals(eachQueryUnit.getState().toString())) {
+ continue;
+ }
+ }
+ int queryUnitSeq = eachQueryUnit.getId().getId();
+ String queryUnitDetailUrl = "queryunit.jsp?queryId=" + paramQueryId + "&ebid=" + paramEbId +
+ "&queryUnitSeq=" + queryUnitSeq + "&sort=" + sort + "&sortOrder=" + sortOrder;
+
+ String queryUnitHost = eachQueryUnit.getSucceededHost() == null ? "-" : eachQueryUnit.getSucceededHost();
+ if(eachQueryUnit.getSucceededHost() != null) {
+ TajoMasterProtocol.WorkerResourceProto worker = workerMap.get(eachQueryUnit.getSucceededHost());
+ if(worker != null) {
+ QueryUnitAttempt lastAttempt = eachQueryUnit.getLastAttempt();
+ if(lastAttempt != null) {
+ QueryUnitAttemptId lastAttemptId = lastAttempt.getId();
+ queryUnitHost = "<a href='http://" + eachQueryUnit.getSucceededHost() + ":" + worker.getInfoPort() + "/taskdetail.jsp?queryUnitAttemptId=" + lastAttemptId + "'>" + eachQueryUnit.getSucceededHost() + "</a>";
+ }
+ }
+ }
+
+ %>
+ <tr>
+ <td><%=rowNo%></td>
+ <td><a href="<%=queryUnitDetailUrl%>"><%=eachQueryUnit.getId()%></a></td>
+ <td><%=eachQueryUnit.getState()%></td>
+ <td><%=JSPUtil.percentFormat(eachQueryUnit.getLastAttempt().getProgress())%>%</td>
+ <td><%=eachQueryUnit.getLaunchTime() == 0 ? "-" : df.format(eachQueryUnit.getLaunchTime())%></td>
+ <td align='right'><%=eachQueryUnit.getLaunchTime() == 0 ? "-" : eachQueryUnit.getRunningTime() + " ms"%></td>
+ <td><%=queryUnitHost%></td>
+ </tr>
+ <%
+ rowNo++;
+ }
+ %>
+ </table>
+ <%
+ %>
+</div>
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/worker/queryunit.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/worker/queryunit.jsp b/tajo-core/src/main/resources/webapps/worker/queryunit.jsp
new file mode 100644
index 0000000..3e8dfef
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/worker/queryunit.jsp
@@ -0,0 +1,171 @@
+<%
+ /*
+ * 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.
+ */
+%>
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+
+<%@ page import="org.apache.tajo.ExecutionBlockId" %>
+<%@ page import="org.apache.tajo.QueryId" %>
+<%@ page import="org.apache.tajo.QueryUnitId" %>
+<%@ page import="org.apache.tajo.catalog.proto.CatalogProtos" %>
+<%@ page import="org.apache.tajo.ipc.TajoWorkerProtocol" %>
+<%@ page import="org.apache.tajo.master.querymaster.Query" %>
+<%@ page import="org.apache.tajo.master.querymaster.QueryMasterTask" %>
+<%@ page import="org.apache.tajo.master.querymaster.QueryUnit" %>
+<%@ page import="org.apache.tajo.master.querymaster.SubQuery" %>
+<%@ page import="org.apache.tajo.storage.DataLocation" %>
+<%@ page import="org.apache.tajo.storage.fragment.FileFragment" %>
+<%@ page import="org.apache.tajo.storage.fragment.FragmentConvertor" %>
+<%@ page import="org.apache.tajo.util.TajoIdUtils" %>
+<%@ page import="org.apache.tajo.webapp.StaticHttpServer" %>
+<%@ page import="org.apache.tajo.worker.TajoWorker" %>
+<%@ page import="java.net.URI" %>
+<%@ page import="java.text.SimpleDateFormat" %>
+<%@ page import="java.util.Map" %>
+<%@ page import="java.util.Set" %>
+<%@ page import="org.apache.tajo.catalog.statistics.TableStats" %>
+<%@ page import="org.apache.tajo.worker.TaskHistory" %>
+
+<%
+ String paramQueryId = request.getParameter("queryId");
+ String paramEbId = request.getParameter("ebid");
+ String status = request.getParameter("status");
+ if(status == null || status.isEmpty() || "null".equals(status)) {
+ status = "ALL";
+ }
+
+ QueryId queryId = TajoIdUtils.parseQueryId(paramQueryId);
+ ExecutionBlockId ebid = TajoIdUtils.createExecutionBlockId(paramEbId);
+
+ int queryUnitSeq = Integer.parseInt(request.getParameter("queryUnitSeq"));
+ TajoWorker tajoWorker = (TajoWorker) StaticHttpServer.getInstance().getAttribute("tajo.info.server.object");
+ QueryMasterTask queryMasterTask = tajoWorker.getWorkerContext()
+ .getQueryMasterManagerService().getQueryMaster().getQueryMasterTask(queryId, true);
+
+ if(queryMasterTask == null) {
+ out.write("<script type='text/javascript'>alert('no query'); history.back(0); </script>");
+ return;
+ }
+
+ Query query = queryMasterTask.getQuery();
+ SubQuery subQuery = query.getSubQuery(ebid);
+
+ if(subQuery == null) {
+ out.write("<script type='text/javascript'>alert('no sub-query'); history.back(0); </script>");
+ return;
+ }
+
+ if(subQuery == null) {
+%>
+<script type="text/javascript">
+ alert("No Execution Block for" + ebid);
+ document.history.back();
+</script>
+<%
+ return;
+ }
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+ QueryUnitId queryUnitId = new QueryUnitId(ebid, queryUnitSeq);
+ QueryUnit queryUnit = subQuery.getQueryUnit(queryUnitId);
+ if(queryUnit == null) {
+%>
+<script type="text/javascript">
+ alert("No QueryUnit for" + queryUnitId);
+ document.history.back();
+</script>
+<%
+ return;
+ }
+
+ String sort = request.getParameter("sort");
+ String sortOrder = request.getParameter("sortOrder");
+
+ String backUrl = "querytasks.jsp?queryId=" + paramQueryId + "&ebid=" + paramEbId + "&sort=" + sort + "&sortOrder=" + sortOrder + "&status=" + status;
+
+ String fragmentInfo = "";
+ String delim = "";
+ for (CatalogProtos.FragmentProto eachFragment : queryUnit.getAllFragments()) {
+ FileFragment fileFragment = FragmentConvertor.convert(FileFragment.class, eachFragment);
+ fragmentInfo += delim + fileFragment.toString();
+ delim = "<br/>";
+ }
+
+ String fetchInfo = "";
+ delim = "";
+ for (Map.Entry<String, Set<URI>> e : queryUnit.getFetchMap().entrySet()) {
+ fetchInfo += delim + "<b>" + e.getKey() + "</b>";
+ delim = "<br/>";
+ for (URI t : e.getValue()) {
+ fetchInfo += delim + t;
+ }
+ }
+
+ String dataLocationInfos = "";
+ delim = "";
+ for(DataLocation eachLocation: queryUnit.getDataLocations()) {
+ dataLocationInfos += delim + eachLocation.toString();
+ delim = "<br/>";
+ }
+
+ int numShuffles = queryUnit.getShuffleOutpuNum();
+ String shuffleKey = "-";
+ String shuffleFileName = "-";
+ if(numShuffles > 0) {
+ TajoWorkerProtocol.ShuffleFileOutput shuffleFileOutputs = queryUnit.getShuffleFileOutputs().get(0);
+ shuffleKey = "" + shuffleFileOutputs.getPartId();
+ shuffleFileName = shuffleFileOutputs.getFileName();
+ }
+
+ //int numIntermediateData = queryUnit.getIntermediateData() == null ? 0 : queryUnit.getIntermediateData().size();
+ TableStats inputStat = queryUnit.getLastAttempt().getInputStats();
+ TableStats outputStat = queryUnit.getLastAttempt().getResultStats();
+%>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <link rel="stylesheet" type="text/css" href="/static/style.css"/>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <title>Query Unit Detail</title>
+</head>
+<body>
+<%@ include file="header.jsp"%>
+<div class='contents'>
+ <h2>Tajo Worker: <a href='index.jsp'><%=tajoWorker.getWorkerContext().getWorkerName()%></a></h2>
+ <hr/>
+ <h3><a href='<%=backUrl%>'><%=ebid.toString()%></a></h3>
+ <hr/>
+ <table border="1" width="100%" class="border_table">
+ <tr><td width="200" align="right">ID</td><td><%=queryUnit.getId()%></td></tr>
+ <tr><td align="right">Progress</td><td><%=JSPUtil.percentFormat(queryUnit.getLastAttempt().getProgress())%>%</td></tr>
+ <tr><td align="right">State</td><td><%=queryUnit.getState()%></td></tr>
+ <tr><td align="right">Launch Time</td><td><%=queryUnit.getLaunchTime() == 0 ? "-" : df.format(queryUnit.getLaunchTime())%></td></tr>
+ <tr><td align="right">Finish Time</td><td><%=queryUnit.getFinishTime() == 0 ? "-" : df.format(queryUnit.getFinishTime())%></td></tr>
+ <tr><td align="right">Running Time</td><td><%=queryUnit.getLaunchTime() == 0 ? "-" : queryUnit.getRunningTime() + " ms"%></td></tr>
+ <tr><td align="right">Host</td><td><%=queryUnit.getSucceededHost() == null ? "-" : queryUnit.getSucceededHost()%></td></tr>
+ <tr><td align="right">Shuffles</td><td># Shuffle Outputs: <%=numShuffles%>, Shuffle Key: <%=shuffleKey%>, Shuffle file: <%=shuffleFileName%></td></tr>
+ <tr><td align="right">Data Locations</td><td><%=dataLocationInfos%></td></tr>
+ <tr><td align="right">Fragment</td><td><%=fragmentInfo%></td></tr>
+ <tr><td align="right">Input Statistics</td><td><%=TaskHistory.toInputStatsString(inputStat)%></td></tr>
+ <tr><td align="right">Output Statistics</td><td><%=TaskHistory.toOutputStatsString(outputStat)%></td></tr>
+ <tr><td align="right">Fetches</td><td><%=fetchInfo%></td></tr>
+ </table>
+</div>
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/worker/taskcontainers.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/worker/taskcontainers.jsp b/tajo-core/src/main/resources/webapps/worker/taskcontainers.jsp
new file mode 100644
index 0000000..be19a42
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/worker/taskcontainers.jsp
@@ -0,0 +1,87 @@
+<%
+ /*
+ * 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.
+ */
+%>
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+
+<%@ page import="java.util.*" %>
+<%@ page import="org.apache.tajo.webapp.StaticHttpServer" %>
+<%@ page import="org.apache.tajo.worker.*" %>
+<%@ page import="java.text.SimpleDateFormat" %>
+
+<%
+ TajoWorker tajoWorker = (TajoWorker) StaticHttpServer.getInstance().getAttribute("tajo.info.server.object");
+
+ List<TaskRunner> taskRunners = new ArrayList<TaskRunner>(tajoWorker.getWorkerContext().getTaskRunnerManager().getTaskRunners());
+ List<TaskRunner> finishedTaskRunners = new ArrayList<TaskRunner>(tajoWorker.getWorkerContext().getTaskRunnerManager().getFinishedTaskRunners());
+
+ JSPUtil.sortTaskRunner(taskRunners);
+ JSPUtil.sortTaskRunner(finishedTaskRunners);
+
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+%>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <link rel="stylesheet" type = "text/css" href = "/static/style.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <title>tajo worker</title>
+</head>
+<body>
+<%@ include file="header.jsp"%>
+<div class='contents'>
+ <h2>Tajo Worker: <a href='index.jsp'><%=tajoWorker.getWorkerContext().getWorkerName()%></a></h2>
+ <hr/>
+ <h3>Running Task Containers</h3>
+ <table width="100%" border="1" class="border_table">
+ <tr><th>ContainerId</th><th>StartTime</th><th>FinishTime</th><th>RunTime</th><th>Status</th></tr>
+<%
+ for(TaskRunner eachTaskRunner: taskRunners) {
+%>
+ <tr>
+ <td><a href="tasks.jsp?containerId=<%=eachTaskRunner.getId()%>"><%=eachTaskRunner.getId()%></a></td>
+ <td><%=df.format(eachTaskRunner.getStartTime())%></td>
+ <td><%=eachTaskRunner.getFinishTime() == 0 ? "-" : df.format(eachTaskRunner.getFinishTime())%></td>
+ <td><%=JSPUtil.getElapsedTime(eachTaskRunner.getStartTime(), eachTaskRunner.getFinishTime())%></td>
+ <td><%=eachTaskRunner.getServiceState()%></td>
+<%
+ }
+%>
+ </table>
+ <p/>
+ <hr/>
+ <h3>Finished Task Containers</h3>
+ <table width="100%" border="1" class="border_table">
+ <tr><th>ContainerId</th><th>StartTime</th><th>FinishTime</th><th>RunTime</th><th>Status</th></tr>
+<%
+ for(TaskRunner eachTaskRunner: finishedTaskRunners) {
+%>
+ <tr>
+ <td><a href="tasks.jsp?containerId=<%=eachTaskRunner.getId()%>"><%=eachTaskRunner.getId()%></a></td>
+ <td><%=df.format(eachTaskRunner.getStartTime())%></td>
+ <td><%=eachTaskRunner.getFinishTime() == 0 ? "-" : df.format(eachTaskRunner.getFinishTime())%></td>
+ <td><%=JSPUtil.getElapsedTime(eachTaskRunner.getStartTime(), eachTaskRunner.getFinishTime())%></td>
+ <td><%=eachTaskRunner.getServiceState()%></td>
+<%
+ }
+%>
+ </table>
+</div>
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/worker/taskdetail.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/worker/taskdetail.jsp b/tajo-core/src/main/resources/webapps/worker/taskdetail.jsp
new file mode 100644
index 0000000..b264081
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/worker/taskdetail.jsp
@@ -0,0 +1,127 @@
+<%
+ /*
+ * 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.
+ */
+%>
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+
+<%@ page import="org.apache.tajo.QueryUnitAttemptId" %>
+<%@ page import="org.apache.tajo.util.TajoIdUtils" %>
+<%@ page import="org.apache.tajo.webapp.StaticHttpServer" %>
+<%@ page import="org.apache.tajo.worker.TajoWorker" %>
+<%@ page import="org.apache.tajo.worker.Task" %>
+<%@ page import="org.apache.tajo.worker.TaskHistory" %>
+<%@ page import="org.apache.tajo.worker.TaskRunner" %>
+<%@ page import="java.text.SimpleDateFormat" %>
+
+<%
+ TajoWorker tajoWorker = (TajoWorker) StaticHttpServer.getInstance().getAttribute("tajo.info.server.object");
+
+ String containerId = request.getParameter("containerId");
+ String quAttemptId = request.getParameter("queryUnitAttemptId");
+ QueryUnitAttemptId queryUnitAttemptId = TajoIdUtils.parseQueryUnitAttemptId(quAttemptId);
+ Task task = null;
+ TaskHistory taskHistory = null;
+ if(containerId == null || containerId.isEmpty() || "null".equals(containerId)) {
+ task = tajoWorker.getWorkerContext().getTaskRunnerManager().findTaskByQueryUnitAttemptId(queryUnitAttemptId);
+ if (task != null) {
+ taskHistory = task.getTaskHistory();
+ } else {
+ taskHistory = tajoWorker.getWorkerContext().getTaskRunnerManager().findTaskHistoryByQueryUnitAttemptId(queryUnitAttemptId);
+ }
+ } else {
+ TaskRunner taskRunner = tajoWorker.getWorkerContext().getTaskRunnerManager().findTaskRunner(containerId);
+ if(taskRunner != null) {
+ task = taskRunner.getContext().getTask(queryUnitAttemptId);
+ if (task != null) {
+ taskHistory = task.getTaskHistory();
+ } else {
+ taskHistory = taskRunner.getContext().getTaskHistory(queryUnitAttemptId);
+ }
+ }
+ }
+ if(taskHistory == null) {
+%>
+<script type="text/javascript">
+ alert("No Task Info for" + quAttemptId);
+ document.history.back();
+</script>
+<%
+ return;
+ }
+
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+%>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <link rel="stylesheet" type = "text/css" href = "/static/style.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <title>tajo worker</title>
+</head>
+<body>
+<%@ include file="header.jsp"%>
+<div class='contents'>
+ <h2>Tajo Worker: <a href='index.jsp'><%=tajoWorker.getWorkerContext().getWorkerName()%></a></h2>
+ <hr/>
+ <h3>Task Detail: <%=quAttemptId%></h3>
+ <table border="1" width="100%" class="border_table">
+ <tr><td width="200" align="right">ID</td><td><%=quAttemptId%></td></tr>
+ <tr><td align="right">State</td><td><%=taskHistory.getStatus()%></td></tr>
+ <tr><td align="right">Start Time</td><td><%=taskHistory.getStartTime() == 0 ? "-" : df.format(taskHistory.getStartTime())%></td></tr>
+ <tr><td align="right">Finish Time</td><td><%=taskHistory.getFinishTime() == 0 ? "-" : df.format(taskHistory.getFinishTime())%></td></tr>
+ <tr><td align="right">Running Time</td><td><%=JSPUtil.getElapsedTime(taskHistory.getStartTime(), taskHistory.getFinishTime())%></td></tr>
+ <tr><td align="right">Progress</td><td><%=JSPUtil.percentFormat(taskHistory.getProgress())%>%</td></tr>
+ <tr><td align="right">Output Path</td><td><%=taskHistory.getOutputPath()%></td></tr>
+ <tr><td align="right">Working Path</td><td><%=taskHistory.getWorkingPath()%></td></tr>
+ <tr><td align="right">Input Statistics</td><td><%=TaskHistory.toInputStatsString(taskHistory.getInputStats())%></td></tr>
+ <tr><td align="right">Output Statistics</td><td><%=TaskHistory.toOutputStatsString(taskHistory.getOutputStats())%></td></tr>
+ </table>
+
+<%
+ if(taskHistory.hasFetcher()) {
+%>
+ <hr/>
+ <h3>Fetch Status</h3>
+ <table border="1" width="100%" class="border_table">
+ <tr><th>No</th><th>StartTime</th><th>FinishTime</th><th>RunTime</th><th>Status</th><th>File Length</th><th># Messages</th><th>URI</th></tr>
+<%
+ int index = 1;
+ for(TaskHistory.FetcherHistory eachFetcher: taskHistory.getFetchers()) {
+%>
+ <tr>
+ <td><%=index%></td>
+ <td><%=df.format(eachFetcher.getStartTime())%></td>
+ <td><%=eachFetcher.getFinishTime() == 0 ? "-" : df.format(eachFetcher.getFinishTime())%></td>
+ <td><%=JSPUtil.getElapsedTime(eachFetcher.getStartTime(), eachFetcher.getFinishTime())%></td>
+ <td><%=eachFetcher.getStatus()%></td>
+ <td align="right"><%=eachFetcher.getFileLen()%></td>
+ <td align="right"><%=eachFetcher.getMessageReceiveCount()%></td>
+ <td><a href="<%=eachFetcher.getUri()%>"><%=eachFetcher.getUri()%></a></td>
+ </tr>
+<%
+ index++;
+ }
+%>
+ </table>
+<%
+ }
+%>
+</div>
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/worker/tasks.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/worker/tasks.jsp b/tajo-core/src/main/resources/webapps/worker/tasks.jsp
new file mode 100644
index 0000000..7b65989
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/worker/tasks.jsp
@@ -0,0 +1,94 @@
+<%
+ /*
+ * 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.
+ */
+%>
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+
+<%@ page import="java.util.*" %>
+<%@ page import="org.apache.tajo.webapp.StaticHttpServer" %>
+<%@ page import="org.apache.tajo.worker.*" %>
+<%@ page import="java.text.SimpleDateFormat" %>
+<%@ page import="org.apache.tajo.QueryUnitAttemptId" %>
+
+<%
+ String containerId = request.getParameter("containerId");
+ TajoWorker tajoWorker = (TajoWorker) StaticHttpServer.getInstance().getAttribute("tajo.info.server.object");
+
+ TaskRunner taskRunner = tajoWorker.getWorkerContext().getTaskRunnerManager().findTaskRunner(containerId);
+ if(taskRunner == null) {
+%>
+<script type="text/javascript">
+ alert("No Task Container for" + containerId);
+ document.history.back();
+</script>
+<%
+ return;
+ }
+
+ TaskRunner.TaskRunnerContext taskRunnerContext = taskRunner.getContext();
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+%>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <link rel="stylesheet" type = "text/css" href = "/static/style.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <title>tajo worker</title>
+</head>
+<body>
+<%@ include file="header.jsp"%>
+<div class='contents'>
+ <h2>Tajo Worker: <a href='index.jsp'><%=tajoWorker.getWorkerContext().getWorkerName()%></a></h2>
+ <hr/>
+ <h3>Tasks</h3>
+ <table width="100%" border="1" class="border_table">
+ <tr><th>Id</th><th>StartTime</th><th>FinishTime</th><th>RunTime</th><th>Status</th></tr>
+<%
+ for(Map.Entry<QueryUnitAttemptId, Task> entry: taskRunnerContext.getTasks().entrySet()) {
+ QueryUnitAttemptId queryUnitId = entry.getKey();
+ TaskHistory eachTask = entry.getValue().getTaskHistory();
+%>
+ <tr>
+ <td><a href="taskdetail.jsp?containerId=<%=containerId%>&queryUnitAttemptId=<%=queryUnitId%>"><%=queryUnitId%></a></td>
+ <td><%=df.format(eachTask.getStartTime())%></td>
+ <td><%=eachTask.getFinishTime() == 0 ? "-" : df.format(eachTask.getFinishTime())%></td>
+ <td><%=JSPUtil.getElapsedTime(eachTask.getStartTime(), eachTask.getFinishTime())%></td>
+ <td><%=eachTask.getStatus()%></td>
+ </tr>
+<%
+ }
+
+ for(Map.Entry<QueryUnitAttemptId, TaskHistory> entry: taskRunnerContext.getTaskHistories().entrySet()) {
+ QueryUnitAttemptId queryUnitId = entry.getKey();
+ TaskHistory eachTask = entry.getValue();
+%>
+ <tr>
+ <td><a href="taskdetail.jsp?containerId=<%=containerId%>&queryUnitAttemptId=<%=queryUnitId%>"><%=queryUnitId%></a></td>
+ <td><%=df.format(eachTask.getStartTime())%></td>
+ <td><%=eachTask.getFinishTime() == 0 ? "-" : df.format(eachTask.getFinishTime())%></td>
+ <td><%=JSPUtil.getElapsedTime(eachTask.getStartTime(), eachTask.getFinishTime())%></td>
+ <td><%=eachTask.getStatus()%></td>
+ </tr>
+<%
+ }
+%>
+ </table>
+</div>
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/worker/thread.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/worker/thread.jsp b/tajo-core/src/main/resources/webapps/worker/thread.jsp
new file mode 100644
index 0000000..7489741
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/worker/thread.jsp
@@ -0,0 +1,45 @@
+<%
+ /*
+ * 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.
+ */
+%>
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+
+<%@ page import="org.apache.tajo.webapp.StaticHttpServer" %>
+<%@ page import="org.apache.tajo.worker.TajoWorker" %>
+
+<%
+ TajoWorker tajoWorker = (TajoWorker) StaticHttpServer.getInstance().getAttribute("tajo.info.server.object");
+%>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <link rel="stylesheet" type = "text/css" href = "/static/style.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <title>tajo worker</title>
+</head>
+<body>
+<%@ include file="header.jsp"%>
+<div class='contents'>
+ <h2>Tajo Worker: <a href='index.jsp'><%=tajoWorker.getWorkerContext().getWorkerName()%></a></h2>
+ <hr/>
+ <h3>Thread Dump</h3>
+ <pre><%tajoWorker.dumpThread(out);%></pre>
+</div>
+</body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/test/java/log4j.properties
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/log4j.properties b/tajo-core/src/test/java/log4j.properties
new file mode 100644
index 0000000..749124c
--- /dev/null
+++ b/tajo-core/src/test/java/log4j.properties
@@ -0,0 +1,28 @@
+##
+# 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.
+#
+
+# log4j configuration used during build and unit tests
+
+log4j.rootLogger=info,stdout
+log4j.threshhold=ALL
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %-5p %c{2} (%F:%M(%L)) - %m%n
+
+log4j.logger.org.apache.hadoop=WARN
+log4j.logger.org.apache.hadoop.conf=ERROR
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/test/java/org/apache/tajo/BackendTestingUtil.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/BackendTestingUtil.java b/tajo-core/src/test/java/org/apache/tajo/BackendTestingUtil.java
new file mode 100644
index 0000000..0064e41
--- /dev/null
+++ b/tajo-core/src/test/java/org/apache/tajo/BackendTestingUtil.java
@@ -0,0 +1,76 @@
+/**
+ * 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.tajo;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.Schema;
+import org.apache.tajo.catalog.TableMeta;
+import org.apache.tajo.catalog.proto.CatalogProtos.StoreType;
+import org.apache.tajo.common.TajoDataTypes.Type;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.datum.DatumFactory;
+import org.apache.tajo.storage.*;
+
+import java.io.IOException;
+
+public class BackendTestingUtil {
+ public final static Schema mockupSchema;
+ public final static TableMeta mockupMeta;
+
+ static {
+ mockupSchema = new Schema();
+ mockupSchema.addColumn("deptname", Type.TEXT);
+ mockupSchema.addColumn("score", Type.INT4);
+ mockupMeta = CatalogUtil.newTableMeta(StoreType.CSV);
+ }
+
+ public static void writeTmpTable(TajoConf conf, Path tablePath)
+ throws IOException {
+ AbstractStorageManager sm = StorageManagerFactory.getStorageManager(conf, tablePath);
+ FileSystem fs = sm.getFileSystem();
+
+ Appender appender;
+
+ Path filePath = new Path(tablePath, "table.csv");
+ if (fs.exists(tablePath)) {
+ fs.delete(tablePath, true);
+ }
+ fs.mkdirs(tablePath);
+
+ appender = sm.getAppender(mockupMeta, mockupSchema, filePath);
+ appender.init();
+
+ int deptSize = 10000;
+ int tupleNum = 100;
+ Tuple tuple;
+ for (int i = 0; i < tupleNum; i++) {
+ tuple = new VTuple(2);
+ String key = "test" + (i % deptSize);
+ tuple.put(0, DatumFactory.createText(key));
+ tuple.put(1, DatumFactory.createInt4(i + 1));
+ appender.addTuple(tuple);
+ }
+ appender.close();
+ }
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/test/java/org/apache/tajo/IntegrationTest.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/IntegrationTest.java b/tajo-core/src/test/java/org/apache/tajo/IntegrationTest.java
new file mode 100644
index 0000000..755b90a
--- /dev/null
+++ b/tajo-core/src/test/java/org/apache/tajo/IntegrationTest.java
@@ -0,0 +1,22 @@
+/**
+ * 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.tajo;
+
+public interface IntegrationTest {
+}
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/test/java/org/apache/tajo/LocalTajoTestingUtility.java
----------------------------------------------------------------------
diff --git a/tajo-core/src/test/java/org/apache/tajo/LocalTajoTestingUtility.java b/tajo-core/src/test/java/org/apache/tajo/LocalTajoTestingUtility.java
new file mode 100644
index 0000000..e651313
--- /dev/null
+++ b/tajo-core/src/test/java/org/apache/tajo/LocalTajoTestingUtility.java
@@ -0,0 +1,136 @@
+/**
+ * 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.tajo;
+
+import com.google.protobuf.ServiceException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.tajo.benchmark.TPCH;
+import org.apache.tajo.catalog.*;
+import org.apache.tajo.catalog.proto.CatalogProtos;
+import org.apache.tajo.catalog.statistics.TableStats;
+import org.apache.tajo.client.TajoClient;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.engine.planner.global.MasterPlan;
+import org.apache.tajo.master.session.Session;
+import org.apache.tajo.util.TajoIdUtils;
+
+import java.io.IOException;
+import java.sql.ResultSet;
+import java.util.UUID;
+
+public class LocalTajoTestingUtility {
+ private static final Log LOG = LogFactory.getLog(LocalTajoTestingUtility.class);
+
+ private TajoTestingCluster util;
+ private TajoConf conf;
+ private TajoClient client;
+
+ private static UserGroupInformation dummyUserInfo;
+
+ static {
+ try {
+ dummyUserInfo = UserGroupInformation.getCurrentUser();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static int taskAttemptId;
+
+ public static QueryUnitAttemptId newQueryUnitAttemptId() {
+ return QueryIdFactory.newQueryUnitAttemptId(
+ QueryIdFactory.newQueryUnitId(new MasterPlan(newQueryId(), null, null).newExecutionBlockId()), taskAttemptId++);
+ }
+ public static QueryUnitAttemptId newQueryUnitAttemptId(MasterPlan plan) {
+ return QueryIdFactory.newQueryUnitAttemptId(QueryIdFactory.newQueryUnitId(plan.newExecutionBlockId()), 0);
+ }
+ public static Session createDummySession() {
+ return new Session(UUID.randomUUID().toString(), dummyUserInfo.getUserName(), TajoConstants.DEFAULT_DATABASE_NAME);
+ }
+
+ /**
+ * for test
+ * @return The generated QueryId
+ */
+ public synchronized static QueryId newQueryId() {
+ return QueryIdFactory.newQueryId(TajoIdUtils.MASTER_ID_FORMAT.format(0));
+ }
+
+ public void setup(String[] names,
+ String[] tablepaths,
+ Schema[] schemas,
+ Options option) throws Exception {
+ LOG.info("===================================================");
+ LOG.info("Starting Test Cluster.");
+ LOG.info("===================================================");
+
+ util = new TajoTestingCluster();
+ util.startMiniCluster(1);
+ conf = util.getConfiguration();
+ client = new TajoClient(conf);
+
+ FileSystem fs = util.getDefaultFileSystem();
+ Path rootDir = util.getMaster().getStorageManager().getWarehouseDir();
+ fs.mkdirs(rootDir);
+ for (int i = 0; i < tablepaths.length; i++) {
+ Path localPath = new Path(tablepaths[i]);
+ Path tablePath = new Path(rootDir, names[i]);
+ fs.mkdirs(tablePath);
+ Path dfsPath = new Path(tablePath, localPath.getName());
+ fs.copyFromLocalFile(localPath, dfsPath);
+ TableMeta meta = CatalogUtil.newTableMeta(CatalogProtos.StoreType.CSV, option);
+
+ // Add fake table statistic data to tables.
+ // It gives more various situations to unit tests.
+ TableStats stats = new TableStats();
+ stats.setNumBytes(TPCH.tableVolumes.get(names[i]));
+ TableDesc tableDesc = new TableDesc(
+ CatalogUtil.buildFQName(TajoConstants.DEFAULT_DATABASE_NAME, names[i]), schemas[i], meta,
+ tablePath);
+ tableDesc.setStats(stats);
+ util.getMaster().getCatalog().createTable(tableDesc);
+ }
+
+ LOG.info("===================================================");
+ LOG.info("Test Cluster ready and test table created.");
+ LOG.info("===================================================");
+
+ }
+
+ public TajoTestingCluster getTestingCluster() {
+ return util;
+ }
+
+ public ResultSet execute(String query) throws IOException, ServiceException {
+ return client.executeQueryAndGetResult(query);
+ }
+
+ public void shutdown() throws IOException {
+ if(client != null) {
+ client.close();
+ }
+ if(util != null) {
+ util.shutdownMiniCluster();
+ }
+ }
+}