zeppelin-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From m...@apache.org
Subject [6/6] incubator-zeppelin git commit: ZEPPELIN-179: Cassandra Interpreter
Date Wed, 05 Aug 2015 06:17:07 GMT
ZEPPELIN-179: Cassandra Interpreter

This is a Cassandra interpreter for Zeppelin.

I tried to make the code as clean & modular as possible. The code coverage is quite high with 75+ tests (unit tests + integration tests).

Below are the features of the interpreters:

- support single-line and multi-line comments
- one CQL statement can span many line
- a magic `prefix` system to pass in runtime parameters to queries
- support for preparing statements before-hand and injecting bound values to prepared statements
- parallel execution of each paragraphs
- the last statement is displayed as tabular data if it is a SELECT statement. For non SELECT statements, execution statistics are returned
- simple syntax validation by the interpreter, CQL syntax validation is delegated to Cassandra
- support for Zeppelin dynamic form with the mustache syntax {{input_name=default value}} or {{select_name=val1 | val2 | ... | valN}}

For all the details about the features of this interpreter, please read the doc **[here]**

[here]: https://docs.google.com/document/d/1krRrpZ3jKx_EOnALp30R1aAL8_tqCiu3W9oz5og0hDg/pub

Author: DuyHai DOAN <doanduyhai@gmail.com>

Closes #162 from doanduyhai/CassandraInterpreter and squashes the following commits:

1ee20a2 [DuyHai DOAN] Update Output message for No Result and Execution Statistics
aa47358 [DuyHai DOAN] Remove redundant tests
c1e09ed [DuyHai DOAN] Upgrade Scala version to 2.11.7
70f55b8 [DuyHai DOAN] Add HELP Command
585571f [DuyHai DOAN] Rename SchemaDisplay to DisplaySystem
a415434 [DuyHai DOAN] Upgrade Scala to 2.11.1
fbc287b [DuyHai DOAN] Add support for schema discovery
7d06073 [DuyHai DOAN] Explicit names for objects in TextBlockHierarchy
ea879af [DuyHai DOAN] Make commands case insensitive
ac373bb [DuyHai DOAN] Add runtime dependency to scala lib
8413581 [DuyHai DOAN] Move collection conversion helper to test
6f1d410 [DuyHai DOAN] Add more unit tests
5166727 [DuyHai DOAN] Refactoring after code review
a7d864b [DuyHai DOAN] Fix test failing in different timezone
b63cefe [DuyHai DOAN] Cassandra Interpreter


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

Branch: refs/heads/master
Commit: b9583c6e0965966ce9b9b23c40997948a8737316
Parents: 67f7f3e
Author: DuyHai DOAN <doanduyhai@gmail.com>
Authored: Fri Jul 31 00:37:11 2015 +0200
Committer: Lee moon soo <moon@apache.org>
Committed: Wed Aug 5 15:16:54 2015 +0900

----------------------------------------------------------------------
 cassandra/pom.xml                               | 279 ++++++
 .../cassandra/CassandraInterpreter.java         | 339 +++++++
 .../zeppelin/cassandra/ParsingException.java    |  26 +
 .../src/main/resources/scalate/allTables.ssp    |  69 ++
 .../main/resources/scalate/clusterContent.ssp   |  54 ++
 .../main/resources/scalate/clusterDetails.ssp   |  44 +
 .../scalate/dropDownMenuForCluster.ssp          |  36 +
 .../scalate/dropDownMenuForKeyspace.ssp         |  52 ++
 .../src/main/resources/scalate/helpMenu.ssp     | 901 +++++++++++++++++++
 .../main/resources/scalate/keyspaceContent.ssp  |  91 ++
 .../main/resources/scalate/keyspaceDetails.ssp  |  61 ++
 cassandra/src/main/resources/scalate/menu.ssp   |  94 ++
 .../src/main/resources/scalate/noResult.ssp     |  24 +
 .../scalate/noResultWithExecutionInfo.ssp       |  65 ++
 .../src/main/resources/scalate/tableDetails.ssp | 147 +++
 .../src/main/resources/scalate/udtDetails.ssp   |  61 ++
 .../zeppelin/cassandra/BoundValuesParser.scala  |  65 ++
 .../zeppelin/cassandra/DisplaySystem.scala      | 298 ++++++
 .../zeppelin/cassandra/EnhancedSession.scala    | 108 +++
 .../zeppelin/cassandra/InterpreterLogic.scala   | 411 +++++++++
 .../zeppelin/cassandra/JavaDriverConfig.scala   | 430 +++++++++
 .../zeppelin/cassandra/MetaDataHierarchy.scala  |  67 ++
 .../zeppelin/cassandra/ParagraphParser.scala    | 267 ++++++
 .../zeppelin/cassandra/TextBlockHierarchy.scala | 139 +++
 .../cassandra/CassandraInterpreterTest.java     | 670 ++++++++++++++
 .../cassandra/InterpreterLogicTest.java         | 311 +++++++
 cassandra/src/test/resources/log4j.xml          |  80 ++
 cassandra/src/test/resources/prepare_data.cql   |  18 +
 cassandra/src/test/resources/prepare_schema.cql | 114 +++
 .../test/resources/scalate/DescribeCluster.html |  98 ++
 .../scalate/DescribeKeyspace_alone.html         |  41 +
 .../scalate/DescribeKeyspace_live_data.html     | 819 +++++++++++++++++
 .../resources/scalate/DescribeKeyspaces.html    | 400 ++++++++
 .../DescribeTable_live_data_complex_table.html  | 326 +++++++
 .../test/resources/scalate/DescribeTables.html  | 313 +++++++
 .../scalate/DescribeType_live_data_address.html | 137 +++
 ...ve_data_address_within_current_keyspace.html | 137 +++
 cassandra/src/test/resources/scalate/Help.html  | 870 ++++++++++++++++++
 .../src/test/resources/scalate/NoResult.html    |   6 +
 .../scalate/NoResultWithExecutionInfo.html      |  42 +
 .../cassandra/BoundValuesParserTest.scala       | 193 ++++
 .../cassandra/ParagraphParserTest.scala         | 585 ++++++++++++
 conf/zeppelin-site.xml.template                 |   2 +-
 pom.xml                                         |   1 +
 .../zeppelin/conf/ZeppelinConfiguration.java    |   3 +-
 45 files changed, 9292 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/b9583c6e/cassandra/pom.xml
----------------------------------------------------------------------
diff --git a/cassandra/pom.xml b/cassandra/pom.xml
new file mode 100644
index 0000000..e12c750
--- /dev/null
+++ b/cassandra/pom.xml
@@ -0,0 +1,279 @@
+<?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.
+  -->
+<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>
+        <artifactId>zeppelin</artifactId>
+        <groupId>org.apache.zeppelin</groupId>
+        <version>0.6.0-incubating-SNAPSHOT</version>
+    </parent>
+
+    <groupId>org.apache.zeppelin</groupId>
+    <artifactId>zeppelin-cassandra</artifactId>
+    <packaging>jar</packaging>
+    <version>0.6.0-incubating-SNAPSHOT</version>
+    <name>Zeppelin: Cassandra</name>
+    <description>Zeppelin cassandra support</description>
+    <url>http://zeppelin.incubator.apache.org</url>
+
+    <properties>
+        <cassandra.driver.version>2.1.7.1</cassandra.driver.version>
+        <scala.version>2.11.7</scala.version>
+        <scala.binary.version>2.11</scala.binary.version>
+        <commons-lang.version>3.3.2</commons-lang.version>
+        <scalate.version>1.7.1</scalate.version>
+
+        <!--TEST-->
+        <scalatest.version>2.2.4</scalatest.version>
+        <junit.version>4.12</junit.version>
+        <achilles.version>3.2.2</achilles.version>
+        <assertj.version>1.7.0</assertj.version>
+        <mockito.version>1.9.5</mockito.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>zeppelin-interpreter</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.datastax.cassandra</groupId>
+            <artifactId>cassandra-driver-core</artifactId>
+            <version>${cassandra.driver.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.scala-lang</groupId>
+            <artifactId>scala-compiler</artifactId>
+            <version>${scala.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.scala-lang</groupId>
+            <artifactId>scala-library</artifactId>
+            <version>${scala.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.scala-lang</groupId>
+            <artifactId>scala-reflect</artifactId>
+            <version>${scala.version}</version>
+            <scope>runtime</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>${commons-lang.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.scalatra.scalate</groupId>
+            <artifactId>scalate-core_${scala.binary.version}</artifactId>
+            <version>${scalate.version}</version>
+        </dependency>
+
+        <!--TEST-->
+        <dependency>
+            <groupId>org.scalatest</groupId>
+            <artifactId>scalatest_${scala.binary.version}</artifactId>
+            <version>${scalatest.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>info.archinnov</groupId>
+            <artifactId>achilles-junit</artifactId>
+            <version>${achilles.version}</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>ch.qos.logback</groupId>
+                    <artifactId>logback-core</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>ch.qos.logback</groupId>
+                    <artifactId>logback-classic</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>16.0</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>${mockito.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <version>${assertj.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+
+    <build>
+        <plugins>
+            <!-- Plugin to compile Scala code -->
+            <plugin>
+                <groupId>org.scala-tools</groupId>
+                <artifactId>maven-scala-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>compile</id>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                        <phase>compile</phase>
+                    </execution>
+                    <execution>
+                        <id>test-compile</id>
+                        <goals>
+                            <goal>testCompile</goal>
+                        </goals>
+                        <phase>test-compile</phase>
+                    </execution>
+                    <execution>
+                        <phase>process-resources</phase>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.scalatest</groupId>
+                <artifactId>scalatest-maven-plugin</artifactId>
+                <version>1.0</version>
+                <executions>
+                    <execution>
+                        <id>test</id>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.scalatra.scalate</groupId>
+                <artifactId>maven-scalate-plugin_${scala.binary.version}</artifactId>
+                <version>1.7.1</version>
+                <executions>
+                    <execution>
+                        <id>compile</id>
+                        <phase>process-classes</phase>
+                        <goals>
+                            <goal>precompile</goal>
+                        </goals>
+                        <configuration>
+                            <resourcesSourceDirectory>${basedir}/src/main/resources/scalate</resourcesSourceDirectory>
+                            <contextClass>org.fusesource.scalate.DefaultRenderContext</contextClass>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-deploy-plugin</artifactId>
+                <version>2.7</version>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <artifactId>maven-enforcer-plugin</artifactId>
+                <version>1.3.1</version>
+                <executions>
+                    <execution>
+                        <id>enforce</id>
+                        <phase>none</phase>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <version>2.8</version>
+                <executions>
+                    <execution>
+                        <id>copy-dependencies</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>copy-dependencies</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/../../interpreter/cassandra</outputDirectory>
+                            <overWriteReleases>false</overWriteReleases>
+                            <overWriteSnapshots>false</overWriteSnapshots>
+                            <overWriteIfNewer>true</overWriteIfNewer>
+                            <includeScope>runtime</includeScope>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>copy-artifact</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>copy</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/../../interpreter/cassandra</outputDirectory>
+                            <overWriteReleases>false</overWriteReleases>
+                            <overWriteSnapshots>false</overWriteSnapshots>
+                            <overWriteIfNewer>true</overWriteIfNewer>
+                            <includeScope>runtime</includeScope>
+                            <artifactItems>
+                                <artifactItem>
+                                    <groupId>${project.groupId}</groupId>
+                                    <artifactId>${project.artifactId}</artifactId>
+                                    <version>${project.version}</version>
+                                    <type>${project.packaging}</type>
+                                </artifactItem>
+                            </artifactItems>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+        </plugins>
+    </build>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/b9583c6e/cassandra/src/main/java/org/apache/zeppelin/cassandra/CassandraInterpreter.java
----------------------------------------------------------------------
diff --git a/cassandra/src/main/java/org/apache/zeppelin/cassandra/CassandraInterpreter.java b/cassandra/src/main/java/org/apache/zeppelin/cassandra/CassandraInterpreter.java
new file mode 100644
index 0000000..cc4520d
--- /dev/null
+++ b/cassandra/src/main/java/org/apache/zeppelin/cassandra/CassandraInterpreter.java
@@ -0,0 +1,339 @@
+/*
+ * 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.zeppelin.cassandra;
+
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.ProtocolOptions.Compression;
+import com.datastax.driver.core.Session;
+import org.apache.zeppelin.interpreter.Interpreter;
+import org.apache.zeppelin.interpreter.InterpreterContext;
+import org.apache.zeppelin.interpreter.InterpreterPropertyBuilder;
+import org.apache.zeppelin.interpreter.InterpreterResult;
+import org.apache.zeppelin.scheduler.Scheduler;
+import org.apache.zeppelin.scheduler.SchedulerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import static com.datastax.driver.core.ProtocolOptions.DEFAULT_MAX_SCHEMA_AGREEMENT_WAIT_SECONDS;
+import static java.lang.Integer.parseInt;
+
+/**
+ * Interpreter for Apache Cassandra CQL query language
+ */
+public class CassandraInterpreter extends Interpreter {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(CassandraInterpreter.class);
+
+  public static final String CASSANDRA_INTERPRETER_PARALLELISM = "cassandra.interpreter" +
+      ".parallelism";
+  public static final String CASSANDRA_HOSTS = "cassandra.hosts";
+  public static final String CASSANDRA_PORT = "cassandra.native.port";
+  public static final String CASSANDRA_PROTOCOL_VERSION = "cassandra.protocol.version";
+  public static final String CASSANDRA_CLUSTER_NAME = "cassandra.cluster";
+  public static final String CASSANDRA_KEYSPACE_NAME = "cassandra.keyspace";
+  public static final String CASSANDRA_COMPRESSION_PROTOCOL = "cassandra.compression.protocol";
+  public static final String CASSANDRA_CREDENTIALS_USERNAME = "cassandra.credentials.username";
+  public static final String CASSANDRA_CREDENTIALS_PASSWORD = "cassandra.credentials.password";
+  public static final String CASSANDRA_LOAD_BALANCING_POLICY = "cassandra.load.balancing.policy";
+  public static final String CASSANDRA_RETRY_POLICY = "cassandra.retry.policy";
+  public static final String CASSANDRA_RECONNECTION_POLICY = "cassandra.reconnection.policy";
+  public static final String CASSANDRA_SPECULATIVE_EXECUTION_POLICY =
+          "cassandra.speculative.execution.policy";
+  public static final String CASSANDRA_MAX_SCHEMA_AGREEMENT_WAIT_SECONDS =
+        "cassandra.max.schema.agreement.wait.second";
+  public static final String CASSANDRA_POOLING_NEW_CONNECTION_THRESHOLD_LOCAL =
+        "cassandra.pooling.new.connection.threshold.local";
+  public static final String CASSANDRA_POOLING_NEW_CONNECTION_THRESHOLD_REMOTE =
+        "cassandra.pooling.new.connection.threshold.remote";
+  public static final String CASSANDRA_POOLING_MAX_CONNECTION_PER_HOST_LOCAL =
+        "cassandra.pooling.max.connection.per.host.local";
+  public static final String CASSANDRA_POOLING_MAX_CONNECTION_PER_HOST_REMOTE =
+        "cassandra.pooling.max.connection.per.host.remote";
+  public static final String CASSANDRA_POOLING_CORE_CONNECTION_PER_HOST_LOCAL =
+          "cassandra.pooling.core.connection.per.host.local";
+  public static final String CASSANDRA_POOLING_CORE_CONNECTION_PER_HOST_REMOTE =
+          "cassandra.pooling.core.connection.per.host.remote";
+  public static final String CASSANDRA_POOLING_MAX_REQUESTS_PER_CONNECTION_LOCAL =
+        "cassandra.pooling.max.request.per.connection.local";
+  public static final String CASSANDRA_POOLING_MAX_REQUESTS_PER_CONNECTION_REMOTE =
+          "cassandra.pooling.max.request.per.connection.remote";
+  public static final String CASSANDRA_POOLING_IDLE_TIMEOUT_SECONDS =
+          "cassandra.pooling.idle.timeout.seconds";
+  public static final String CASSANDRA_POOLING_POOL_TIMEOUT_MILLIS =
+          "cassandra.pooling.pool.timeout.millisecs";
+  public static final String CASSANDRA_POOLING_HEARTBEAT_INTERVAL_SECONDS =
+          "cassandra.pooling.heartbeat.interval.seconds";
+  public static final String CASSANDRA_QUERY_DEFAULT_CONSISTENCY =
+          "cassandra.query.default.consistency";
+  public static final String CASSANDRA_QUERY_DEFAULT_SERIAL_CONSISTENCY =
+          "cassandra.query.default.serial.consistency";
+  public static final String CASSANDRA_QUERY_DEFAULT_FETCH_SIZE =
+          "cassandra.query.default.fetchSize";
+  public static final String CASSANDRA_QUERY_DEFAULT_IDEMPOTENCE =
+          "cassandra.query.default.idempotence";
+  public static final String CASSANDRA_SOCKET_CONNECTION_TIMEOUT_MILLIS =
+          "cassandra.socket.connection.timeout.millisecs";
+  public static final String CASSANDRA_SOCKET_KEEP_ALIVE =
+          "cassandra.socket.keep.alive";
+  public static final String CASSANDRA_SOCKET_READ_TIMEOUT_MILLIS =
+          "cassandra.socket.read.timeout.millisecs";
+  public static final String CASSANDRA_SOCKET_RECEIVED_BUFFER_SIZE_BYTES =
+          "cassandra.socket.received.buffer.size.bytes";
+  public static final String CASSANDRA_SOCKET_REUSE_ADDRESS =
+          "cassandra.socket.reuse.address";
+  public static final String CASSANDRA_SOCKET_SEND_BUFFER_SIZE_BYTES =
+          "cassandra.socket.send.buffer.size.bytes";
+  public static final String CASSANDRA_SOCKET_SO_LINGER =
+          "cassandra.socket.soLinger";
+  public static final String CASSANDRA_SOCKET_TCP_NO_DELAY =
+          "cassandra.socket.tcp.no_delay";
+
+  public static final String DEFAULT_HOST = "localhost";
+  public static final String DEFAULT_PORT = "9042";
+  public static final String DEFAULT_CLUSTER = "Test Cluster";
+  public static final String DEFAULT_KEYSPACE = "system";
+  public static final String DEFAULT_PROTOCOL_VERSION = "3";
+  public static final String DEFAULT_COMPRESSION = "NONE";
+  public static final String DEFAULT_CREDENTIAL = "none";
+  public static final String DEFAULT_POLICY = "DEFAULT";
+  public static final String DEFAULT_PARALLELISM = "10";
+  static String DEFAULT_NEW_CONNECTION_THRESHOLD_LOCAL = "100";
+  static String DEFAULT_NEW_CONNECTION_THRESHOLD_REMOTE = "100";
+  static String DEFAULT_CORE_CONNECTION_PER_HOST_LOCAL = "2";
+  static String DEFAULT_CORE_CONNECTION_PER_HOST_REMOTE = "1";
+  static String DEFAULT_MAX_CONNECTION_PER_HOST_LOCAL = "8";
+  static String DEFAULT_MAX_CONNECTION_PER_HOST_REMOTE = "2";
+  static String DEFAULT_MAX_REQUEST_PER_CONNECTION_LOCAL = "1024";
+  static String DEFAULT_MAX_REQUEST_PER_CONNECTION_REMOTE = "256";
+  public static final String DEFAULT_IDLE_TIMEOUT = "120";
+  public static final String DEFAULT_POOL_TIMEOUT = "5000";
+  public static final String DEFAULT_HEARTBEAT_INTERVAL = "30";
+  public static final String DEFAULT_CONSISTENCY = "ONE";
+  public static final String DEFAULT_SERIAL_CONSISTENCY = "SERIAL";
+  public static final String DEFAULT_FETCH_SIZE = "5000";
+  public static final String DEFAULT_CONNECTION_TIMEOUT = "5000";
+  public static final String DEFAULT_READ_TIMEOUT = "12000";
+  public static final String DEFAULT_TCP_NO_DELAY = "true";
+
+  public static final String DOWNGRADING_CONSISTENCY_RETRY = "DOWNGRADING_CONSISTENCY";
+  public static final String FALLTHROUGH_RETRY = "FALLTHROUGH";
+  public static final String LOGGING_DEFAULT_RETRY = "LOGGING_DEFAULT";
+  public static final String LOGGING_DOWNGRADING_RETRY = "LOGGING_DOWNGRADING";
+  public static final String LOGGING_FALLTHROUGH_RETRY = "LOGGING_FALLTHROUGH";
+
+  public static final List<String> NO_COMPLETION = new ArrayList<>();
+
+  InterpreterLogic helper;
+  Cluster cluster;
+  Session session;
+  private JavaDriverConfig driverConfig = new JavaDriverConfig();
+
+  public CassandraInterpreter(Properties properties) {
+    super(properties);
+  }
+
+  static {
+    LOGGER.info("Bootstrapping Cassandra Interpreter");
+    Interpreter.register("cassandra", "cassandra", CassandraInterpreter.class.getName(),
+      new InterpreterPropertyBuilder()
+        .add(CASSANDRA_HOSTS, DEFAULT_HOST,
+                "Comma separated Cassandra hosts (DNS name or " +
+                "IP address). Default = localhost. Ex: '192.168.0.12,node2,node3'")
+        .add(CASSANDRA_PORT, DEFAULT_PORT, "Cassandra native port. Default = 9042")
+        .add(CASSANDRA_PROTOCOL_VERSION, DEFAULT_PROTOCOL_VERSION,
+                "Cassandra protocol version. Default = 3")
+        .add(CASSANDRA_CLUSTER_NAME, DEFAULT_CLUSTER, "Cassandra cluster name. " +
+                "Default = 'Test Cluster'")
+        .add(CASSANDRA_KEYSPACE_NAME, DEFAULT_KEYSPACE, "Cassandra keyspace name. " +
+                "Default = 'system'")
+        .add(CASSANDRA_COMPRESSION_PROTOCOL, DEFAULT_COMPRESSION,
+                "Cassandra compression protocol. " +
+                "Available values: NONE, SNAPPY, LZ4. Default = NONE")
+        .add(CASSANDRA_CREDENTIALS_USERNAME, DEFAULT_CREDENTIAL,
+                "Cassandra credentials username. " +
+                "Default = 'none'")
+        .add(CASSANDRA_CREDENTIALS_PASSWORD, DEFAULT_CREDENTIAL,
+                "Cassandra credentials password. " +
+                "Default = 'none'")
+        .add(CASSANDRA_LOAD_BALANCING_POLICY, DEFAULT_POLICY, "Cassandra Load Balancing Policy. " +
+                "Default = new TokenAwarePolicy(new DCAwareRoundRobinPolicy())")
+        .add(CASSANDRA_RETRY_POLICY, DEFAULT_POLICY, "Cassandra Retry Policy. " +
+                "Default = DefaultRetryPolicy.INSTANCE")
+        .add(CASSANDRA_RECONNECTION_POLICY, DEFAULT_POLICY, "Cassandra Reconnection Policy. " +
+                "Default = new ExponentialReconnectionPolicy(1000, 10 * 60 * 1000)")
+        .add(CASSANDRA_SPECULATIVE_EXECUTION_POLICY, DEFAULT_POLICY,
+                "Cassandra Speculative Execution Policy. " +
+                        "Default = NoSpeculativeExecutionPolicy.INSTANCE")
+        .add(CASSANDRA_INTERPRETER_PARALLELISM, DEFAULT_PARALLELISM,
+                "Cassandra interpreter parallelism" +
+                ".Default = 10")
+        .add(CASSANDRA_MAX_SCHEMA_AGREEMENT_WAIT_SECONDS,
+                DEFAULT_MAX_SCHEMA_AGREEMENT_WAIT_SECONDS + ""
+                , "Cassandra max schema agreement wait in second" +
+                ".Default = ProtocolOptions.DEFAULT_MAX_SCHEMA_AGREEMENT_WAIT_SECONDS")
+
+        .add(CASSANDRA_POOLING_NEW_CONNECTION_THRESHOLD_LOCAL,
+                DEFAULT_NEW_CONNECTION_THRESHOLD_LOCAL,
+                "Cassandra new connection threshold local. " +
+                        "Protocol V2 and below default = 100" +
+                        "Protocol V3 and above default = 800")
+        .add(CASSANDRA_POOLING_NEW_CONNECTION_THRESHOLD_REMOTE,
+                DEFAULT_NEW_CONNECTION_THRESHOLD_REMOTE,
+                "Cassandra new connection threshold remove. " +
+                "Protocol V2 and below default = 100" +
+                "Protocol V3 and above default = 200")
+
+        .add(CASSANDRA_POOLING_CORE_CONNECTION_PER_HOST_LOCAL,
+                DEFAULT_CORE_CONNECTION_PER_HOST_LOCAL,
+                "Cassandra core connection per host local. " +
+                        "Protocol V2 and below default = 2" +
+                        "Protocol V3 and above default = 1")
+        .add(CASSANDRA_POOLING_CORE_CONNECTION_PER_HOST_REMOTE,
+                DEFAULT_CORE_CONNECTION_PER_HOST_REMOTE,
+                "Cassandra core connection per host remove. " +
+                "Protocol V2 and below default = 1" +
+                "Protocol V3 and above default = 1")
+
+        .add(CASSANDRA_POOLING_MAX_CONNECTION_PER_HOST_LOCAL,
+                DEFAULT_MAX_CONNECTION_PER_HOST_LOCAL,
+                "Cassandra max connection per host local. " +
+                        "Protocol V2 and below default = 8" +
+                        "Protocol V3 and above default = 1")
+        .add(CASSANDRA_POOLING_MAX_CONNECTION_PER_HOST_REMOTE,
+                DEFAULT_MAX_CONNECTION_PER_HOST_REMOTE,
+                "Cassandra max connection per host remote. " +
+                "Protocol V2 and below default = 2" +
+                "Protocol V3 and above default = 1")
+
+        .add(CASSANDRA_POOLING_MAX_REQUESTS_PER_CONNECTION_LOCAL,
+                DEFAULT_MAX_REQUEST_PER_CONNECTION_LOCAL,
+                "Cassandra max request per connection local. " +
+                        "Protocol V2 and below default = 128" +
+                        "Protocol V3 and above default = 1024")
+        .add(CASSANDRA_POOLING_MAX_REQUESTS_PER_CONNECTION_REMOTE,
+                DEFAULT_MAX_REQUEST_PER_CONNECTION_REMOTE,
+                "Cassandra max request per connection remote. " +
+                "Protocol V2 and below default = 128" +
+                "Protocol V3 and above default = 256")
+
+        .add(CASSANDRA_POOLING_IDLE_TIMEOUT_SECONDS, DEFAULT_IDLE_TIMEOUT,
+                "Cassandra idle time out in seconds. Default = 120")
+        .add(CASSANDRA_POOLING_POOL_TIMEOUT_MILLIS, DEFAULT_POOL_TIMEOUT,
+                "Cassandra pool time out in millisecs. Default = 5000")
+        .add(CASSANDRA_POOLING_HEARTBEAT_INTERVAL_SECONDS, DEFAULT_HEARTBEAT_INTERVAL,
+                "Cassandra pool heartbeat interval in secs. Default = 30")
+        .add(CASSANDRA_QUERY_DEFAULT_CONSISTENCY, DEFAULT_CONSISTENCY,
+                "Cassandra query default consistency level. Default = ONE")
+        .add(CASSANDRA_QUERY_DEFAULT_SERIAL_CONSISTENCY, DEFAULT_SERIAL_CONSISTENCY,
+                "Cassandra query default serial consistency level. Default = SERIAL")
+        .add(CASSANDRA_QUERY_DEFAULT_FETCH_SIZE, DEFAULT_FETCH_SIZE,
+                "Cassandra query default fetch size. Default = 5000")
+        .add(CASSANDRA_SOCKET_CONNECTION_TIMEOUT_MILLIS, DEFAULT_CONNECTION_TIMEOUT,
+                "Cassandra socket default connection timeout in millisecs. Default = 5000")
+        .add(CASSANDRA_SOCKET_READ_TIMEOUT_MILLIS, DEFAULT_READ_TIMEOUT,
+                "Cassandra socket read timeout in millisecs. Default = 12000")
+        .add(CASSANDRA_SOCKET_TCP_NO_DELAY, DEFAULT_TCP_NO_DELAY,
+                "Cassandra socket TCP no delay. Default = true")
+        .build());
+  }
+
+  @Override
+  public void open() {
+
+    final String[] addresses = getProperty(CASSANDRA_HOSTS).split(",");
+    final int port = parseInt(getProperty(CASSANDRA_PORT));
+    StringBuilder hosts = new StringBuilder();
+    for (String address : addresses) {
+      hosts.append(address).append(",");
+    }
+
+    LOGGER.info("Bootstrapping Cassandra Java Driver to connect to " + hosts.toString() +
+                  "on port " + port);
+
+    Compression compression = driverConfig.getCompressionProtocol(this);
+
+    cluster  = Cluster.builder()
+      .addContactPoints(addresses)
+      .withPort(port)
+      .withProtocolVersion(driverConfig.getProtocolVersion(this))
+      .withClusterName(getProperty(CASSANDRA_CLUSTER_NAME))
+      .withCompression(compression)
+      .withCredentials(getProperty(CASSANDRA_CREDENTIALS_USERNAME),
+              getProperty(CASSANDRA_CREDENTIALS_PASSWORD))
+      .withLoadBalancingPolicy(driverConfig.getLoadBalancingPolicy(this))
+      .withRetryPolicy(driverConfig.getRetryPolicy(this))
+      .withReconnectionPolicy(driverConfig.getReconnectionPolicy(this))
+      .withSpeculativeExecutionPolicy(driverConfig.getSpeculativeExecutionPolicy(this))
+      .withMaxSchemaAgreementWaitSeconds(
+              parseInt(getProperty(CASSANDRA_MAX_SCHEMA_AGREEMENT_WAIT_SECONDS)))
+      .withPoolingOptions(driverConfig.getPoolingOptions(this))
+      .withQueryOptions(driverConfig.getQueryOptions(this))
+      .withSocketOptions(driverConfig.getSocketOptions(this))
+      .build();
+
+    session = cluster.connect();
+    helper = new InterpreterLogic(session);
+  }
+
+  @Override
+  public void close() {
+    session.close();
+    cluster.close();
+  }
+
+  @Override
+  public InterpreterResult interpret(String st, InterpreterContext context) {
+    return helper.interpret(session, st, context);
+  }
+
+  @Override
+  public void cancel(InterpreterContext context) {
+
+  }
+
+  @Override
+  public FormType getFormType() {
+    return FormType.NATIVE;
+  }
+
+  @Override
+  public int getProgress(InterpreterContext context) {
+    return 0;
+  }
+
+  @Override
+  public List<String> completion(String buf, int cursor) {
+    return NO_COMPLETION;
+  }
+
+  @Override
+  public Scheduler getScheduler() {
+    return SchedulerFactory.singleton()
+            .createOrGetParallelScheduler(CassandraInterpreter.class.getName() + this.hashCode(),
+                    parseInt(getProperty(CASSANDRA_INTERPRETER_PARALLELISM)));
+  }
+
+  @Override
+  public void destroy() {
+    super.destroy();
+    this.close();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/b9583c6e/cassandra/src/main/java/org/apache/zeppelin/cassandra/ParsingException.java
----------------------------------------------------------------------
diff --git a/cassandra/src/main/java/org/apache/zeppelin/cassandra/ParsingException.java b/cassandra/src/main/java/org/apache/zeppelin/cassandra/ParsingException.java
new file mode 100644
index 0000000..da9bb0c
--- /dev/null
+++ b/cassandra/src/main/java/org/apache/zeppelin/cassandra/ParsingException.java
@@ -0,0 +1,26 @@
+/*
+ * 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.zeppelin.cassandra;
+
+/**
+ * Parsing Exception for Cassandra CQL statement
+ */
+public class ParsingException extends RuntimeException{
+  public ParsingException(String message) {
+    super(message);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/b9583c6e/cassandra/src/main/resources/scalate/allTables.ssp
----------------------------------------------------------------------
diff --git a/cassandra/src/main/resources/scalate/allTables.ssp b/cassandra/src/main/resources/scalate/allTables.ssp
new file mode 100644
index 0000000..b363bee
--- /dev/null
+++ b/cassandra/src/main/resources/scalate/allTables.ssp
@@ -0,0 +1,69 @@
+<%--
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*    http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+--%>
+#import(org.apache.zeppelin.cassandra.MetaDataHierarchy._)
+#import(java.util.UUID)
+<%@ val allTables: Map[(UUID,String),List[String]] %>
+<div class="container">
+
+    <div class="row">
+        <div class="panel-group" role="tablist" aria-multiselectable="true">
+            #for (((ksId,ksName), tables) <- allTables)
+
+            <div class="panel panel-default">
+                <div class="panel-heading" role="tab">
+                    <h4 class="panel-title">
+                        <a role="button" data-toggle="collapse" data-target="#${ksId}" aria-expanded="false">
+                            <span class="text-danger"><i class="glyphicon glyphicon-folder-open"/>&nbsp;&nbsp;${ksName}</span>
+                        </a>
+                    </h4>
+                </div>
+                <div id="${ksId}" class="panel-collapse collapse" role="tabpanel">
+                    <div class="panel-body">
+                        <div class="row">
+                            <div class="col-md-2"/>
+                            <div class="col-md-8 col-offset-md-2 table-responsive table-bordered">
+                                #if (tables.nonEmpty)
+
+                                <table class="table">
+                                    <thead>
+                                        <tr><th>Tables</th></tr>
+                                    </thead>
+                                    <tbody>
+                                        #for (table <- tables)
+
+                                        <tr class="text-primary"><td>${table}</td></tr>
+                                        #end
+
+                                    </tbody>
+                                </table>
+                                #else
+                                <span><h4>No Table</h4></span>
+
+                                #end
+                            </div>
+                            <div class="col-md-2"/>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            #end
+
+        </div>
+    </div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/b9583c6e/cassandra/src/main/resources/scalate/clusterContent.ssp
----------------------------------------------------------------------
diff --git a/cassandra/src/main/resources/scalate/clusterContent.ssp b/cassandra/src/main/resources/scalate/clusterContent.ssp
new file mode 100644
index 0000000..9ae7e5c
--- /dev/null
+++ b/cassandra/src/main/resources/scalate/clusterContent.ssp
@@ -0,0 +1,54 @@
+<%--
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*    http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+--%>
+#import(org.apache.zeppelin.cassandra.MetaDataHierarchy._)
+<%@ val clusterContent: ClusterContent %>
+<div class="container">
+    <!-- Cluster -->
+    ${unescape(clusterContent.clusterDetails)}
+
+
+    <div class="row"></div>
+    <!-- Keyspaces -->
+    <table width="100%">
+        <td><hr /></td>
+        <td style="width:1px; padding: 0 10px; white-space: nowrap;"><strong class="text-danger">Keyspaces</strong></td>
+        <td><hr /></td>
+    </table>
+    <div class="row">
+        <div class="panel-group" role="tablist" aria-multiselectable="true">
+
+            #for ((id, name, keyspaceHTML) <- clusterContent.keyspaces)
+            <div class="panel panel-default">
+                <div class="panel-heading" role="tab">
+                    <h4 class="panel-title">
+                        <a role="button" data-toggle="collapse" data-target="#${id}" aria-expanded="false">
+                            <span class="text-danger"><i class="glyphicon glyphicon-folder-open"/>&nbsp;&nbsp;${name}</span>
+                        </a>
+                    </h4>
+                </div>
+                <div id="${id}" class="panel-collapse collapse" role="tabpanel">
+                    <div class="panel-body">
+                        ${unescape(keyspaceHTML)}
+                    </div>
+                </div>
+            </div>
+            #end
+        </div>
+    </div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/b9583c6e/cassandra/src/main/resources/scalate/clusterDetails.ssp
----------------------------------------------------------------------
diff --git a/cassandra/src/main/resources/scalate/clusterDetails.ssp b/cassandra/src/main/resources/scalate/clusterDetails.ssp
new file mode 100644
index 0000000..6473d60
--- /dev/null
+++ b/cassandra/src/main/resources/scalate/clusterDetails.ssp
@@ -0,0 +1,44 @@
+<%--
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*    http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+--%>
+#import(org.apache.zeppelin.cassandra.MetaDataHierarchy._)
+<%@ val clusterDetails: ClusterDetails %>
+<div class="row">
+    <div class="col-md-4"></div>
+    <div class="col-md-4 col-offset-md-4">
+        <div class="table-responsive table-bordered">
+            <table class="table">
+                <caption>
+                    <h4 class="text-muted">
+                        <i class="glyphicon glyphicon-dashboard"/>&nbsp;${clusterDetails.name}
+                    </h4>
+                </caption>
+                <thead>
+                <tr>
+                    <th>Partitioner</th>
+                </tr>
+                </thead>
+                <tbody>
+                <tr>
+                    <td>${clusterDetails.partitioner}</td>
+                </tr>
+                <tbody>
+            </table>
+        </div>
+    </div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/b9583c6e/cassandra/src/main/resources/scalate/dropDownMenuForCluster.ssp
----------------------------------------------------------------------
diff --git a/cassandra/src/main/resources/scalate/dropDownMenuForCluster.ssp b/cassandra/src/main/resources/scalate/dropDownMenuForCluster.ssp
new file mode 100644
index 0000000..fbe6d5d
--- /dev/null
+++ b/cassandra/src/main/resources/scalate/dropDownMenuForCluster.ssp
@@ -0,0 +1,36 @@
+<%--
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*    http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+--%>
+#import(org.apache.zeppelin.cassandra.MetaDataHierarchy._)
+<%@ val clusterContent: ClusterContent %>
+<li role="presentation" class="dropdown">
+    <a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
+        <span class="text-muted"><i class="glyphicon glyphicon-dashboard"/>&nbsp;<strong>${clusterContent.clusterName}</strong></span>
+        <span class="text-muted caret"></span>
+        <ul class="dropdown-menu">
+            <li class="dropdown-header"><span class="text-danger">Keyspaces</span></li>
+            #for((id, name, _) <- clusterContent.keyspaces)
+            <li>
+                <a role="button" data-toggle="collapse" data-target="#${id}">
+                    <span class="text-danger"><i class="glyphicon glyphicon-folder-open"/>&nbsp;&nbsp;${name}</span>
+                </a>
+            </li>
+            #end
+        </ul>
+    </a>
+</li>

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/b9583c6e/cassandra/src/main/resources/scalate/dropDownMenuForKeyspace.ssp
----------------------------------------------------------------------
diff --git a/cassandra/src/main/resources/scalate/dropDownMenuForKeyspace.ssp b/cassandra/src/main/resources/scalate/dropDownMenuForKeyspace.ssp
new file mode 100644
index 0000000..74f6fbc
--- /dev/null
+++ b/cassandra/src/main/resources/scalate/dropDownMenuForKeyspace.ssp
@@ -0,0 +1,52 @@
+<%--
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*    http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+--%>
+#import(org.apache.zeppelin.cassandra.MetaDataHierarchy._)
+<%@ val ksContent: KeyspaceContent %>
+<li role="presentation" class="dropdown">
+    <a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
+        <span class="text-danger"><i class="glyphicon glyphicon-folder-open"/>&nbsp;&nbsp;<strong>${ksContent.keyspaceName}</strong></span>
+        <span class="text-danger caret"></span>
+        <ul class="dropdown-menu">
+            #if(ksContent.tables.nonEmpty)
+
+            <li class="dropdown-header"><span class="text-primary">Tables</span></li>
+                #for((id,name,_) <- ksContent.tables)
+            <li>
+                <a role="button" data-toggle="collapse" data-target="#${id}">
+                    <span class="text-primary"><i class="glyphicon glyphicon-th-list"/>&nbsp;${name}</span>
+                </a>
+            </li>
+                #end
+            #end
+
+            #if(ksContent.udts.nonEmpty)
+
+            <li role="separator" class="divider text-muted"></li>
+            <li class="dropdown-header"><span class="text-warning">User Defined Types</span></li>
+                #for((id,name,_) <- ksContent.udts)
+            <li>
+                <a role="button" data-toggle="collapse" data-target="#${id}">
+                    <span class="text-warning"><i class="glyphicon glyphicon-copyright-mark"/>&nbsp;${name}</span>
+                </a>
+            </li>
+                #end
+            #end
+        </ul>
+    </a>
+</li>
\ No newline at end of file


Mime
View raw message