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 13:44:19 UTC
[16/57] [abbrv] [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/proto/TajoWorkerProtocol.proto
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/proto/TajoWorkerProtocol.proto b/tajo-core/src/main/proto/TajoWorkerProtocol.proto
new file mode 100644
index 0000000..7c94e33
--- /dev/null
+++ b/tajo-core/src/main/proto/TajoWorkerProtocol.proto
@@ -0,0 +1,258 @@
+/**
+ * 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.
+ */
+
+// TajoMaster -> TajoWorker, TajoWorker(QueryMaster) <-> TajoWorker Protocol
+option java_package = "org.apache.tajo.ipc";
+option java_outer_classname = "TajoWorkerProtocol";
+option java_generic_services = true;
+option java_generate_equals_and_hash = true;
+
+import "yarn_protos.proto";
+import "tajo_protos.proto";
+import "TajoIdProtos.proto";
+import "CatalogProtos.proto";
+import "PrimitiveProtos.proto";
+
+message SessionProto {
+ required string session_id = 1;
+ required string username = 2;
+ required string current_database = 3;
+ required int64 last_access_time = 4;
+ required KeyValueSetProto variables = 5;
+}
+
+message TaskStatusProto {
+ required QueryUnitAttemptIdProto id = 1;
+ required string workerName = 2;
+ required float progress = 3;
+ required TaskAttemptState state = 4;
+ optional StatSetProto stats = 5;
+ optional TableStatsProto inputStats = 6;
+ optional TableStatsProto resultStats = 7;
+ repeated ShuffleFileOutput shuffleFileOutputs = 8;
+}
+
+message TaskCompletionReport {
+ required QueryUnitAttemptIdProto id = 1;
+ optional StatSetProto stats = 2;
+ optional TableStatsProto inputStats = 3;
+ optional TableStatsProto resultStats = 4;
+ repeated ShuffleFileOutput shuffleFileOutputs = 5;
+}
+
+message TaskFatalErrorReport {
+ required QueryUnitAttemptIdProto id = 1;
+ optional string error_message = 2;
+}
+
+message QueryUnitRequestProto {
+ required QueryUnitAttemptIdProto id = 1;
+ repeated FragmentProto fragments = 2;
+ required string outputTable = 3;
+ required bool clusteredOutput = 4;
+ required string serializedData = 5;
+ optional bool interQuery = 6 [default = false];
+ repeated Fetch fetches = 7;
+ optional bool shouldDie = 8;
+ optional KeyValueSetProto queryContext = 9;
+ optional DataChannelProto dataChannel = 10;
+ optional EnforcerProto enforcer = 11;
+}
+
+message Fetch {
+ required string name = 1;
+ required string urls = 2;
+}
+
+message QueryUnitResponseProto {
+ required string id = 1;
+ required QueryState status = 2;
+}
+
+message StatusReportProto {
+ required int64 timestamp = 1;
+ required string serverName = 2;
+ repeated TaskStatusProto status = 3;
+ repeated QueryUnitAttemptIdProto pings = 4;
+}
+
+message CommandRequestProto {
+ repeated Command command = 1;
+}
+
+message CommandResponseProto {
+}
+
+message Command {
+ required QueryUnitAttemptIdProto id = 1;
+ required CommandType type = 2;
+}
+
+enum CommandType {
+ PREPARE = 0;
+ LAUNCH = 1;
+ STOP = 2;
+ FINALIZE = 3;
+}
+
+message ShuffleFileOutput {
+ required int32 partId = 1;
+ optional string fileName = 2;
+}
+
+message QueryExecutionRequestProto {
+ required QueryIdProto queryId = 1;
+ required SessionProto session = 2;
+ required KeyValueSetProto queryContext = 3;
+ required StringProto sql = 4;
+ optional StringProto logicalPlanJson = 5;
+}
+
+message GetTaskRequestProto {
+ required hadoop.yarn.ContainerIdProto containerId = 1;
+ required ExecutionBlockIdProto executionBlockId = 2;
+}
+
+enum ShuffleType {
+ NONE_SHUFFLE = 0;
+ HASH_SHUFFLE = 1;
+ RANGE_SHUFFLE = 2;
+}
+
+enum TransmitType {
+ PUSH_TRANSMIT = 0;
+ PULL_TRANSMIT = 1;
+ FILE_WRITE = 2;
+}
+
+message DataChannelProto {
+ required ExecutionBlockIdProto srcId = 1;
+ required ExecutionBlockIdProto targetId = 2;
+
+ required TransmitType transmitType = 3 [default = PULL_TRANSMIT];
+ required ShuffleType shuffleType = 4;
+
+ optional SchemaProto schema = 5;
+
+ repeated ColumnProto shuffleKeys = 7;
+ optional int32 numOutputs = 9 [default = 1];
+
+ optional StoreType storeType = 10 [default = CSV];
+}
+
+message RunExecutionBlockRequestProto {
+ required string executionBlockId = 1;
+ required string queryMasterHost = 2;
+ required int32 queryMasterPort = 3;
+ required string nodeId = 4;
+ required string containerId = 5;
+ optional string queryOutputPath = 6;
+}
+
+service TajoWorkerProtocolService {
+ rpc ping (QueryUnitAttemptIdProto) returns (BoolProto);
+
+ // from QueryMaster(Worker)
+ rpc executeExecutionBlock(RunExecutionBlockRequestProto) returns (BoolProto);
+ rpc killTaskAttempt(QueryUnitAttemptIdProto) returns (BoolProto);
+ rpc cleanup(QueryIdProto) returns (BoolProto);
+}
+
+message EnforceProperty {
+ enum EnforceType {
+ SORTED_INPUT = 0;
+ OUTPUT_DISTINCT = 1;
+ GROUP_BY = 2;
+ JOIN = 3;
+ SORT = 4;
+ BROADCAST = 5;
+ COLUMN_PARTITION = 6;
+ }
+
+ // Identifies which field is filled in.
+ required EnforceType type = 1;
+
+ // One of the following will be filled in.
+ optional SortedInputEnforce sortedInput = 2;
+ optional OutputDistinctEnforce outputDistinct = 3;
+ optional GroupbyEnforce groupby = 4;
+ optional JoinEnforce join = 5;
+ optional SortEnforce sort = 6;
+ optional BroadcastEnforce broadcast = 7;
+ optional ColumnPartitionEnforcer columnPartition = 8;
+}
+
+message SortedInputEnforce {
+ required string tableName = 1;
+ repeated SortSpecProto sortSpecs = 2;
+}
+
+message OutputDistinctEnforce {
+}
+
+message JoinEnforce {
+ enum JoinAlgorithm {
+ NESTED_LOOP_JOIN = 0;
+ BLOCK_NESTED_LOOP_JOIN = 1;
+ IN_MEMORY_HASH_JOIN = 2;
+ HYBRID_HASH_JOIN = 3;
+ MERGE_JOIN = 4;
+ }
+
+ required int32 pid = 1;
+ required JoinAlgorithm algorithm = 2;
+}
+
+message GroupbyEnforce {
+ enum GroupbyAlgorithm {
+ HASH_AGGREGATION = 0;
+ SORT_AGGREGATION = 1;
+ }
+
+ required int32 pid = 1;
+ required GroupbyAlgorithm algorithm = 2;
+ repeated SortSpecProto sortSpecs = 3;
+}
+
+message SortEnforce {
+ enum SortAlgorithm {
+ IN_MEMORY_SORT = 0;
+ MERGE_SORT = 1;
+ }
+
+ required int32 pid = 1;
+ required SortAlgorithm algorithm = 2;
+}
+
+message BroadcastEnforce {
+ required string tableName = 1;
+}
+
+message ColumnPartitionEnforcer {
+ enum ColumnPartitionAlgorithm {
+ HASH_PARTITION = 0;
+ SORT_PARTITION = 1;
+ }
+
+ required int32 pid = 1;
+ required ColumnPartitionAlgorithm algorithm = 2;
+}
+
+message EnforcerProto {
+ repeated EnforceProperty properties = 1;
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/catalog-default.xml
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/catalog-default.xml b/tajo-core/src/main/resources/catalog-default.xml
new file mode 100644
index 0000000..7d37dff
--- /dev/null
+++ b/tajo-core/src/main/resources/catalog-default.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+
+<!--
+ 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.
+ -->
+
+<configuration>
+ <property>
+ <name>tajo.catalog.store.class</name>
+ <value>org.apache.tajo.catalog.store.DerbyStore</value>
+ </property>
+
+ <property>
+ <name>tajo.catalog.uri</name>
+ <value>jdbc:derby:/tmp/tajo-catalog-${user.name}/db;create=true</value>
+ </property>
+</configuration>
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/log4j.properties b/tajo-core/src/main/resources/log4j.properties
new file mode 100644
index 0000000..007c8f5
--- /dev/null
+++ b/tajo-core/src/main/resources/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=INFO
+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/main/resources/tajo-default.xml
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/tajo-default.xml b/tajo-core/src/main/resources/tajo-default.xml
new file mode 100644
index 0000000..c49e8e5
--- /dev/null
+++ b/tajo-core/src/main/resources/tajo-default.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+
+<!--
+ 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.
+ -->
+
+<configuration>
+ <property>
+ <name>tajo.worker.tmpdir.locations</name>
+ <value>/tmp/tajo-${user.name}/tmpdir</value>
+ </property>
+
+ <property>
+ <name>tajo.worker.mode.querymaster</name>
+ <value>true</value>
+ <description></description>
+ </property>
+
+ <property>
+ <name>tajo.worker.mode.taskrunner</name>
+ <value>true</value>
+ <description></description>
+ </property>
+
+ <property>
+ <name>tajo.querymaster.task-scheduler</name>
+ <value>org.apache.tajo.master.DefaultTaskScheduler</value>
+ </property>
+
+ <property>
+ <name>tajo.querymaster.lazy-task-scheduler.algorithm</name>
+ <value>org.apache.tajo.master.GreedyFragmentScheduleAlgorithm</value>
+ </property>
+
+</configuration>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/tajo-metrics.properties
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/tajo-metrics.properties b/tajo-core/src/main/resources/tajo-metrics.properties
new file mode 100644
index 0000000..4ae6a6c
--- /dev/null
+++ b/tajo-core/src/main/resources/tajo-metrics.properties
@@ -0,0 +1,75 @@
+##
+# 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.
+#
+
+###############################################################################
+# report definition
+# syntax: reporter.<name>=<class>
+reporter.null=org.apache.tajo.util.metrics.reporter.NullReporter
+reporter.file=org.apache.tajo.util.metrics.reporter.MetricsFileScheduledReporter
+reporter.console=org.apache.tajo.util.metrics.reporter.MetricsConsoleScheduledReporter
+reporter.ganglia=org.apache.tajo.util.metrics.reporter.GangliaReporter
+###############################################################################
+
+###############################################################################
+# syntax: <metrics group name>.reporters=<reporter name1>[,<reporter name2>,...]
+# syntax: <metrics group name>.<reporter name>.<options>=<value>
+###############################################################################
+
+###############################################################################
+# tajo master
+###############################################################################
+tajomaster.reporters=null
+
+#tajomaster.reporters=file,console
+#tajomaster.console.period=60
+#tajomaster.file.filename=/tmp/tajo/tajomaster-metrics.out
+#tajomaster.file.period=60
+#tajomaster.ganglia.server=my.ganglia.com
+#tajomaster.ganglia.port=8649
+#tajomaster.ganglia.period=60
+###############################################################################
+
+###############################################################################
+# tajo master-jvm
+###############################################################################
+tajomaster-jvm.reporters=null
+#tajomaster-jvm.reporters=console
+#tajomaster-jvm.console.period=60
+#tajomaster-jvm.file.filename=/tmp/tajo/tajomaster-jvm-metrics.out
+#tajomaster-jvm.file.period=60
+###############################################################################
+
+###############################################################################
+# worker
+###############################################################################
+worker.reporters=null
+#worker.reporters=file,console
+#worker.console.period=60
+#worker.file.filename=/tmp/tajo/worker-metrics.out
+#worker.file.period=60
+###############################################################################
+
+###############################################################################
+# worker-jvm
+###############################################################################
+worker-jvm.reporters=null
+#worker-jvm.reporters=console
+#worker-jvm.console.period=60
+#worker-jvm.file.filename=/tmp/tajo/worker-jvm-metrics.out
+#worker-jvm.file.period=60
+###############################################################################
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/admin/WEB-INF/jetty-web.xml
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/admin/WEB-INF/jetty-web.xml b/tajo-core/src/main/resources/webapps/admin/WEB-INF/jetty-web.xml
new file mode 100644
index 0000000..7221fbc
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/admin/WEB-INF/jetty-web.xml
@@ -0,0 +1,23 @@
+<?xml version="1.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.
+-->
+<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN"
+ "http://jetty.mortbay.org/configure.dtd">
+<Configure id="WebAppContext" class="org.mortbay.jetty.webapp.WebAppContext">
+ <Set name="maxFormContentSize" type="int">2147483647</Set>
+</Configure>
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/admin/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/admin/WEB-INF/web.xml b/tajo-core/src/main/resources/webapps/admin/WEB-INF/web.xml
new file mode 100644
index 0000000..dc7c62c
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/admin/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 Master</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/admin/catalogview.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/admin/catalogview.jsp b/tajo-core/src/main/resources/webapps/admin/catalogview.jsp
new file mode 100644
index 0000000..29fd05c
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/admin/catalogview.jsp
@@ -0,0 +1,166 @@
+<%
+ /*
+ * 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.catalog.CatalogService" %>
+<%@ page import="org.apache.tajo.catalog.Column" %>
+<%@ page import="org.apache.tajo.catalog.TableDesc" %>
+<%@ page import="org.apache.tajo.master.TajoMaster" %>
+<%@ page import="org.apache.tajo.util.FileUtil" %>
+<%@ page import="org.apache.tajo.webapp.StaticHttpServer" %>
+<%@ page import="java.util.Collection" %>
+<%@ page import="java.util.List" %>
+<%@ page import="java.util.Map" %>
+<%
+ TajoMaster master = (TajoMaster) StaticHttpServer.getInstance().getAttribute("tajo.info.server.object");
+ CatalogService catalog = master.getCatalog();
+
+ String catalogType = request.getParameter("type");
+ if(catalogType != null && "function".equals(catalogType)) {
+%>
+<script type="text/javascript">
+ document.location.href = 'functions.jsp';
+</script>
+ return;
+<%
+ }
+ String selectedDatabase = request.getParameter("database");
+ if(selectedDatabase == null || selectedDatabase.trim().isEmpty()) {
+ selectedDatabase = "default";
+ }
+
+ TableDesc tableDesc = null;
+ String selectedTable = request.getParameter("table");
+ if(selectedTable != null && !selectedTable.trim().isEmpty()) {
+ tableDesc = catalog.getTableDesc(selectedDatabase, selectedTable);
+ } else {
+ selectedTable = "";
+ }
+
+ //TODO filter with database
+ Collection<String> tableNames = catalog.getAllTableNames(selectedDatabase);
+%>
+
+<!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 Master: <%=master.getMasterName()%></h2>
+ <hr/>
+ <h3>Catalog</h3>
+ <div>
+ <div style='float:left; margin-right:10px'><a href='catalogview.jsp'>[Table]</a></div>
+ <div style='float:left; margin-right:10px'><a href='functions.jsp'>[Function]</a></div>
+ <div style='clear:both'></div>
+ </div>
+ <p/>
+ <table width="100%" border='0'>
+ <tr>
+ <!-- left -->
+ <td width="20%" valign="top">
+ <div>
+ <b>Database:</b>
+ <select width="190" style="width: 190px" onchange="document.location.href='catalogview.jsp?database=' + this.value">
+ <%
+ for (String databaseName : catalog.getAllDatabaseNames()) {
+ if (selectedDatabase.equals(databaseName)) { %>
+ <option value="<%=databaseName%>" selected><%=databaseName%>
+ <%} else {%>
+ <option value="<%=databaseName%>"><%=databaseName%></option>
+ <%}
+ }
+ %>
+ </select>
+ </div>
+ <!-- table list -->
+ <div style='margin-top:5px'>
+<%
+ if(tableNames == null || tableNames.isEmpty()) {
+ out.write("No tables");
+ } else {
+%>
+ <table width="100%" border="1" class="border_table">
+ <tr><th>Table Name</th></tr>
+<%
+ for(String eachTableName: tableNames) {
+ String bold = "";
+ if(eachTableName.equals(selectedTable)) {
+ bold = "font-weight:bold";
+ }
+ String detailLink = "catalogview.jsp?database=" + selectedDatabase + "&table=" + eachTableName;
+ out.write("<tr><td><span style='" + bold + "'><a href='" + detailLink + "'>" + eachTableName + "</a></span></td></tr>");
+ }
+%>
+ </table>
+<%
+ }
+%>
+ </div>
+ </td>
+ <!-- right -->
+ <td width="80%" valign="top">
+ <div style='margin-left: 15px'>
+ <div style='font-weight:bold'>Table name: <%=selectedTable%></div>
+ <div style='margin-top:5px'>
+<%
+ if(tableDesc != null) {
+ List<Column> columns = tableDesc.getSchema().getColumns();
+ out.write("<table border='1' class='border_table'><tr><th>No</th><th>Column name</th><th>Type</th></tr>");
+ int columnIndex = 1;
+ for(Column eachColumn: columns) {
+ out.write("<tr><td width='30' align='right'>" + columnIndex + "</td><td width='320'>" + eachColumn.getSimpleName() + "</td><td width='150'>" + eachColumn.getDataType().getType() + "</td></tr>");
+ columnIndex++;
+ }
+
+ String optionStr = "";
+ String prefix = "";
+ for(Map.Entry<String, String> entry: tableDesc.getMeta().toMap().entrySet()) {
+ optionStr += prefix + "'" + entry.getKey() + "'='" + entry.getValue() + "'";
+ prefix = "<br/>";
+ }
+ out.write("</table>");
+%>
+ </div>
+ <div style='margin-top:10px'>
+ <div style=''>Detail</div>
+ <table border="1" class='border_table'>
+ <tr><td width='100'>Table path</td><td width='410'><%=tableDesc.getPath()%></td></tr>
+ <tr><td>Store type</td><td><%=tableDesc.getMeta().getStoreType()%></td></tr>
+ <tr><td># rows</td><td><%=(tableDesc.hasStats() ? ("" + tableDesc.getStats().getNumRows()) : "-")%></td></tr>
+ <tr><td>Volume</td><td><%=(tableDesc.hasStats() ? FileUtil.humanReadableByteCount(tableDesc.getStats().getNumBytes(),true) : "-")%></td></tr>
+ <tr><td>Options</td><td><%=optionStr%></td></tr>
+ </table>
+ </div>
+ </div>
+<%
+ }
+%>
+ </td>
+ </tr>
+ </table>
+</div>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/admin/cluster.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/admin/cluster.jsp b/tajo-core/src/main/resources/webapps/admin/cluster.jsp
new file mode 100644
index 0000000..f454c66
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/admin/cluster.jsp
@@ -0,0 +1,216 @@
+<%
+ /*
+ * 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.master.*" %>
+<%@ page import="org.apache.tajo.master.rm.*" %>
+<%@ page import="org.apache.tajo.util.JSPUtil" %>
+<%@ page import="org.apache.tajo.webapp.StaticHttpServer" %>
+<%@ page import="java.util.*" %>
+
+<%
+ TajoMaster master = (TajoMaster) StaticHttpServer.getInstance().getAttribute("tajo.info.server.object");
+ Map<String, Worker> workers = master.getContext().getResourceManager().getWorkers();
+ List<String> wokerKeys = new ArrayList<String>(workers.keySet());
+ Collections.sort(wokerKeys);
+
+ int runningQueryMasterTasks = 0;
+
+ Set<Worker> liveWorkers = new TreeSet<Worker>();
+ Set<Worker> deadWorkers = new TreeSet<Worker>();
+ Set<Worker> decommissionWorkers = new TreeSet<Worker>();
+
+ Set<Worker> liveQueryMasters = new TreeSet<Worker>();
+ Set<Worker> deadQueryMasters = new TreeSet<Worker>();
+
+ for(Worker eachWorker: workers.values()) {
+ if(eachWorker.getResource().isQueryMasterMode()) {
+ liveQueryMasters.add(eachWorker);
+ runningQueryMasterTasks += eachWorker.getResource().getNumQueryMasterTasks();
+ }
+
+ if(eachWorker.getResource().isTaskRunnerMode()) {
+ liveWorkers.add(eachWorker);
+ }
+ }
+
+ for (Worker inactiveWorker : master.getContext().getResourceManager().getInactiveWorkers().values()) {
+ WorkerState state = inactiveWorker.getState();
+
+ if (state == WorkerState.LOST) {
+ if (inactiveWorker.getResource().isQueryMasterMode()) {
+ deadQueryMasters.add(inactiveWorker);
+ }
+ if (inactiveWorker.getResource().isTaskRunnerMode()) {
+ deadWorkers.add(inactiveWorker);
+ }
+ } else if (state == WorkerState.DECOMMISSIONED) {
+ decommissionWorkers.add(inactiveWorker);
+ }
+ }
+
+ String deadWorkersHtml = deadWorkers.isEmpty() ? "0": "<font color='red'>" + deadWorkers.size() + "</font>";
+ String deadQueryMastersHtml = deadQueryMasters.isEmpty() ? "0": "<font color='red'>" + deadQueryMasters.size() + "</font>";
+%>
+
+<!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 Master: <%=master.getMasterName()%></h2>
+ <hr/>
+ <h2>Query Master</h2>
+ <div>Live:<%=liveQueryMasters.size()%>, Dead: <%=deadQueryMastersHtml%>, QueryMaster Tasks: <%=runningQueryMasterTasks%></div>
+ <h3>Live QueryMasters</h3>
+<%
+ if(liveQueryMasters.isEmpty()) {
+ out.write("No Live QueryMasters\n");
+ } else {
+%>
+ <table width="100%" class="border_table" border="1">
+ <tr><th>No</th><th>QueryMaster</th><th>Client Port</th><th>Running Query</th><th>Heap(free/total/max)</th><th>Heartbeat</th><th>Status</th></tr>
+
+<%
+ int no = 1;
+ for(Worker queryMaster: liveQueryMasters) {
+ WorkerResource resource = queryMaster.getResource();
+ String queryMasterHttp = "http://" + queryMaster.getHostName() + ":" + queryMaster.getHttpPort() + "/index.jsp";
+%>
+ <tr>
+ <td width='30' align='right'><%=no++%></td>
+ <td><a href='<%=queryMasterHttp%>'><%=queryMaster.getHostName() + ":" + queryMaster.getQueryMasterPort()%></a></td>
+ <td width='100' align='center'><%=queryMaster.getClientPort()%></td>
+ <td width='200' align='right'><%=resource.getNumQueryMasterTasks()%></td>
+ <td width='200' align='center'><%=resource.getFreeHeap()/1024/1024%>/<%=resource.getTotalHeap()/1024/1024%>/<%=resource.getMaxHeap()/1024/1024%> MB</td>
+ <td width='100' align='right'><%=JSPUtil.getElapsedTime(queryMaster.getLastHeartbeatTime(), System.currentTimeMillis())%></td>
+ <td width='100' align='center'><%=queryMaster.getState()%></td>
+ </tr>
+<%
+ } //end fo for
+%>
+ </table>
+<%
+ } //end of if
+%>
+
+ <p/>
+
+<%
+ if(!deadQueryMasters.isEmpty()) {
+%>
+ <hr/>
+ <h3>Dead QueryMaster</h3>
+ <table width="300" class="border_table" border="1">
+ <tr><th>No</th><th>QueryMaster</th>
+<%
+ int no = 1;
+ for(Worker queryMaster: deadQueryMasters) {
+%>
+ <tr>
+ <td width='30' align='right'><%=no++%></td>
+ <td><%=queryMaster.getHostName() + ":" + queryMaster.getQueryMasterPort()%></td>
+ </tr>
+<%
+ } //end fo for
+%>
+ </table>
+ <p/>
+<%
+ } //end of if
+%>
+
+ <hr/>
+ <h2>Worker</h2>
+ <div>Live:<%=liveWorkers.size()%>, Dead: <%=deadWorkersHtml%></div>
+ <hr/>
+ <h3>Live Workers</h3>
+<%
+ if(liveWorkers.isEmpty()) {
+ out.write("No Live Workers\n");
+ } else {
+%>
+ <table width="100%" class="border_table" border="1">
+ <tr><th>No</th><th>Worker</th><th>PullServer<br/>Port</th><th>Running Tasks</th><th>Memory Resource<br/>(used/total)</th><th>Disk Resource<br/>(used/total)</th><th>Heap<br/>(free/total/max)</th><th>Heartbeat</th><th>Status</th></tr>
+<%
+ int no = 1;
+ for(Worker worker: liveWorkers) {
+ WorkerResource resource = worker.getResource();
+ String workerHttp = "http://" + worker.getHostName() + ":" + worker.getHttpPort() + "/index.jsp";
+%>
+ <tr>
+ <td width='30' align='right'><%=no++%></td>
+ <td><a href='<%=workerHttp%>'><%=worker.getHostName() + ":" + worker.getPeerRpcPort()%></a></td>
+ <td width='80' align='center'><%=worker.getPullServerPort()%></td>
+ <td width='100' align='right'><%=resource.getNumRunningTasks()%></td>
+ <td width='150' align='center'><%=resource.getUsedMemoryMB()%>/<%=resource.getMemoryMB()%></td>
+ <td width='100' align='center'><%=resource.getUsedDiskSlots()%>/<%=resource.getDiskSlots()%></td>
+ <td width='200' align='center'><%=resource.getFreeHeap()/1024/1024%>/<%=resource.getTotalHeap()/1024/1024%>/<%=resource.getMaxHeap()/1024/1024%> MB</td>
+ <td width='100' align='right'><%=JSPUtil.getElapsedTime(worker.getLastHeartbeatTime(), System.currentTimeMillis())%></td>
+ <td width='100' align='center'><%=worker.getState()%></td>
+ </tr>
+<%
+ } //end fo for
+%>
+ </table>
+<%
+ } //end of if
+%>
+
+ <p/>
+ <hr/>
+ <p/>
+ <h3>Dead Workers</h3>
+
+<%
+ if(deadWorkers.isEmpty()) {
+%>
+ No Dead Workers
+<%
+ } else {
+%>
+ <table width="300" class="border_table" border="1">
+ <tr><th>No</th><th>Worker</th></tr>
+<%
+ int no = 1;
+ for(Worker worker: deadWorkers) {
+ WorkerResource resource = worker.getResource();
+%>
+ <tr>
+ <td width='30' align='right'><%=no++%></td>
+ <td><%=worker.getHostName() + ":" + worker.getPeerRpcPort()%></td>
+ </tr>
+<%
+ } //end fo for
+%>
+ </table>
+<%
+ } //end of if
+%>
+</div>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/admin/conf.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/admin/conf.jsp b/tajo-core/src/main/resources/webapps/admin/conf.jsp
new file mode 100644
index 0000000..80073d9
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/admin/conf.jsp
@@ -0,0 +1,56 @@
+<%
+ /*
+ * 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.master.*" %>
+<%@ page import="org.apache.tajo.conf.*" %>
+<%@ page import="java.util.Map" %>
+
+<%
+ TajoMaster master = (TajoMaster) StaticHttpServer.getInstance().getAttribute("tajo.info.server.object");
+ TajoMaster.MasterContext context = master.getContext();
+ TajoConf tajoConf = context.getConf();
+%>
+
+<!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 Master: <%=master.getMasterName()%></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/admin/env.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/admin/env.jsp b/tajo-core/src/main/resources/webapps/admin/env.jsp
new file mode 100644
index 0000000..34965fc
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/admin/env.jsp
@@ -0,0 +1,67 @@
+<%
+ /*
+ * 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.master.*" %>
+<%@ page import="java.util.Map" %>
+
+<%
+ TajoMaster master = (TajoMaster) 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</title>
+</head>
+<body>
+<%@ include file="header.jsp"%>
+<div class='contents'>
+ <h2>Tajo Master: <%=master.getMasterName()%></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/admin/functions.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/admin/functions.jsp b/tajo-core/src/main/resources/webapps/admin/functions.jsp
new file mode 100644
index 0000000..68e127b
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/admin/functions.jsp
@@ -0,0 +1,77 @@
+<%
+ /*
+ * 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.master.*" %>
+<%@ page import="org.apache.tajo.catalog.*" %>
+<%@ page import="org.apache.hadoop.http.HtmlQuoting" %>
+<%@ page import="org.apache.tajo.util.JSPUtil" %>
+<%
+ TajoMaster master = (TajoMaster) StaticHttpServer.getInstance().getAttribute("tajo.info.server.object");
+ CatalogService catalog = master.getCatalog();
+
+ List<FunctionDesc> functions = new ArrayList<FunctionDesc>(catalog.getFunctions());
+ JSPUtil.sortFunctionDesc(functions);
+%>
+
+<!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 Master: <%=master.getMasterName()%></h2>
+ <hr/>
+ <h3>Catalog</h3>
+ <div>
+ <div style='float:left; margin-right:10px'><a href='catalogview.jsp'>[Table]</a></div>
+ <div style='float:left; margin-right:10px'><a href='functions.jsp'>[Function]</a></div>
+ <div style='clear:both'></div>
+ </div>
+ <p/>
+ <table border="1" class='border_table'>
+ <tr><th width='5%'>Name</th><th width='20%'>Signature</th><th width="5%">Type</th><th width='40%'>Description</th><th>Example</th></tr>
+<%
+ for(FunctionDesc eachFunction: functions) {
+ String fullDecription = eachFunction.getDescription();
+ if(eachFunction.getDetail() != null && !eachFunction.getDetail().isEmpty()) {
+ fullDecription += "\n" + eachFunction.getDetail();
+ }
+%>
+ <tr>
+ <td><%=eachFunction.getSignature()%></td>
+ <td><%=eachFunction.getHelpSignature()%></td>
+ <td><%=eachFunction.getFuncType()%></td>
+ <td><%=HtmlQuoting.quoteHtmlChars(fullDecription).replace("\n", "<br/>")%></td>
+ <td><%=HtmlQuoting.quoteHtmlChars(eachFunction.getExample()).replace("\n", "<br/>")%></td>
+ </tr>
+<%
+ }
+%>
+ </table>
+</div>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/admin/getCSV.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/admin/getCSV.jsp b/tajo-core/src/main/resources/webapps/admin/getCSV.jsp
new file mode 100644
index 0000000..f398304
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/admin/getCSV.jsp
@@ -0,0 +1,31 @@
+<%
+ /*
+ * 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 = "charset=utf-8" %>
+<%
+ response.setHeader("Content-Type", "application/octet-stream;");
+ response.setHeader("Content-Disposition", "attachment; filename=\"result.csv\";");
+ response.setHeader("Content-Description", "JSP Generated Data");
+ response.setHeader("cache-control", "no-cache");
+ response.setHeader("expires", "0");
+ response.setHeader("pragma", "no-cache");
+ out.print(request.getParameter("csvData"));
+ out.flush();
+%>
+
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/admin/header.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/admin/header.jsp b/tajo-core/src/main/resources/webapps/admin/header.jsp
new file mode 100644
index 0000000..f98c3d5
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/admin/header.jsp
@@ -0,0 +1,32 @@
+<%
+ /*
+ * 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"%>
+<div class="menu">
+ <div style='float:left; margin-left:12px; margin-top:6px;'><a href='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='index.jsp'>Home</a></li>
+ <li><a class='top_menu_item' href='cluster.jsp'>Cluster</a></li>
+ <li><a class='top_menu_item' href='query.jsp'>Query</a></li>
+ <li><a class='top_menu_item' href='catalogview.jsp'>Catalog</a></li>
+ <li><a class='top_menu_item' href='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/admin/index.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/admin/index.jsp b/tajo-core/src/main/resources/webapps/admin/index.jsp
new file mode 100644
index 0000000..ebd017d
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/admin/index.jsp
@@ -0,0 +1,184 @@
+<%
+ /*
+ * 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.hadoop.fs.FileSystem" %>
+<%@ page import="org.apache.tajo.conf.TajoConf" %>
+<%@ page import="org.apache.tajo.ipc.TajoMasterProtocol" %>
+<%@ page import="org.apache.tajo.master.TajoMaster" %>
+<%@ page import="org.apache.tajo.master.querymaster.QueryInProgress" %>
+<%@ page import="org.apache.tajo.master.rm.Worker" %>
+<%@ page import="org.apache.tajo.master.rm.WorkerState" %>
+<%@ page import="org.apache.tajo.util.NetUtils" %>
+<%@ page import="org.apache.tajo.webapp.StaticHttpServer" %>
+<%@ page import="java.util.Collection" %>
+<%@ page import="java.util.Date" %>
+<%@ page import="java.util.Map" %>
+
+<%
+ TajoMaster master = (TajoMaster) StaticHttpServer.getInstance().getAttribute("tajo.info.server.object");
+ Map<String, Worker> workers = master.getContext().getResourceManager().getWorkers();
+ Map<String, Worker> inactiveWorkers = master.getContext().getResourceManager().getInactiveWorkers();
+
+ int numWorkers = 0;
+ int numLiveWorkers = 0;
+ int numDeadWorkers = 0;
+ int numDecommissionWorkers = 0;
+
+ int numQueryMasters = 0;
+ int numLiveQueryMasters = 0;
+ int numDeadQueryMasters = 0;
+ int runningQueryMasterTask = 0;
+
+
+ TajoMasterProtocol.ClusterResourceSummary clusterResourceSummary =
+ master.getContext().getResourceManager().getClusterResourceSummary();
+
+ for(Worker eachWorker: workers.values()) {
+ if(eachWorker.getResource().isQueryMasterMode()) {
+ numQueryMasters++;
+ numLiveQueryMasters++;
+ runningQueryMasterTask += eachWorker.getResource().getNumQueryMasterTasks();
+ }
+ if(eachWorker.getResource().isTaskRunnerMode()) {
+ numWorkers++;
+ numLiveWorkers++;
+ }
+ }
+
+ for (Worker eachWorker : inactiveWorkers.values()) {
+ if (eachWorker.getState() == WorkerState.LOST) {
+ if(eachWorker.getResource().isQueryMasterMode()) {
+ numQueryMasters++;
+ numDeadQueryMasters++;
+ }
+ if(eachWorker.getResource().isTaskRunnerMode()) {
+ numWorkers++;
+ numDeadWorkers++;
+ }
+ } else if(eachWorker.getState() == WorkerState.DECOMMISSIONED) {
+ numDecommissionWorkers++;
+ }
+ }
+
+ String numDeadWorkersHtml = numDeadWorkers == 0 ? "0" : "<font color='red'>" + numDeadWorkers + "</font>";
+ String numDeadQueryMastersHtml = numDeadQueryMasters == 0 ? "0" : "<font color='red'>" + numDeadQueryMasters + "</font>";
+
+ Collection<QueryInProgress> runningQueries = master.getContext().getQueryJobManager().getRunningQueries();
+ Collection<QueryInProgress> finishedQueries = master.getContext().getQueryJobManager().getFinishedQueries();
+
+ int avgQueryTime = 0;
+ int minQueryTime = Integer.MAX_VALUE;
+ int maxQueryTime = 0;
+
+ long totalTime = 0;
+ for(QueryInProgress eachQuery: finishedQueries) {
+ int runTime = (int)(eachQuery.getQueryInfo().getFinishTime() == 0 ? -1 :
+ eachQuery.getQueryInfo().getFinishTime() - eachQuery.getQueryInfo().getStartTime());
+ if(runTime > 0) {
+ totalTime += runTime;
+
+ if(runTime < minQueryTime) {
+ minQueryTime = runTime;
+ }
+
+ if(runTime > maxQueryTime) {
+ maxQueryTime = runTime;
+ }
+ }
+ }
+
+ if(minQueryTime == Integer.MAX_VALUE) {
+ minQueryTime = 0;
+ }
+ if(finishedQueries.size() > 0) {
+ avgQueryTime = (int)(totalTime / (long)finishedQueries.size());
+ }
+%>
+
+<!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 Master: <%=master.getMasterName()%></h2>
+ <hr/>
+ <h3>Master Status</h3>
+ <table border='0'>
+ <tr><td width='150'>Version:</td><td><%=master.getVersion()%></td></tr>
+ <tr><td width='150'>Started:</td><td><%=new Date(master.getStartTime())%></td></tr>
+ <tr><td width='150'>File System:</td><td><%=master.getContext().getConf().get(FileSystem.FS_DEFAULT_NAME_KEY)%></td></tr>
+ <tr><td width='150'>Root dir:</td><td><%=TajoConf.getTajoRootDir(master.getContext().getConf())%></td></tr>
+ <tr><td width='150'>System dir:</td><td><%=TajoConf.getSystemDir(master.getContext().getConf())%></td></tr>
+ <tr><td width='150'>Warehouse dir:</td><td><%=TajoConf.getWarehouseDir(master.getContext().getConf())%></td></tr>
+ <tr><td width='150'>Staging dir:</td><td><%=TajoConf.getStagingDir(master.getContext().getConf())%></td></tr>
+ <tr><td width='150'>Client Service:</td><td><%=NetUtils.normalizeInetSocketAddress(master.getTajoMasterClientService().getBindAddress())%></td></tr>
+ <tr><td width='150'>Catalog Service:</td><td><%=master.getCatalogServer().getCatalogServerName()%></td></tr>
+ <tr><td width='150'>Heap(Free/Total/Max): </td><td><%=Runtime.getRuntime().freeMemory()/1024/1024%> MB / <%=Runtime.getRuntime().totalMemory()/1024/1024%> MB / <%=Runtime.getRuntime().maxMemory()/1024/1024%> MB</td>
+ <tr><td width='150'>Configuration:</td><td><a href='conf.jsp'>detail...</a></td></tr>
+ <tr><td width='150'>Environment:</td><td><a href='env.jsp'>detail...</a></td></tr>
+ <tr><td width='150'>Threads:</td><td><a href='thread.jsp'>thread dump...</a></tr>
+ </table>
+ <hr/>
+
+ <h3>Cluster Summary</h3>
+ <table width="100%" class="border_table" border="1">
+ <tr><th>Type</th><th>Total</th><th>Live</th><th>Dead</th><th>Running Master</th><th>Memory Resource<br/>(used/total)</th><th>Disk Resource<br/>(used/total)</th></tr>
+ <tr>
+ <td><a href='cluster.jsp'>Query Master</a></td>
+ <td align='right'><%=numQueryMasters%></td>
+ <td align='right'><%=numLiveQueryMasters%></td>
+ <td align='right'><%=numDeadQueryMastersHtml%></td>
+ <td align='right'><%=runningQueryMasterTask%></td>
+ <td align='center'>-</td>
+ <td align='center'>-</td>
+ </tr>
+ <tr>
+ <td><a href='cluster.jsp'>Worker</a></td>
+ <td align='right'><%=numWorkers%></td>
+ <td align='right'><%=numLiveWorkers%></td>
+ <td align='right'><%=numDeadWorkersHtml%></td>
+ <td align='right'>-</td>
+ <td align='center'><%=clusterResourceSummary.getTotalMemoryMB() - clusterResourceSummary.getTotalAvailableMemoryMB()%>/<%=clusterResourceSummary.getTotalMemoryMB()%></td>
+ <td align='center'><%=clusterResourceSummary.getTotalDiskSlots() - clusterResourceSummary.getTotalAvailableDiskSlots()%>/<%=clusterResourceSummary.getTotalDiskSlots()%></td>
+ </tr>
+ </table>
+ <p/>
+ <hr/>
+
+ <h3>Query Summary</h3>
+ <table width="100%" class="border_table" border="1">
+ <tr><th>Running Queries</th><th>Finished Queries</th><th>Average Execution Time</th><th>Min. Execution Time</th><th>Max. Execution Time</th></tr>
+ <tr>
+ <td align='right'><%=runningQueries.size()%></td>
+ <td align='right'><%=finishedQueries.size()%></td>
+ <td align='left'><%=avgQueryTime/1000%> sec</td>
+ <td align='left'><%=minQueryTime/1000%> sec</td>
+ <td align='left'><%=maxQueryTime/1000%> sec</td>
+ </tr>
+ </table>
+</div>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/admin/query.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/admin/query.jsp b/tajo-core/src/main/resources/webapps/admin/query.jsp
new file mode 100644
index 0000000..6f15a0e
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/admin/query.jsp
@@ -0,0 +1,137 @@
+<%
+ /*
+ * 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.TajoMaster" %>
+<%@ page import="org.apache.tajo.master.querymaster.QueryInProgress" %>
+<%@ page import="org.apache.tajo.master.rm.Worker" %>
+<%@ page import="org.apache.tajo.util.JSPUtil" %>
+<%@ page import="org.apache.tajo.util.StringUtils" %>
+<%@ page import="org.apache.tajo.webapp.StaticHttpServer" %>
+<%@ page import="java.text.SimpleDateFormat" %>
+<%@ page import="java.util.Collection" %>
+<%@ page import="java.util.HashMap" %>
+<%@ page import="java.util.List" %>
+<%@ page import="java.util.Map" %>
+
+<%
+ TajoMaster master = (TajoMaster) StaticHttpServer.getInstance().getAttribute("tajo.info.server.object");
+
+ List<QueryInProgress> runningQueries =
+ JSPUtil.sortQueryInProgress(master.getContext().getQueryJobManager().getRunningQueries(), true);
+
+ List<QueryInProgress> finishedQueries =
+ JSPUtil.sortQueryInProgress(master.getContext().getQueryJobManager().getFinishedQueries(), true);
+
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+ Map<String, Worker> workers = master.getContext().getResourceManager().getWorkers();
+ Map<String, Integer> portMap = new HashMap<String, Integer>();
+
+ Collection<String> queryMasters = master.getContext().getResourceManager().getQueryMasters();
+ if (queryMasters == null || queryMasters.isEmpty()) {
+ queryMasters = master.getContext().getResourceManager().getWorkers().keySet();
+ }
+ for(String eachQueryMasterKey: queryMasters) {
+ Worker queryMaster = workers.get(eachQueryMasterKey);
+ if(queryMaster != null) {
+ portMap.put(queryMaster.getHostName(), queryMaster.getHttpPort());
+ }
+ }
+%>
+
+<!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 Master: <%=master.getMasterName()%></h2>
+ <hr/>
+ <h3>Running Queries</h3>
+<%
+ if(runningQueries.isEmpty()) {
+ out.write("No running queries");
+ } else {
+%>
+ <table width="100%" border="1" class='border_table'>
+ <tr></tr><th>QueryId</th><th>Query Master</th><th>Started</th><th>Progress</th><th>Time</th><th>Status</th></th><th>sql</th></tr>
+ <%
+ for(QueryInProgress eachQuery: runningQueries) {
+ long time = System.currentTimeMillis() - eachQuery.getQueryInfo().getStartTime();
+ String detailView = "http://" + eachQuery.getQueryInfo().getQueryMasterHost() + ":" + portMap.get(eachQuery.getQueryInfo().getQueryMasterHost()) +
+ "/querydetail.jsp?queryId=" + eachQuery.getQueryId();
+ %>
+ <tr>
+ <td><a href='<%=detailView%>'><%=eachQuery.getQueryId()%></a></td>
+ <td><%=eachQuery.getQueryInfo().getQueryMasterHost()%></td>
+ <td><%=df.format(eachQuery.getQueryInfo().getStartTime())%></td>
+ <td><%=(int)(eachQuery.getQueryInfo().getProgress() * 100.0f)%>%</td>
+ <td><%=StringUtils.formatTime(time)%></td>
+ <td><%=eachQuery.getQueryInfo().getQueryState()%></td>
+ <td><%=eachQuery.getQueryInfo().getSql()%></td>
+ </tr>
+ <%
+ }
+ %>
+ </table>
+<%
+ }
+%>
+ <p/>
+ <hr/>
+ <h3>Finished Queries</h3>
+ <%
+ if(finishedQueries.isEmpty()) {
+ out.write("No finished queries");
+ } else {
+ %>
+ <table width="100%" border="1" class='border_table'>
+ <tr></tr><th>QueryId</th><th>Query Master</th><th>Started</th><th>Finished</th><th>Time</th><th>Status</th><th>sql</th></tr>
+ <%
+ for(QueryInProgress eachQuery: finishedQueries) {
+ long runTime = eachQuery.getQueryInfo().getFinishTime() > 0 ?
+ eachQuery.getQueryInfo().getFinishTime() - eachQuery.getQueryInfo().getStartTime() : -1;
+ String detailView = "http://" + eachQuery.getQueryInfo().getQueryMasterHost() + ":" + portMap.get(eachQuery.getQueryInfo().getQueryMasterHost()) +
+ "/querydetail.jsp?queryId=" + eachQuery.getQueryId();
+ %>
+ <tr>
+ <td><a href='<%=detailView%>'><%=eachQuery.getQueryId()%></a></td>
+ <td><%=eachQuery.getQueryInfo().getQueryMasterHost()%></td>
+ <td><%=df.format(eachQuery.getQueryInfo().getStartTime())%></td>
+ <td><%=eachQuery.getQueryInfo().getFinishTime() > 0 ? df.format(eachQuery.getQueryInfo().getFinishTime()) : "-"%></td>
+ <td><%=runTime == -1 ? "-" : StringUtils.formatTime(runTime) %></td>
+ <td><%=eachQuery.getQueryInfo().getQueryState()%></td>
+ <td><%=eachQuery.getQueryInfo().getSql()%></td>
+ </tr>
+ <%
+ }
+ %>
+ </table>
+<%
+ }
+%>
+</div>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/admin/query_executor.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/admin/query_executor.jsp b/tajo-core/src/main/resources/webapps/admin/query_executor.jsp
new file mode 100644
index 0000000..736b202
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/admin/query_executor.jsp
@@ -0,0 +1,312 @@
+<%
+ /*
+ * 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.TajoMaster" %>
+<%@ page import="org.apache.tajo.webapp.StaticHttpServer" %>
+
+<%
+ TajoMaster master = (TajoMaster) 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</title>
+<style type="text/css">
+ #progress_bar {
+ border:1px solid #000000;
+ background:#ffffff;
+ width:400px;
+ height:16px;
+ border-radius: 16px;
+ }
+ #progress_status {background:#fbcb46; width:0%; height:16px; border-radius: 10px; }
+</style>
+<script src="/static/js/jquery.js" type="text/javascript"></script>
+<script type="text/javascript">
+var progressInterval = 1000;
+var progressTimer = null;
+var queryRunnerId = null;
+var PRINT_LIMIT = 25;
+var SIZE_LIMIT = 104857600; // Limit size of displayed results.(Bytes)
+var pageNum = 0;
+var pageCount, storedColumns, storedData;
+
+$(document).ready(function() {
+ $('#btnSubmit').click(function() {
+ runQuery();
+ });
+});
+
+function init() {
+ $("#progress_status").css("width", "0%");
+ $("#progress_text").text("0%");
+ $("#queryStatus").html("");
+ $("#queryResult").html("");
+ queryRunnerId = null;
+}
+
+function runQuery() {
+ if(Math.ceil(Number($("#sizeLimit").val())) >= 2048) {
+ SIZE_LIMIT = 2048 * 1024 * 1024 - 1;
+ } else if(Math.ceil(Number($("#sizeLimit").val())) > 0) {
+ SIZE_LIMIT = Number($("#sizeLimit").val()) * 1024 * 1024;
+ }
+ if(Math.ceil(Number($("#printLimit").val())) > 0) {
+ PRINT_LIMIT = Number($("#printLimit").val());
+ }
+ if(progressTimer != null) {
+ alert("Already query running.");
+ return;
+ }
+ init();
+ var query = $("#query").val();
+
+ $.ajax({
+ type: "POST",
+ url: "query_exec",
+ data: { action: "runQuery", query: query, limitSize:SIZE_LIMIT }
+ })
+ .done(function(msg) {
+ var resultJson = $.parseJSON(msg);
+ if(resultJson.success == "false") {
+ clearTimer();
+ alert(resultJson.errorMessage);
+ return;
+ }
+ queryRunnerId = resultJson.queryRunnerId;
+ progressTimer = setInterval(function () {
+ $.ajax({
+ type: "GET",
+ url: "query_exec",
+ data: { action: "getQueryProgress", queryRunnerId: queryRunnerId }
+ })
+ .done(function( msg ) {
+ var resultJson = $.parseJSON(msg);
+ if(resultJson.success == "false") {
+ clearTimer();
+ alert(resultJson.errorMessage);
+ $("#queryStatus").html(getQueryStatusHtml(resultJson));
+ return;
+ }
+ var progress = parseInt(resultJson.progress, 0);
+ $("#progress_status").css("width", progress + "%");
+ $("#progress_text").text(progress + "%");
+ $("#queryStatus").html(getQueryStatusHtml(resultJson));
+ if(progress >= 100) {
+ clearTimer();
+ getResult();
+ }
+ });
+ }, progressInterval);
+ });
+}
+
+function clearTimer() {
+ if(progressTimer != null) {
+ clearInterval(progressTimer);
+ }
+ progressTimer = null;
+}
+
+function getQueryStatusHtml(status) {
+ if(status.success == "false") {
+ return "<div style='color:#ff0000; margin-top: 5px'>" + status.errorMessage + "</div>";
+ } else {
+ var statusHtml = "<div style='margin-top: 5px'>Start: " + status.startTime + "</div>";
+ statusHtml += "<div style='margin-top: 5px'>Finish: " + status.finishTime + "</div>";
+ statusHtml += "<div style='margin-top: 5px'> Running time: " + status.runningTime + "</div>";
+ return statusHtml;
+ }
+}
+
+function getResult() {
+ $.ajax({
+ type: "POST",
+ url: "query_exec",
+ data: { action: "getQueryResult", queryRunnerId: queryRunnerId }
+ })
+ .done(function(msg) {
+ var printedLine = 0;
+ var resultJson = $.parseJSON(msg);
+ if(resultJson.success == "false") {
+ alert(resultJson.errorMessage);
+ $("#queryStatus").html(getQueryStatusHtml(resultJson));
+ return;
+ }
+ $("#queryResult").html("");
+ var resultColumns = resultJson.resultColumns;
+ var resultData = resultJson.resultData;
+
+ storedColumns = resultColumns;
+ storedData = resultData;
+ pageCount = Math.ceil((storedData.length / PRINT_LIMIT)) - 1 ;
+
+ var resultTable = "<table width='100%' class='border_table'><tr>";
+ for(var i = 0; i < resultColumns.length; i++) {
+ resultTable += "<th>" + resultColumns[i] + "</th>";
+ }
+ resultTable += "</tr>";
+ for(var i = 0; i < resultData.length; i++) {
+ resultTable += "<tr>";
+ for(var j = 0; j < resultData[i].length; j++) {
+ resultTable += "<td>" + resultData[i][j] + "</td>";
+ }
+ resultTable += "</tr>";
+ if(++printedLine >= PRINT_LIMIT) break;
+ }
+ resultTable += "</table>";
+ $("#queryResult").html(resultTable);
+ $("#queryResultTools").html("");
+ $("#queryResultTools").append("<input type='button' value='Download to CSV' onclick='getCSV();'/> ");
+ $("#queryResultTools").append("<input type='button' value='Prev' onclick='getPrev();'/> ");
+ $("#queryResultTools").append("<input type='button' value='Next' onclick='getNext();'/> ");
+ var selectPage = "<select id='selectPage'>";
+ for(var i = 0; i <= pageCount; i++) {
+ selectPage += "<option value="+i+">"+(i+1)+"</option>";
+ }
+ selectPage += "</select>";
+ $("#queryResultTools").append(selectPage);
+ $("#selectPage").change(getSelectedPage);
+ })
+}
+
+function getCSV() {
+ var csvData = "";
+ var rowCount = storedData.length;
+ var colCount = storedColumns.length;
+ for(var colIndex = 0; colIndex < colCount; colIndex++) {
+ if(colIndex == 0) {
+ csvData += storedColumns[colIndex];
+ } else {
+ csvData += "," + storedColumns[colIndex];
+ }
+ }
+ csvData += "\n";
+ for(var rowIndex=0; rowIndex < rowCount; rowIndex++) {
+ for(var colIndex = 0; colIndex < colCount; colIndex++){
+ if(colIndex == 0) {
+ csvData += storedData[rowIndex][colIndex];
+ } else {
+ csvData += "," + storedData[rowIndex][colIndex];
+ }
+ }
+ csvData += "\n";
+ }
+ $("#csvData").val(csvData);
+ $("#dataForm").submit();
+}
+
+function getNext() {
+ var printedLine = 0;
+ if(pageCount > pageNum) {
+ pageNum++;
+ document.getElementById("selectPage").options.selectedIndex = pageNum;
+ }else {
+ alert("There's no next page.");
+ return;
+ }
+ getPage();
+}
+
+function getPrev() {
+ if(pageNum > 0 ) {
+ pageNum--;
+ document.getElementById("selectPage").options.selectedIndex = pageNum;
+ } else {
+ alert("There's no previous page.");
+ return;
+ }
+ getPage();
+}
+
+function getSelectedPage() {
+ if(pageNum >= 0 && pageNum <= pageCount ) {
+ pageNum = $("#selectPage option:selected").val();
+ } else {
+ alert("Out of range.");
+ return;
+ }
+ getPage();
+}
+
+function getPage() {
+ var printedLine = 0;
+ $("#queryResult").html("");
+ var resultTable = "<table width='100%' class='border_table'><tr>";
+ for(var i = 0; i < storedColumns.length; i++) {
+ resultTable += "<th>" + storedColumns[i] + "</th>";
+ }
+ resultTable += "</tr>";
+ for(var i = pageNum * PRINT_LIMIT; i < storedData.length; i++) {
+ resultTable += "<tr>";
+ for(var j = 0; j < storedData[i].length; j++) {
+ resultTable += "<td>" + storedData[i][j] + "</td>";
+ }
+ resultTable += "</tr>";
+ if(++printedLine >= PRINT_LIMIT) break;
+ }
+ resultTable += "</table>";
+ $("#queryResult").html(resultTable);
+}
+
+</script>
+</head>
+
+<body>
+<%@ include file="header.jsp"%>
+<div class='contents'>
+ <h2>Tajo Master: <%=master.getMasterName()%></h2>
+ <hr/>
+ <h3>Query</h3>
+ <textarea id="query" style="width:800px; height:250px; font-family:Tahoma; font-size:12px;"></textarea>
+ <p />
+ Limit : <input id="sizeLimit" type="text" value="10" style="width:30px; text-align:center;" /> MB
+ <p />
+ Rows/Page : <input id="printLimit" type="text" value="25" style="width:30px; text-align:center;" />
+ <hr />
+ <input id="btnSubmit" type="submit" value="Submit">
+ <hr/>
+ <div>
+ <div style="float:left; width:60px">Progress:</div>
+ <div style='float:left; margin-left:10px'>
+ <div id='progress_bar'>
+ <div id='progress_status'></div>
+ </div>
+ </div>
+ <div style='float:left; margin-left:10px;'>
+ <div id="progress_text" style='font-family:Tahoma; font-size:14px; color:#000000; font-weight:bold'>0%</div>
+ </div>
+ <div style='clear:both'></div>
+ </div>
+ <div id="queryStatus">
+ </div>
+ <hr/>
+ <h3>Query Result</h3>
+ <div id="queryResult"></div>
+ <hr/>
+ <div id="queryResultTools"></div>
+ <hr/>
+ <div style="dispaly:none;"><form name="dataForm" id="dataForm" method="post" action="getCSV.jsp"><input type="hidden" id="csvData" name="csvData" value="" /></div>
+</div>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/admin/thread.jsp
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/admin/thread.jsp b/tajo-core/src/main/resources/webapps/admin/thread.jsp
new file mode 100644
index 0000000..3eddef2
--- /dev/null
+++ b/tajo-core/src/main/resources/webapps/admin/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.master.*" %>
+
+<%
+ TajoMaster master = (TajoMaster) 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</title>
+</head>
+<body>
+<%@ include file="header.jsp"%>
+<div class='contents'>
+ <h2>Tajo Master: <%=master.getMasterName()%></h2>
+ <hr/>
+ <h3>Thread Dump</h3>
+ <pre><%master.dumpThread(out);%></pre>
+</div>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/static/img/logo_tajo.gif
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/static/img/logo_tajo.gif b/tajo-core/src/main/resources/webapps/static/img/logo_tajo.gif
new file mode 100644
index 0000000..13674e3
Binary files /dev/null and b/tajo-core/src/main/resources/webapps/static/img/logo_tajo.gif differ
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/static/img/on.jpg
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/static/img/on.jpg b/tajo-core/src/main/resources/webapps/static/img/on.jpg
new file mode 100644
index 0000000..dc96459
Binary files /dev/null and b/tajo-core/src/main/resources/webapps/static/img/on.jpg differ
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/static/img/tajo_logo.png
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/static/img/tajo_logo.png b/tajo-core/src/main/resources/webapps/static/img/tajo_logo.png
new file mode 100644
index 0000000..cfb10dd
Binary files /dev/null and b/tajo-core/src/main/resources/webapps/static/img/tajo_logo.png differ
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/static/img/tajochar.jpg
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/static/img/tajochar.jpg b/tajo-core/src/main/resources/webapps/static/img/tajochar.jpg
new file mode 100644
index 0000000..1dec9d0
Binary files /dev/null and b/tajo-core/src/main/resources/webapps/static/img/tajochar.jpg differ
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/static/img/tajochar_catalog_small.jpg
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/static/img/tajochar_catalog_small.jpg b/tajo-core/src/main/resources/webapps/static/img/tajochar_catalog_small.jpg
new file mode 100644
index 0000000..2a1cb1e
Binary files /dev/null and b/tajo-core/src/main/resources/webapps/static/img/tajochar_catalog_small.jpg differ
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/static/img/tajochar_little.jpg
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/static/img/tajochar_little.jpg b/tajo-core/src/main/resources/webapps/static/img/tajochar_little.jpg
new file mode 100644
index 0000000..f5c958f
Binary files /dev/null and b/tajo-core/src/main/resources/webapps/static/img/tajochar_little.jpg differ
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/static/img/tajochar_middle.jpg
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/static/img/tajochar_middle.jpg b/tajo-core/src/main/resources/webapps/static/img/tajochar_middle.jpg
new file mode 100644
index 0000000..3e39d9d
Binary files /dev/null and b/tajo-core/src/main/resources/webapps/static/img/tajochar_middle.jpg differ
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/static/img/tajochar_queries_small.jpg
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/static/img/tajochar_queries_small.jpg b/tajo-core/src/main/resources/webapps/static/img/tajochar_queries_small.jpg
new file mode 100644
index 0000000..ace30a4
Binary files /dev/null and b/tajo-core/src/main/resources/webapps/static/img/tajochar_queries_small.jpg differ
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/static/img/tajochar_small.jpg
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/static/img/tajochar_small.jpg b/tajo-core/src/main/resources/webapps/static/img/tajochar_small.jpg
new file mode 100644
index 0000000..ae5fda2
Binary files /dev/null and b/tajo-core/src/main/resources/webapps/static/img/tajochar_small.jpg differ
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/static/img/tajochar_title.jpg
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/static/img/tajochar_title.jpg b/tajo-core/src/main/resources/webapps/static/img/tajochar_title.jpg
new file mode 100644
index 0000000..7dcf45f
Binary files /dev/null and b/tajo-core/src/main/resources/webapps/static/img/tajochar_title.jpg differ
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/static/img/tajochar_title_small.jpg
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/static/img/tajochar_title_small.jpg b/tajo-core/src/main/resources/webapps/static/img/tajochar_title_small.jpg
new file mode 100644
index 0000000..f951f49
Binary files /dev/null and b/tajo-core/src/main/resources/webapps/static/img/tajochar_title_small.jpg differ
http://git-wip-us.apache.org/repos/asf/tajo/blob/6594ac1c/tajo-core/src/main/resources/webapps/static/img/tajochar_worker_small.jpg
----------------------------------------------------------------------
diff --git a/tajo-core/src/main/resources/webapps/static/img/tajochar_worker_small.jpg b/tajo-core/src/main/resources/webapps/static/img/tajochar_worker_small.jpg
new file mode 100644
index 0000000..8d883b6
Binary files /dev/null and b/tajo-core/src/main/resources/webapps/static/img/tajochar_worker_small.jpg differ