mirror of
https://github.com/apache/zeppelin
synced 2026-05-24 09:38:26 +00:00
Merge branch 'master' of https://github.com/apache/zeppelin into py4jPythonInterpreter
This commit is contained in:
commit
c3f5b78d76
23 changed files with 945 additions and 638 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -100,6 +100,9 @@ Thumbs.db
|
|||
target/
|
||||
**/target/
|
||||
|
||||
# maven flattened pom files
|
||||
**/.flattened-pom.xml
|
||||
|
||||
# Generated by Jekyll
|
||||
docs/_site/
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ cache:
|
|||
- ${HOME}/R
|
||||
- zeppelin-web/node
|
||||
- zeppelin-web/node_modules
|
||||
- zeppelin-web/bower_components
|
||||
|
||||
addons:
|
||||
apt:
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ if [[ ($# -ne 1) || ( $1 == "--help") || $1 == "-h" ]]; then
|
|||
usage
|
||||
fi
|
||||
|
||||
TO_VERSION=$1
|
||||
TO_VERSION="$1"
|
||||
|
||||
check_scala_version() {
|
||||
for i in ${VALID_VERSIONS[*]}; do [ $i = "$1" ] && return 0; done
|
||||
|
|
@ -42,12 +42,14 @@ check_scala_version() {
|
|||
exit 1
|
||||
}
|
||||
|
||||
check_scala_version "$TO_VERSION"
|
||||
check_scala_version "${TO_VERSION}"
|
||||
|
||||
if [ $TO_VERSION = "2.11" ]; then
|
||||
if [ "${TO_VERSION}" = "2.11" ]; then
|
||||
FROM_VERSION="2.10"
|
||||
SCALA_LIB_VERSION="2.11.7"
|
||||
else
|
||||
FROM_VERSION="2.11"
|
||||
SCALA_LIB_VERSION="2.10.5"
|
||||
fi
|
||||
|
||||
sed_i() {
|
||||
|
|
@ -57,11 +59,17 @@ sed_i() {
|
|||
export -f sed_i
|
||||
|
||||
BASEDIR=$(dirname $0)/..
|
||||
find "$BASEDIR" -name 'pom.xml' -not -path '*target*' -print \
|
||||
-exec bash -c "sed_i 's/\(artifactId.*\)_'$FROM_VERSION'/\1_'$TO_VERSION'/g' {}" \;
|
||||
find "${BASEDIR}" -name 'pom.xml' -not -path '*target*' -print \
|
||||
-exec bash -c "sed_i 's/\(artifactId.*\)_'${FROM_VERSION}'/\1_'${TO_VERSION}'/g' {}" \;
|
||||
|
||||
# Also update <scala.binary.version> in parent POM
|
||||
# update <scala.binary.version> in parent POM
|
||||
# Match any scala binary version to ensure idempotency
|
||||
sed_i '1,/<scala\.binary\.version>[0-9]*\.[0-9]*</s/<scala\.binary\.version>[0-9]*\.[0-9]*</<scala.binary.version>'$TO_VERSION'</' \
|
||||
"$BASEDIR/pom.xml"
|
||||
sed_i '1,/<scala\.binary\.version>[0-9]*\.[0-9]*</s/<scala\.binary\.version>[0-9]*\.[0-9]*</<scala.binary.version>'${TO_VERSION}'</' \
|
||||
"${BASEDIR}/pom.xml"
|
||||
|
||||
# update <scala.version> in parent POM
|
||||
# This is to make variables in leaf pom to be substituted to real value when flattened-pom is created.
|
||||
# maven-flatten plugin doesn't take properties defined under profile even if scala-2.11/scala-2.10 is activated via -Pscala-2.11/-Pscala-2.10,
|
||||
# and use default defined properties to create flatten pom.
|
||||
sed_i '1,/<scala\.version>[0-9]*\.[0-9]*\.[0-9]*</s/<scala\.version>[0-9]*\.[0-9]*\.[0-9]*</<scala.version>'${SCALA_LIB_VERSION}'</' \
|
||||
"${BASEDIR}/pom.xml"
|
||||
|
|
|
|||
|
|
@ -167,6 +167,10 @@ There are more JDBC interpreter properties you can specify like below.
|
|||
<td>default.jceks.credentialKey</td>
|
||||
<td>jceks credential key</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>zeppelin.jdbc.precode</td>
|
||||
<td>Some SQL which executes while opening connection</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
You can also add more properties by using this [method](http://docs.oracle.com/javase/7/docs/api/java/sql/DriverManager.html#getConnection%28java.lang.String,%20java.util.Properties%29).
|
||||
|
|
@ -423,8 +427,13 @@ Here are some examples you can refer to. Including the below connectors, you can
|
|||
<td>default.password</td>
|
||||
<td>hive_password</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>hive.proxy.user</td>
|
||||
<td>true or false</td>
|
||||
</table>
|
||||
|
||||
Connection to Hive JDBC with a proxy user can be disabled with `hive.proxy.user` property (set to true by default)
|
||||
|
||||
[Apache Hive 1 JDBC Driver Docs](https://cwiki.apache.org/confluence/display/Hive/HiveServer2+Clients#HiveServer2Clients-JDBC)
|
||||
[Apache Hive 2 JDBC Driver Docs](https://cwiki.apache.org/confluence/display/Hive/HiveServer2+Clients#HiveServer2Clients-JDBC)
|
||||
|
||||
|
|
|
|||
|
|
@ -111,9 +111,9 @@ You can also install 3rd party interpreters located in the maven repository by u
|
|||
./bin/install-interpreter.sh --name interpreter1 --artifact groupId1:artifact1:version1
|
||||
```
|
||||
|
||||
The above command will download maven artifact `groupId1:artifact1:version1` and all of it's transitive dependencies into `interpreter/interpreter1` directory.
|
||||
The above command will download maven artifact `groupId1:artifact1:version1` and all of its transitive dependencies into `interpreter/interpreter1` directory.
|
||||
|
||||
After restart Zeppelin, then [create interpreter setting](../manual/interpreters.html#what-is-zeppelin-interpreter) and [bind it with your notebook](../manual/interpreters.html#what-is-zeppelin-interpreter-setting).
|
||||
After restart Zeppelin, then [create interpreter setting](../manual/interpreters.html#what-is-zeppelin-interpreter) and [bind it with your note](../manual/interpreters.html#what-is-zeppelin-interpreter-setting).
|
||||
|
||||
#### Install multiple 3rd party interpreters at once
|
||||
|
||||
|
|
|
|||
|
|
@ -14,14 +14,7 @@
|
|||
*/
|
||||
package org.apache.zeppelin.jdbc;
|
||||
|
||||
import static org.apache.commons.lang.StringUtils.containsIgnoreCase;
|
||||
import static org.apache.commons.lang.StringUtils.isEmpty;
|
||||
import static org.apache.commons.lang.StringUtils.isNotEmpty;
|
||||
import static org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod.KERBEROS;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
|
|
@ -37,11 +30,11 @@ import java.util.Map;
|
|||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import org.apache.commons.dbcp2.ConnectionFactory;
|
||||
import org.apache.commons.dbcp2.DriverManagerConnectionFactory;
|
||||
import org.apache.commons.dbcp2.PoolableConnectionFactory;
|
||||
import org.apache.commons.dbcp2.PoolingDriver;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.pool2.ObjectPool;
|
||||
import org.apache.commons.pool2.impl.GenericObjectPool;
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
|
|
@ -49,7 +42,10 @@ import org.apache.hadoop.security.UserGroupInformation;
|
|||
import org.apache.hadoop.security.alias.CredentialProvider;
|
||||
import org.apache.hadoop.security.alias.CredentialProviderFactory;
|
||||
import org.apache.thrift.transport.TTransportException;
|
||||
import org.apache.zeppelin.interpreter.*;
|
||||
import org.apache.zeppelin.interpreter.Interpreter;
|
||||
import org.apache.zeppelin.interpreter.InterpreterContext;
|
||||
import org.apache.zeppelin.interpreter.InterpreterException;
|
||||
import org.apache.zeppelin.interpreter.InterpreterResult;
|
||||
import org.apache.zeppelin.interpreter.InterpreterResult.Code;
|
||||
import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion;
|
||||
import org.apache.zeppelin.jdbc.security.JDBCSecurityImpl;
|
||||
|
|
@ -61,9 +57,13 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.Sets.SetView;
|
||||
|
||||
import static org.apache.commons.lang.StringUtils.containsIgnoreCase;
|
||||
import static org.apache.commons.lang.StringUtils.isEmpty;
|
||||
import static org.apache.commons.lang.StringUtils.isNotEmpty;
|
||||
import static org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod.KERBEROS;
|
||||
|
||||
/**
|
||||
* JDBC interpreter for Zeppelin. This interpreter can also be used for accessing HAWQ,
|
||||
|
|
@ -103,6 +103,7 @@ public class JDBCInterpreter extends Interpreter {
|
|||
static final String PASSWORD_KEY = "password";
|
||||
static final String JDBC_JCEKS_FILE = "jceks.file";
|
||||
static final String JDBC_JCEKS_CREDENTIAL_KEY = "jceks.credentialKey";
|
||||
static final String ZEPPELIN_JDBC_PRECODE_KEY = "zeppelin.jdbc.precode";
|
||||
static final String DOT = ".";
|
||||
|
||||
private static final char WHITESPACE = ' ';
|
||||
|
|
@ -340,6 +341,9 @@ public class JDBCInterpreter extends Interpreter {
|
|||
|
||||
if (!getJDBCConfiguration(user).isConnectionInDBDriverPool(propertyKey)) {
|
||||
createConnectionPool(url, user, propertyKey, properties);
|
||||
try (Connection connection = DriverManager.getConnection(jdbcDriver)) {
|
||||
executePrecode(connection);
|
||||
}
|
||||
}
|
||||
return DriverManager.getConnection(jdbcDriver);
|
||||
}
|
||||
|
|
@ -374,16 +378,20 @@ public class JDBCInterpreter extends Interpreter {
|
|||
if (lastIndexOfUrl == -1) {
|
||||
lastIndexOfUrl = connectionUrl.length();
|
||||
}
|
||||
connectionUrl.insert(lastIndexOfUrl, ";hive.server2.proxy.user=" + user + ";");
|
||||
boolean hasProxyUser = property.containsKey("hive.proxy.user");
|
||||
if (!hasProxyUser || !property.getProperty("hive.proxy.user").equals("false")){
|
||||
logger.debug("Using hive proxy user");
|
||||
connectionUrl.insert(lastIndexOfUrl, ";hive.server2.proxy.user=" + user + ";");
|
||||
}
|
||||
connection = getConnectionFromPool(connectionUrl.toString(),
|
||||
user, propertyKey, properties);
|
||||
user, propertyKey, properties);
|
||||
} else {
|
||||
UserGroupInformation ugi = null;
|
||||
try {
|
||||
ugi = UserGroupInformation.createProxyUser(user,
|
||||
UserGroupInformation.getCurrentUser());
|
||||
ugi = UserGroupInformation.createProxyUser(
|
||||
user, UserGroupInformation.getCurrentUser());
|
||||
} catch (Exception e) {
|
||||
logger.error("Error in createProxyUser", e);
|
||||
logger.error("Error in getCurrentUser", e);
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append(e.getMessage()).append("\n");
|
||||
stringBuilder.append(e.getCause());
|
||||
|
|
@ -540,6 +548,20 @@ public class JDBCInterpreter extends Interpreter {
|
|||
return queries;
|
||||
}
|
||||
|
||||
private void executePrecode(Connection connection) throws SQLException {
|
||||
String precode = getProperty(ZEPPELIN_JDBC_PRECODE_KEY);
|
||||
if (StringUtils.isNotBlank(precode)) {
|
||||
precode = StringUtils.trim(precode);
|
||||
logger.info("Run SQL precode '{}'", precode);
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
statement.execute(precode);
|
||||
if (!connection.getAutoCommit()) {
|
||||
connection.commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private InterpreterResult executeSql(String propertyKey, String sql,
|
||||
InterpreterContext interpreterContext) {
|
||||
Connection connection;
|
||||
|
|
@ -761,4 +783,3 @@ public class JDBCInterpreter extends Interpreter {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,12 @@
|
|||
"propertyName": "zeppelin.jdbc.principal",
|
||||
"defaultValue": "",
|
||||
"description": "Kerberos principal"
|
||||
},
|
||||
"zeppelin.jdbc.precode": {
|
||||
"envName": null,
|
||||
"propertyName": "zeppelin.jdbc.precode",
|
||||
"defaultValue": "",
|
||||
"description": "SQL which executes while opening connection"
|
||||
}
|
||||
},
|
||||
"editor": {
|
||||
|
|
|
|||
|
|
@ -43,6 +43,9 @@ import org.junit.Before;
|
|||
import org.junit.Test;
|
||||
|
||||
import com.mockrunner.jdbc.BasicJDBCTestCaseAdapter;
|
||||
|
||||
import static org.apache.zeppelin.jdbc.JDBCInterpreter.ZEPPELIN_JDBC_PRECODE_KEY;
|
||||
|
||||
/**
|
||||
* JDBC interpreter unit tests
|
||||
*/
|
||||
|
|
@ -386,4 +389,43 @@ public class JDBCInterpreterTest extends BasicJDBCTestCaseAdapter {
|
|||
assertNull(user2JDBC2Conf.getPropertyMap("default").get("password"));
|
||||
jdbc2.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrecode() throws SQLException, IOException {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty("default.driver", "org.h2.Driver");
|
||||
properties.setProperty("default.url", getJdbcConnection());
|
||||
properties.setProperty("default.user", "");
|
||||
properties.setProperty("default.password", "");
|
||||
properties.setProperty(ZEPPELIN_JDBC_PRECODE_KEY, "SET @testVariable=1");
|
||||
JDBCInterpreter jdbcInterpreter = new JDBCInterpreter(properties);
|
||||
jdbcInterpreter.open();
|
||||
|
||||
String sqlQuery = "select @testVariable";
|
||||
|
||||
InterpreterResult interpreterResult = jdbcInterpreter.interpret(sqlQuery, interpreterContext);
|
||||
|
||||
assertEquals(InterpreterResult.Code.SUCCESS, interpreterResult.code());
|
||||
assertEquals(InterpreterResult.Type.TABLE, interpreterResult.message().get(0).getType());
|
||||
assertEquals("@TESTVARIABLE\n1\n", interpreterResult.message().get(0).getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIncorrectPrecode() throws SQLException, IOException {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty("default.driver", "org.h2.Driver");
|
||||
properties.setProperty("default.url", getJdbcConnection());
|
||||
properties.setProperty("default.user", "");
|
||||
properties.setProperty("default.password", "");
|
||||
properties.setProperty(ZEPPELIN_JDBC_PRECODE_KEY, "incorrect command");
|
||||
JDBCInterpreter jdbcInterpreter = new JDBCInterpreter(properties);
|
||||
jdbcInterpreter.open();
|
||||
|
||||
String sqlQuery = "select 1";
|
||||
|
||||
InterpreterResult interpreterResult = jdbcInterpreter.interpret(sqlQuery, interpreterContext);
|
||||
|
||||
assertEquals(InterpreterResult.Code.ERROR, interpreterResult.code());
|
||||
assertEquals(InterpreterResult.Type.TEXT, interpreterResult.message().get(0).getType());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1095
livy/pom.xml
1095
livy/pom.xml
File diff suppressed because it is too large
Load diff
28
pom.xml
28
pom.xml
|
|
@ -308,6 +308,32 @@
|
|||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>flatten-maven-plugin</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<configuration>
|
||||
<flattenMode>ossrh</flattenMode>
|
||||
<updatePomFile>true</updatePomFile>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>flatten</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>flatten</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>flatten.clean</id>
|
||||
<phase>clean</phase>
|
||||
<goals>
|
||||
<goal>clean</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- Test coverage plugin -->
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
|
|
@ -475,7 +501,7 @@
|
|||
<version>${plugin.deploy.version}</version>
|
||||
</plugin>
|
||||
|
||||
<!--TODO(alex): make part of the build and reconcile conflicts
|
||||
<!--TODO(alex): make part of the build and reconcile conflicts
|
||||
<plugin>
|
||||
<groupId>com.ning.maven.plugins</groupId>
|
||||
<artifactId>maven-duplicate-finder-plugin</artifactId>
|
||||
|
|
|
|||
|
|
@ -54,8 +54,11 @@ def getBuildStatus(author, commit):
|
|||
# get latest 25 builds
|
||||
resp = requests.get(url=travisApi + "/repos/" + author + "/zeppelin/builds")
|
||||
data = json.loads(resp.text)
|
||||
|
||||
build = None
|
||||
|
||||
if len(data) == 0:
|
||||
return build;
|
||||
|
||||
for b in data:
|
||||
if b["commit"][:len(commit)] == commit:
|
||||
resp = requests.get(url=travisApi + "/repos/" + author + "/zeppelin/builds/" + str(b["id"]))
|
||||
|
|
@ -103,8 +106,8 @@ for sleep in check:
|
|||
info("Get build status ...")
|
||||
build = getBuildStatus(author, commit)
|
||||
if build == None:
|
||||
info("Can't find build for commit= " + commit)
|
||||
sys.exit(1)
|
||||
info("Can't find build for commit " + commit + " from " + author)
|
||||
sys.exit(2)
|
||||
|
||||
print("Build https://travis-ci.org/" + author + "/zeppelin/builds/" + str(build["id"]))
|
||||
failure, running = printBuildStatus(build)
|
||||
|
|
|
|||
|
|
@ -34,6 +34,10 @@ public class HeliumPackage {
|
|||
// [[ .. and .. and .. ] or [ .. and .. and ..] ..]
|
||||
private String license;
|
||||
private String icon;
|
||||
private String published;
|
||||
|
||||
private String groupId; // get groupId of INTERPRETER type package
|
||||
private String artifactId; // get artifactId of INTERPRETER type package
|
||||
|
||||
private SpellPackageInfo spell;
|
||||
private Map<String, Object> config;
|
||||
|
|
@ -108,6 +112,18 @@ public class HeliumPackage {
|
|||
return icon;
|
||||
}
|
||||
|
||||
public String getPublishedDate() {
|
||||
return published;
|
||||
}
|
||||
|
||||
public String getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public String getArtifactId() {
|
||||
return artifactId;
|
||||
}
|
||||
|
||||
public SpellPackageInfo getSpellInfo() {
|
||||
return spell;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,15 @@ export default function HeliumCtrl($scope, $rootScope, $sce,
|
|||
$scope.showVersions = {};
|
||||
$scope.bundleOrder = [];
|
||||
$scope.bundleOrderChanged = false;
|
||||
$scope.vizTypePkg = {}
|
||||
$scope.spellTypePkg = {}
|
||||
$scope.intpTypePkg = {}
|
||||
$scope.appTypePkg = {}
|
||||
$scope.numberOfEachPackageByType = {}
|
||||
$scope.allPackageTypes = [HeliumType][0]
|
||||
$scope.pkgListByType = 'VISUALIZATION'
|
||||
$scope.defaultPackageConfigs = {}; // { pkgName, [{name, type, desc, value, defaultValue}] }
|
||||
$scope.intpDefaultIcon = $sce.trustAsHtml('<img src="../assets/images/maven_default_icon.png" style="width: 12px"/>');
|
||||
|
||||
function init() {
|
||||
// get all package info and set config
|
||||
|
|
@ -31,6 +39,7 @@ export default function HeliumCtrl($scope, $rootScope, $sce,
|
|||
.then(({ pkgSearchResults, defaultPackages }) => {
|
||||
$scope.pkgSearchResults = pkgSearchResults;
|
||||
$scope.defaultPackages = defaultPackages;
|
||||
classifyPkgType($scope.defaultPackages)
|
||||
return heliumService.getAllPackageConfigs()
|
||||
})
|
||||
.then(defaultPackageConfigs => {
|
||||
|
|
@ -45,6 +54,38 @@ export default function HeliumCtrl($scope, $rootScope, $sce,
|
|||
});
|
||||
}
|
||||
|
||||
var classifyPkgType = function(packageInfos) {
|
||||
var vizTypePkg = {}
|
||||
var spellTypePkg = {}
|
||||
var intpTypePkg = {}
|
||||
var appTypePkg = {}
|
||||
|
||||
for (var name in packageInfos) {
|
||||
var pkgs = packageInfos[name]
|
||||
var pkgType = pkgs.pkg.type
|
||||
|
||||
switch (pkgType) {
|
||||
case HeliumType.VISUALIZATION:
|
||||
vizTypePkg[name] = pkgs;
|
||||
break;
|
||||
case HeliumType.SPELL:
|
||||
spellTypePkg[name] = pkgs;
|
||||
break;
|
||||
case HeliumType.INTERPRETER:
|
||||
intpTypePkg[name] = pkgs;
|
||||
break;
|
||||
case HeliumType.APPLICATION:
|
||||
appTypePkg[name] = pkgs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$scope.vizTypePkg = vizTypePkg
|
||||
$scope.spellTypePkg = spellTypePkg
|
||||
$scope.appTypePkg = appTypePkg
|
||||
$scope.intpTypePkg = intpTypePkg
|
||||
};
|
||||
|
||||
$scope.bundleOrderListeners = {
|
||||
accept: function(sourceItemHandleScope, destSortableScope) {return true;},
|
||||
itemMoved: function(event) {},
|
||||
|
|
@ -108,40 +149,58 @@ export default function HeliumCtrl($scope, $rootScope, $sce,
|
|||
return license;
|
||||
}
|
||||
|
||||
$scope.enable = function(name, artifact) {
|
||||
$scope.enable = function(name, artifact, type, groupId) {
|
||||
var license = getLicense(name, artifact);
|
||||
|
||||
var confirm = BootstrapDialog.confirm({
|
||||
closable: false,
|
||||
closeByBackdrop: false,
|
||||
closeByKeyboard: false,
|
||||
var mavenArtifactInfoToHTML = groupId +':'+ artifact.split('@')[0] + ':' + artifact.split('@')[1];
|
||||
var zeppelinVersion = $rootScope.zeppelinVersion;
|
||||
var url = 'https://zeppelin.apache.org/docs/' + zeppelinVersion + '/manual/interpreterinstallation.html';
|
||||
|
||||
var confirm = ''
|
||||
if (type === 'INTERPRETER') {
|
||||
confirm = BootstrapDialog.show({
|
||||
title: '',
|
||||
message: 'Do you want to enable ' + name + '?' +
|
||||
'<div style="color:gray">' + artifact + '</div>' +
|
||||
'<div style="border-top: 1px solid #efefef; margin-top: 10px; padding-top: 5px;">License</div>' +
|
||||
'<div style="color:gray">' + license + '</div>',
|
||||
callback: function(result) {
|
||||
if (result) {
|
||||
confirm.$modalFooter.find('button').addClass('disabled');
|
||||
confirm.$modalFooter.find('button:contains("OK")')
|
||||
.html('<i class="fa fa-circle-o-notch fa-spin"></i> Enabling');
|
||||
heliumService.enable(name, artifact).
|
||||
success(function(data, status) {
|
||||
init();
|
||||
confirm.close();
|
||||
}).
|
||||
error(function(data, status) {
|
||||
confirm.close();
|
||||
console.log('Failed to enable package %o %o. %o', name, artifact, data);
|
||||
BootstrapDialog.show({
|
||||
title: 'Error on enabling ' + name,
|
||||
message: data.message
|
||||
});
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
message: '<p>Below command will download maven artifact ' +
|
||||
'<code style="font-size: 11.5px; background-color: #f5f5f5; color: #0a0a0a">' +
|
||||
mavenArtifactInfoToHTML + '</code>' +
|
||||
' and all of its transitive dependencies into interpreter/interpreter-name directory.<p>' +
|
||||
'<div class="highlight"><pre><code class="text language-text" data-lang="text" style="font-size: 11.5px">' +
|
||||
'./bin/install-interpreter.sh --name "interpreter-name" --artifact ' +
|
||||
mavenArtifactInfoToHTML +' </code></pre>' +
|
||||
'<p>After restart Zeppelin, create interpreter setting and bind it with your note. ' +
|
||||
'For more detailed information, see <a target="_blank" href=' +
|
||||
url + '>Interpreter Installation.</a></p>'
|
||||
});
|
||||
} else {
|
||||
confirm = BootstrapDialog.confirm({
|
||||
closable: false,
|
||||
closeByBackdrop: false,
|
||||
closeByKeyboard: false,
|
||||
title: '',
|
||||
message: 'Do you want to enable ' + name + '?' +
|
||||
'<div style="color:gray">' + artifact + '</div>' +
|
||||
'<div style="border-top: 1px solid #efefef; margin-top: 10px; padding-top: 5px;">License</div>' +
|
||||
'<div style="color:gray">' + license + '</div>',
|
||||
callback: function (result) {
|
||||
if (result) {
|
||||
confirm.$modalFooter.find('button').addClass('disabled');
|
||||
confirm.$modalFooter.find('button:contains("OK")')
|
||||
.html('<i class="fa fa-circle-o-notch fa-spin"></i> Enabling');
|
||||
heliumService.enable(name, artifact, type).success(function (data, status) {
|
||||
init();
|
||||
confirm.close();
|
||||
}).error(function (data, status) {
|
||||
confirm.close();
|
||||
console.log('Failed to enable package %o %o. %o', name, artifact, data);
|
||||
BootstrapDialog.show({
|
||||
title: 'Error on enabling ' + name,
|
||||
message: data.message
|
||||
});
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$scope.disable = function(name) {
|
||||
|
|
@ -194,6 +253,20 @@ export default function HeliumCtrl($scope, $rootScope, $sce,
|
|||
!$scope.isLocalPackage(pkgSearchResult);
|
||||
};
|
||||
|
||||
$scope.hasMavenLink = function(pkgSearchResult) {
|
||||
const pkg = pkgSearchResult.pkg;
|
||||
return (pkg.type === HeliumType.APPLICATION || pkg.type === HeliumType.INTERPRETER) &&
|
||||
!$scope.isLocalPackage(pkgSearchResult);
|
||||
};
|
||||
|
||||
$scope.getPackageSize = function(pkgSearchResult, targetPkgType) {
|
||||
var result = []
|
||||
_.map(pkgSearchResult, function (pkg) {
|
||||
result.push(_.find(pkg, {type: targetPkgType}))
|
||||
})
|
||||
return _.compact(result).length
|
||||
}
|
||||
|
||||
$scope.configExists = function(pkgSearchResult) {
|
||||
// helium package config is persisted per version
|
||||
return pkgSearchResult.pkg.config && pkgSearchResult.pkg.artifact;
|
||||
|
|
|
|||
|
|
@ -136,6 +136,33 @@
|
|||
color: #636363;
|
||||
}
|
||||
|
||||
.heliumLearnMore {
|
||||
margin-top:10px;
|
||||
}
|
||||
|
||||
.heliumLearnMore a {
|
||||
cursor:pointer;
|
||||
margin-right:10px;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
.heliumRepoBtn {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.heliumRepoBtn:hover, .heliumRepoBtn:focus {
|
||||
margin-right: 8px;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.localPkgInfo {
|
||||
margin: 10px 12px 0 0;
|
||||
font-size: 11px;
|
||||
font-style: italic;
|
||||
color: #aaaaaa;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.heliumConfig {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 10px;
|
||||
|
|
@ -147,10 +174,6 @@
|
|||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.heliumConfigValueInput {
|
||||
|
||||
}
|
||||
|
||||
.heliumConfigValueText {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,23 @@ limitations under the License.
|
|||
<h3 class="new_h3">
|
||||
Helium
|
||||
</h3>
|
||||
<div class="pull-right heliumLearnMore">
|
||||
<a target="_blank"
|
||||
class="helium-repo-btn"
|
||||
ng-href="https://zeppelin.apache.org/helium_packages.html"
|
||||
tooltip-placement="bottom"
|
||||
tooltip="Learn more">
|
||||
<i class="icon-question" ng-style="{color: 'black'}"></i>
|
||||
</a>
|
||||
<button tabindex="0" class="btn btn-default btn-sm heliumRepoBtn helium-popover"
|
||||
role="button"
|
||||
ng-repeat="pkgTypes in allPackageTypes"
|
||||
ng-click="$parent.pkgListByType = pkgTypes">
|
||||
<i class="fa fa-cube"></i>
|
||||
{{pkgTypes}}
|
||||
</button>
|
||||
<p class="localPkgInfo">* Local registry package's name is gray colored.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-show="bundleOrder.length > 1"
|
||||
|
|
@ -34,8 +51,8 @@ limitations under the License.
|
|||
</div>
|
||||
</div>
|
||||
<span class="saveLink"
|
||||
ng-show="bundleOrderChanged"
|
||||
ng-click="saveBundleOrder()">
|
||||
ng-show="bundleOrderChanged"
|
||||
ng-click="saveBundleOrder()">
|
||||
save
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -44,28 +61,46 @@ limitations under the License.
|
|||
</div>
|
||||
|
||||
<div class="box width-full heliumPackageContainer">
|
||||
<div class="row"
|
||||
style="padding-bottom: 15px"
|
||||
ng-if="getPackageSize(defaultPackages, pkgListByType) === 0">
|
||||
<div class="col-md-12 gray40-message">
|
||||
<em>Currently there is no available package to be listed</em>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row heliumPackageList"
|
||||
ng-repeat="(pkgName, pkgSearchResult) in defaultPackages">
|
||||
|
||||
ng-repeat="pkgSearchResult in defaultPackages | toArray:false | orderBy: 'pkg.published':true"
|
||||
ng-show="$parent.pkgListByType === pkgSearchResult.pkg.type">
|
||||
<div class="col-md-12">
|
||||
<div class="heliumPackageHead">
|
||||
<div class="heliumPackageIcon"
|
||||
ng-if="pkgSearchResult.pkg.type !== 'INTERPRETER'"
|
||||
ng-bind-html=pkgSearchResult.pkg.icon></div>
|
||||
<div class="heliumPackageIcon"
|
||||
ng-if="pkgSearchResult.pkg.type === 'INTERPRETER'"
|
||||
ng-bind-html=intpDefaultIcon></div>
|
||||
<div class="heliumPackageName">
|
||||
<span ng-if="hasNpmLink(pkgSearchResult)">
|
||||
<a target="_blank" href="https://www.npmjs.com/package/{{pkgName}}">{{pkgName}}</a>
|
||||
<a target="_blank" href="https://www.npmjs.com/package/{{pkgSearchResult.pkg.name}}">{{pkgSearchResult.pkg.name}}</a>
|
||||
</span>
|
||||
<span ng-if="!hasNpmLink(pkgSearchResult)" ng-class="{'heliumLocalPackage': isLocalPackage(pkgSearchResult)}">
|
||||
{{pkgName}}
|
||||
<span ng-if="!hasNpmLink(pkgSearchResult) && !hasMavenLink(pkgSearchResult)" ng-class="{'heliumLocalPackage': isLocalPackage(pkgSearchResult)}">
|
||||
{{pkgSearchResult.pkg.name}}
|
||||
</span>
|
||||
<span ng-if="hasMavenLink(pkgSearchResult)">
|
||||
<a target="_blank"
|
||||
href="http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22{{pkgSearchResult.pkg.artifact.split('@')[0]}}%22%20AND%20v%3A%22{{pkgSearchResult.pkg.artifact.split('@')[1]}}%22">
|
||||
{{pkgSearchResult.pkg.name}}
|
||||
</a>
|
||||
</span>
|
||||
<span class="heliumType">{{pkgSearchResult.pkg.type}}</span>
|
||||
</div>
|
||||
<div ng-show="!pkgSearchResult.enabled"
|
||||
ng-click="enable(pkgName, pkgSearchResult.pkg.artifact)"
|
||||
ng-click="enable(pkgSearchResult.pkg.name, pkgSearchResult.pkg.artifact, pkgSearchResult.pkg.type, pkgSearchResult.pkg.groupId)"
|
||||
class="btn btn-success btn-xs"
|
||||
style="float:right">Enable</div>
|
||||
<div ng-show="pkgSearchResult.enabled"
|
||||
ng-click="disable(pkgName)"
|
||||
ng-click="disable(pkgSearchResult.pkg.name)"
|
||||
ng-if="pkgSearchResult.pkg.type !== 'INTERPRETER'"
|
||||
class="btn btn-info btn-xs"
|
||||
style="float:right">Disable</div>
|
||||
<div ng-show="configExists(pkgSearchResult)"
|
||||
|
|
@ -76,20 +111,27 @@ limitations under the License.
|
|||
</div>
|
||||
<div ng-class="{heliumPackageDisabledArtifact: !pkgSearchResult.enabled, heliumPackageEnabledArtifact: pkgSearchResult.enabled}">
|
||||
{{pkgSearchResult.pkg.artifact}}
|
||||
<span ng-show="pkgSearchResults[pkgName].length > 0"
|
||||
ng-click="toggleVersions(pkgName)">
|
||||
<span ng-show="pkgSearchResults[pkgSearchResult.pkg.name].length > 0"
|
||||
ng-click="toggleVersions(pkgSearchResult.pkg.name)">
|
||||
versions
|
||||
</span>
|
||||
</div>
|
||||
<ul class="heliumPackageVersions"
|
||||
ng-show="showVersions[pkgName]">
|
||||
ng-show="showVersions[pkgSearchResult.pkg.name]">
|
||||
<li class="heliumPackageDisabledArtifact"
|
||||
ng-repeat="pkgSearchResult in pkgSearchResults[pkgName]">
|
||||
ng-repeat="pkgSearchResult in pkgSearchResults[pkgSearchResult.pkg.name]">
|
||||
{{pkgSearchResult.pkg.artifact}} -
|
||||
<span ng-click="enable(pkgName, pkgSearchResult.pkg.artifact)"
|
||||
<span ng-click="enable(pkgSearchResult.pkg.name, pkgSearchResult.pkg.artifact, pkgSearchResult.pkg.type, pkgSearchResult.pkg.groupId)"
|
||||
ng-if="pkgSearchResult.pkg.type !== 'INTERPRETER'"
|
||||
style="margin-left:3px;cursor:pointer;text-decoration: underline;color:#3071a9">
|
||||
enable
|
||||
</span>
|
||||
<a target="_blank"
|
||||
ng-if="pkgSearchResult.pkg.type === 'INTERPRETER'"
|
||||
style="margin-left:3px;cursor:pointer;text-decoration: underline;color:#3071a9"
|
||||
href="http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22{{pkgSearchResult.pkg.artifact.split('@')[0]}}%22%20AND%20v%3A%22{{pkgSearchResult.pkg.artifact.split('@')[1]}}%22">
|
||||
see more
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="heliumPackageDescription">
|
||||
|
|
|
|||
|
|
@ -267,9 +267,7 @@ function ResultCtrl($scope, $rootScope, $route, $window, $routeParams, $location
|
|||
|
||||
$scope.renderDefaultDisplay = function(targetElemId, type, data, refresh) {
|
||||
if (type === DefaultDisplayType.TABLE) {
|
||||
$timeout(function() {
|
||||
$scope.renderGraph(targetElemId, $scope.graphMode, refresh);
|
||||
}, 10);
|
||||
$scope.renderGraph(targetElemId, $scope.graphMode, refresh);
|
||||
} else if (type === DefaultDisplayType.HTML) {
|
||||
renderHtml(targetElemId, data);
|
||||
} else if (type === DefaultDisplayType.ANGULAR) {
|
||||
|
|
|
|||
|
|
@ -28,10 +28,10 @@ limitations under the License.
|
|||
&& config.graph.optionOpen && !asIframe && !viewOnly">
|
||||
<div ng-repeat="viz in builtInTableDataVisualizationList track by $index"
|
||||
id="trsetting{{id}}_{{viz.id}}"
|
||||
ng-show="graphMode == viz.id"></div>
|
||||
ng-if="graphMode == viz.id"></div>
|
||||
<div ng-repeat="viz in builtInTableDataVisualizationList track by $index"
|
||||
id="vizsetting{{id}}_{{viz.id}}"
|
||||
ng-show="graphMode == viz.id"></div>
|
||||
ng-if="graphMode == viz.id"></div>
|
||||
</div>
|
||||
|
||||
<!-- graph -->
|
||||
|
|
@ -40,7 +40,7 @@ limitations under the License.
|
|||
ng-class="{'noOverflow': graphMode=='table'}">
|
||||
<div ng-repeat="viz in builtInTableDataVisualizationList track by $index"
|
||||
id="p{{id}}_{{viz.id}}"
|
||||
ng-show="graphMode == viz.id">
|
||||
ng-if="graphMode == viz.id">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
BIN
zeppelin-web/src/assets/images/maven_default_icon.png
Normal file
BIN
zeppelin-web/src/assets/images/maven_default_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
|
|
@ -15,4 +15,6 @@
|
|||
export const HeliumType = {
|
||||
VISUALIZATION: 'VISUALIZATION',
|
||||
SPELL: 'SPELL',
|
||||
INTERPRETER: 'INTERPRETER',
|
||||
APPLICATION: 'APPLICATION',
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,11 @@ function websocketEvents($rootScope, $websocket, $location, baseUrlSrv) {
|
|||
label: 'Cancel',
|
||||
action: function(dialog) {
|
||||
dialog.close();
|
||||
$location.path('/');
|
||||
// using $rootScope.apply to trigger angular digest cycle
|
||||
// changing $location.path inside bootstrap modal wont trigger digest
|
||||
$rootScope.$apply(function() {
|
||||
$location.path('/');
|
||||
});
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import java.net.URL;
|
|||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Load helium visualization
|
||||
* Load helium visualization & spell
|
||||
*/
|
||||
public class HeliumBundleFactory {
|
||||
Logger logger = LoggerFactory.getLogger(HeliumBundleFactory.class);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@
|
|||
"babel-core": "^6.23.1",
|
||||
"babel-loader": "^6.3.2",
|
||||
"babel-preset-es2015": "^6.22.0",
|
||||
"babel-preset-stage-0": "^6.22.0"
|
||||
"babel-preset-stage-0": "^6.22.0",
|
||||
"css-loader": "^0.26.2",
|
||||
"style-loader": "^0.13.2",
|
||||
"url-loader": "^0.5.8",
|
||||
"file-loader": "^0.10.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,11 +19,36 @@ module.exports = {
|
|||
entry: './load.js',
|
||||
output: { path: './', filename: 'helium.bundle.js', },
|
||||
module: {
|
||||
loaders: [{
|
||||
loaders: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
// DON'T exclude. since zeppelin will bundle all necessary packages: `exclude: /node_modules/,`
|
||||
loader: 'babel-loader',
|
||||
query: { presets: ['es2015', 'stage-0'] },
|
||||
}]
|
||||
},
|
||||
{
|
||||
test: /(\.css)$/,
|
||||
loaders: ['style', 'css?sourceMap&importLoaders=1'],
|
||||
},
|
||||
{
|
||||
test: /\.woff(\?\S*)?$/,
|
||||
loader: 'url-loader?limit=10000&minetype=application/font-woff',
|
||||
},
|
||||
{
|
||||
test: /\.woff2(\?\S*)?$/,
|
||||
loader: 'url-loader?limit=10000&minetype=application/font-woff',
|
||||
},
|
||||
{
|
||||
test: /\.eot(\?\S*)?$/,
|
||||
loader: 'url-loader',
|
||||
}, {
|
||||
test: /\.ttf(\?\S*)?$/,
|
||||
loader: 'url-loader',
|
||||
},
|
||||
{
|
||||
test: /\.svg(\?\S*)?$/,
|
||||
loader: 'url-loader',
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue