mirror of
https://github.com/apache/zeppelin
synced 2026-05-24 09:38:26 +00:00
Merge branch 'master' into ZEPPELIN-732-up
This commit is contained in:
commit
e36d2fbfbb
40 changed files with 1373 additions and 607 deletions
|
|
@ -125,8 +125,8 @@ please check [its own contribution guidelines](https://github.com/apache/incubat
|
|||
|
||||
### Code convention
|
||||
We are following Google Code style:
|
||||
* [Java style](http://google-styleguide.googlecode.com/svn/trunk/javaguide.html)
|
||||
* [Shell style](https://google-styleguide.googlecode.com/svn/trunk/shell.xml)
|
||||
* [Java style](https://google.github.io/styleguide/javaguide.html)
|
||||
* [Shell style](https://google.github.io/styleguide/shell.xml)
|
||||
|
||||
Check style report location are in `${submodule}/target/site/checkstyle.html`
|
||||
Test coverage report location are in `${submodule}/target/site/cobertura/index.html`
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ mvn clean package -Pspark-1.5 -Pmapr50 -DskipTests
|
|||
#### Ignite Interpreter
|
||||
|
||||
```sh
|
||||
mvn clean package -Dignite.version=1.1.0-incubating -DskipTests
|
||||
mvn clean package -Dignite.version=1.6.0 -DskipTests
|
||||
```
|
||||
|
||||
#### Scalding Interpreter
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
<ul class="dropdown-menu">
|
||||
<!-- li><span><b>Overview</b><span></li -->
|
||||
<li><a href="{{BASE_PATH}}/index.html">Overview</a></li>
|
||||
<li><a href="{{BASE_PATH}}/quickstart/explorezeppelinui.html">Explore Zeppelin UI</a></li>
|
||||
<li><a href="{{BASE_PATH}}/quickstart/tutorial.html">Tutorial</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<!-- li><span><b>Install</b><span></li -->
|
||||
<li><a href="{{BASE_PATH}}/install/install.html">Install</a></li>
|
||||
|
|
@ -28,11 +30,6 @@
|
|||
<li role="separator" class="divider"></li>
|
||||
<li><a href="{{BASE_PATH}}/install/upgrade.html">Upgrade Version</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<!-- li><span><b>Tutorial</b><span></li -->
|
||||
<li><a href="{{BASE_PATH}}/tutorial/tutorial.html">Tutorial</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a href="{{BASE_PATH}}/ui_layout/zeppelin_layout.html">UI Layout</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<!-- li><span><b>Guide</b><span></li -->
|
||||
<li><a href="{{BASE_PATH}}/manual/dynamicform.html">Dynamic Form</a></li>
|
||||
<li><a href="{{BASE_PATH}}/manual/publish.html">Publish your Paragraph</a></li>
|
||||
|
|
@ -57,7 +54,7 @@
|
|||
<li><a href="{{BASE_PATH}}/interpreter/livy.html">Livy</a></li>
|
||||
<li><a href="{{BASE_PATH}}/interpreter/markdown.html">Markdown</a></li>
|
||||
<li><a href="{{BASE_PATH}}/interpreter/python.html">Python</a></li>
|
||||
<li><a href="{{BASE_PATH}}/interpreter/postgresql.html">Postgresql, hawq</a></li>
|
||||
<li><a href="{{BASE_PATH}}/interpreter/postgresql.html">Postgresql, HAWQ</a></li>
|
||||
<li><a href="{{BASE_PATH}}/interpreter/r.html">R</a></li>
|
||||
<li><a href="{{BASE_PATH}}/interpreter/scalding.html">Scalding</a></li>
|
||||
<li><a href="{{BASE_PATH}}/pleasecontribute.html">Shell</a></li>
|
||||
|
|
@ -71,8 +68,8 @@
|
|||
<li>
|
||||
<a href="#" data-toggle="dropdown" class="dropdown-toggle">Display System <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="{{BASE_PATH}}/displaysystem/display.html">Text</a></li>
|
||||
<li><a href="{{BASE_PATH}}/displaysystem/display.html#html">Html</a></li>
|
||||
<li><a href="{{BASE_PATH}}/displaysystem/text.html">Text</a></li>
|
||||
<li><a href="{{BASE_PATH}}/displaysystem/html.html">Html</a></li>
|
||||
<li><a href="{{BASE_PATH}}/displaysystem/table.html">Table</a></li>
|
||||
<li><a href="{{BASE_PATH}}/displaysystem/back-end-angular.html">Angular (backend API)</a></li>
|
||||
<li><a href="{{BASE_PATH}}/displaysystem/front-end-angular.html">Angular (frontend API)</a></li>
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
{% include themes/zeppelin/_navigation.html %}
|
||||
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
{{ content }}
|
||||
<hr>
|
||||
<footer>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,77 @@
|
|||
/* Move down content because we have a fixed navbar that is 50px tall */
|
||||
@import url(//fonts.googleapis.com/css?family=Patua+One);
|
||||
@import url(//fonts.googleapis.com/css?family=Open+Sans);
|
||||
|
||||
body {
|
||||
padding-top: 50px;
|
||||
padding-bottom: 20px;
|
||||
font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #4c555a;
|
||||
letter-spacing: .2px;
|
||||
}
|
||||
|
||||
.jumbotron {
|
||||
background: #3071a9;
|
||||
background-color: #3071a9;
|
||||
}
|
||||
|
||||
.jumbotron h1,
|
||||
.jumbotron p {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.jumbotron p {
|
||||
font-size: 19px;
|
||||
}
|
||||
|
||||
.jumbotron .btn {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.jumbotron .thumbnail {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.jumbotron.small {
|
||||
padding: 0 0 0 0;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.jumbotron.small .title{
|
||||
float: left;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
height: 30px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.jumbotron.small .subtitle{
|
||||
font-size: 14px;
|
||||
height: 30px;
|
||||
vertical-align: text-bottom;
|
||||
padding-top: 7px;
|
||||
}
|
||||
|
||||
.jumbotron.small .description{
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
.jumbotron h1 {
|
||||
font-family: 'Patua One', cursive;
|
||||
|
||||
.jumbotron h1 {
|
||||
font-family: 'Patua One', cursive;
|
||||
}
|
||||
|
||||
.jumbotron small {
|
||||
font-size: 60%;
|
||||
color: #FFF;
|
||||
}
|
||||
}
|
||||
|
||||
.jumbotron small {
|
||||
font-size: 60%;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
|
|
@ -147,85 +211,11 @@ body {
|
|||
}
|
||||
}
|
||||
|
||||
.jumbotron h1,
|
||||
.jumbotron p {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.jumbotron .thumbnail {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.jumbotron.small {
|
||||
padding: 0 0 0 0;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.jumbotron.small .title{
|
||||
float: left;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
height: 30px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.jumbotron.small .subtitle{
|
||||
font-size: 14px;
|
||||
height: 30px;
|
||||
vertical-align:text-bottom;
|
||||
padding-top:7px;
|
||||
}
|
||||
|
||||
.jumbotron.small .description{
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
/* screenshot img inside of doc */
|
||||
.screenshot {
|
||||
width: 800px;
|
||||
}
|
||||
|
||||
/* Table on the index page */
|
||||
.table-container {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.table-stack {
|
||||
width: 200px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.table-stack table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.table-stack tr td{
|
||||
border: 1px solid white;
|
||||
height: 40px;
|
||||
background: #6371a9;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.table-stack .gray {
|
||||
background:#DDDDDD;
|
||||
color:#777777;
|
||||
}
|
||||
|
||||
/* Table for property */
|
||||
.table-configuration {
|
||||
width : 100%;
|
||||
border : 1px solid gray;
|
||||
}
|
||||
.table-configuration tr td {
|
||||
border: 1px solid gray;
|
||||
padding: 5px;
|
||||
}
|
||||
.table-configuration tr th {
|
||||
border: 1px solid gray;
|
||||
padding: 5px;
|
||||
background: #B0C4DE;
|
||||
}
|
||||
|
||||
.rotate270 {
|
||||
width: 15px;
|
||||
padding: 10px 0 0 0;
|
||||
|
|
@ -237,132 +227,205 @@ body {
|
|||
}
|
||||
|
||||
/* Custom container */
|
||||
.content {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.content :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 64em) {
|
||||
.content {
|
||||
max-width: 64em;
|
||||
padding: 2rem 6rem;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 42em) and (max-width: 64em) {
|
||||
.content {
|
||||
padding: 2rem 4rem;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 42em) {
|
||||
.content {
|
||||
padding: 2rem 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* <a> */
|
||||
.container a {
|
||||
color: #4183C4; }
|
||||
.content a {
|
||||
color: #4183C4;
|
||||
}
|
||||
a.absent {
|
||||
color: #cc0000; }
|
||||
color: #cc0000;
|
||||
}
|
||||
a.anchor {
|
||||
display: block;
|
||||
padding-left: 30px;
|
||||
margin-left: -30px;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
display: block;
|
||||
padding-left: 30px;
|
||||
margin-left: -30px;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
/* <hn> */
|
||||
.container h1, h2, h3, h4, h5, h6 {
|
||||
margin: 20px 0 10px;
|
||||
padding: 0;
|
||||
font-weight: bold;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
cursor: text;
|
||||
position: relative; }
|
||||
.container h1 {
|
||||
font-size: 30px;
|
||||
color: black; }
|
||||
.container h2 {
|
||||
font-size: 28px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
border-bottom: 1px solid #E5E5E5;}
|
||||
.container h3 {
|
||||
font-size: 22px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
border-bottom: 1px solid #E5E5E5;}
|
||||
.container h4 {
|
||||
font-size: 18px; }
|
||||
.container h5 {
|
||||
font-size: 14px; }
|
||||
.container h6 {
|
||||
font-size: 14px;
|
||||
color: #777777;}
|
||||
|
||||
/* <li, ul, ol> */
|
||||
.container li {
|
||||
margin: 0; }
|
||||
.container li p.first {
|
||||
display: inline-block;}
|
||||
.container ul :first-child, ol :first-child {
|
||||
margin-top: 0;
|
||||
.content h1, h2, h3, h4, h5, h6 {
|
||||
font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
margin-top: 3rem;
|
||||
margin-bottom: 1rem;
|
||||
font-weight: bold;
|
||||
color: rgba(21,21,21,0.8);
|
||||
}
|
||||
.content h1 {
|
||||
font-size: 30px;
|
||||
color: black;
|
||||
}
|
||||
.content h2 {
|
||||
font-size: 28px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
border-bottom: 1px solid #E5E5E5;
|
||||
}
|
||||
.content h3 {
|
||||
font-size: 22px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
.content h4 {
|
||||
font-size: 18px;
|
||||
}
|
||||
.content h5 {
|
||||
font-size: 14px;
|
||||
}
|
||||
.content h6 {
|
||||
font-size: 14px;
|
||||
color: #777777;
|
||||
}
|
||||
|
||||
/* <table> */
|
||||
.container table {
|
||||
width : 100%;
|
||||
padding: 0;
|
||||
border-collapse: collapse; }
|
||||
.container table tr {
|
||||
border-top: 1px solid #cccccc;
|
||||
background-color: white;
|
||||
margin: 0;
|
||||
padding: 0; }
|
||||
.container table tr th {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
border: 1px solid #cccccc;
|
||||
margin: 0;
|
||||
padding: 6px 13px; }
|
||||
.container table tr td {
|
||||
border: 1px solid #cccccc;
|
||||
margin: 0;
|
||||
padding: 6px 13px;
|
||||
.content img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* <li, ul, ol> */
|
||||
.content li {
|
||||
margin: 0;
|
||||
}
|
||||
.content li p.first {
|
||||
display: inline-block;
|
||||
}
|
||||
.content ul :first-child, ol :first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.content .nav-tabs {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* <code> */
|
||||
.container code{
|
||||
color:#000000;
|
||||
font-size: 90%;
|
||||
font-family: "Menlo", "Lucida Console", monospace;
|
||||
background-color: #f8f8f8;
|
||||
border: 1px solid #cccccc;
|
||||
.content code {
|
||||
padding: 2px 4px;
|
||||
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 90%;
|
||||
color: #567482;
|
||||
background-color: #f3f6fa;
|
||||
border-radius: 0.3rem;
|
||||
}
|
||||
|
||||
/* <pre> */
|
||||
.container pre {
|
||||
background-color: #f8f8f8;
|
||||
border: 1px solid #cccccc;
|
||||
line-height: 19px;
|
||||
overflow: auto;
|
||||
padding: 6px 10px;
|
||||
border-radius: 3px;}
|
||||
.container pre code {
|
||||
font-size: 95%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
white-space: pre;
|
||||
border: none;
|
||||
background: transparent;
|
||||
.content pre {
|
||||
padding: 0.8rem;
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
font: Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 90%;
|
||||
color: #567482;
|
||||
word-wrap: normal;
|
||||
background-color: #f3f6fa;
|
||||
border: solid 1px #dce6f0;
|
||||
border-radius: 0.3rem;
|
||||
}
|
||||
.content pre > code {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 95%;
|
||||
color: #567482;
|
||||
word-break: normal;
|
||||
white-space: pre;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
}
|
||||
.content .highlight {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.content .highlight pre {
|
||||
margin-bottom: 0;
|
||||
word-break: normal;
|
||||
}
|
||||
.content .highlight pre,
|
||||
.content pre {
|
||||
padding: 0.8rem;
|
||||
overflow: auto;
|
||||
font-size: 90%;
|
||||
line-height: 1.45;
|
||||
border-radius: 0.3rem;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
.content pre code,
|
||||
.content pre tt {
|
||||
display: inline;
|
||||
max-width: initial;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: initial;
|
||||
line-height: inherit;
|
||||
word-wrap: normal;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
}
|
||||
.content pre code:before, .main-content pre code:after,
|
||||
.content pre tt:before,
|
||||
.content pre tt:after {
|
||||
content: normal;
|
||||
}
|
||||
|
||||
/* <blockquote> */
|
||||
.container blockquote {
|
||||
border-left: 4px solid #dddddd;
|
||||
padding: 0 15px;
|
||||
color: #777777; }
|
||||
.container blockquote > :first-child {
|
||||
margin-top: 0; }
|
||||
.container blockquote > :last-child {
|
||||
margin-bottom: 0; }
|
||||
.container blockquote p{
|
||||
font-size: 14px;
|
||||
/* <blockquotes> */
|
||||
.content blockquote {
|
||||
padding: 0 1rem;
|
||||
margin-left: 0;
|
||||
color: #819198;
|
||||
border-left: 0.3rem solid #dce6f0;
|
||||
}
|
||||
.content blockquote > :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
.content blockquote > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.content blockquote p {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* <p>, <blockquote>, <table>, <pre>, <img> margin */
|
||||
.container p, blockquote, table, pre, img {
|
||||
margin: 12px 0;
|
||||
/* <table> */
|
||||
.content table {
|
||||
display: block;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
word-break: normal;
|
||||
word-break: keep-all;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
.container-narrow {
|
||||
margin: 0 auto;
|
||||
.content table th {
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
background-color: rgba(91, 138, 179, 0.10);
|
||||
}
|
||||
|
||||
.container-narrow > hr {
|
||||
margin: 30px 0;
|
||||
.content table th,
|
||||
.content table td {
|
||||
padding: 0.5rem 1rem;
|
||||
border: 1px solid #e9ebec;
|
||||
}
|
||||
|
||||
/* posts index */
|
||||
|
|
@ -432,15 +495,6 @@ a.anchor {
|
|||
color: white;
|
||||
}
|
||||
|
||||
.jumbotron h1 {
|
||||
font-family: 'Patua One', cursive;
|
||||
}
|
||||
|
||||
.jumbotron small {
|
||||
font-size: 60%;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-family: 'Patua One', cursive;
|
||||
}
|
||||
|
|
@ -455,9 +509,11 @@ a.anchor {
|
|||
max-height: 50px;
|
||||
}
|
||||
|
||||
#apache .caret {
|
||||
.navbar-inverse .navbar-nav a .caret,
|
||||
.navbar-inverse .navbar-nav a:hover .caret {
|
||||
margin-left: 4px;
|
||||
border-top-color: white;
|
||||
border-bottom-color: white;
|
||||
}
|
||||
|
||||
.navbar-inverse .navbar-nav > .open > a,
|
||||
|
|
@ -472,7 +528,6 @@ a.anchor {
|
|||
.jumbotron h1 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.navbar-brand small {
|
||||
display: none;
|
||||
color: white;
|
||||
|
|
@ -497,7 +552,7 @@ and (max-width: 1024px) {
|
|||
}
|
||||
}
|
||||
|
||||
/* docs dropdown menu */
|
||||
/* master branch docs dropdown menu */
|
||||
#menu .dropdown-menu li span {
|
||||
padding: 3px 10px 10px 10px;
|
||||
font-size: 13px;
|
||||
|
|
@ -517,6 +572,13 @@ and (max-width: 1024px) {
|
|||
margin-right: 50px;
|
||||
}
|
||||
|
||||
.row img {
|
||||
max-width: 100%;
|
||||
/* gh-pages branch docs dropdown menu */
|
||||
#docs .dropdown-menu {
|
||||
left: 0;
|
||||
right: auto;
|
||||
}
|
||||
|
||||
#docs .dropdown-menu li span {
|
||||
padding: 3px 10px 10px 10px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ group: development
|
|||
# Contributing to Apache Zeppelin ( Website )
|
||||
|
||||
## IMPORTANT
|
||||
Apache Zeppelin (incubating) is an [Apache2 License](http://www.apache.org/licenses/LICENSE-2.0.html) Software.
|
||||
Apache Zeppelin is an [Apache2 License](http://www.apache.org/licenses/LICENSE-2.0.html) Software.
|
||||
Any contribution to Zeppelin (Source code, Documents, Image, Website) means you agree license all your contributions as Apache2 License.
|
||||
|
||||
|
||||
|
|
@ -52,4 +52,4 @@ Zeppelin manages its issues in Jira. [https://issues.apache.org/jira/browse/ZEPP
|
|||
## Stay involved
|
||||
Contributors should join the Zeppelin mailing lists.
|
||||
|
||||
* [dev@zeppelin.apache.org](http://mail-archives.apache.org/mod_mbox/incubator-zeppelin-dev/) is for people who want to contribute code to Zeppelin. [subscribe](mailto:dev-subscribe@zeppelin.apache.org?subject=send this email to subscribe), [unsubscribe](mailto:dev-unsubscribe@zeppelin.apache.org?subject=send this email to unsubscribe), [archives](http://mail-archives.apache.org/mod_mbox/incubator-zeppelin-dev/)
|
||||
* [dev@zeppelin.apache.org](http://mail-archives.apache.org/mod_mbox/zeppelin-dev/) is for people who want to contribute code to Zeppelin. [subscribe](mailto:dev-subscribe@zeppelin.apache.org?subject=send this email to subscribe), [unsubscribe](mailto:dev-unsubscribe@zeppelin.apache.org?subject=send this email to unsubscribe), [archives](http://mail-archives.apache.org/mod_mbox/zeppelin-dev/)
|
||||
|
|
|
|||
25
docs/displaysystem/html.md
Normal file
25
docs/displaysystem/html.md
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Html Display System"
|
||||
description: ""
|
||||
group: display
|
||||
---
|
||||
<!--
|
||||
Licensed 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.
|
||||
-->
|
||||
{% include JB/setup %}
|
||||
## Html
|
||||
|
||||
With '%html' directive, Zeppelin treats your output as html
|
||||
|
||||
<img src="/assets/themes/zeppelin/img/screenshots/display_html.png" />
|
||||
|
|
@ -19,8 +19,7 @@ limitations under the License.
|
|||
-->
|
||||
{% include JB/setup %}
|
||||
|
||||
|
||||
### Table
|
||||
## Table
|
||||
|
||||
If you have data that row seprated by '\n' (newline) and column separated by '\t' (tab) with first row as header row, for example
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Text/Html Display System"
|
||||
title: "Text Display System"
|
||||
description: ""
|
||||
group: display
|
||||
---
|
||||
|
|
@ -18,12 +18,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
-->
|
||||
{% include JB/setup %}
|
||||
|
||||
|
||||
<a name="text"> </a>
|
||||
<br />
|
||||
<br />
|
||||
### Text
|
||||
## Text
|
||||
|
||||
Zeppelin prints output of language backend in text, by default.
|
||||
|
||||
|
|
@ -34,12 +29,3 @@ You can explicitly say you're using text display system.
|
|||
<img src="/assets/themes/zeppelin/img/screenshots/display_text1.png" />
|
||||
|
||||
Note that display system is backend independent.
|
||||
|
||||
<a name="html"> </a>
|
||||
<br />
|
||||
<br />
|
||||
### Html
|
||||
|
||||
With '%html' directive, Zeppelin treats your output as html
|
||||
|
||||
<img src="/assets/themes/zeppelin/img/screenshots/display_html.png" />
|
||||
|
|
@ -20,7 +20,7 @@ limitations under the License.
|
|||
{% include JB/setup %}
|
||||
<br />
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<div class="col-md-6">
|
||||
<h2>Multi-purpose Notebook</h2>
|
||||
|
||||
<p style="font-size:16px; color:#555555;font-style:italic;margin-bottom: 15px;">
|
||||
|
|
@ -34,7 +34,7 @@ limitations under the License.
|
|||
</ul>
|
||||
|
||||
</div>
|
||||
<div class="col-md-7"><img class="img-responsive" style="border: 1px solid #ecf0f1;" height="auto" src="/assets/themes/zeppelin/img/notebook.png" /></div>
|
||||
<div class="col-md-6"><img class="img-responsive" style="border: 1px solid #ecf0f1;" height="auto" src="/assets/themes/zeppelin/img/notebook.png" /></div>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
|
|
|||
|
|
@ -23,6 +23,11 @@ Additional requirements for the Livy interpreter are:
|
|||
* Livy server.
|
||||
|
||||
### Configuration
|
||||
We added some common configurations for spark, and you can set any configuration you want.
|
||||
This link contains all spark configurations: http://spark.apache.org/docs/latest/configuration.html#available-properties.
|
||||
And instead of starting property with `spark.` it should be replaced with `livy.spark.`.
|
||||
Example: `spark.master` to `livy.spark.master`
|
||||
|
||||
<table class="table-configuration">
|
||||
<tr>
|
||||
<th>Property</th>
|
||||
|
|
@ -30,7 +35,7 @@ Additional requirements for the Livy interpreter are:
|
|||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>zeppelin.livy.master</td>
|
||||
<td>livy.spark.master</td>
|
||||
<td>local[*]</td>
|
||||
<td>Spark master uri. ex) spark://masterhost:7077</td>
|
||||
</tr>
|
||||
|
|
@ -44,6 +49,56 @@ Additional requirements for the Livy interpreter are:
|
|||
<td>1000</td>
|
||||
<td>Max number of SparkSQL result to display.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>livy.spark.driver.cores</td>
|
||||
<td></td>
|
||||
<td>Driver cores. ex) 1, 2.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>livy.spark.driver.memory</td>
|
||||
<td></td>
|
||||
<td>Driver memory. ex) 512m, 32g.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>livy.spark.executor.instances</td>
|
||||
<td></td>
|
||||
<td>Executor instances. ex) 1, 4.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>livy.spark.executor.cores</td>
|
||||
<td></td>
|
||||
<td>Num cores per executor. ex) 1, 4.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>livy.spark.executor.memory</td>
|
||||
<td></td>
|
||||
<td>Executor memory per worker instance. ex) 512m, 32g.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>livy.spark.dynamicAllocation.enabled</td>
|
||||
<td></td>
|
||||
<td>Use dynamic resource allocation. ex) True, False.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>livy.spark.dynamicAllocation.cachedExecutorIdleTimeout</td>
|
||||
<td></td>
|
||||
<td>Remove an executor which has cached data blocks.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>livy.spark.dynamicAllocation.minExecutors</td>
|
||||
<td></td>
|
||||
<td>Lower bound for the number of executors.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>livy.spark.dynamicAllocation.initialExecutors</td>
|
||||
<td></td>
|
||||
<td>Initial number of executors to run.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>livy.spark.dynamicAllocation.maxExecutors</td>
|
||||
<td></td>
|
||||
<td>Upper bound for the number of executors.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
|
@ -105,3 +160,6 @@ The session would have timed out, you may need to restart the interpreter.
|
|||
> Blacklisted configuration values in session config: spark.master
|
||||
|
||||
edit `conf/spark-blacklist.conf` file in livy server and comment out `#spark.master` line.
|
||||
|
||||
if you choose to work on livy in `apps/spark/java` directory in https://github.com/cloudera/hue ,
|
||||
copy `spark-user-configurable-options.template` to `spark-user-configurable-options.conf` file in livy server and comment out `#spark.master`
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ group: manual
|
|||
|
||||
## Spark Interpreter for Apache Zeppelin
|
||||
[Apache Spark](http://spark.apache.org) is supported in Zeppelin with
|
||||
Spark Interpreter group, which consisted of 4 interpreters.
|
||||
Spark Interpreter group, which consists of five interpreters.
|
||||
|
||||
<table class="table-configuration">
|
||||
<tr>
|
||||
|
|
@ -354,14 +354,14 @@ Logical setup with Zeppelin, Kerberos Key Distribution Center (KDC), and Spark o
|
|||
1. On the server that Zeppelin is installed, install Kerberos client modules and configuration, krb5.conf.
|
||||
This is to make the server communicate with KDC.
|
||||
|
||||
2. Set SPARK\_HOME in [ZEPPELIN\_HOME]/conf/zeppelin-env.sh to use spark-submit
|
||||
( Additionally, you might have to set “export HADOOP\_CONF\_DIR=/etc/hadoop/conf” )
|
||||
2. Set SPARK\_HOME in `[ZEPPELIN\_HOME]/conf/zeppelin-env.sh` to use spark-submit
|
||||
(Additionally, you might have to set `export HADOOP\_CONF\_DIR=/etc/hadoop/conf`)
|
||||
|
||||
3. Add the two properties below to spark configuration ( [SPARK_HOME]/conf/spark-defaults.conf ):
|
||||
3. Add the two properties below to spark configuration (`[SPARK_HOME]/conf/spark-defaults.conf`):
|
||||
|
||||
spark.yarn.principal
|
||||
spark.yarn.keytab
|
||||
|
||||
> **NOTE:** If you do not have access to the above spark-defaults.conf file, optionally, you may add the lines to the Spark Interpreter through the Interpreter tab in the Zeppelin UI.
|
||||
|
||||
4. That's it. Play with Zeppelin !
|
||||
4. That's it. Play with Zeppelin!
|
||||
|
|
|
|||
|
|
@ -30,37 +30,37 @@ This mode creates form using simple template language. It's simple and easy to u
|
|||
|
||||
#### Text input form
|
||||
|
||||
To create text input form, use _${formName}_ templates.
|
||||
To create text input form, use `${formName}` templates.
|
||||
|
||||
for example
|
||||
|
||||
<img src="../assets/themes/zeppelin/img/screenshots/form_input.png" />
|
||||
|
||||
|
||||
Also you can provide default value, using _${formName=defaultValue}_.
|
||||
Also you can provide default value, using `${formName=defaultValue}`.
|
||||
|
||||
<img src="../assets/themes/zeppelin/img/screenshots/form_input_default.png" />
|
||||
|
||||
|
||||
#### Select form
|
||||
|
||||
To create select form, use _${formName=defaultValue,option1|option2...}_
|
||||
To create select form, use `${formName=defaultValue,option1|option2...}`
|
||||
|
||||
for example
|
||||
|
||||
<img src="../assets/themes/zeppelin/img/screenshots/form_select.png" />
|
||||
|
||||
Also you can separate option's display name and value, using _${formName=defaultValue,option1(DisplayName)|option2(DisplayName)...}_
|
||||
Also you can separate option's display name and value, using `${formName=defaultValue,option1(DisplayName)|option2(DisplayName)...}`
|
||||
|
||||
<img src="../assets/themes/zeppelin/img/screenshots/form_select_displayname.png" />
|
||||
|
||||
#### Checkbox form
|
||||
|
||||
For multi-selection, you can create a checkbox form using _${checkbox:formName=defaultValue1|defaultValue2...,option1|option2...}_. The variable will be substituted by a comma-separated string based on the selected items. For example:
|
||||
For multi-selection, you can create a checkbox form using `${checkbox:formName=defaultValue1|defaultValue2...,option1|option2...}`. The variable will be substituted by a comma-separated string based on the selected items. For example:
|
||||
|
||||
<img src="../assets/themes/zeppelin/img/screenshots/form_checkbox.png">
|
||||
|
||||
Besides, you can specify the delimiter using _${checkbox(delimiter):formName=...}_:
|
||||
Besides, you can specify the delimiter using `${checkbox(delimiter):formName=...}`:
|
||||
|
||||
<img src="../assets/themes/zeppelin/img/screenshots/form_checkbox_delimiter.png">
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Zeppelin UI Layout"
|
||||
title: "Explore Zeppelin UI"
|
||||
description: "Description of Zeppelin UI Layout"
|
||||
group: ui_layout
|
||||
group: quickstart
|
||||
---
|
||||
<!--
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
|
@ -26,7 +26,7 @@ The first time you connect to Zeppelin, you'll land at the main page similar to
|
|||
On the left of the page are listed all existing notes. Those notes are stored by default in the `$ZEPPELIN_HOME/notebook` folder.
|
||||
|
||||
You can filter them by name using the input text form. You can also create an new note, refresh the list of existing notes
|
||||
(in case you manually copy them into the `$ZEPPELIN_HOME/notebook` folder) and import a note
|
||||
(in case you manually copy them into the `$ZEPPELIN_HOME/notebook` folder) and import a note.
|
||||
|
||||
<img src="../assets/themes/zeppelin/img/ui-img/notes_management.png" />
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ if you provide the URL.
|
|||
|
||||
<img src="../assets/themes/zeppelin/img/ui-img/note_import_dialog.png" />
|
||||
|
||||
By default, the name of the imported note is the same as the original note but you can override it by providing a new name
|
||||
By default, the name of the imported note is the same as the original note but you can override it by providing a new name.
|
||||
|
||||
<br />
|
||||
## Menus
|
||||
|
|
@ -106,11 +106,11 @@ From this dialog, you can (in descending order):
|
|||
|
||||
### Note toolbar
|
||||
|
||||
At the top of the note, you can find a toolbar which exposes command buttons as well as configuration, security and display options
|
||||
At the top of the note, you can find a toolbar which exposes command buttons as well as configuration, security and display options.
|
||||
|
||||
<img src="../assets/themes/zeppelin/img/ui-img/note_toolbar.png" />
|
||||
|
||||
On the far right is displayed the note name, just click on it to reveal the input form and update it
|
||||
On the far right is displayed the note name, just click on it to reveal the input form and update it.
|
||||
|
||||
In the middle of the toolbar you can find the command buttons:
|
||||
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
layout: page
|
||||
title: "Tutorial"
|
||||
description: "Tutorial is valid for Spark 1.3 and higher"
|
||||
group: tutorial
|
||||
group: quickstart
|
||||
---
|
||||
<!--
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
|
@ -20,29 +20,23 @@ limitations under the License.
|
|||
{% include JB/setup %}
|
||||
|
||||
## Zeppelin REST API
|
||||
Zeppelin provides several REST API's for interaction and remote activation of zeppelin functionality.
|
||||
Zeppelin provides several REST APIs for interaction and remote activation of zeppelin functionality.
|
||||
|
||||
All REST API are available starting with the following endpoint ```http://[zeppelin-server]:[zeppelin-port]/api```
|
||||
All REST APIs are available starting with the following endpoint `http://[zeppelin-server]:[zeppelin-port]/api`. Note that zeppelin REST APIs receive or return JSON objects, it is recommended for you to install some JSON viewers such as [JSONView](https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc).
|
||||
|
||||
Note that Zeppelin REST API receive or return JSON objects, it it recommended you install some JSON viewers such as
|
||||
[JSONView](https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc)
|
||||
|
||||
|
||||
If you work with zeppelin and find a need for an additional REST API please [file an issue or send us mail](../../community.html)
|
||||
If you work with Zeppelin and find a need for an additional REST API, please [file an issue or send us mail](../../community.html).
|
||||
|
||||
<br />
|
||||
### Configuration REST API list
|
||||
|
||||
## Configuration REST API list
|
||||
|
||||
### List Configurations
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>List configurations</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```GET``` method return all key/value pair of configurations on the server.<br/>
|
||||
Note: For security reason, some pairs would not be shown.</td>
|
||||
Note: For security reason, some pairs would not be shown.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>URL</td>
|
||||
|
|
@ -61,48 +55,43 @@ limitations under the License.
|
|||
</td>
|
||||
<td>
|
||||
<pre>
|
||||
{
|
||||
"status":"OK",
|
||||
"message":"",
|
||||
"body":{
|
||||
"zeppelin.war.tempdir":"webapps",
|
||||
"zeppelin.notebook.homescreen.hide":"false",
|
||||
"zeppelin.interpreter.remoterunner":"bin/interpreter.sh",
|
||||
"zeppelin.notebook.s3.user":"user",
|
||||
"zeppelin.server.port":"8089",
|
||||
"zeppelin.dep.localrepo":"local-repo",
|
||||
"zeppelin.ssl.truststore.type":"JKS",
|
||||
"zeppelin.ssl.keystore.path":"keystore",
|
||||
"zeppelin.notebook.s3.bucket":"zeppelin",
|
||||
"zeppelin.server.addr":"0.0.0.0",
|
||||
"zeppelin.ssl.client.auth":"false",
|
||||
"zeppelin.server.context.path":"/",
|
||||
"zeppelin.ssl.keystore.type":"JKS",
|
||||
"zeppelin.ssl.truststore.path":"truststore",
|
||||
"zeppelin.interpreters":"org.apache.zeppelin.spark.SparkInterpreter,org.apache.zeppelin.spark.PySparkInterpreter,org.apache.zeppelin.spark.SparkRInterpreter,org.apache.zeppelin.spark.SparkSqlInterpreter,org.apache.zeppelin.spark.DepInterpreter,org.apache.zeppelin.markdown.Markdown,org.apache.zeppelin.angular.AngularInterpreter,org.apache.zeppelin.shell.ShellInterpreter,org.apache.zeppelin.hive.HiveInterpreter,org.apache.zeppelin.tajo.TajoInterpreter,org.apache.zeppelin.flink.FlinkInterpreter,org.apache.zeppelin.lens.LensInterpreter,org.apache.zeppelin.ignite.IgniteInterpreter,org.apache.zeppelin.ignite.IgniteSqlInterpreter,org.apache.zeppelin.cassandra.CassandraInterpreter,org.apache.zeppelin.geode.GeodeOqlInterpreter,org.apache.zeppelin.postgresql.PostgreSqlInterpreter,org.apache.zeppelin.phoenix.PhoenixInterpreter,org.apache.zeppelin.kylin.KylinInterpreter,org.apache.zeppelin.elasticsearch.ElasticsearchInterpreter,org.apache.zeppelin.scalding.ScaldingInterpreter",
|
||||
"zeppelin.ssl":"false",
|
||||
"zeppelin.notebook.autoInterpreterBinding":"true",
|
||||
"zeppelin.notebook.homescreen":"",
|
||||
"zeppelin.notebook.storage":"org.apache.zeppelin.notebook.repo.VFSNotebookRepo",
|
||||
"zeppelin.interpreter.connect.timeout":"30000",
|
||||
"zeppelin.anonymous.allowed":"true",
|
||||
"zeppelin.server.allowed.origins":"*",
|
||||
"zeppelin.encoding":"UTF-8"
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</td>
|
||||
{
|
||||
"status": "OK",
|
||||
"message": "",
|
||||
"body": {
|
||||
"zeppelin.war.tempdir": "webapps",
|
||||
"zeppelin.notebook.homescreen.hide": "false",
|
||||
"zeppelin.interpreter.remoterunner": "bin/interpreter.sh",
|
||||
"zeppelin.notebook.s3.user": "user",
|
||||
"zeppelin.server.port": "8089",
|
||||
"zeppelin.dep.localrepo": "local-repo",
|
||||
"zeppelin.ssl.truststore.type": "JKS",
|
||||
"zeppelin.ssl.keystore.path": "keystore",
|
||||
"zeppelin.notebook.s3.bucket": "zeppelin",
|
||||
"zeppelin.server.addr": "0.0.0.0",
|
||||
"zeppelin.ssl.client.auth": "false",
|
||||
"zeppelin.server.context.path": "/",
|
||||
"zeppelin.ssl.keystore.type": "JKS",
|
||||
"zeppelin.ssl.truststore.path": "truststore",
|
||||
"zeppelin.interpreters": "org.apache.zeppelin.spark.SparkInterpreter,org.apache.zeppelin.spark.PySparkInterpreter,org.apache.zeppelin.spark.SparkRInterpreter,org.apache.zeppelin.spark.SparkSqlInterpreter,org.apache.zeppelin.spark.DepInterpreter,org.apache.zeppelin.markdown.Markdown,org.apache.zeppelin.angular.AngularInterpreter,org.apache.zeppelin.shell.ShellInterpreter,org.apache.zeppelin.hive.HiveInterpreter,org.apache.zeppelin.tajo.TajoInterpreter,org.apache.zeppelin.flink.FlinkInterpreter,org.apache.zeppelin.lens.LensInterpreter,org.apache.zeppelin.ignite.IgniteInterpreter,org.apache.zeppelin.ignite.IgniteSqlInterpreter,org.apache.zeppelin.cassandra.CassandraInterpreter,org.apache.zeppelin.geode.GeodeOqlInterpreter,org.apache.zeppelin.postgresql.PostgreSqlInterpreter,org.apache.zeppelin.phoenix.PhoenixInterpreter,org.apache.zeppelin.kylin.KylinInterpreter,org.apache.zeppelin.elasticsearch.ElasticsearchInterpreter,org.apache.zeppelin.scalding.ScaldingInterpreter",
|
||||
"zeppelin.ssl": "false",
|
||||
"zeppelin.notebook.autoInterpreterBinding": "true",
|
||||
"zeppelin.notebook.homescreen": "",
|
||||
"zeppelin.notebook.storage": "org.apache.zeppelin.notebook.repo.VFSNotebookRepo",
|
||||
"zeppelin.interpreter.connect.timeout": "30000",
|
||||
"zeppelin.anonymous.allowed": "true",
|
||||
"zeppelin.server.allowed.origins":"*",
|
||||
"zeppelin.encoding": "UTF-8"
|
||||
}
|
||||
}</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
### List Configurations(prefix match)
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>List configurations (prefix match)</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```GET``` method return all prefix matched key/value pair of configurations on the server.<br/>
|
||||
|
|
@ -123,21 +112,19 @@ limitations under the License.
|
|||
<tr>
|
||||
<td> sample JSON response
|
||||
</td>
|
||||
<td>
|
||||
<pre>
|
||||
{
|
||||
"status":"OK",
|
||||
"message":"",
|
||||
"body":{
|
||||
"zeppelin.ssl.keystore.type":"JKS",
|
||||
"zeppelin.ssl.truststore.path":"truststore",
|
||||
"zeppelin.ssl.truststore.type":"JKS",
|
||||
"zeppelin.ssl.keystore.path":"keystore",
|
||||
"zeppelin.ssl":"false",
|
||||
"zeppelin.ssl.client.auth":"false"
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
<td><pre>
|
||||
{
|
||||
"status": "OK",
|
||||
"message": "",
|
||||
"body": {
|
||||
"zeppelin.ssl.keystore.type": "JKS",
|
||||
"zeppelin.ssl.truststore.path": "truststore",
|
||||
"zeppelin.ssl.truststore.type": "JKS",
|
||||
"zeppelin.ssl.keystore.path": "keystore",
|
||||
"zeppelin.ssl": "false",
|
||||
"zeppelin.ssl.client.auth": "false"
|
||||
}
|
||||
}</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -20,27 +20,21 @@ limitations under the License.
|
|||
{% include JB/setup %}
|
||||
|
||||
## Zeppelin REST API
|
||||
Zeppelin provides several REST API's for interaction and remote activation of zeppelin functionality.
|
||||
Zeppelin provides several REST APIs for interaction and remote activation of zeppelin functionality.
|
||||
|
||||
All REST API are available starting with the following endpoint `http://[zeppelin-server]:[zeppelin-port]/api`.
|
||||
Note that Zeppelin REST API receive or return JSON objects, it it recommended you install some JSON viewers such as
|
||||
[JSON View](https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc).
|
||||
All REST APIs are available starting with the following endpoint `http://[zeppelin-server]:[zeppelin-port]/api`. Note that zeppelin REST APIs receive or return JSON objects, it is recommended for you to install some JSON viewers such as [JSONView](https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc).
|
||||
|
||||
If you work with zeppelin and find a need for an additional REST API, please [file an issue or send us mail](http://zeppelin.apache.org/community.html).
|
||||
If you work with Zeppelin and find a need for an additional REST API, please [file an issue or send us mail](http://zeppelin.apache.org/community.html).
|
||||
|
||||
<br />
|
||||
## Interpreter REST API List
|
||||
|
||||
The role of registered interpreters, settings and interpreters group are described in [here](../manual/interpreters.html).
|
||||
|
||||
### 1. List of Registered Interpreters & Interpreter Settings
|
||||
### List of Registered Interpreters
|
||||
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>List of registered interpreters</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```GET``` method returns all the registered interpreters available on the server.</td>
|
||||
|
|
@ -109,12 +103,9 @@ limitations under the License.
|
|||
|
||||
<br/>
|
||||
|
||||
### List of Interpreter Settings
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>List of interpreters settings</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```GET``` method returns all the interpreters settings registered on the server.</td>
|
||||
|
|
@ -186,14 +177,10 @@ limitations under the License.
|
|||
</table>
|
||||
|
||||
<br/>
|
||||
### 2. Create an Interpreter Setting
|
||||
### Create an Interpreter Setting
|
||||
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Create an interpreter setting</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```POST``` method adds a new interpreter setting using a registered interpreter to the server.</td>
|
||||
|
|
@ -272,13 +259,9 @@ limitations under the License.
|
|||
|
||||
<br/>
|
||||
|
||||
### 3. Update an Interpreter Setting
|
||||
### Update an Interpreter Setting
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Update an interpreter setting</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```PUT``` method updates an interpreter setting with new properties.</td>
|
||||
|
|
@ -356,14 +339,10 @@ limitations under the License.
|
|||
|
||||
|
||||
<br/>
|
||||
### 4. Delete an Interpreter Setting
|
||||
### Delete an Interpreter Setting
|
||||
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Delete an interpreter setting</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```DELETE``` method deletes an given interpreter setting.</td>
|
||||
|
|
@ -390,14 +369,10 @@ limitations under the License.
|
|||
|
||||
|
||||
<br/>
|
||||
### 5. Restart an Interpreter
|
||||
### Restart an Interpreter
|
||||
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Restart an interpreter</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```PUT``` method restarts the given interpreter id.</td>
|
||||
|
|
@ -423,14 +398,10 @@ limitations under the License.
|
|||
</table>
|
||||
|
||||
<br/>
|
||||
### 6. Add repository for dependency resolving
|
||||
### Add repository for dependency resolving
|
||||
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Add new repository for dependency loader</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```POST``` method adds new repository.</td>
|
||||
|
|
@ -468,14 +439,10 @@ limitations under the License.
|
|||
</table>
|
||||
|
||||
<br/>
|
||||
### 7. Delete repository for dependency resolving
|
||||
### Delete repository for dependency resolving
|
||||
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Delete repository for dependency loader</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```DELETE``` method delete repository with given id.</td>
|
||||
|
|
|
|||
|
|
@ -22,25 +22,19 @@ limitations under the License.
|
|||
## Zeppelin REST API
|
||||
Zeppelin provides several REST APIs for interaction and remote activation of zeppelin functionality.
|
||||
|
||||
All REST APIs are available starting with the following endpoint ```http://[zeppelin-server]:[zeppelin-port]/api```
|
||||
All REST APIs are available starting with the following endpoint `http://[zeppelin-server]:[zeppelin-port]/api`. Note that zeppelin REST APIs receive or return JSON objects, it is recommended for you to install some JSON viewers such as [JSONView](https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc).
|
||||
|
||||
Note that zeppelin REST APIs receive or return JSON objects, it is recommended for you to install some JSON viewers
|
||||
such as [JSONView](https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc)
|
||||
If you work with Zeppelin and find a need for an additional REST API, please [file an issue or send us mail](../../community.html).
|
||||
|
||||
<br />
|
||||
|
||||
If you work with zeppelin and find a need for an additional REST API please [file an issue or send us mail](../../community.html)
|
||||
## Notebook REST API List
|
||||
|
||||
<br />
|
||||
### Notebook REST API list
|
||||
|
||||
Notebooks REST API supports the following operations: List, Create, Get, Delete, Clone, Run, Export, Import as detailed in the following table
|
||||
Notebooks REST API supports the following operations: List, Create, Get, Delete, Clone, Run, Export, Import as detailed in the following tables.
|
||||
|
||||
### List Notebooks
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>List notebooks</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```GET``` method lists the available notebooks on your server.
|
||||
|
|
@ -61,18 +55,29 @@ limitations under the License.
|
|||
</tr>
|
||||
<tr>
|
||||
<td> sample JSON response </td>
|
||||
<td><pre>{"status":"OK","message":"","body":[{"name":"Homepage","id":"2AV4WUEMK"},{"name":"Zeppelin Tutorial","id":"2A94M5J1Z"}]}</pre></td>
|
||||
<td><pre>
|
||||
{
|
||||
"status": "OK",
|
||||
"message": "",
|
||||
"body": [
|
||||
{
|
||||
"name":"Homepage",
|
||||
"id":"2AV4WUEMK"
|
||||
},
|
||||
{
|
||||
"name":"Zeppelin Tutorial",
|
||||
"id":"2A94M5J1Z"
|
||||
}
|
||||
]
|
||||
}</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
### Create Notebook
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Create notebook</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```POST``` method creates a new notebook using the given name or default name if none given.
|
||||
|
|
@ -93,7 +98,7 @@ limitations under the License.
|
|||
</tr>
|
||||
<tr>
|
||||
<td> sample JSON input (without paragraphs) </td>
|
||||
<td><pre>{ "name": "name of new notebook" }</pre></td>
|
||||
<td><pre>{"name": "name of new notebook"}</pre></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> sample JSON input (with initial paragraphs) </td>
|
||||
|
|
@ -110,23 +115,24 @@ limitations under the License.
|
|||
"text": "paragraph text2"
|
||||
}
|
||||
]
|
||||
}
|
||||
</pre></td>
|
||||
}</pre></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> sample JSON response </td>
|
||||
<td><pre>{"status": "CREATED","message": "","body": "2AZPHY918"}</pre></td>
|
||||
<td><pre>
|
||||
{
|
||||
"status": "CREATED",
|
||||
"message": "",
|
||||
"body": "2AZPHY918"
|
||||
}</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
### Get Notebook
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Get notebook</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```GET``` method retrieves an existing notebook's information using the given id.
|
||||
|
|
@ -194,8 +200,8 @@ limitations under the License.
|
|||
"params": {},
|
||||
"forms": {}
|
||||
},
|
||||
"jobName": "paragraph_1423500782552_-1439281894",
|
||||
"id": "20150210-015302_1492795503",
|
||||
"jobName": "paragraph\_1423500782552\_-1439281894",
|
||||
"id": "20150210-015302\_1492795503",
|
||||
"result": {
|
||||
"code": "SUCCESS",
|
||||
"type": "TABLE",
|
||||
|
|
@ -216,19 +222,15 @@ limitations under the License.
|
|||
},
|
||||
"info": {}
|
||||
}
|
||||
}
|
||||
</pre></td>
|
||||
}</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
### Delete Notebook
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Delete notebook</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```DELETE``` method deletes a notebook by the given notebook id.
|
||||
|
|
@ -248,18 +250,15 @@ limitations under the License.
|
|||
</tr>
|
||||
<tr>
|
||||
<td> sample JSON response </td>
|
||||
<td><pre>{"status":"OK","message":""}</pre></td>
|
||||
<td><pre>{"status": "OK","message": ""}</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
### Clone Notebook
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Clone notebook</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```POST``` method clones a notebook by the given id and create a new notebook using the given name
|
||||
|
|
@ -285,18 +284,20 @@ limitations under the License.
|
|||
</tr>
|
||||
<tr>
|
||||
<td> sample JSON response </td>
|
||||
<td><pre>{"status": "CREATED","message": "","body": "2AZPHY918"}</pre></td>
|
||||
<td><pre>
|
||||
{
|
||||
"status": "CREATED",
|
||||
"message": "",
|
||||
"body": "2AZPHY918"
|
||||
}</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
### Run Notebook Job
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Run notebook job</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```POST``` method runs all paragraph in the given notebook id.
|
||||
|
|
@ -316,18 +317,15 @@ limitations under the License.
|
|||
</tr>
|
||||
<tr>
|
||||
<td> sample JSON response </td>
|
||||
<td><pre>{"status":"OK"}</pre></td>
|
||||
<td><pre>{"status": "OK"}</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
### Stop Notebook Job
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Stop notebook job</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```DELETE``` method stops all paragraph in the given notebook id.
|
||||
|
|
@ -353,14 +351,9 @@ limitations under the License.
|
|||
|
||||
<br/>
|
||||
|
||||
<br/>
|
||||
|
||||
### Get Notebook Job
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Get notebook job</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```GET``` method gets all paragraph status by the given notebook id.
|
||||
|
|
@ -381,18 +374,33 @@ limitations under the License.
|
|||
</tr>
|
||||
<tr>
|
||||
<td> sample JSON response </td>
|
||||
<td><pre>{"status":"OK","body":[{"id":"20151121-212654_766735423","status":"FINISHED","finished":"Tue Nov 24 14:21:40 KST 2015","started":"Tue Nov 24 14:21:39 KST 2015"},{"progress":"1","id":"20151121-212657_730976687","status":"RUNNING","finished":"Tue Nov 24 14:21:35 KST 2015","started":"Tue Nov 24 14:21:40 KST 2015"}]}</pre></td>
|
||||
<td><pre>
|
||||
{
|
||||
"status": "OK",
|
||||
"body": [
|
||||
{
|
||||
"id":"20151121-212654\_766735423",
|
||||
"status":"FINISHED",
|
||||
"finished":"Tue Nov 24 14:21:40 KST 2015",
|
||||
"started":"Tue Nov 24 14:21:39 KST 2015"
|
||||
},
|
||||
{
|
||||
"progress":"1",
|
||||
"id":"20151121-212657\_730976687",
|
||||
"status":"RUNNING",
|
||||
"finished":"Tue Nov 24 14:21:35 KST 2015",
|
||||
"started":"Tue Nov 24 14:21:40 KST 2015"
|
||||
}
|
||||
]
|
||||
}</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
### Run Paragraph Job
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Run paragraph job</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```POST``` method runs the paragraph by given notebook and paragraph id.
|
||||
|
|
@ -419,23 +427,19 @@ limitations under the License.
|
|||
"formLabel1": "value1",
|
||||
"formLabel2": "value2"
|
||||
}
|
||||
}
|
||||
</pre></td>
|
||||
}</pre></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> sample JSON response </td>
|
||||
<td><pre>{"status":"OK"}</pre></td>
|
||||
<td><pre>{"status": "OK"}</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
### Stop Paragraph Job
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Stop paragraph job</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```DELETE``` method stops the paragraph by given notebook and paragraph id.
|
||||
|
|
@ -455,18 +459,15 @@ limitations under the License.
|
|||
</tr>
|
||||
<tr>
|
||||
<td> sample JSON response </td>
|
||||
<td><pre>{"status":"OK"}</pre></td>
|
||||
<td><pre>{"status": "OK"}</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
### Add Cron Job
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Add cron job</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```POST``` method adds cron job by the given notebook id.
|
||||
|
|
@ -490,18 +491,15 @@ limitations under the License.
|
|||
</tr>
|
||||
<tr>
|
||||
<td> sample JSON response </td>
|
||||
<td><pre>{"status":"OK"}</pre></td>
|
||||
<td><pre>{"status": "OK"}</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
### Remove Cron Job
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Remove cron job</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```DELETE``` method removes cron job by the given notebook id.
|
||||
|
|
@ -521,18 +519,15 @@ limitations under the License.
|
|||
</tr>
|
||||
<tr>
|
||||
<td> sample JSON response </td>
|
||||
<td><pre>{"status":"OK"}</pre></td>
|
||||
<td><pre>{"status": "OK"}</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
### Get Cron Job
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Get cron job</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```GET``` method gets cron job expression of given notebook id.
|
||||
|
|
@ -553,16 +548,15 @@ limitations under the License.
|
|||
</tr>
|
||||
<tr>
|
||||
<td> sample JSON response </td>
|
||||
<td><pre>{"status":"OK","body":"* * * * * ?"}</pre></td>
|
||||
<td><pre>{"status": "OK", "body": "* * * * * ?"}</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br />
|
||||
|
||||
### Full Text Search Through the Paragraphs in All Notebooks
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Full-text search through the paragraphs in all notebooks</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>```GET``` request will return list of matching paragraphs
|
||||
|
|
@ -582,19 +576,26 @@ limitations under the License.
|
|||
</tr>
|
||||
<tr>
|
||||
<td>Sample JSON response </td>
|
||||
<td><pre>{"status":"OK", body: [{"id":"<noteId>/paragraph/<paragraphId>", "name":"Notebook Name", "snippet":"", "text":""}]}</pre></td>
|
||||
<td><pre>
|
||||
{
|
||||
"status": "OK",
|
||||
"body": [
|
||||
{
|
||||
"id": "<noteId>/paragraph/<paragraphId>",
|
||||
"name":"Notebook Name",
|
||||
"snippet":"",
|
||||
"text":""
|
||||
}
|
||||
]
|
||||
}</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
### Create Paragraph
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Create paragraph</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```POST``` method create a new paragraph using JSON payload.
|
||||
|
|
@ -616,35 +617,36 @@ limitations under the License.
|
|||
<tr>
|
||||
<td> sample JSON input (add to the last) </td>
|
||||
<td><pre>
|
||||
{
|
||||
"title": "Paragraph insert revised",
|
||||
"text": "%spark\nprintln(\"Paragraph insert revised\")"
|
||||
}</pre></td>
|
||||
{
|
||||
"title": "Paragraph insert revised",
|
||||
"text": "%spark\nprintln(\"Paragraph insert revised\")"
|
||||
}</pre></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> sample JSON input (add to specific index) </td>
|
||||
<td><pre>
|
||||
{
|
||||
"title": "Paragraph insert revised",
|
||||
"text": "%spark\nprintln(\"Paragraph insert revised\")",
|
||||
"index": 0
|
||||
}
|
||||
</pre></td>
|
||||
{
|
||||
"title": "Paragraph insert revised",
|
||||
"text": "%spark\nprintln(\"Paragraph insert revised\")",
|
||||
"index": 0
|
||||
}</pre></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> sample JSON response </td>
|
||||
<td><pre>{"status": "CREATED","message": "","body": "20151218-100330_1754029574"}</pre></td>
|
||||
<td><pre>
|
||||
{
|
||||
"status": "CREATED",
|
||||
"message": "",
|
||||
"body": "20151218-100330\_1754029574"
|
||||
}</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
### Get Paragraph
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Get paragraph</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```GET``` method retrieves an existing paragraph's information using the given id.
|
||||
|
|
@ -692,8 +694,8 @@ limitations under the License.
|
|||
"params": {},
|
||||
"forms": {}
|
||||
},
|
||||
"jobName": "paragraph_1450391574392_-1890856722",
|
||||
"id": "20151218-073254_1105602047",
|
||||
"jobName": "paragraph\_1450391574392\_-1890856722",
|
||||
"id": "20151218-073254\_1105602047",
|
||||
"result": {
|
||||
"code": "SUCCESS",
|
||||
"type": "TEXT",
|
||||
|
|
@ -705,19 +707,15 @@ limitations under the License.
|
|||
"status": "FINISHED",
|
||||
"progressUpdateIntervalMs": 500
|
||||
}
|
||||
}
|
||||
</pre></td>
|
||||
}</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
### Move Paragraph
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Move paragraph</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```POST``` method moves a paragraph to the specific index (order) from the notebook.
|
||||
|
|
@ -737,19 +735,16 @@ limitations under the License.
|
|||
</tr>
|
||||
<tr>
|
||||
<td> sample JSON response </td>
|
||||
<td><pre>{"status":"OK","message":""}</pre></td>
|
||||
<td><pre>{"status": "OK","message": ""}</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<br/>
|
||||
|
||||
### Delete Paragraph
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Delete paragraph</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```DELETE``` method deletes a paragraph by the given notebook and paragraph id.
|
||||
|
|
@ -769,18 +764,15 @@ limitations under the License.
|
|||
</tr>
|
||||
<tr>
|
||||
<td> sample JSON response </td>
|
||||
<td><pre>{"status":"OK","message":""}</pre></td>
|
||||
<td><pre>{"status": "OK","message": ""}</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
### Export Notebook
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Export notebook</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```GET``` method exports a notebook by the given id and gernerates a JSON
|
||||
|
|
@ -811,8 +803,8 @@ limitations under the License.
|
|||
"params": {},
|
||||
"forms": {}
|
||||
},
|
||||
"jobName": "paragraph_1452300578795_1196072540",
|
||||
"id": "20160108-164938_1685162144",
|
||||
"jobName": "paragraph\_1452300578795\_1196072540",
|
||||
"id": "20160108-164938\_1685162144",
|
||||
"dateCreated": "Jan 8, 2016 4:49:38 PM",
|
||||
"status": "READY",
|
||||
"progressUpdateIntervalMs": 500
|
||||
|
|
@ -827,12 +819,11 @@ limitations under the License.
|
|||
</tr>
|
||||
</table>
|
||||
|
||||
<br />
|
||||
|
||||
### Import Notebook
|
||||
<table class="table-configuration">
|
||||
<col width="200">
|
||||
<tr>
|
||||
<th>Export notebook</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>This ```POST``` method imports a notebook from the notebook JSON input
|
||||
|
|
@ -850,8 +841,9 @@ limitations under the License.
|
|||
<td> Fail code</td>
|
||||
<td> 500 </td>
|
||||
</tr>
|
||||
<td> sample JSON input </td>
|
||||
<td><pre>{
|
||||
<td>sample JSON input</td>
|
||||
<td><pre>
|
||||
{
|
||||
"paragraphs": [
|
||||
{
|
||||
"text": "%md This is my new paragraph in my new note",
|
||||
|
|
@ -863,8 +855,8 @@ limitations under the License.
|
|||
"params": {},
|
||||
"forms": {}
|
||||
},
|
||||
"jobName": "paragraph_1452300578795_1196072540",
|
||||
"id": "20160108-164938_1685162144",
|
||||
"jobName": "paragraph\_1452300578795\_1196072540",
|
||||
"id": "20160108-164938\_1685162144",
|
||||
"dateCreated": "Jan 8, 2016 4:49:38 PM",
|
||||
"status": "READY",
|
||||
"progressUpdateIntervalMs": 500
|
||||
|
|
@ -876,9 +868,14 @@ limitations under the License.
|
|||
"config": {},
|
||||
"info": {}
|
||||
}</pre></td>
|
||||
<tr>
|
||||
<td> sample JSON response </td>
|
||||
<td><pre>"status": "CREATED","message": "","body": "2AZPHY918"}</pre></td>
|
||||
<tr>
|
||||
<td>sample JSON response</td>
|
||||
<td><pre>
|
||||
{
|
||||
"status": "CREATED",
|
||||
"message": "",
|
||||
"body": "2AZPHY918"
|
||||
}</pre></td>
|
||||
</tr>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ 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.
|
||||
-->
|
||||
### Notebook Storage
|
||||
## Notebook Storage
|
||||
|
||||
Zeppelin has a pluggable notebook storage mechanism controlled by `zeppelin.notebook.storage` configuration option with multiple implementations.
|
||||
There are few Notebook storage systems available for a use out of the box:
|
||||
|
|
@ -31,7 +31,7 @@ By default, only first two of them will be automatically kept in sync by Zeppeli
|
|||
|
||||
</br>
|
||||
|
||||
#### Notebook Storage in local Git repository <a name="Git"></a>
|
||||
## Notebook Storage in local Git repository <a name="Git"></a>
|
||||
|
||||
To enable versioning for all your local notebooks though a standard Git repository - uncomment the next property in `zeppelin-site.xml` in order to use GitNotebookRepo class:
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ To enable versioning for all your local notebooks though a standard Git reposito
|
|||
|
||||
</br>
|
||||
|
||||
#### Notebook Storage in S3 <a name="S3"></a>
|
||||
## Notebook Storage in S3 <a name="S3"></a>
|
||||
|
||||
Notebooks may be stored in S3, and optionally encrypted. The [``DefaultAWSCredentialsProviderChain``](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.html) credentials provider is used for credentials and checks the following:
|
||||
|
||||
|
|
@ -103,9 +103,9 @@ Comment out the next property to disable local notebook storage (the default):
|
|||
</property>
|
||||
```
|
||||
|
||||
#### Data Encryption in S3
|
||||
### Data Encryption in S3
|
||||
|
||||
##### AWS KMS encryption keys
|
||||
#### AWS KMS encryption keys
|
||||
|
||||
To use an [AWS KMS](https://aws.amazon.com/kms/) encryption key to encrypt notebooks, set the following environment variable in the file **zeppelin-env.sh**:
|
||||
|
||||
|
|
@ -114,6 +114,7 @@ export ZEPPELIN_NOTEBOOK_S3_KMS_KEY_ID = kms-key-id
|
|||
```
|
||||
|
||||
Or using the following setting in **zeppelin-site.xml**:
|
||||
|
||||
```
|
||||
<property>
|
||||
<name>zeppelin.notebook.s3.kmsKeyID</name>
|
||||
|
|
@ -122,7 +123,7 @@ Or using the following setting in **zeppelin-site.xml**:
|
|||
</property>
|
||||
```
|
||||
|
||||
##### Custom Encryption Materials Provider class
|
||||
#### Custom Encryption Materials Provider class
|
||||
|
||||
You may use a custom [``EncryptionMaterialsProvider``](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/model/EncryptionMaterialsProvider.html) class as long as it is available in the classpath and able to initialize itself from system properties or another mechanism. To use this, set the following environment variable in the file **zeppelin-env.sh**:
|
||||
|
||||
|
|
@ -132,6 +133,7 @@ export ZEPPELIN_NOTEBOOK_S3_EMP = class-name
|
|||
```
|
||||
|
||||
Or using the following setting in **zeppelin-site.xml**:
|
||||
|
||||
```
|
||||
<property>
|
||||
<name>zeppelin.notebook.s3.encryptionMaterialsProvider</name>
|
||||
|
|
@ -140,7 +142,7 @@ Or using the following setting in **zeppelin-site.xml**:
|
|||
```
|
||||
|
||||
</br>
|
||||
#### Notebook Storage in Azure <a name="Azure"></a>
|
||||
## Notebook Storage in Azure <a name="Azure"></a>
|
||||
|
||||
Using `AzureNotebookRepo` you can connect your Zeppelin with your Azure account for notebook storage.
|
||||
|
||||
|
|
@ -203,7 +205,7 @@ Optionally, you can specify Azure folder structure name in the file **zeppelin-s
|
|||
```
|
||||
|
||||
</br>
|
||||
#### Notebook Storage in ZeppelinHub <a name="ZeppelinHub"></a>
|
||||
## Storage in ZeppelinHub <a name="ZeppelinHub"></a>
|
||||
|
||||
ZeppelinHub storage layer allows out of the box connection of Zeppelin instance with your ZeppelinHub account. First of all, you need to either comment out the following property in **zeppelin-site.xml**:
|
||||
|
||||
|
|
|
|||
|
|
@ -106,21 +106,6 @@ public class JDBCInterpreter extends Interpreter {
|
|||
|
||||
private final Map<String, ArrayList<Connection>> propertyKeyUnusedConnectionListMap;
|
||||
private final Map<String, Connection> paragraphIdConnectionMap;
|
||||
|
||||
static {
|
||||
Interpreter.register(
|
||||
"sql",
|
||||
"jdbc",
|
||||
JDBCInterpreter.class.getName(),
|
||||
new InterpreterPropertyBuilder()
|
||||
.add(DEFAULT_URL, "jdbc:postgresql://localhost:5432/", "The URL for JDBC.")
|
||||
.add(DEFAULT_USER, "gpadmin", "The JDBC user name")
|
||||
.add(DEFAULT_PASSWORD, "",
|
||||
"The JDBC user password")
|
||||
.add(DEFAULT_DRIVER, "org.postgresql.Driver", "JDBC Driver Name")
|
||||
.add(COMMON_MAX_LINE, MAX_LINE_DEFAULT,
|
||||
"Max number of SQL result to display.").build());
|
||||
}
|
||||
|
||||
public JDBCInterpreter(Properties property) {
|
||||
super(property);
|
||||
|
|
|
|||
39
jdbc/src/main/resources/interpreter-setting.json
Normal file
39
jdbc/src/main/resources/interpreter-setting.json
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
[
|
||||
{
|
||||
"group": "jdbc",
|
||||
"name": "sql",
|
||||
"className": "org.apache.zeppelin.jdbc.JDBCInterpreter",
|
||||
"properties": {
|
||||
"default.url": {
|
||||
"envName": null,
|
||||
"propertyName": "default.url",
|
||||
"defaultValue": "jdbc:postgresql://localhost:5432/",
|
||||
"description": "The URL for JDBC."
|
||||
},
|
||||
"default.user": {
|
||||
"envName": null,
|
||||
"propertyName": "default.user",
|
||||
"defaultValue": "gpadmin",
|
||||
"description": "The JDBC user name"
|
||||
},
|
||||
"default.password": {
|
||||
"envName": null,
|
||||
"propertyName": "default.password",
|
||||
"defaultValue": "",
|
||||
"description": "The JDBC user password"
|
||||
},
|
||||
"default.driver": {
|
||||
"envName": null,
|
||||
"propertyName": "default.driver",
|
||||
"defaultValue": "org.postgresql.Driver",
|
||||
"description": "JDBC Driver Name"
|
||||
},
|
||||
"common.max_count": {
|
||||
"envName": null,
|
||||
"propertyName": "common.max_count",
|
||||
"defaultValue": "1000",
|
||||
"description": "Max number of SQL result to display."
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -51,6 +51,17 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter {
|
|||
}
|
||||
return jdbcConnection;
|
||||
}
|
||||
|
||||
public static Properties getJDBCTestProperties() {
|
||||
Properties p = new Properties();
|
||||
p.setProperty("default.driver", "org.postgresql.Driver");
|
||||
p.setProperty("default.url", "jdbc:postgresql://localhost:5432/");
|
||||
p.setProperty("default.user", "gpadmin");
|
||||
p.setProperty("default.password", "");
|
||||
p.setProperty("common.max_count", "1000");
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
|
@ -116,7 +127,7 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter {
|
|||
|
||||
@Test
|
||||
public void testDefaultProperties() throws SQLException {
|
||||
JDBCInterpreter jdbcInterpreter = new JDBCInterpreter(new Properties());
|
||||
JDBCInterpreter jdbcInterpreter = new JDBCInterpreter(getJDBCTestProperties());
|
||||
|
||||
assertEquals("org.postgresql.Driver", jdbcInterpreter.getProperty(DEFAULT_DRIVER));
|
||||
assertEquals("jdbc:postgresql://localhost:5432/", jdbcInterpreter.getProperty(DEFAULT_URL));
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package org.apache.zeppelin.livy;
|
|||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
|
|
@ -40,7 +41,9 @@ import java.io.InputStreamReader;
|
|||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
|
||||
|
||||
|
|
@ -60,27 +63,28 @@ public class LivyHelper {
|
|||
|
||||
public Integer createSession(InterpreterContext context, String kind) throws Exception {
|
||||
try {
|
||||
Map<String, String> conf = new HashMap<String, String>();
|
||||
|
||||
Iterator<Entry<Object, Object>> it = property.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Entry<Object, Object> pair = it.next();
|
||||
if (pair.getKey().toString().startsWith("livy.spark.") &&
|
||||
!pair.getValue().toString().isEmpty())
|
||||
conf.put(pair.getKey().toString().substring(5), pair.getValue().toString());
|
||||
}
|
||||
|
||||
String confData = gson.toJson(conf);
|
||||
|
||||
String json = executeHTTP(property.getProperty("zeppelin.livy.url") + "/sessions",
|
||||
"POST",
|
||||
"POST",
|
||||
"{" +
|
||||
"\"kind\": \"" + kind + "\", " +
|
||||
"\"master\": \"" + property.getProperty("zeppelin.livy.master") + "\", " +
|
||||
"\"proxyUser\": \"" + context.getAuthenticationInfo().getUser() + "\"" +
|
||||
"\"conf\": " + confData + ", " +
|
||||
"\"proxyUser\": " + context.getAuthenticationInfo().getUser() +
|
||||
"}",
|
||||
context.getParagraphId()
|
||||
);
|
||||
if (json.contains("CreateInteractiveRequest[\\\"master\\\"]")) {
|
||||
json = executeHTTP(property.getProperty("zeppelin.livy.url") + "/sessions",
|
||||
"POST",
|
||||
"{" +
|
||||
"\"kind\": \"" + kind + "\", " +
|
||||
"\"conf\":{\"spark.master\": \""
|
||||
+ property.getProperty("zeppelin.livy.master") + "\"}," +
|
||||
"\"proxyUser\": \"" + context.getAuthenticationInfo().getUser() + "\"" +
|
||||
"}",
|
||||
context.getParagraphId()
|
||||
);
|
||||
}
|
||||
|
||||
Map jsonMap = (Map<Object, Object>) gson.fromJson(json,
|
||||
new TypeToken<Map<Object, Object>>() {
|
||||
}.getType());
|
||||
|
|
|
|||
|
|
@ -45,7 +45,22 @@ public class LivySparkInterpreter extends Interpreter {
|
|||
LivySparkInterpreter.class.getName(),
|
||||
new InterpreterPropertyBuilder()
|
||||
.add("zeppelin.livy.url", DEFAULT_URL, "The URL for Livy Server.")
|
||||
.add("zeppelin.livy.master", LOCAL, "Spark master uri. ex) spark://masterhost:7077")
|
||||
.add("livy.spark.master", LOCAL, "Spark master uri. ex) spark://masterhost:7077")
|
||||
.add("livy.spark.driver.cores", "", "Driver cores. ex) 1, 2")
|
||||
.add("livy.spark.driver.memory", "", "Driver memory. ex) 512m, 32g")
|
||||
.add("livy.spark.executor.instances", "", "Executor instances. ex) 1, 4")
|
||||
.add("livy.spark.executor.cores", "", "Num cores per executor. ex) 1, 4")
|
||||
.add("livy.spark.executor.memory", "",
|
||||
"Executor memory per worker instance. ex) 512m, 32g")
|
||||
.add("livy.spark.dynamicAllocation.enabled", "", "Use dynamic resource allocation")
|
||||
.add("livy.spark.dynamicAllocation.cachedExecutorIdleTimeout", "",
|
||||
"Remove an executor which has cached data blocks")
|
||||
.add("livy.spark.dynamicAllocation.minExecutors", "",
|
||||
"Lower bound for the number of executors if dynamic allocation is enabled. ")
|
||||
.add("livy.spark.dynamicAllocation.initialExecutors", "",
|
||||
"Initial number of executors to run if dynamic allocation is enabled. ")
|
||||
.add("livy.spark.dynamicAllocation.maxExecutors", "",
|
||||
"Upper bound for the number of executors if dynamic allocation is enabled. ")
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
|
|
|||
1
pom.xml
1
pom.xml
|
|
@ -475,6 +475,7 @@
|
|||
<exclude>conf/zeppelin-env.sh</exclude>
|
||||
<exclude>spark-*-bin*/**</exclude>
|
||||
<exclude>.spark-dist/**</exclude>
|
||||
<exclude>**/interpreter-setting.json</exclude>
|
||||
|
||||
<!-- bundled from bootstrap -->
|
||||
<exclude>docs/assets/themes/zeppelin/bootstrap/**</exclude>
|
||||
|
|
|
|||
|
|
@ -45,27 +45,12 @@ public class ShellInterpreter extends Interpreter {
|
|||
Logger logger = LoggerFactory.getLogger(ShellInterpreter.class);
|
||||
private static final String EXECUTOR_KEY = "executor";
|
||||
public static final String SHELL_COMMAND_TIMEOUT = "shell.command.timeout.millisecs";
|
||||
public static final String DEFAULT_COMMAND_TIMEOUT = "600000";
|
||||
int commandTimeOut;
|
||||
private static final boolean isWindows = System
|
||||
.getProperty("os.name")
|
||||
.startsWith("Windows");
|
||||
final String shell = isWindows ? "cmd /c" : "bash -c";
|
||||
|
||||
static {
|
||||
Interpreter.register(
|
||||
"sh",
|
||||
"sh",
|
||||
ShellInterpreter.class.getName(),
|
||||
new InterpreterPropertyBuilder()
|
||||
.add(
|
||||
SHELL_COMMAND_TIMEOUT,
|
||||
DEFAULT_COMMAND_TIMEOUT,
|
||||
"Shell command time out in millisecs. Default = 600000")
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
public ShellInterpreter(Properties property) {
|
||||
super(property);
|
||||
}
|
||||
|
|
|
|||
15
shell/src/main/resources/interpreter-setting.json
Normal file
15
shell/src/main/resources/interpreter-setting.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
[
|
||||
{
|
||||
"group": "sh",
|
||||
"name": "sh",
|
||||
"className": "org.apache.zeppelin.shell.ShellInterpreter",
|
||||
"properties": {
|
||||
"shell.command.timeout.millisecs": {
|
||||
"envName": "SHELL_COMMAND_TIMEOUT",
|
||||
"propertyName": "shell.command.timeout.millisecs",
|
||||
"defaultValue": "60000",
|
||||
"description": "Shell command time out in millisecs. Default = 60000"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -76,15 +76,17 @@ if [[ ! -d "${SPARK_HOME}" ]]; then
|
|||
echo "${SPARK_CACHE} does not have ${SPARK_ARCHIVE} downloading ..."
|
||||
|
||||
# download archive if not cached
|
||||
if [[ "${SPARK_VER_RANGE}" == "<=1.2" ]]; then
|
||||
# spark 1.1.x and spark 1.2.x can be downloaded from archive
|
||||
if [[ "${SPARK_VERSION}" = "1.1.1" || "${SPARK_VERSION}" = "1.2.2" || "${SPARK_VERSION}" = "1.3.1" || "${SPARK_VERSION}" = "1.4.1" ]]; then
|
||||
echo "${SPARK_VERSION} being downloaded from archives"
|
||||
# spark old versions are only available only on the archives (prior to 1.5.2)
|
||||
STARTTIME=`date +%s`
|
||||
#timeout -s KILL "${MAX_DOWNLOAD_TIME_SEC}" wget "http://archive.apache.org/dist/spark/spark-${SPARK_VERSION}/${SPARK_ARCHIVE}.tgz"
|
||||
download_with_retry "http://archive.apache.org/dist/spark/spark-${SPARK_VERSION}/${SPARK_ARCHIVE}.tgz"
|
||||
ENDTIME=`date +%s`
|
||||
DOWNLOADTIME="$((ENDTIME-STARTTIME))"
|
||||
else
|
||||
# spark 1.3.x and later can be downloaded from mirror
|
||||
echo "${SPARK_VERSION} being downloaded from mirror"
|
||||
# spark 1.5.2 and up and later can be downloaded from mirror
|
||||
# get download address from mirror
|
||||
MIRROR_INFO=$(curl -s "http://www.apache.org/dyn/closer.cgi/spark/spark-${SPARK_VERSION}/${SPARK_ARCHIVE}.tgz?asjson=1")
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* 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.rest;
|
||||
|
||||
import org.apache.commons.lang3.reflect.FieldUtils;
|
||||
import org.apache.shiro.realm.jdbc.JdbcRealm;
|
||||
import org.apache.shiro.realm.ldap.JndiLdapContextFactory;
|
||||
import org.apache.shiro.realm.ldap.JndiLdapRealm;
|
||||
import org.apache.shiro.realm.text.IniRealm;
|
||||
import org.apache.shiro.util.JdbcUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.SearchControls;
|
||||
import javax.naming.directory.SearchResult;
|
||||
import javax.naming.ldap.LdapContext;
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This is class which help fetching users from different realms.
|
||||
* getUserList() function is overloaded and according to the realm passed to the function it
|
||||
* extracts users from its respective realm
|
||||
*/
|
||||
public class GetUserList {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(GetUserList.class);
|
||||
|
||||
/**
|
||||
* function to extract users from shiro.ini
|
||||
*/
|
||||
public List<String> getUserList(IniRealm r) {
|
||||
List<String> userList = new ArrayList<>();
|
||||
Map getIniUser = r.getIni().get("users");
|
||||
Iterator it = getIniUser.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry pair = (Map.Entry) it.next();
|
||||
userList.add(pair.getKey().toString());
|
||||
}
|
||||
return userList;
|
||||
}
|
||||
|
||||
/**
|
||||
* function to extract users from LDAP
|
||||
*/
|
||||
public List<String> getUserList(JndiLdapRealm r) {
|
||||
List<String> userList = new ArrayList<>();
|
||||
String userDnTemplate = r.getUserDnTemplate();
|
||||
String userDn[] = userDnTemplate.split(",", 2);
|
||||
String userDnPrefix = userDn[0].split("=")[0];
|
||||
String userDnSuffix = userDn[1];
|
||||
JndiLdapContextFactory CF = (JndiLdapContextFactory) r.getContextFactory();
|
||||
try {
|
||||
LdapContext ctx = CF.getSystemLdapContext();
|
||||
SearchControls constraints = new SearchControls();
|
||||
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
|
||||
String[] attrIDs = {userDnPrefix};
|
||||
constraints.setReturningAttributes(attrIDs);
|
||||
NamingEnumeration result = ctx.search(userDnSuffix, "(objectclass=*)", constraints);
|
||||
while (result.hasMore()) {
|
||||
Attributes attrs = ((SearchResult) result.next()).getAttributes();
|
||||
if (attrs.get(userDnPrefix) != null) {
|
||||
String currentUser = attrs.get(userDnPrefix).toString();
|
||||
userList.add(currentUser.split(":")[1]);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error retrieving User list from Ldap Realm", e);
|
||||
}
|
||||
return userList;
|
||||
}
|
||||
|
||||
/**
|
||||
* function to extract users from JDBCs
|
||||
*/
|
||||
public List<String> getUserList(JdbcRealm obj) {
|
||||
List<String> userlist = new ArrayList<>();
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
DataSource dataSource = null;
|
||||
String authQuery = "";
|
||||
String retval[];
|
||||
String tablename = "";
|
||||
String username = "";
|
||||
String userquery = "";
|
||||
try {
|
||||
dataSource = (DataSource) FieldUtils.readField(obj, "dataSource", true);
|
||||
authQuery = (String) FieldUtils.readField(obj, "DEFAULT_AUTHENTICATION_QUERY", true);
|
||||
LOG.info(authQuery);
|
||||
String authQueryLowerCase = authQuery.toLowerCase();
|
||||
retval = authQueryLowerCase.split("from", 2);
|
||||
if (retval.length >= 2) {
|
||||
retval = retval[1].split("with|where", 2);
|
||||
tablename = retval[0];
|
||||
retval = retval[1].split("where", 2);
|
||||
if (retval.length >= 2)
|
||||
retval = retval[1].split("=", 2);
|
||||
else
|
||||
retval = retval[0].split("=", 2);
|
||||
username = retval[0];
|
||||
}
|
||||
|
||||
if (username.equals("") || tablename.equals("")){
|
||||
return userlist;
|
||||
}
|
||||
|
||||
userquery = "select " + username + " from " + tablename;
|
||||
|
||||
} catch (IllegalAccessException e) {
|
||||
LOG.error("Error while accessing dataSource for JDBC Realm", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
Connection con = dataSource.getConnection();
|
||||
ps = con.prepareStatement(userquery);
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
userlist.add(rs.getString(1));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error retrieving User list from JDBC Realm", e);
|
||||
} finally {
|
||||
JdbcUtils.closeResultSet(rs);
|
||||
JdbcUtils.closeStatement(ps);
|
||||
}
|
||||
return userlist;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -17,6 +17,13 @@
|
|||
|
||||
package org.apache.zeppelin.rest;
|
||||
|
||||
|
||||
import org.apache.shiro.realm.Realm;
|
||||
import org.apache.shiro.realm.jdbc.JdbcRealm;
|
||||
import org.apache.shiro.realm.ldap.JndiLdapRealm;
|
||||
import org.apache.shiro.realm.text.IniRealm;
|
||||
import org.apache.shiro.util.ThreadContext;
|
||||
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
|
||||
import org.apache.zeppelin.annotation.ZeppelinApi;
|
||||
import org.apache.zeppelin.conf.ZeppelinConfiguration;
|
||||
import org.apache.zeppelin.server.JsonResponse;
|
||||
|
|
@ -27,11 +34,10 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Zeppelin security rest api endpoint.
|
||||
|
|
@ -81,4 +87,54 @@ public class SecurityRestApi {
|
|||
LOG.warn(response.toString());
|
||||
return response.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get userlist
|
||||
* Returns list of all user from available realms
|
||||
*
|
||||
* @return 200 response
|
||||
*/
|
||||
@GET
|
||||
@Path("userlist/{searchText}")
|
||||
public Response getUserList(@PathParam("searchText") String searchText) {
|
||||
|
||||
List<String> usersList = new ArrayList<>();
|
||||
try {
|
||||
GetUserList getUserListObj = new GetUserList();
|
||||
DefaultWebSecurityManager defaultWebSecurityManager;
|
||||
String key = ThreadContext.SECURITY_MANAGER_KEY;
|
||||
defaultWebSecurityManager = (DefaultWebSecurityManager) ThreadContext.get(key);
|
||||
Collection<Realm> realms = defaultWebSecurityManager.getRealms();
|
||||
List realmsList = new ArrayList(realms);
|
||||
for (int i = 0; i < realmsList.size(); i++) {
|
||||
String name = ((Realm) realmsList.get(i)).getName();
|
||||
if (name.equals("iniRealm")) {
|
||||
usersList.addAll(getUserListObj.getUserList((IniRealm) realmsList.get(i)));
|
||||
} else if (name.equals("ldapRealm")) {
|
||||
usersList.addAll(getUserListObj.getUserList((JndiLdapRealm) realmsList.get(i)));
|
||||
} else if (name.equals("jdbcRealm")) {
|
||||
usersList.addAll(getUserListObj.getUserList((JdbcRealm) realmsList.get(i)));
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
LOG.error("Exception in retrieving Users from realms ", e);
|
||||
}
|
||||
List<String> autoSuggestList = new ArrayList<>();
|
||||
Collections.sort(usersList);
|
||||
int maxLength = 0;
|
||||
for (int i = 0; i < usersList.size(); i++) {
|
||||
String userLowerCase = usersList.get(i).toLowerCase();
|
||||
String searchTextLowerCase = searchText.toLowerCase();
|
||||
if (userLowerCase.indexOf(searchTextLowerCase) != -1) {
|
||||
maxLength++;
|
||||
autoSuggestList.add(usersList.get(i));
|
||||
}
|
||||
if (maxLength == 5) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new JsonResponse<>(Response.Status.OK, "", autoSuggestList).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,19 +28,8 @@ angular.module('zeppelinWebApp').controller('HomeCtrl', function($scope, noteboo
|
|||
|
||||
$scope.isReloading = false;
|
||||
|
||||
var getZeppelinVersion = function() {
|
||||
$http.get(baseUrlSrv.getRestApiBase() +'/version').
|
||||
success(function (data, status, headers, config) {
|
||||
$scope.zeppelinVersion = data.body;
|
||||
}).
|
||||
error(function(data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
});
|
||||
};
|
||||
|
||||
var initHome = function() {
|
||||
websocketMsgSrv.getHomeNotebook();
|
||||
getZeppelinVersion();
|
||||
};
|
||||
|
||||
initHome();
|
||||
|
|
|
|||
|
|
@ -272,9 +272,10 @@ a.navbar-brand:hover {
|
|||
}
|
||||
}
|
||||
|
||||
.server-status {
|
||||
i.server-status {
|
||||
font-size: 12px;
|
||||
margin-top: 8px;
|
||||
top: -2px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.server-connected {
|
||||
|
|
@ -756,3 +757,25 @@ This part should be removed when new version of bootstrap handles this issue.
|
|||
.bootstrap-dialog.type-primary .modal-header {
|
||||
background: #3071a9;
|
||||
}
|
||||
|
||||
.about{
|
||||
height: 200px;
|
||||
padding-top: 20px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.about .logo {
|
||||
width: 20%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.about .content{
|
||||
float: left;
|
||||
padding-left: 10px;
|
||||
top: -30px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.about .logo img{
|
||||
width: 100%;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ limitations under the License.
|
|||
</div>
|
||||
<div style="margin-top: -380px;">
|
||||
<h1 class="box-heading" id="welcome">
|
||||
Welcome to Zeppelin! <small>({{zeppelinVersion}})</small>
|
||||
Welcome to Zeppelin!
|
||||
</h1>
|
||||
Zeppelin is web-based notebook that enables interactive data analytics.<br>
|
||||
You can make beautiful data-driven, interactive, collaborative document with SQL, code and even more!<br>
|
||||
|
|
|
|||
|
|
@ -43,6 +43,18 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl',
|
|||
|
||||
var connectedOnce = false;
|
||||
|
||||
// user auto complete related
|
||||
$scope.suggestions = [];
|
||||
$scope.selectIndex = -1;
|
||||
var selectedUser = '';
|
||||
var selectedUserIndex = 0;
|
||||
var previousSelectedList = [];
|
||||
var previousSelectedListOwners = [];
|
||||
var previousSelectedListReaders = [];
|
||||
var previousSelectedListWriters = [];
|
||||
var searchText = [];
|
||||
$scope.role = '';
|
||||
|
||||
$scope.$on('setConnectedStatus', function(event, param) {
|
||||
if(connectedOnce && param){
|
||||
initNotebook();
|
||||
|
|
@ -683,36 +695,57 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl',
|
|||
}
|
||||
};
|
||||
|
||||
$scope.savePermissions = function() {
|
||||
$http.put(baseUrlSrv.getRestApiBase() + '/notebook/' +$scope.note.id + '/permissions',
|
||||
function convertPermissionsToArray() {
|
||||
if (!angular.isArray($scope.permissions.owners)) {
|
||||
$scope.permissions.owners = $scope.permissions.owners.split(',');
|
||||
}
|
||||
if (!angular.isArray($scope.permissions.readers)) {
|
||||
$scope.permissions.readers = $scope.permissions.readers.split(',');
|
||||
}
|
||||
if (!angular.isArray($scope.permissions.writers)) {
|
||||
$scope.permissions.writers = $scope.permissions.writers.split(',');
|
||||
}
|
||||
}
|
||||
|
||||
$scope.savePermissions = function () {
|
||||
convertPermissionsToArray();
|
||||
$http.put(baseUrlSrv.getRestApiBase() + '/notebook/' + $scope.note.id + '/permissions',
|
||||
$scope.permissions, {withCredentials: true}).
|
||||
success(function(data, status, headers, config) {
|
||||
console.log('Note permissions %o saved', $scope.permissions);
|
||||
$scope.showPermissions = false;
|
||||
}).
|
||||
error(function(data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
BootstrapDialog.show({
|
||||
success(function (data, status, headers, config) {
|
||||
console.log('Note permissions %o saved', $scope.permissions);
|
||||
BootstrapDialog.alert({
|
||||
closable: true,
|
||||
title: 'Insufficient privileges',
|
||||
title: 'Permissions Saved Successfully!!!',
|
||||
message: 'Owners : ' + $scope.permissions.owners + '\n\n' + 'Readers : ' + $scope.permissions.readers + '\n\n' + 'Writers : ' + $scope.permissions.writers
|
||||
});
|
||||
$scope.showPermissions = false;
|
||||
}).
|
||||
error(function (data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
BootstrapDialog.show({
|
||||
closable: true,
|
||||
title: 'Insufficient privileges',
|
||||
message: data.message,
|
||||
buttons: [{
|
||||
buttons: [
|
||||
{
|
||||
label: 'Login',
|
||||
action: function(dialog) {
|
||||
dialog.close();
|
||||
angular.element('#loginModal').modal({
|
||||
show: 'true'
|
||||
});
|
||||
action: function (dialog) {
|
||||
dialog.close();
|
||||
angular.element('#loginModal').modal({
|
||||
show: 'true'
|
||||
});
|
||||
}
|
||||
}, {
|
||||
},
|
||||
{
|
||||
label: 'Cancel',
|
||||
action: function(dialog){
|
||||
dialog.close();
|
||||
action: function (dialog) {
|
||||
dialog.close();
|
||||
}
|
||||
}]
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
$scope.togglePermissions = function() {
|
||||
if ($scope.showPermissions) {
|
||||
|
|
@ -739,4 +772,183 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl',
|
|||
}
|
||||
};
|
||||
|
||||
function checkPreviousRole(role) {
|
||||
var i = 0;
|
||||
if (role !== $scope.role) {
|
||||
if ($scope.role === 'owners') {
|
||||
previousSelectedListOwners = [];
|
||||
for (i = 0; i < previousSelectedList.length; i++) {
|
||||
previousSelectedListOwners[i] = previousSelectedList[i];
|
||||
}
|
||||
}
|
||||
if ($scope.role === 'readers') {
|
||||
previousSelectedListReaders = [];
|
||||
for (i = 0; i < previousSelectedList.length; i++) {
|
||||
previousSelectedListReaders[i] = previousSelectedList[i];
|
||||
}
|
||||
}
|
||||
if ($scope.role === 'writers') {
|
||||
previousSelectedListWriters = [];
|
||||
for (i = 0; i < previousSelectedList.length; i++) {
|
||||
previousSelectedListWriters[i] = previousSelectedList[i];
|
||||
}
|
||||
}
|
||||
|
||||
$scope.role = role;
|
||||
previousSelectedList = [];
|
||||
if (role === 'owners') {
|
||||
for (i = 0; i < previousSelectedListOwners.length; i++) {
|
||||
previousSelectedList[i] = previousSelectedListOwners[i];
|
||||
}
|
||||
}
|
||||
if (role === 'readers') {
|
||||
for (i = 0; i < previousSelectedListReaders.length; i++) {
|
||||
previousSelectedList[i] = previousSelectedListReaders[i];
|
||||
}
|
||||
}
|
||||
if (role === 'writers') {
|
||||
for (i = 0; i < previousSelectedListWriters.length; i++) {
|
||||
previousSelectedList[i] = previousSelectedListWriters[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function convertToArray(role) {
|
||||
if (role === 'owners') {
|
||||
searchText = $scope.permissions.owners.split(',');
|
||||
}
|
||||
else if (role === 'readers') {
|
||||
searchText = $scope.permissions.readers.split(',');
|
||||
}
|
||||
else if (role === 'writers') {
|
||||
searchText = $scope.permissions.writers.split(',');
|
||||
}
|
||||
for (var i = 0; i < searchText.length; i++) {
|
||||
searchText[i] = searchText[i].trim();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function convertToString(role) {
|
||||
if (role === 'owners') {
|
||||
$scope.permissions.owners = searchText.join();
|
||||
}
|
||||
else if (role === 'readers') {
|
||||
$scope.permissions.readers = searchText.join();
|
||||
}
|
||||
else if (role === 'writers') {
|
||||
$scope.permissions.writers = searchText.join();
|
||||
}
|
||||
}
|
||||
|
||||
function getSuggestions (searchQuery) {
|
||||
$scope.suggestions =[];
|
||||
$http.get(baseUrlSrv.getRestApiBase() + '/security/userlist/' + searchQuery ).then(function
|
||||
(response) {
|
||||
var userlist = angular.fromJson(response.data).body;
|
||||
for (var k in userlist) {
|
||||
$scope.suggestions.push(userlist[k]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updatePreviousList() {
|
||||
for (var i = 0; i < searchText.length; i++) {
|
||||
previousSelectedList[i] = searchText[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var getChangedIndex = function() {
|
||||
if (previousSelectedList.length === 0) {
|
||||
selectedUserIndex = searchText.length - 1;
|
||||
}
|
||||
else {
|
||||
for (var i = 0; i < searchText.length; i++) {
|
||||
if (previousSelectedList[i] !== searchText[i]) {
|
||||
selectedUserIndex = i;
|
||||
previousSelectedList = [];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
updatePreviousList();
|
||||
};
|
||||
|
||||
// function to find suggestion list on change
|
||||
$scope.search = function(role) {
|
||||
convertToArray(role);
|
||||
checkPreviousRole(role);
|
||||
getChangedIndex();
|
||||
$scope.selectIndex = -1;
|
||||
$scope.suggestions = [];
|
||||
selectedUser = searchText[selectedUserIndex];
|
||||
if(selectedUser !== ''){
|
||||
getSuggestions(selectedUser);
|
||||
}
|
||||
else
|
||||
{
|
||||
$scope.suggestions = [];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var checkIfSelected = function() {
|
||||
if (($scope.suggestions.length === 0) && ($scope.selectIndex < 0 || $scope.selectIndex >= $scope.suggestions.length) || ( $scope.suggestions.length !== 0 && ( $scope.selectIndex < 0 || $scope.selectIndex >= $scope.suggestions.length ))) {
|
||||
searchText[selectedUserIndex] = selectedUser;
|
||||
$scope.suggestions = [];
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$scope.checkKeyDown = function(event, role) {
|
||||
if (event.keyCode === 40) {
|
||||
event.preventDefault();
|
||||
if ($scope.selectIndex + 1 !== $scope.suggestions.length) {
|
||||
$scope.selectIndex++;
|
||||
}
|
||||
}
|
||||
else if (event.keyCode === 38) {
|
||||
event.preventDefault();
|
||||
|
||||
if ($scope.selectIndex - 1 !== -1) {
|
||||
$scope.selectIndex--;
|
||||
|
||||
}
|
||||
}
|
||||
else if (event.keyCode === 13) {
|
||||
event.preventDefault();
|
||||
if (!checkIfSelected()) {
|
||||
selectedUser = $scope.suggestions[$scope.selectIndex];
|
||||
searchText[selectedUserIndex] = $scope.suggestions[$scope.selectIndex];
|
||||
updatePreviousList();
|
||||
convertToString(role);
|
||||
$scope.suggestions = [];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.checkKeyUp = function(event) {
|
||||
if (event.keyCode !== 8 || event.keyCode !== 46) {
|
||||
if (searchText[selectedUserIndex] === '') {
|
||||
$scope.suggestions = [];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$scope.assignValueAndHide = function(index, role) {
|
||||
searchText[selectedUserIndex] = $scope.suggestions[index];
|
||||
updatePreviousList();
|
||||
convertToString(role);
|
||||
$scope.suggestions = [];
|
||||
};
|
||||
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -154,6 +154,20 @@
|
|||
border: 1px solid #E5E5E5;
|
||||
}
|
||||
|
||||
.permissions .owners {
|
||||
width:60px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.permissions .readers {
|
||||
width:60px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.permissions .writers {
|
||||
width:60px;
|
||||
display: inline-block;
|
||||
}
|
||||
/*
|
||||
Note Setting Panel
|
||||
*/
|
||||
|
|
@ -222,3 +236,52 @@
|
|||
text-decoration: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.userlist {
|
||||
width: 230px;
|
||||
font-family: Georgia, Times, serif;
|
||||
font-size: 15px;
|
||||
position: absolute;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.userlist ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.userlist ul li {
|
||||
box-shadow: 3px 3px 5px #888888;
|
||||
display: list-item;
|
||||
text-decoration: none;
|
||||
color: #000000;
|
||||
background-color: #FFFFFF;
|
||||
line-height: 30px;
|
||||
border-bottom-style: none;
|
||||
border-bottom-width: 1px;
|
||||
border-bottom:1px #CCCCCC solid;
|
||||
padding-left: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.userlist ul li:first-child {
|
||||
border-top-right-radius: 5px;
|
||||
border-top-left-radius: 5px;
|
||||
}
|
||||
|
||||
.userlist ul li:last-child {
|
||||
border-bottom-right-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
}
|
||||
|
||||
.userlist ul li strong {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.userlist li:hover {
|
||||
background-color: #E0E0E0;
|
||||
}
|
||||
|
||||
.userlist li:active,
|
||||
.userlist li.active {
|
||||
background-color: #428BCA;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,9 +70,49 @@ limitations under the License.
|
|||
</p>
|
||||
<div class="permissionsForm"
|
||||
data-ng-model="permissions">
|
||||
<p>Owners : <input ng-list ng-model="permissions.owners" placeholder="*"> Owners can change permissions, read and write the note. </p>
|
||||
<p>Readers : <input ng-list ng-model="permissions.readers" placeholder="*"> Readers can only read the note.</p>
|
||||
<p>Writers : <input ng-list ng-model="permissions.writers" placeholder="*"> Writers can read and write the note.</p>
|
||||
<p><span class="owners">Owners </span><input ng-model="permissions.owners"
|
||||
placeholder="search for users"
|
||||
class="input" ng-change="search('owners')"
|
||||
ng-keydown="checkKeyDown($event,'owners')"
|
||||
ng-keyup="checkKeyUp($event)"> Owners can change permissions,read
|
||||
and write the note.</p>
|
||||
<div ng-if="role === 'owners'" class="userlist" >
|
||||
<ul>
|
||||
<li ng-repeat="suggestion in suggestions"
|
||||
ng-class="{active : selectIndex === $index }"
|
||||
ng-click="assignValueAndHide($index,'owners')" >
|
||||
{{suggestion}}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p><span class="readers">Readers </span><input ng-model="permissions.readers"
|
||||
placeholder="search for users"
|
||||
class="input" ng-change="search('readers')"
|
||||
ng-keydown="checkKeyDown($event,'readers')"
|
||||
ng-keyup="checkKeyUp($event)"> Readers can only read the note.</p>
|
||||
<div ng-if="role === 'readers'" class="userlist">
|
||||
<ul>
|
||||
<li ng-repeat="suggestion in suggestions"
|
||||
ng-class="{active : selectIndex === $index }"
|
||||
ng-click="assignValueAndHide($index,'readers')" >
|
||||
{{suggestion}}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p><span class="writers">Writers </span><input ng-model="permissions.writers"
|
||||
placeholder="search for users"
|
||||
class="input" ng-change="search('writers')"
|
||||
ng-keydown="checkKeyDown($event,'writers')"
|
||||
ng-keyup="checkKeyUp($event)"> Writers can read and write the note.</p>
|
||||
<div ng-if="role === 'writers'" class="userlist">
|
||||
<ul>
|
||||
<li ng-repeat="suggestion in suggestions"
|
||||
ng-class="{active : selectIndex === $index }"
|
||||
ng-click="assignValueAndHide($index,'writers')">
|
||||
{{suggestion}}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ limitations under the License.
|
|||
<li>
|
||||
<a ng-click="goToSingleParagraph()"><span class="icon-share-alt"></span> Link this paragraph</a>
|
||||
</li>
|
||||
<li>
|
||||
<a ng-click="exportToTSV()"><span class="icon-share-alt"></span> Export to TSV</a>
|
||||
</li>
|
||||
<li>
|
||||
<a ng-click="clearParagraphOutput()"><span class="fa fa-eraser"></span> Clear output</a>
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
angular.module('zeppelinWebApp')
|
||||
.controller('ParagraphCtrl', function($scope,$rootScope, $route, $window, $element, $routeParams, $location,
|
||||
$timeout, $compile, $http, websocketMsgSrv, baseUrlSrv, ngToast) {
|
||||
$timeout, $compile, $http, websocketMsgSrv, baseUrlSrv, ngToast, SaveAsService) {
|
||||
var ANGULAR_FUNCTION_OBJECT_NAME_PREFIX = '_Z_ANGULAR_FUNC_';
|
||||
$scope.parentNote = null;
|
||||
$scope.paragraph = null;
|
||||
|
|
@ -2202,6 +2202,24 @@ angular.module('zeppelinWebApp')
|
|||
$scope.keepScrollDown = false;
|
||||
};
|
||||
|
||||
$scope.exportToTSV = function () {
|
||||
var data = $scope.paragraph.result;
|
||||
var tsv = '';
|
||||
for (var titleIndex in $scope.paragraph.result.columnNames) {
|
||||
tsv += $scope.paragraph.result.columnNames[titleIndex].name + '\t';
|
||||
}
|
||||
tsv = tsv.substring(0, tsv.length - 1) + '\n';
|
||||
for (var r in $scope.paragraph.result.msgTable) {
|
||||
var row = $scope.paragraph.result.msgTable[r];
|
||||
var tsvRow = '';
|
||||
for (var index in row) {
|
||||
tsvRow += row[index].value + '\t';
|
||||
}
|
||||
tsv += tsvRow.substring(0, tsvRow.length - 1) + '\n';
|
||||
}
|
||||
SaveAsService.SaveAs(tsv, 'data', 'tsv');
|
||||
};
|
||||
|
||||
// Helium ---------------------------------------------
|
||||
|
||||
// app states
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@ angular.module('zeppelinWebApp').controller('NavCtrl', function($scope, $rootSco
|
|||
$rootScope.truncatedUsername = $rootScope.ticket.principal.substr(0, MAX_USERNAME_LENGTH) + '..';
|
||||
}
|
||||
}
|
||||
if (_.isEmpty($rootScope.truncatedUsername)) {
|
||||
$rootScope.truncatedUsername = 'Connected';
|
||||
}
|
||||
};
|
||||
|
||||
$scope.$on('loginSuccess', function(event, param) {
|
||||
|
|
@ -100,9 +103,21 @@ angular.module('zeppelinWebApp').controller('NavCtrl', function($scope, $rootSco
|
|||
}
|
||||
};
|
||||
|
||||
function getZeppelinVersion() {
|
||||
console.log('version');
|
||||
$http.get(baseUrlSrv.getRestApiBase() + '/version').success(
|
||||
function(data, status, headers, config) {
|
||||
$rootScope.zeppelinVersion = data.body;
|
||||
}).error(
|
||||
function(data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
});
|
||||
}
|
||||
|
||||
vm.loadNotes = loadNotes;
|
||||
vm.isActive = isActive;
|
||||
|
||||
getZeppelinVersion();
|
||||
vm.loadNotes();
|
||||
$scope.checkUsername();
|
||||
|
||||
|
|
|
|||
|
|
@ -61,11 +61,11 @@ limitations under the License.
|
|||
</ul>
|
||||
|
||||
|
||||
<ul class="nav navbar-nav navbar-right" style="margin-top:10px; margin-right:5px;">
|
||||
<li ng-if="ticket">
|
||||
<ul class="nav navbar-nav navbar-right" style="margin-right:5px;">
|
||||
<li ng-if="ticket" style="margin-top:10px;">
|
||||
<!--TODO(bzz): move to Typeahead https://angular-ui.github.io/bootstrap -->
|
||||
<form role="search"
|
||||
style="display: inline-block; margin: 0 10px"
|
||||
style="display: inline-block; margin: 0px"
|
||||
class="navbar-form"
|
||||
ng-submit="search(searchTerm)">
|
||||
<div class="input-group">
|
||||
|
|
@ -89,19 +89,76 @@ limitations under the License.
|
|||
</div>
|
||||
</form>
|
||||
</li>
|
||||
<li class="server-status" >
|
||||
<i class="fa fa-circle" ng-class="{'server-connected':navbar.connected, 'server-disconnected':!navbar.connected}"></i>
|
||||
<span ng-show="navbar.connected" ng-if="ticket.principal == 'anonymous' ">Connected</span>
|
||||
<span ng-show="navbar.connected" ng-if="ticket.principal != 'anonymous' " tooltip-placement="bottom" tooltip="{{fullUsername}}">{{truncatedUsername}}</span>
|
||||
<span ng-show="!navbar.connected">Disconnected</span>
|
||||
<li class="dropdown " dropdown="">
|
||||
<a class="dropdown-toggle" type="button" data-toggle="dropdown" href="#"
|
||||
ng-show="navbar.connected" ng-if="ticket.principal == 'anonymous' ">
|
||||
<i class="fa fa-circle server-status"
|
||||
ng-class="{'server-connected':navbar.connected, 'server-disconnected':!navbar.connected}"></i>
|
||||
Connected
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<a class="dropdown-toggle" type="button" data-toggle="dropdown" href="#"
|
||||
ng-show="navbar.connected" ng-if="ticket.principal != 'anonymous' "
|
||||
tooltip-placement="bottom" tooltip="{{fullUsername}}">
|
||||
<i class="fa fa-circle server-status"
|
||||
ng-class="{'server-connected':navbar.connected, 'server-disconnected':!navbar.connected}"></i>
|
||||
{{truncatedUsername}}
|
||||
<span class="caret"></span></a>
|
||||
<a class="dropdown-toggle" type="button" data-toggle="dropdown" href="#"
|
||||
ng-show="!navbar.connected">
|
||||
<i class="fa fa-circle server-status"
|
||||
ng-class="{'server-connected':navbar.connected, 'server-disconnected':!navbar.connected}"></i>
|
||||
Disconnected
|
||||
<span class="caret"></span></a>
|
||||
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="" data-toggle="modal" data-target="#aboutModal">
|
||||
<i style="font-size: 15px;" class="fa fa-info"></i> About</a></li>
|
||||
<li ng-show="ticket.principal && ticket.principal!='anonymous'" style="left: 5px;">
|
||||
<a ng-click="logout()">Logout</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li ng-if="!ticket">
|
||||
<button class="btn btn-default" data-toggle="modal" data-target="#loginModal" ng-click="showLoginWindow()" style="margin-left: 10px">Login</button>
|
||||
</li>
|
||||
<li ng-show="ticket.principal && ticket.principal!='anonymous'" style="left: 5px;">
|
||||
<button class="btn btn-default" ng-click="logout()" tooltip-placement="bottom" tooltip="logout">Logout</button>
|
||||
<button class="btn btn-default" data-toggle="modal" data-target="#loginModal"
|
||||
ng-click="showLoginWindow()" style="margin-top: 8px">Login
|
||||
</button>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="aboutModal" class="modal fade" role="dialog"
|
||||
tabindex='-1'>
|
||||
<div class="modal-dialog">
|
||||
|
||||
<!-- Modal content-->
|
||||
<div class="modal-content" id="NoteImportCtrl" ng-init="NoteImportInit">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h4 class="modal-title">About Zeppelin</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="about">
|
||||
<div class="logo">
|
||||
<img src="assets/images/zepLogo.png" alt="Apache Zeppelin" title="Apache Zeppelin">
|
||||
</div>
|
||||
<div class="content">
|
||||
<h3>Apache Zeppelin</h3>
|
||||
<br>
|
||||
<span id="i18n-14">Version</span>
|
||||
{{zeppelinVersion}}
|
||||
<br>
|
||||
<br>
|
||||
<a href="http://zeppelin.apache.org/" target="_blank"><span id="i18n-15">Get involved!</span></a>
|
||||
<br>
|
||||
<a href="http://www.apache.org/licenses/LICENSE-2.0" target="_blank"><span id="i18n-16">Licensed under the Apache License, Version 2.0</span></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue