PHOENIX-2186 Creating backend services for the Phoenix Tracing Web App (Nishani)

Conflicts:
        pom.xml


Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/2f18fc82
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/2f18fc82
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/2f18fc82

Branch: refs/heads/master
Commit: 2f18fc821c6284a13de2878db27142e84b7bf9f0
Parents: 926bc72
Author: ayolajayamaha <raphaelan...@gmail.com>
Authored: Mon Jul 27 22:27:27 2015 +0530
Committer: Nick Dimiduk <ndimi...@apache.org>
Committed: Wed Sep 9 16:54:19 2015 -0700

----------------------------------------------------------------------
 bin/phoenix_utils.py                            |   8 +
 bin/traceserver.py                              | 188 +++++++++++++
 phoenix-tracing-webapp/README.md                |  15 +
 phoenix-tracing-webapp/pom.xml                  | 122 ++++++++
 .../src/build/trace-server-runnable.xml         |  60 ++++
 .../src/main/config/checkstyle/checker.xml      | 281 +++++++++++++++++++
 .../src/main/config/checkstyle/header.txt       |  16 ++
 .../src/main/config/checkstyle/suppressions.xml |  46 +++
 .../tracingwebapp/http/ConnectionFactory.java   |  43 +++
 .../tracingwebapp/http/EntityFactory.java       | 101 +++++++
 .../apache/phoenix/tracingwebapp/http/Main.java |  81 ++++++
 .../tracingwebapp/http/TraceServlet.java        | 152 ++++++++++
 .../src/main/webapp/WEB-INF/web.xml             |  15 +
 .../src/main/webapp/index.html                  |  16 ++
 pom.xml                                         |   2 +
 15 files changed, 1146 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f18fc82/bin/phoenix_utils.py
----------------------------------------------------------------------
diff --git a/bin/phoenix_utils.py b/bin/phoenix_utils.py
index bfb4737..13dd360 100755
--- a/bin/phoenix_utils.py
+++ b/bin/phoenix_utils.py
@@ -56,6 +56,7 @@ def setPath():
     PHOENIX_CLIENT_JAR_PATTERN = "phoenix-*-client.jar"
     PHOENIX_THIN_CLIENT_JAR_PATTERN = "phoenix-*-thin-client.jar"
     PHOENIX_QUERYSERVER_JAR_PATTERN = "phoenix-server-*-runnable.jar"
+    PHOENIX_TRACESERVER_JAR_PATTERN = "phoenix-tracing-webapp-*-runnable.jar"
     PHOENIX_TESTS_JAR_PATTERN = "phoenix-core-*-tests*.jar"
 
     # Backward support old env variable PHOENIX_LIB_DIR replaced by 
PHOENIX_CLASS_PATH
@@ -119,6 +120,13 @@ def setPath():
     if phoenix_queryserver_jar == "":
         phoenix_queryserver_jar = 
findFileInPathWithoutRecursion(PHOENIX_QUERYSERVER_JAR_PATTERN, 
os.path.join(current_dir, ".."))
 
+    global phoenix_traceserver_jar
+    phoenix_traceserver_jar = find(PHOENIX_TRACESERVER_JAR_PATTERN, 
os.path.join(current_dir, "..", "phoenix-tracing-webapp", "target", "*"))
+    if phoenix_traceserver_jar == "":
+        phoenix_traceserver_jar = 
findFileInPathWithoutRecursion(PHOENIX_TRACESERVER_JAR_PATTERN, 
os.path.join(current_dir, "..", "lib"))
+    if phoenix_traceserver_jar == "":
+        phoenix_traceserver_jar = 
findFileInPathWithoutRecursion(PHOENIX_TRACESERVER_JAR_PATTERN, 
os.path.join(current_dir, ".."))
+
 
     global phoenix_thin_client_jar
     phoenix_thin_client_jar = find(PHOENIX_THIN_CLIENT_JAR_PATTERN, 
os.path.join(current_dir, "..", "phoenix-server-client", "target", "*"))

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f18fc82/bin/traceserver.py
----------------------------------------------------------------------
diff --git a/bin/traceserver.py b/bin/traceserver.py
new file mode 100755
index 0000000..3d12193
--- /dev/null
+++ b/bin/traceserver.py
@@ -0,0 +1,188 @@
+#!/usr/bin/env python
+############################################################################
+#
+# 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.
+#
+############################################################################
+
+#
+# Script to handle launching the trace server process.
+#
+# usage: traceserver.py [start|stop]
+#
+
+import datetime
+import getpass
+import os
+import os.path
+import signal
+import subprocess
+import sys
+import tempfile
+
+try:
+    import daemon
+    daemon_supported = True
+except ImportError:
+    # daemon script not supported on some platforms (windows?)
+    daemon_supported = False
+
+import phoenix_utils
+
+phoenix_utils.setPath()
+
+command = None
+args = sys.argv
+
+if len(args) > 1:
+    if args[1] == 'start':
+        command = 'start'
+    elif args[1] == 'stop':
+        command = 'stop'
+if command:
+    args = args[2:]
+
+if os.name == 'nt':
+    args = subprocess.list2cmdline(args[1:])
+else:
+    import pipes    # pipes module isn't available on Windows
+    args = " ".join([pipes.quote(v) for v in args[1:]])
+
+# HBase configuration folder path (where hbase-site.xml reside) for
+# HBase/Phoenix client side property override
+hbase_config_path = phoenix_utils.hbase_conf_dir
+
+# default paths ## TODO: add windows support
+java_home = os.getenv('JAVA_HOME')
+hbase_pid_dir = os.path.join(tempfile.gettempdir(), 'phoenix')
+phoenix_log_dir = os.path.join(tempfile.gettempdir(), 'phoenix')
+phoenix_file_basename = 'phoenix-%s-traceserver' % getpass.getuser()
+phoenix_log_file = '%s.log' % phoenix_file_basename
+phoenix_out_file = '%s.out' % phoenix_file_basename
+phoenix_pid_file = '%s.pid' % phoenix_file_basename
+opts = os.getenv('PHOENIX_TRACESERVER_OPTS', '')
+
+# load hbase-env.??? to extract JAVA_HOME, HBASE_PID_DIR, HBASE_LOG_DIR
+hbase_env_path = None
+hbase_env_cmd  = None
+if os.name == 'posix':
+    hbase_env_path = os.path.join(hbase_config_path, 'hbase-env.sh')
+    hbase_env_cmd = ['bash', '-c', 'source %s && env' % hbase_env_path]
+elif os.name == 'nt':
+    hbase_env_path = os.path.join(hbase_config_path, 'hbase-env.cmd')
+    hbase_env_cmd = ['cmd.exe', '/c', 'call %s & set' % hbase_env_path]
+if not hbase_env_path or not hbase_env_cmd:
+    print >> sys.stderr, "hbase-env file unknown on platform %s" % os.name
+    sys.exit(-1)
+
+hbase_env = {}
+if os.path.isfile(hbase_env_path):
+    p = subprocess.Popen(hbase_env_cmd, stdout = subprocess.PIPE)
+    for x in p.stdout:
+        (k, _, v) = x.partition('=')
+        hbase_env[k.strip()] = v.strip()
+
+if hbase_env.has_key('JAVA_HOME'):
+    java_home = hbase_env['JAVA_HOME']
+if hbase_env.has_key('HBASE_PID_DIR'):
+    hbase_pid_dir = hbase_env['HBASE_PID_DIR']
+if hbase_env.has_key('HBASE_LOG_DIR'):
+    phoenix_log_dir = hbase_env['HBASE_LOG_DIR']
+if hbase_env.has_key('PHOENIX_TRACESERVER_OPTS'):
+    opts = hbase_env['PHOENIX_TRACESERVER_OPTS']
+
+log_file_path = os.path.join(phoenix_log_dir, phoenix_log_file)
+out_file_path = os.path.join(phoenix_log_dir, phoenix_out_file)
+pid_file_path = os.path.join(hbase_pid_dir, phoenix_pid_file)
+
+if java_home:
+    java = os.path.join(java_home, 'bin', 'java')
+else:
+    java = 'java'
+
+#    " -Xdebug -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n " 
+ \
+#    " -XX:+UnlockCommercialFeatures -XX:+FlightRecorder 
-XX:FlightRecorderOptions=defaultrecording=true,dumponexit=true" + \
+java_cmd = '%(java)s -cp ' + hbase_config_path + os.pathsep + 
phoenix_utils.phoenix_traceserver_jar + \
+    " -Dproc_phoenixtraceserver" + \
+    " -Dlog4j.configuration=file:" + os.path.join(phoenix_utils.current_dir, 
"log4j.properties") + \
+    " -Dpsql.root.logger=%(root_logger)s" + \
+    " -Dpsql.log.dir=%(log_dir)s" + \
+    " -Dpsql.log.file=%(log_file)s" + \
+    " " + opts + \
+    " org.apache.phoenix.tracingwebapp.http.Main " + args
+
+if command == 'start':
+    if not daemon_supported:
+        print >> sys.stderr, "daemon mode not supported on this platform"
+        sys.exit(-1)
+
+    # run in the background
+    d = os.path.dirname(out_file_path)
+    if not os.path.exists(d):
+        os.makedirs(d)
+    with open(out_file_path, 'a+') as out:
+        context = daemon.DaemonContext(
+            pidfile = daemon.PidFile(pid_file_path, 'Trace Server already 
running, PID file found: %s' % pid_file_path),
+            stdout = out,
+            stderr = out,
+        )
+        print 'starting Trace Server, logging to %s' % log_file_path
+        with context:
+            # this block is the main() for the forked daemon process
+            child = None
+            cmd = java_cmd % {'java': java, 'root_logger': 'INFO,DRFA', 
'log_dir': phoenix_log_dir, 'log_file': phoenix_log_file}
+
+            # notify the child when we're killed
+            def handler(signum, frame):
+                if child:
+                    child.send_signal(signum)
+                sys.exit(0)
+            signal.signal(signal.SIGTERM, handler)
+
+            print '%s launching %s' % (datetime.datetime.now(), cmd)
+            child = subprocess.Popen(cmd.split())
+            sys.exit(child.wait())
+
+elif command == 'stop':
+    if not daemon_supported:
+        print >> sys.stderr, "daemon mode not supported on this platform"
+        sys.exit(-1)
+
+    if not os.path.exists(pid_file_path):
+        print >> sys.stderr, "no Trace Server to stop because PID file not 
found, %s" % pid_file_path
+        sys.exit(0)
+
+    if not os.path.isfile(pid_file_path):
+        print >> sys.stderr, "PID path exists but is not a file! %s" % 
pid_file_path
+        sys.exit(1)
+
+    pid = None
+    with open(pid_file_path, 'r') as p:
+        pid = int(p.read())
+    if not pid:
+        sys.exit("cannot read PID file, %s" % pid_file_path)
+
+    print "stopping Trace Server pid %s" % pid
+    with open(out_file_path, 'a+') as out:
+        print >> out, "%s terminating Trace Server" % datetime.datetime.now()
+    os.kill(pid, signal.SIGTERM)
+
+else:
+    # run in the foreground using defaults from log4j.properties
+    cmd = java_cmd % {'java': java, 'root_logger': 'INFO,console', 'log_dir': 
'.', 'log_file': 'psql.log'}
+    child = subprocess.Popen(cmd.split())
+    sys.exit(child.wait())
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f18fc82/phoenix-tracing-webapp/README.md
----------------------------------------------------------------------
diff --git a/phoenix-tracing-webapp/README.md b/phoenix-tracing-webapp/README.md
new file mode 100755
index 0000000..d2af448
--- /dev/null
+++ b/phoenix-tracing-webapp/README.md
@@ -0,0 +1,15 @@
+# TracingWebApp
+1. Build the web application-
+ *mvn clean install*
+
+2. Start the TracingWebApp
+ *java -jar target/phoenix-tracing-webapp-4.5.0-SNAPSHOT-runnable.jar*
+
+3. View the Content -
+ *http://localhost:8864/webapp/#*
+
+ ###Note
+ You can set the port of the trace app by 
-Dphoenix.traceserver.http.port={portNo}
+
+ eg:
+ `-Dphoenix.traceserver.http.port=8887` server will start in 8887

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f18fc82/phoenix-tracing-webapp/pom.xml
----------------------------------------------------------------------
diff --git a/phoenix-tracing-webapp/pom.xml b/phoenix-tracing-webapp/pom.xml
new file mode 100755
index 0000000..a13bbc3
--- /dev/null
+++ b/phoenix-tracing-webapp/pom.xml
@@ -0,0 +1,122 @@
+<?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.
+
+-->
+
+  <project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+      <groupId>org.apache.phoenix</groupId>
+      <artifactId>phoenix</artifactId>
+      <version>4.6.0-HBase-1.1-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>phoenix-tracing-webapp</artifactId>
+    <name>Phoenix - Tracing Web Application</name>
+    <description>Tracing web application will visualize the phoenix 
traces</description>
+
+    <properties>
+       <top.dir>${project.basedir}/..</top.dir>
+    </properties>
+
+    <dependencies>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-server</artifactId>
+        <!-- TODO : pick the same jetty version throughout the project 
(PHOENIX-2211)-->
+        <version>${jettyVersion}</version>
+        <scope>provided</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-webapp</artifactId>
+        <!-- TODO : pick the same jetty version throughout the project 
(PHOENIX-2211)-->
+        <version>${jettyVersion}</version>
+        <scope>provided</scope>
+      </dependency>
+      <dependency>
+          <groupId>org.apache.hadoop</groupId>
+          <artifactId>hadoop-common</artifactId>
+          <scope>provided</scope>
+        </dependency>
+      <dependency>
+        <groupId>org.apache.phoenix</groupId>
+        <artifactId>phoenix-core</artifactId>
+        <scope>provided</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.hbase</groupId>
+        <artifactId>hbase-common</artifactId>
+        <scope>provided</scope>
+      </dependency>
+      <dependency>
+        <groupId>commons-logging</groupId>
+        <artifactId>commons-logging</artifactId>
+        <scope>provided</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.jackson</groupId>
+        <artifactId>jackson-core-asl</artifactId>
+        <scope>provided</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.jackson</groupId>
+        <artifactId>jackson-mapper-asl</artifactId>
+        <scope>provided</scope>
+      </dependency>
+    </dependencies>
+
+    <build>
+      <plugins>
+        <plugin>
+          <groupId>org.codehaus.mojo</groupId>
+          <artifactId>build-helper-maven-plugin</artifactId>
+        </plugin>
+        <plugin>
+          <artifactId>maven-assembly-plugin</artifactId>
+          <executions>
+            <execution>
+              <id>runnable</id>
+              <phase>package</phase>
+              <goals>
+                <goal>single</goal>
+              </goals>
+              <configuration>
+                <attach>true</attach>
+                <archive>
+                  <manifest>
+                    <addClasspath>true</addClasspath>
+                    
<mainClass>org.apache.phoenix.tracingwebapp.http.Main</mainClass>
+                  </manifest>
+                </archive>
+                <finalName>${project.artifactId}-${project.version}</finalName>
+                <descriptors>
+                  <descriptor>src/build/trace-server-runnable.xml</descriptor>
+                </descriptors>
+              </configuration>
+            </execution>
+          </executions>
+        </plugin>
+      </plugins>
+    </build>
+
+  </project>

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f18fc82/phoenix-tracing-webapp/src/build/trace-server-runnable.xml
----------------------------------------------------------------------
diff --git a/phoenix-tracing-webapp/src/build/trace-server-runnable.xml 
b/phoenix-tracing-webapp/src/build/trace-server-runnable.xml
new file mode 100755
index 0000000..21b3bde
--- /dev/null
+++ b/phoenix-tracing-webapp/src/build/trace-server-runnable.xml
@@ -0,0 +1,60 @@
+<?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.
+
+-->
+
+<assembly 
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0";
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+  
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0
 http://maven.apache.org/xsd/assembly-1.1.0.xsd";>
+  <id>runnable</id>
+  <formats>
+    <format>jar</format>
+  </formats>
+  <includeBaseDirectory>false</includeBaseDirectory>
+  <containerDescriptorHandlers>
+    <containerDescriptorHandler>
+      <!--
+          aggregate SPI's so that things like HDFS FileSystem works in uberjar
+          http://docs.oracle.com/javase/tutorial/sound/SPI-intro.html
+      -->
+      <handlerName>metaInf-services</handlerName>
+    </containerDescriptorHandler>
+  </containerDescriptorHandlers>
+  <dependencySets>
+    <dependencySet>
+      <outputDirectory>/</outputDirectory>
+      <useProjectArtifact>true</useProjectArtifact>
+      <unpack>true</unpack>
+      <scope>provided</scope>
+    </dependencySet>
+  </dependencySets>
+  <fileSets>
+    <fileSet>
+      <directory>src/main/webapp</directory>
+    </fileSet>
+  </fileSets>
+  <files>
+    <file>
+      <source>README.md</source>
+      <outputDirectory>/</outputDirectory>
+      <filtered>true</filtered>
+    </file>
+  </files>
+</assembly>

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f18fc82/phoenix-tracing-webapp/src/main/config/checkstyle/checker.xml
----------------------------------------------------------------------
diff --git a/phoenix-tracing-webapp/src/main/config/checkstyle/checker.xml 
b/phoenix-tracing-webapp/src/main/config/checkstyle/checker.xml
new file mode 100755
index 0000000..ecf3946
--- /dev/null
+++ b/phoenix-tracing-webapp/src/main/config/checkstyle/checker.xml
@@ -0,0 +1,281 @@
+<?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.
+-->
+
+<!--
+  This version of checkstyle is based on the Apache Calcite checkstyle
+  checkstyle configuration, which in turn is based on Giraph and Hadoop and
+  common-math configurations.
+
+  The documentation for checkstyle is available at
+
+  http://checkstyle.sourceforge.net
+-->
+
+<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.1//EN" 
"http://www.puppycrawl.com/dtds/configuration_1_1.dtd";>
+
+<!-- Calcite customization of default Checkstyle behavior -->
+<module name="Checker">
+  <property name="localeLanguage" value="en"/>
+
+  <!-- Checks for headers -->
+  <!-- See http://checkstyle.sf.net/config_header.html -->
+    <!-- Verify that EVERY source file has the appropriate license -->
+  <module name="Header">
+    <property name="headerFile" value="${checkstyle.header.file}"/>
+  </module>
+
+  <!-- Checks for Javadoc comments (checker).           -->
+  <!-- See http://checkstyle.sf.net/config_javadoc.html -->
+    <!-- Require package javadoc -->
+  <module name="JavadocPackage"/>
+
+  <!-- Miscellaneous other checks (checker).         -->
+  <!-- See http://checkstyle.sf.net/config_misc.html -->
+    <!-- Require files to end with newline characters -->
+  <module name="NewlineAtEndOfFile">
+    <property name="lineSeparator" value="lf"/>
+  </module>
+
+  <!-- Checks for whitespace (tree walker)                 -->
+  <!-- See http://checkstyle.sf.net/config_whitespace.html -->
+    <!-- No tabs allowed! -->
+  <module name="FileTabCharacter"/>
+
+  <module name="TreeWalker">
+    <property name="cacheFile" value="target/checkstyle-cachefile"/>
+
+    <!-- Checks for blocks. You know, those {}'s         -->
+    <!-- See http://checkstyle.sf.net/config_blocks.html -->
+      <!-- No empty blocks (i.e. catch); must contain at least a comment -->
+    <module name="EmptyBlock">
+      <property name="option" value="text"/>
+    </module>
+    <module name="AvoidNestedBlocks">
+        <property name="allowInSwitchCase" value="true"/>
+    </module>
+    <module name="LeftCurly"/>
+      <!-- No if/else/do/for/while without braces -->
+    <module name="NeedBraces"/>
+    <module name="RightCurly"/>
+
+    <!-- Checks for class design                         -->
+    <!-- See http://checkstyle.sf.net/config_design.html -->
+      <!-- Utility class should not be instantiated, they must have a
+          private constructor -->
+    <module name="HideUtilityClassConstructor"/>
+
+    <!-- Checks for common coding problems               -->
+    <!-- See http://checkstyle.sf.net/config_coding.html -->
+    <module name="EmptyStatement"/>
+      <!-- Require hash code override when equals is -->
+    <module name="EqualsHashCode"/>
+      <!-- Disallow unnecessary instantiation of Boolean, String -->
+    <module name="IllegalInstantiation">
+      <property name="classes" value="java.lang.Boolean, java.lang.String"/>
+    </module>
+      <!-- Switch statements should be complete and with independent cases -->
+    <module name="FallThrough"/>
+    <!-- For hadoop_yarn profile, some YARN exceptions aren't loading in 
checkstyle -->
+    <module name="RedundantThrows">
+        <property name="suppressLoadErrors" value="true" />
+    </module>
+    <module name="SimplifyBooleanExpression"/>
+    <module name="SimplifyBooleanReturn"/>
+      <!-- Only one statement per line allowed -->
+    <module name="OneStatementPerLine"/>
+      <!-- Don't add up parentheses when they are not required -->
+    <module name="UnnecessaryParentheses" />
+      <!-- Don't use = or != for string comparisons -->
+    <module name="StringLiteralEquality" />
+      <!-- Don't declare multiple variables in the same statement -->
+    <module name="MultipleVariableDeclarations" />
+      <!-- String literals more than one character long should not be
+          repeated several times -->
+      <!-- the "unchecked" string is also accepted to allow
+          @SuppressWarnings("unchecked") -->
+      <!-- Disabling for now until we have a better ignoreStringsRegexp -->
+      <!--
+    <module name="MultipleStringLiterals" >
+      <property name="ignoreStringsRegexp" 
value='^(("")|(".")|("unchecked"))$'/>
+    </module>
+      -->
+
+    <!-- Checks for imports                              -->
+    <!-- See http://checkstyle.sf.net/config_import.html -->
+    <module name="RedundantImport"/>
+      <!-- Import should be explicit, and only from pure java packages.
+           But we allow imports that are only used in javadoc. -->
+    <module name="UnusedImports">
+      <property name="processJavadoc" value="true"/>
+    </module>
+    <module name="IllegalImport" />
+    <module name="AvoidStarImport" />
+    <module name="ImportOrder">
+      <property name="groups" 
value="java,javax,lib,shared,common,platform,org,com,io,net,scala,clover"/>
+      <property name="ordered" value="true"/>
+      <property name="separated" value="true"/>
+      <property name="option" value="bottom"/>
+    </module>
+
+    <!-- Checks for Javadoc comments (tree walker).       -->
+    <!-- See http://checkstyle.sf.net/config_javadoc.html -->
+      <!-- Javadoc must be formatted correctly -->
+    <module name="JavadocStyle">
+      <property name="checkFirstSentence" value="false"/>
+    </module>
+      <!-- Must have class / interface header comments -->
+    <module name="JavadocType"/>
+
+    <!-- Miscellaneous other checks (tree walker).     -->
+    <!-- See http://checkstyle.sf.net/config_misc.html -->
+      <!-- Java style arrays -->
+    <module name="ArrayTypeStyle"/>
+      <!-- Indentation -->
+    <module name="Indentation">
+      <property name="caseIndent" value="0"/>
+      <property name="basicOffset" value="4"/>
+      <property name="braceAdjustment" value="0"/>
+    </module>
+      <!-- Turn this on to see what needs to be done
+    <module name="TodoComment"/>
+       -->
+    <module name="UpperEll"/>
+
+    <module name="OperatorWrap"/>
+
+    <!-- Modifier Checks                                    -->
+    <!-- See http://checkstyle.sf.net/config_modifiers.html -->
+      <!-- Use a consistent way to put modifiers -->
+    <module name="ModifierOrder"/>
+    <module name="RedundantModifier"/>
+
+    <!-- Checks for Naming Conventions.                  -->
+    <!-- See http://checkstyle.sf.net/config_naming.html -->
+      <!-- Constant names should obey the traditional all uppercase
+          naming convention -->
+    <module name="ConstantName"/>
+    <module name="LocalFinalVariableName">
+      <!-- Allow '_' except first. -->
+      <property name="format" value="^[a-z][a-zA-Z0-9_]*$"/>
+    </module>
+    <module name="LocalVariableName">
+      <!-- Allow '_' except first. -->
+      <property name="format" value="^[a-z][a-zA-Z0-9_]*$"/>
+    </module>
+    <module name="MemberName"/>
+    <module name="MethodName">
+      <!-- Allow trailing '_', signifying private methods.
+           Also allow '_' prefix, indicating disabled method or junit test. -->
+      <property name="format" value="^_?[a-z][a-zA-Z0-9]*_?$"/>
+    </module>
+    <module name="PackageName"/>
+    <module name="ParameterName">
+      <!-- Allow trailing '_'. -->
+      <property name="format" value="^[a-z][a-zA-Z0-9]*_?$"/>
+    </module>
+    <module name="StaticVariableName"/>
+    <module name="TypeName"/>
+
+    <!-- Checks for regexp expressions.                  -->
+    <!-- See http://checkstyle.sf.net/config_regexp.html -->
+
+    <!-- No trailing whitespace -->
+    <module name="Regexp">
+      <property name="format" value="[ \t]+$"/>
+      <property name="illegalPattern" value="true"/>
+      <property name="message" value="Trailing whitespace"/>
+    </module>
+
+    <!-- Authors should be in pom.xml file -->
+    <module name="Regexp">
+      <property name="format" value="@author"/>
+      <property name="illegalPattern" value="true"/>
+      <property name="message" value="developers names should be in pom file"/>
+    </module>
+
+    <!-- No multi-line C-style comments except at start of line. -->
+    <module name="Regexp">
+      <property name="format" value="^ +/\*[^*][^/]$"/>
+      <property name="illegalPattern" value="true"/>
+      <property name="message" value="C-style comment"/>
+    </module>
+
+    <module name="Regexp">
+      <property name="format" value="^ +/\*$"/>
+      <property name="illegalPattern" value="true"/>
+      <property name="message" value="C-style comment"/>
+    </module>
+
+    <!-- Checks for Size Violations.                    -->
+    <!-- See http://checkstyle.sf.net/config_sizes.html -->
+    <!-- Lines cannot exceed 100 chars, except if they are hyperlinks
+         or strings (possibly preceded by '+' and followed by say '),'. -->
+    <module name="LineLength">
+      <property name="max" value="100"/>
+      <property name="ignorePattern" 
value="^import|@see|@link|@BaseMessage|href|^[ +]*&quot;.*&quot;[);,]*$"/>
+    </module>
+      <!-- Over time, we will revise this down -->
+    <module name="MethodLength">
+      <property name="max" value="390"/>
+    </module>
+
+    <!-- Checks for whitespace (tree walker)                 -->
+    <!-- See http://checkstyle.sf.net/config_whitespace.html -->
+    <module name="EmptyForIteratorPad"/>
+      <!-- Spacing around methods -->
+    <module name="MethodParamPad">
+      <property name="option" value="nospace"/>
+      <property name="allowLineBreaks" value="true"/>
+     </module>
+      <!-- No whitespace before a token -->
+    <module name="NoWhitespaceBefore"/>
+      <!-- Whitespace after tokens is required -->
+    <module name="WhitespaceAfter"/>
+      <!-- Whitespace around tokens is required -->
+    <module name="WhitespaceAround">
+        <property name="allowEmptyConstructors" value="true"/>
+        <property name="allowEmptyMethods" value="true"/>
+    </module>
+    <module name="ParenPad"/>
+    <module name="TypecastParenPad"/>
+      <!-- No extra whitespace around types -->
+    <module name="GenericWhitespace"/>
+
+    <!-- Required for SuppressionCommentFilter below -->
+    <module name="FileContentsHolder"/>
+  </module>
+
+  <!-- Setup special comments to suppress specific checks from source files -->
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CHECKSTYLE\: stop ([\w\|]+)"/>
+    <property name="onCommentFormat"  value="CHECKSTYLE\: resume ([\w\|]+)"/>
+    <property name="checkFormat"      value="$1"/>
+  </module>
+
+  <!-- Turn off all checks between OFF and ON -->
+  <module name="SuppressionCommentFilter">
+    <property name="offCommentFormat" value="CHECKSTYLE\: OFF"/>
+    <property name="onCommentFormat"  value="CHECKSTYLE\: ON"/>
+  </module>
+
+  <!-- Turn off checks for the next N lines. -->
+  <module name="SuppressWithNearbyCommentFilter">
+    <property name="commentFormat" value="CHECKSTYLE: +IGNORE (\d+)"/>
+    <property name="influenceFormat" value="$1"/>
+  </module>
+</module>

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f18fc82/phoenix-tracing-webapp/src/main/config/checkstyle/header.txt
----------------------------------------------------------------------
diff --git a/phoenix-tracing-webapp/src/main/config/checkstyle/header.txt 
b/phoenix-tracing-webapp/src/main/config/checkstyle/header.txt
new file mode 100755
index 0000000..2a42971
--- /dev/null
+++ b/phoenix-tracing-webapp/src/main/config/checkstyle/header.txt
@@ -0,0 +1,16 @@
+/*
+ * 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.
+ */

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f18fc82/phoenix-tracing-webapp/src/main/config/checkstyle/suppressions.xml
----------------------------------------------------------------------
diff --git a/phoenix-tracing-webapp/src/main/config/checkstyle/suppressions.xml 
b/phoenix-tracing-webapp/src/main/config/checkstyle/suppressions.xml
new file mode 100755
index 0000000..6662eca
--- /dev/null
+++ b/phoenix-tracing-webapp/src/main/config/checkstyle/suppressions.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!DOCTYPE suppressions PUBLIC
+        "-//Puppy Crawl//DTD Suppressions 1.1//EN"
+        "http://www.puppycrawl.com/dtds/suppressions_1_1.dtd";>
+<!--
+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.
+-->
+<suppressions>
+  <!-- Suppress checks on generated files. -->
+  <suppress checks="Header" files="CalciteResource.properties"/>
+  <suppress checks=".*" files="org-apache-calcite-jdbc.properties"/>
+  <suppress checks=".*" files="Foo.java"/>
+  <suppress checks=".*" files=".*/target/maven-archiver/pom.properties"/>
+  <suppress checks=".*" files="git.properties"/>
+  <suppress checks=".*" files="trace.properties"/>
+  <suppress checks=".*" files="release.properties"/>
+
+  <!-- This file triggers https://github.com/checkstyle/checkstyle/issues/92,
+       through no fault of its own. -->
+  <suppress checks=".*" files="SqlSimpleParser.java"/>
+
+  <!-- Don't complain about field names such as cust_id -->
+  <suppress checks=".*Name" files="JdbcExample.java"/>
+
+  <!-- Suppress JavadocPackage in the test packages -->
+  <suppress checks="JavadocPackage" files="src[/\\]test[/\\]java[/\\]"/>
+
+  <!-- And likewise in ubenchmark -->
+  <suppress checks="JavadocPackage" files="StatementTest.java"/>
+
+  <!-- Method names in Resource can have underscores -->
+  <suppress checks="MethodName" files="CalciteResource.java"/>
+</suppressions>

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f18fc82/phoenix-tracing-webapp/src/main/java/org/apache/phoenix/tracingwebapp/http/ConnectionFactory.java
----------------------------------------------------------------------
diff --git 
a/phoenix-tracing-webapp/src/main/java/org/apache/phoenix/tracingwebapp/http/ConnectionFactory.java
 
b/phoenix-tracing-webapp/src/main/java/org/apache/phoenix/tracingwebapp/http/ConnectionFactory.java
new file mode 100644
index 0000000..b7a1df1
--- /dev/null
+++ 
b/phoenix-tracing-webapp/src/main/java/org/apache/phoenix/tracingwebapp/http/ConnectionFactory.java
@@ -0,0 +1,43 @@
+/*
+ * 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.phoenix.tracingwebapp.http;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+/**
+*
+* ConnectionFactory is to handle database connection
+*
+*/
+public class ConnectionFactory {
+
+  private static Connection con;
+  //TODO : need to get port and host from configuration
+  protected static String PHOENIX_HOST = "localhost";
+  protected static int PHOENIX_PORT = 2181;
+
+  public static Connection getConnection() throws SQLException, 
ClassNotFoundException {
+    if (con == null || con.isClosed()) {
+      Class.forName("org.apache.phoenix.jdbc.PhoenixDriver");
+      con = 
DriverManager.getConnection("jdbc:phoenix:"+PHOENIX_HOST+":"+PHOENIX_PORT);
+    }
+    return con;
+  }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f18fc82/phoenix-tracing-webapp/src/main/java/org/apache/phoenix/tracingwebapp/http/EntityFactory.java
----------------------------------------------------------------------
diff --git 
a/phoenix-tracing-webapp/src/main/java/org/apache/phoenix/tracingwebapp/http/EntityFactory.java
 
b/phoenix-tracing-webapp/src/main/java/org/apache/phoenix/tracingwebapp/http/EntityFactory.java
new file mode 100644
index 0000000..afb6312
--- /dev/null
+++ 
b/phoenix-tracing-webapp/src/main/java/org/apache/phoenix/tracingwebapp/http/EntityFactory.java
@@ -0,0 +1,101 @@
+/*
+ * 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.phoenix.tracingwebapp.http;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * EntityFactory is used to get results entities For SQL query
+ */
+public class EntityFactory {
+
+  private String queryString;
+  protected Connection connection;
+
+  public EntityFactory(Connection connection, String queryString) {
+    this.queryString = queryString;
+    this.connection = connection;
+  }
+
+  public Map<String, Object> findSingle(Object[] params) throws SQLException {
+    List<Map<String, Object>> objects = this.findMultiple(params);
+
+    if (objects.size() != 1) {
+      throw new SQLException("Query did not produce one object it produced: "
+          + objects.size() + " objects.");
+    }
+
+    Map<String, Object> object = objects.get(0); // get first record;
+
+    return object;
+  }
+
+  public List<Map<String, Object>> findMultiple(Object[] params)
+      throws SQLException {
+    ResultSet rs = null;
+    PreparedStatement ps = null;
+    try {
+      ps = this.connection.prepareStatement(this.queryString);
+      for (int i = 0; i < params.length; ++i) {
+        ps.setObject(1, params[i]);
+      }
+
+      rs = ps.executeQuery();
+      return getEntitiesFromResultSet(rs);
+    } catch (SQLException e) {
+      throw (e);
+    } finally {
+      if (rs != null) {
+        rs.close();
+      }
+      if (ps != null) {
+        ps.close();
+      }
+    }
+  }
+
+  protected static List<Map<String, Object>> getEntitiesFromResultSet(
+      ResultSet resultSet) throws SQLException {
+    ArrayList<Map<String, Object>> entities = new ArrayList<>();
+    while (resultSet.next()) {
+      entities.add(getEntityFromResultSet(resultSet));
+    }
+    return entities;
+  }
+
+  protected static Map<String, Object> getEntityFromResultSet(ResultSet 
resultSet)
+      throws SQLException {
+    ResultSetMetaData metaData = resultSet.getMetaData();
+    int columnCount = metaData.getColumnCount();
+    Map<String, Object> resultsMap = new HashMap<>();
+    for (int i = 1; i <= columnCount; ++i) {
+      String columnName = metaData.getColumnName(i).toLowerCase();
+      Object object = resultSet.getObject(i);
+      resultsMap.put(columnName, object);
+    }
+    return resultsMap;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f18fc82/phoenix-tracing-webapp/src/main/java/org/apache/phoenix/tracingwebapp/http/Main.java
----------------------------------------------------------------------
diff --git 
a/phoenix-tracing-webapp/src/main/java/org/apache/phoenix/tracingwebapp/http/Main.java
 
b/phoenix-tracing-webapp/src/main/java/org/apache/phoenix/tracingwebapp/http/Main.java
new file mode 100755
index 0000000..5875fc1
--- /dev/null
+++ 
b/phoenix-tracing-webapp/src/main/java/org/apache/phoenix/tracingwebapp/http/Main.java
@@ -0,0 +1,81 @@
+/*
+ * 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.phoenix.tracingwebapp.http;
+
+import java.net.URL;
+import java.security.ProtectionDomain;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configured;
+import org.apache.hadoop.hbase.HBaseConfiguration;
+import org.apache.hadoop.util.Tool;
+import org.apache.hadoop.util.ToolRunner;
+import org.apache.log4j.BasicConfigurator;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.webapp.WebAppContext;
+
+/**
+ * tracing web app runner
+ */
+public final class Main extends Configured implements Tool {
+
+    protected static final Log LOG = LogFactory.getLog(Main.class);
+    public static final String PHONIX_DBSERVER_PORT_KEY =
+        "phoenix.dbserver.port";
+    public static final int DEFAULT_DBSERVER_PORT = 2181;
+    public static final String PHONIX_DBSERVER_HOST_KEY =
+        "phoenix.dbserver.host";
+    public static final String DEFAULT_DBSERVER_HOST = "localhost";
+    public static final String TRACE_SERVER_HTTP_PORT_KEY =
+            "phoenix.traceserver.http.port";
+    public static final int DEFAULT_HTTP_PORT = 8864;
+    public static final String TRACE_SERVER_HTTP_JETTY_HOME_KEY =
+            "phoenix.traceserver.http.home";
+    public static final String DEFAULT_HTTP_HOME = "/";
+
+    public static void main(String[] args) throws Exception {
+        int ret = ToolRunner.run(HBaseConfiguration.create(), new Main(), 
args);
+        System.exit(ret);
+    }
+
+    @Override
+    public int run(String[] arg0) throws Exception {
+        // logProcessInfo(getConf());
+        final int port = getConf().getInt(TRACE_SERVER_HTTP_PORT_KEY,
+                DEFAULT_HTTP_PORT);
+        BasicConfigurator.configure();
+        final String home = getConf().get(TRACE_SERVER_HTTP_JETTY_HOME_KEY,
+                DEFAULT_HTTP_HOME);
+        //setting up the embedded server
+        ProtectionDomain domain = Main.class.getProtectionDomain();
+        URL location = domain.getCodeSource().getLocation();
+        String webappDirLocation = location.toString().split("target")[0] 
+"src/main/webapp";
+        Server server = new Server(port);
+        WebAppContext root = new WebAppContext();
+
+        root.setContextPath(home);
+        root.setDescriptor(webappDirLocation + "/WEB-INF/web.xml");
+        root.setResourceBase(webappDirLocation);
+        root.setParentLoaderPriority(true);
+        server.setHandler(root);
+
+        server.start();
+        server.join();
+        return 0;
+    }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f18fc82/phoenix-tracing-webapp/src/main/java/org/apache/phoenix/tracingwebapp/http/TraceServlet.java
----------------------------------------------------------------------
diff --git 
a/phoenix-tracing-webapp/src/main/java/org/apache/phoenix/tracingwebapp/http/TraceServlet.java
 
b/phoenix-tracing-webapp/src/main/java/org/apache/phoenix/tracingwebapp/http/TraceServlet.java
new file mode 100755
index 0000000..de047ba
--- /dev/null
+++ 
b/phoenix-tracing-webapp/src/main/java/org/apache/phoenix/tracingwebapp/http/TraceServlet.java
@@ -0,0 +1,152 @@
+/*
+ * 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.phoenix.tracingwebapp.http;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.codehaus.jackson.map.ObjectMapper;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ * Server to show trace information
+ *
+ */
+public class TraceServlet extends HttpServlet {
+
+  private static final long serialVersionUID = -354285100083055559L;
+  private static Connection con;
+  protected String DEFAULT_LIMIT = "25";
+  protected String DEFAULT_COUNTBY = "hostname";
+  protected String LOGIC_AND = "AND";
+  protected String LOGIC_OR = "OR";
+  protected String TRACING_TABLE = "SYSTEM.TRACING_STATS";
+
+
+
+  protected void doGet(HttpServletRequest request, HttpServletResponse 
response)
+      throws ServletException, IOException {
+
+    //reading url params
+    String action = request.getParameter("action");
+    String limit = request.getParameter("limit");
+    String traceid = request.getParameter("traceid");
+    String parentid = request.getParameter("parentid");
+    String jsonObject = "{}";
+    if ("getall".equals(action)) {
+      jsonObject = getAll(limit);
+    } else if ("getCount".equals(action)) {
+      jsonObject = getCount("description");
+    } else if ("getDistribution".equals(action)) {
+      jsonObject = getCount(DEFAULT_COUNTBY);
+    } else if ("searchTrace".equals(action)) {
+      jsonObject = searchTrace(parentid, traceid, LOGIC_OR);
+    } else {
+      jsonObject = "{ \"Server\": \"Phoenix Tracing Web App\", \"API 
version\": 0.1 }";
+    }
+    //response send as json
+    response.setContentType("application/json");
+    String output = jsonObject;
+    PrintWriter out = response.getWriter();
+    out.print(output);
+    out.flush();
+  }
+
+  //get all trace results with limit count
+  protected String getAll(String limit) {
+    String json = null;
+    if(limit == null) {
+      limit = DEFAULT_LIMIT;
+    }
+    String sqlQuery = "SELECT * FROM " + TRACING_TABLE + " LIMIT "+limit;
+    json = getResults(sqlQuery);
+    return getJson(json);
+  }
+
+  //get count on traces can pick on param to count
+  protected String getCount(String countby) {
+    String json = null;
+    if(countby == null) {
+      countby = DEFAULT_COUNTBY;
+    }
+    String sqlQuery = "SELECT "+countby+", COUNT(*) AS count FROM " + 
TRACING_TABLE + " GROUP BY "+countby+" HAVING COUNT(*) > 1 ";
+    json = getResults(sqlQuery);
+    return json;
+  }
+
+  //search the trace over parent id or trace id
+  protected String searchTrace(String parentId, String traceId,String logic) {
+    String json = null;
+    String query = null;
+    if(parentId != null && traceId != null) {
+      query = "SELECT * FROM " + TRACING_TABLE + " WHERE 
parent_id="+parentId+" "+logic+" trace_id="+traceId;
+    }else if (parentId != null && traceId == null) {
+      query = "SELECT * FROM " + TRACING_TABLE + " WHERE parent_id="+parentId;
+    }else if(parentId == null && traceId != null) {
+      query = "SELECT * FROM " + TRACING_TABLE + " WHERE trace_id="+traceId;
+    }
+    json = getResults(query);
+    return getJson(json);
+  }
+
+  //return json string
+  protected String getJson(String json) {
+    String output = json.toString().replace("_id\":", "_id\":\"")
+        .replace(",\"hostname", "\",\"hostname")
+        .replace(",\"parent", "\",\"parent")
+        .replace(",\"end", "\",\"end");
+    return output;
+  }
+
+  //get results with passing sql query
+  protected String getResults(String sqlQuery) {
+    String json = null;
+    if(sqlQuery == null){
+      json = "{error:true,msg:'SQL was null'}";
+    }else{
+    try {
+      con = ConnectionFactory.getConnection();
+      EntityFactory nutrientEntityFactory = new EntityFactory(con,sqlQuery);
+      List<Map<String, Object>> nutrients = nutrientEntityFactory
+          .findMultiple(new Object[] {});
+      ObjectMapper mapper = new ObjectMapper();
+      json = mapper.writeValueAsString(nutrients);
+    } catch (Exception e) {
+      json = "{error:true,msg:'Serrver Error:"+e.getMessage()+"'}";
+    } finally {
+      if (con != null) {
+        try {
+          con.close();
+        } catch (SQLException e) {
+          json = "{error:true,msg:'SQL Serrver Error:"+e.getMessage()+"'}";
+        }
+      }
+    }
+    }
+    return json;
+  }
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f18fc82/phoenix-tracing-webapp/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/phoenix-tracing-webapp/src/main/webapp/WEB-INF/web.xml 
b/phoenix-tracing-webapp/src/main/webapp/WEB-INF/web.xml
new file mode 100755
index 0000000..ed4ced2
--- /dev/null
+++ b/phoenix-tracing-webapp/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<web-app
+   xmlns="http://java.sun.com/xml/ns/javaee";
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd";
+   version="2.5">
+  <servlet>
+    <servlet-name>Trace</servlet-name>
+    
<servlet-class>org.apache.phoenix.tracingwebapp.http.TraceServlet</servlet-class>
+  </servlet>
+  <servlet-mapping>
+    <servlet-name>Trace</servlet-name>
+    <url-pattern>/trace/*</url-pattern>
+  </servlet-mapping>
+</web-app>

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f18fc82/phoenix-tracing-webapp/src/main/webapp/index.html
----------------------------------------------------------------------
diff --git a/phoenix-tracing-webapp/src/main/webapp/index.html 
b/phoenix-tracing-webapp/src/main/webapp/index.html
new file mode 100755
index 0000000..7f131fc
--- /dev/null
+++ b/phoenix-tracing-webapp/src/main/webapp/index.html
@@ -0,0 +1,16 @@
+<html>
+
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <meta name="description" content="Phoenix Tracing WebApp">
+    <meta name="author" content="nishani">
+    <title>Phoenix Tracing WebApp</title>
+  </head>
+
+  <body>
+    <h1>Phoenix Tracing Web App</h1>
+  </body>
+
+</html>

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2f18fc82/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 703831a..161343a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -31,6 +31,7 @@
     <module>phoenix-pherf</module>
     <module>phoenix-spark</module>
     <module>phoenix-assembly</module>
+    <module>phoenix-tracing-webapp</module>
   </modules>
 
   <repositories>
@@ -110,6 +111,7 @@
     <jodatime.version>2.7</jodatime.version>
     <joni.version>2.1.2</joni.version>
     <calcite.version>1.3.0-incubating</calcite.version>
+    <jettyVersion>8.1.7.v20120910</jettyVersion>
 
     <!-- Test Dependencies -->
     <mockito-all.version>1.8.5</mockito-all.version>

Reply via email to