Merge branch 'master' of https://github.com/apache/zeppelin into ZEPPELIN-1564

This commit is contained in:
Mina Lee 2016-11-03 15:20:47 +09:00
commit fb7e6ae0c5
110 changed files with 1380 additions and 467 deletions

View file

@ -2,7 +2,7 @@
**Documentation:** [User Guide](http://zeppelin.apache.org/docs/latest/index.html)<br/>
**Mailing Lists:** [User and Dev mailing list](http://zeppelin.apache.org/community.html)<br/>
**Continuous Integration:** [![Build Status](https://secure.travis-ci.org/apache/zeppelin.png?branch=master)](https://travis-ci.org/apache/zeppelin) <br/>
**Continuous Integration:** [![Build Status](https://travis-ci.org/apache/zeppelin.svg?branch=master)](https://travis-ci.org/apache/zeppelin) <br/>
**Contributing:** [Contribution Guide](https://zeppelin.apache.org/contribution/contributions.html)<br/>
**Issue Tracker:** [Jira](https://issues.apache.org/jira/browse/ZEPPELIN)<br/>
**License:** [Apache 2.0](https://github.com/apache/zeppelin/blob/master/LICENSE)

View file

@ -135,7 +135,7 @@ public class AlluxioInterpreter extends Interpreter {
private String[] splitAndRemoveEmpty(String st, String splitSeparator) {
String[] voices = st.split(splitSeparator);
ArrayList<String> result = new ArrayList<String>();
ArrayList<String> result = new ArrayList<>();
for (String voice : voices) {
if (!voice.trim().isEmpty()) {
result.add(voice);
@ -145,7 +145,7 @@ public class AlluxioInterpreter extends Interpreter {
}
private String[] splitAndRemoveEmpty(String[] sts, String splitSeparator) {
ArrayList<String> result = new ArrayList<String>();
ArrayList<String> result = new ArrayList<>();
for (String st : sts) {
result.addAll(Arrays.asList(splitAndRemoveEmpty(st, splitSeparator)));
}

View file

@ -93,7 +93,7 @@ public class AlluxioInterpreterTest {
List expectedResultThree = Arrays.asList(
new InterpreterCompletion("copyFromLocal", "copyFromLocal"),
new InterpreterCompletion("copyToLocal", "copyToLocal"));
List expectedResultNone = new ArrayList<String>();
List expectedResultNone = new ArrayList<>();
List<InterpreterCompletion> resultOne = alluxioInterpreter.completion("c", 0);
List<InterpreterCompletion> resultTwo = alluxioInterpreter.completion("co", 0);

View file

@ -31,7 +31,11 @@ When you connect to Apache Zeppelin, you will be asked to enter your credentials
## Security Setup
You can setup **Zeppelin notebook authentication** in some simple steps.
### 1. Secure the HTTP channel
### 1. Enable Shiro
By default in `conf`, you will find `shiro.ini.template`, this file is used as an example and it is strongly recommended
to create a `shiro.ini` file by doing the following command line `cp conf/shiro.ini.template conf/shiro.ini`.
### 2. Secure the HTTP channel
To secure the HTTP channel, you have to change both **anon** and **authc** settings in `conf/shiro.ini`. In here, **anon** means "the access is anonymous" and **authc** means "formed auth security".
The default status of them is
@ -49,10 +53,10 @@ Deactivate the line "/** = anon" and activate the line "/** = authc" in `conf/sh
For the further information about `shiro.ini` file format, please refer to [Shiro Configuration](http://shiro.apache.org/configuration.html#Configuration-INISections).
### 2. Secure the Websocket channel
### 3. Secure the Websocket channel
Set to property **zeppelin.anonymous.allowed** to **false** in `conf/zeppelin-site.xml`. If you don't have this file yet, just copy `conf/zeppelin-site.xml.template` to `conf/zeppelin-site.xml`.
### 3. Start Zeppelin
### 4. Start Zeppelin
```
bin/zeppelin-daemon.sh start (or restart)
@ -60,7 +64,7 @@ bin/zeppelin-daemon.sh start (or restart)
Then you can browse Zeppelin at [http://localhost:8080](http://localhost:8080).
### 4. Login
### 5. Login
Finally, you can login using one of the below **username/password** combinations.
<center><img src="../assets/themes/zeppelin/img/docs-img/zeppelin-login.png"></center>
@ -94,7 +98,7 @@ ldapRealm.contextFactory.url = ldap://ldap.test.com:389
ldapRealm.userDnTemplate = uid={0},ou=Users,dc=COMPANY,dc=COM
ldapRealm.contextFactory.authenticationMechanism = SIMPLE
```
also define roles/groups that you want to have in system, like below;
```
@ -159,8 +163,8 @@ securityManager.realms = $zeppelinHubRealm
> Note: ZeppelinHub is not releated to apache Zeppelin project.
## Secure your Zeppelin information (optional)
By default, anyone who defined in `[users]` can share **Interpreter Setting**, **Credential** and **Configuration** information in Apache Zeppelin.
Sometimes you might want to hide these information for your use case.
By default, anyone who defined in `[users]` can share **Interpreter Setting**, **Credential** and **Configuration** information in Apache Zeppelin.
Sometimes you might want to hide these information for your use case.
Since Shiro provides **url-based security**, you can hide the information by commenting or uncommenting these below lines in `conf/shiro.ini`.
```
@ -171,9 +175,8 @@ Since Shiro provides **url-based security**, you can hide the information by com
/api/credential/** = authc, roles[admin]
```
In this case, only who have `admin` role can see **Interpreter Setting**, **Credential** and **Configuration** information.
In this case, only who have `admin` role can see **Interpreter Setting**, **Credential** and **Configuration** information.
If you want to grant this permission to other users, you can change **roles[ ]** as you defined at `[users]` section.
<br/>
> **NOTE :** All of the above configurations are defined in the `conf/shiro.ini` file. This documentation is originally from [SECURITY-README.md](https://github.com/apache/zeppelin/blob/master/SECURITY-README.md).

View file

@ -123,7 +123,7 @@ public class HDFSFileInterpreterTest extends TestCase {
* Store command results from curl against a real file system
*/
class MockFileSystem {
HashMap<String, String> mfs = new HashMap<String, String>();
HashMap<String, String> mfs = new HashMap<>();
void addListStatusData() {
mfs.put("/?op=LISTSTATUS",
"{\"FileStatuses\":{\"FileStatus\":[\n" +

View file

@ -175,7 +175,7 @@ public class FlinkInterpreter extends Interpreter {
pathSettings.v_$eq(classpath);
settings.scala$tools$nsc$settings$ScalaSettings$_setter_$classpath_$eq(pathSettings);
settings.explicitParentLoader_$eq(new Some<ClassLoader>(Thread.currentThread()
settings.explicitParentLoader_$eq(new Some<>(Thread.currentThread()
.getContextClassLoader()));
BooleanSetting b = (BooleanSetting) settings.usejavacp();
b.v_$eq(true);
@ -197,7 +197,7 @@ public class FlinkInterpreter extends Interpreter {
}
private List<File> classPath(ClassLoader cl) {
List<File> paths = new LinkedList<File>();
List<File> paths = new LinkedList<>();
if (cl == null) {
return paths;
}
@ -217,7 +217,7 @@ public class FlinkInterpreter extends Interpreter {
public Object getLastObject() {
Object obj = imain.lastRequest().lineRep().call(
"$result",
JavaConversions.asScalaBuffer(new LinkedList<Object>()));
JavaConversions.asScalaBuffer(new LinkedList<>()));
return obj;
}

View file

@ -178,7 +178,7 @@ public class IgniteInterpreter extends Interpreter {
public Object getLastObject() {
Object obj = imain.lastRequest().lineRep().call(
"$result",
JavaConversions.asScalaBuffer(new LinkedList<Object>()));
JavaConversions.asScalaBuffer(new LinkedList<>()));
return obj;
}

View file

@ -76,9 +76,9 @@ public class LensInterpreter extends Interpreter {
private static Pattern s_queryExecutePattern = Pattern.compile(".*query\\s+execute\\s+(.*)");
private static Map<String, ExecutionDetail> s_paraToQH =
new ConcurrentHashMap<String, ExecutionDetail> (); //tracks paragraphId -> Lens QueryHandle
new ConcurrentHashMap<> (); //tracks paragraphId -> Lens QueryHandle
private static Map<LensClient, Boolean> s_clientMap =
new ConcurrentHashMap<LensClient, Boolean>();
new ConcurrentHashMap<>();
private int m_maxResults;
private int m_maxThreads;

View file

@ -41,6 +41,8 @@
<assertj.version>1.7.0</assertj.version>
<mockito.version>1.9.5</mockito.version>
<livy.version>0.2.0</livy.version>
<spark.version>1.5.2</spark.version>
<hadoop.version>2.6.0</hadoop.version>
</properties>
<dependencies>
@ -111,38 +113,218 @@
<groupId>com.cloudera.livy</groupId>
<artifactId>livy-integration-test</artifactId>
<version>${livy.version}</version>
<scope>compile</scope>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.xerial.snappy</groupId>
<artifactId>snappy-java</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.10</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_2.10</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.spark</groupId>
<artifactId>spark-streaming_2.10</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.spark</groupId>
<artifactId>spark-hive_2.10</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.spark</groupId>
<artifactId>spark-repl_2.10</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.spark</groupId>
<artifactId>spark-yarn_2.10</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-auth</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-yarn-client</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-yarn-server-tests</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.cloudera.livy</groupId>
<artifactId>livy-test-lib</artifactId>
<version>${livy.version}</version>
<scope>compile</scope>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.xerial.snappy</groupId>
<artifactId>snappy-java</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.10</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_2.10</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.spark</groupId>
<artifactId>spark-streaming_2.10</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.spark</groupId>
<artifactId>spark-hive_2.10</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.spark</groupId>
<artifactId>spark-repl_2.10</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.spark</groupId>
<artifactId>spark-yarn_2.10</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.cloudera.livy</groupId>
<artifactId>livy-core</artifactId>
<version>${livy.version}</version>
<scope>compile</scope>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.xerial.snappy</groupId>
<artifactId>snappy-java</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.10</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_2.10</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.spark</groupId>
<artifactId>spark-streaming_2.10</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.spark</groupId>
<artifactId>spark-hive_2.10</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.spark</groupId>
<artifactId>spark-repl_2.10</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.spark</groupId>
<artifactId>spark-yarn_2.10</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_${scala.binary.version}</artifactId>
<version>${spark.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-streaming_${scala.binary.version}</artifactId>
<version>${spark.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-hive_${scala.binary.version}</artifactId>
<version>${spark.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-repl_${scala.binary.version}</artifactId>
<version>${spark.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-yarn_${scala.binary.version}</artifactId>
<version>${spark.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-yarn_${scala.binary.version}</artifactId>
<version>${spark.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-auth</artifactId>
<version>2.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>${hadoop.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>${hadoop.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>${hadoop.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-yarn-client</artifactId>
<version>${hadoop.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-yarn-server-tests</artifactId>
<version>${hadoop.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
@ -250,9 +432,10 @@
</goals>
<configuration>
<target>
<delete file="${project.build.directory}/unit-tests.log" quiet="true" />
<delete file="${project.build.directory}/jacoco.exec" quiet="true" />
<delete dir="${project.build.directory}/tmp" quiet="true" />
<delete file="${project.build.directory}/unit-tests.log"
quiet="true"/>
<delete file="${project.build.directory}/jacoco.exec" quiet="true"/>
<delete dir="${project.build.directory}/tmp" quiet="true"/>
</target>
</configuration>
</execution>
@ -265,7 +448,7 @@
</goals>
<configuration>
<target>
<mkdir dir="${project.build.directory}/tmp" />
<mkdir dir="${project.build.directory}/tmp"/>
</target>
</configuration>
</execution>

View file

@ -57,7 +57,7 @@ public class LivyHelper {
public Integer createSession(InterpreterContext context, String kind) throws Exception {
try {
Map<String, String> conf = new HashMap<String, String>();
Map<String, String> conf = new HashMap<>();
Iterator<Entry<Object, Object>> it = property.entrySet().iterator();
while (it.hasNext()) {
@ -352,16 +352,16 @@ public class LivyHelper {
ResponseEntity<String> response = null;
try {
if (method.equals("POST")) {
HttpEntity<String> entity = new HttpEntity<String>(jsonData, headers);
HttpEntity<String> entity = new HttpEntity<>(jsonData, headers);
response = restTemplate.exchange(targetURL, HttpMethod.POST, entity, String.class);
paragraphHttpMap.put(paragraphId, response);
} else if (method.equals("GET")) {
HttpEntity<String> entity = new HttpEntity<String>(headers);
HttpEntity<String> entity = new HttpEntity<>(headers);
response = restTemplate.exchange(targetURL, HttpMethod.GET, entity, String.class);
paragraphHttpMap.put(paragraphId, response);
} else if (method.equals("DELETE")) {
HttpEntity<String> entity = new HttpEntity<String>(headers);
HttpEntity<String> entity = new HttpEntity<>(headers);
response = restTemplate.exchange(targetURL, HttpMethod.DELETE, entity, String.class);
}
} catch (HttpClientErrorException e) {

View file

@ -68,7 +68,7 @@ public class PigQueryInterpreter extends BasePigInterpreter {
// '-' is invalid for pig alias
String alias = "paragraph_" + context.getParagraphId().replace("-", "_");
String[] lines = st.split("\n");
List<String> queries = new ArrayList<String>();
List<String> queries = new ArrayList<>();
for (int i = 0; i < lines.length; ++i) {
if (i == lines.length - 1) {
lines[i] = alias + " = " + lines[i];

View file

@ -324,7 +324,7 @@ public class PostgreSqlInterpreter extends Interpreter {
@Override
public List<InterpreterCompletion> completion(String buf, int cursor) {
List<CharSequence> candidates = new ArrayList<CharSequence>();
List<CharSequence> candidates = new ArrayList<>();
if (sqlCompleter != null && sqlCompleter.complete(buf, cursor, candidates) >= 0) {
List completion = Lists.transform(candidates, sequenceToStringTransformer);
return completion;

View file

@ -65,7 +65,7 @@ public class SqlCompleter extends StringsCompleter {
}
};
private Set<String> modelCompletions = new HashSet<String>();
private Set<String> modelCompletions = new HashSet<>();
public SqlCompleter(Set<String> allCompletions, Set<String> dataModelCompletions) {
super(allCompletions);
@ -150,7 +150,7 @@ public class SqlCompleter extends StringsCompleter {
keywords += "," + driverKeywords.toUpperCase();
}
Set<String> completions = new TreeSet<String>();
Set<String> completions = new TreeSet<>();
// Add the keywords from the current JDBC connection
@ -193,7 +193,7 @@ public class SqlCompleter extends StringsCompleter {
public static Set<String> getDataModelMetadataCompletions(Connection connection)
throws SQLException {
Set<String> completions = new TreeSet<String>();
Set<String> completions = new TreeSet<>();
getColumnNames(connection.getMetaData(), completions);
getSchemaNames(connection.getMetaData(), completions);
return completions;

View file

@ -39,7 +39,7 @@ public class SqlCompleterTest extends BasicJDBCTestCaseAdapter {
private Logger logger = LoggerFactory.getLogger(SqlCompleterTest.class);
private final static Set<String> EMPTY = new HashSet<String>();
private final static Set<String> EMPTY = new HashSet<>();
private CompleterTester tester;
@ -157,7 +157,7 @@ public class SqlCompleterTest extends BasicJDBCTestCaseAdapter {
private void expectedCompletions(String buffer, int cursor, Set<String> expected) {
ArrayList<CharSequence> candidates = new ArrayList<CharSequence>();
ArrayList<CharSequence> candidates = new ArrayList<>();
completer.complete(buffer, cursor, candidates);

View file

@ -60,7 +60,7 @@ public class ShellInterpreter extends Interpreter {
@Override
public void open() {
LOGGER.info("Command timeout property: {}", getProperty(TIMEOUT_PROPERTY));
executors = new ConcurrentHashMap<String, DefaultExecutor>();
executors = new ConcurrentHashMap<>();
if (!StringUtils.isAnyEmpty(getProperty("zeppelin.shell.auth.type"))) {
ShellSecurityImpl.createSecureConfiguration(getProperty(), shell);
}

View file

@ -153,7 +153,7 @@ public class DepInterpreter extends Interpreter {
settings.scala$tools$nsc$settings$ScalaSettings$_setter_$classpath_$eq(pathSettings);
// set classloader for scala compiler
settings.explicitParentLoader_$eq(new Some<ClassLoader>(Thread.currentThread()
settings.explicitParentLoader_$eq(new Some<>(Thread.currentThread()
.getContextClassLoader()));
BooleanSetting b = (BooleanSetting) settings.usejavacp();
@ -219,7 +219,7 @@ public class DepInterpreter extends Interpreter {
public Object getLastObject() {
IMain.Request r = (IMain.Request) Utils.invokeMethod(intp, "lastRequest");
Object obj = r.lineRep().call("$result",
JavaConversions.asScalaBuffer(new LinkedList<Object>()));
JavaConversions.asScalaBuffer(new LinkedList<>()));
return obj;
}
@ -290,7 +290,7 @@ public class DepInterpreter extends Interpreter {
Candidates ret = c.complete(buf, cursor);
List<String> candidates = WrapAsJava$.MODULE$.seqAsJavaList(ret.candidates());
List<InterpreterCompletion> completions = new LinkedList<InterpreterCompletion>();
List<InterpreterCompletion> completions = new LinkedList<>();
for (String candidate : candidates) {
completions.add(new InterpreterCompletion(candidate, candidate));
@ -298,7 +298,7 @@ public class DepInterpreter extends Interpreter {
return completions;
} else {
return new LinkedList<InterpreterCompletion>();
return new LinkedList<>();
}
}
@ -314,7 +314,7 @@ public class DepInterpreter extends Interpreter {
}
private List<File> classPath(ClassLoader cl) {
List<File> paths = new LinkedList<File>();
List<File> paths = new LinkedList<>();
if (cl == null) {
return paths;
}

View file

@ -115,7 +115,7 @@ public class PySparkInterpreter extends Interpreter implements ExecuteResultHand
// load libraries from Dependency Interpreter
URL [] urls = new URL[0];
List<URL> urlList = new LinkedList<URL>();
List<URL> urlList = new LinkedList<>();
if (depInterpreter != null) {
SparkDependencyContext depc = depInterpreter.getDependencyContext();

View file

@ -596,7 +596,7 @@ public class SparkInterpreter extends Interpreter {
}
String[] argsArray = args.split(" ");
LinkedList<String> argList = new LinkedList<String>();
LinkedList<String> argList = new LinkedList<>();
for (String arg : argsArray) {
argList.add(arg);
}
@ -719,7 +719,7 @@ public class SparkInterpreter extends Interpreter {
// set classloader for scala compiler
settings.explicitParentLoader_$eq(new Some<ClassLoader>(Thread.currentThread()
settings.explicitParentLoader_$eq(new Some<>(Thread.currentThread()
.getContextClassLoader()));
BooleanSetting b = (BooleanSetting) settings.usejavacp();
b.v_$eq(true);
@ -957,7 +957,7 @@ public class SparkInterpreter extends Interpreter {
}
private List<File> classPath(ClassLoader cl) {
List<File> paths = new LinkedList<File>();
List<File> paths = new LinkedList<>();
if (cl == null) {
return paths;
}
@ -978,7 +978,7 @@ public class SparkInterpreter extends Interpreter {
public List<InterpreterCompletion> completion(String buf, int cursor) {
if (completer == null) {
logger.warn("Can't find completer");
return new LinkedList<InterpreterCompletion>();
return new LinkedList<>();
}
if (buf.length() < cursor) {
@ -994,7 +994,7 @@ public class SparkInterpreter extends Interpreter {
Candidates ret = c.complete(completionText, cursor);
List<String> candidates = WrapAsJava$.MODULE$.seqAsJavaList(ret.candidates());
List<InterpreterCompletion> completions = new LinkedList<InterpreterCompletion>();
List<InterpreterCompletion> completions = new LinkedList<>();
for (String candidate : candidates) {
completions.add(new InterpreterCompletion(candidate, candidate));
@ -1067,7 +1067,7 @@ public class SparkInterpreter extends Interpreter {
return null;
}
Object obj = r.lineRep().call("$result",
JavaConversions.asScalaBuffer(new LinkedList<Object>()));
JavaConversions.asScalaBuffer(new LinkedList<>()));
return obj;
}

View file

@ -61,7 +61,7 @@ public class ZeppelinContext {
// given replName in parapgraph
private static final Map<String, String> interpreterClassMap;
static {
interpreterClassMap = new HashMap<String, String>();
interpreterClassMap = new HashMap<>();
interpreterClassMap.put("spark", "org.apache.zeppelin.spark.SparkInterpreter");
interpreterClassMap.put("sql", "org.apache.zeppelin.spark.SparkSqlInterpreter");
interpreterClassMap.put("dep", "org.apache.zeppelin.spark.DepInterpreter");
@ -134,7 +134,7 @@ public class ZeppelinContext {
@ZeppelinApi
public scala.collection.Iterable<Object> checkbox(String name,
scala.collection.Iterable<Tuple2<Object, String>> options) {
List<Object> allChecked = new LinkedList<Object>();
List<Object> allChecked = new LinkedList<>();
for (Tuple2<Object, String> option : asJavaIterable(options)) {
allChecked.add(option._1());
}
@ -400,7 +400,7 @@ public class ZeppelinContext {
@ZeppelinApi
public List<String> listParagraphs() {
List<String> paragraphs = new LinkedList<String>();
List<String> paragraphs = new LinkedList<>();
for (InterpreterContextRunner r : interpreterContext.getRunners()) {
paragraphs.add(r.getParagraphId());

View file

@ -49,16 +49,16 @@ import scala.Console;
*
*/
public class SparkDependencyContext {
List<Dependency> dependencies = new LinkedList<Dependency>();
List<Repository> repositories = new LinkedList<Repository>();
List<Dependency> dependencies = new LinkedList<>();
List<Repository> repositories = new LinkedList<>();
List<File> files = new LinkedList<File>();
List<File> filesDist = new LinkedList<File>();
List<File> files = new LinkedList<>();
List<File> filesDist = new LinkedList<>();
private RepositorySystem system = Booter.newRepositorySystem();
private RepositorySystemSession session;
private RemoteRepository mavenCentral = Booter.newCentralRepository();
private RemoteRepository mavenLocal = Booter.newLocalRepository();
private List<RemoteRepository> additionalRepos = new LinkedList<RemoteRepository>();
private List<RemoteRepository> additionalRepos = new LinkedList<>();
public SparkDependencyContext(String localRepoPath, String additionalRemoteRepository) {
session = Booter.newRepositorySystemSession(system, localRepoPath);
@ -88,11 +88,11 @@ public class SparkDependencyContext {
public void reset() {
Console.println("DepInterpreter(%dep) deprecated. "
+ "Remove dependencies and repositories through GUI interpreter menu instead.");
dependencies = new LinkedList<Dependency>();
repositories = new LinkedList<Repository>();
dependencies = new LinkedList<>();
repositories = new LinkedList<>();
files = new LinkedList<File>();
filesDist = new LinkedList<File>();
files = new LinkedList<>();
filesDist = new LinkedList<>();
}
private void addRepoFromProperty(String listOfRepo) {

View file

@ -114,7 +114,7 @@ public class SparkDependencyResolver extends AbstractDependencyResolver {
}
// NOTE: Must use reflection until this is exposed/fixed upstream in Scala
List<String> classPaths = new LinkedList<String>();
List<String> classPaths = new LinkedList<>();
for (URL url : urls) {
classPaths.add(url.getPath());
}
@ -151,7 +151,7 @@ public class SparkDependencyResolver extends AbstractDependencyResolver {
private MergedClassPath<AbstractFile> mergeUrlsIntoClassPath(JavaPlatform platform, URL[] urls) {
IndexedSeq<ClassPath<AbstractFile>> entries =
((MergedClassPath<AbstractFile>) platform.classPath()).entries();
List<ClassPath<AbstractFile>> cp = new LinkedList<ClassPath<AbstractFile>>();
List<ClassPath<AbstractFile>> cp = new LinkedList<>();
for (int i = 0; i < entries.size(); i++) {
cp.add(entries.apply(i));
@ -200,7 +200,7 @@ public class SparkDependencyResolver extends AbstractDependencyResolver {
return loadFromMvn(artifact, excludes, addSparkContext);
} else {
loadFromFs(artifact, addSparkContext);
LinkedList<String> libs = new LinkedList<String>();
LinkedList<String> libs = new LinkedList<>();
libs.add(artifact);
return libs;
}
@ -224,8 +224,8 @@ public class SparkDependencyResolver extends AbstractDependencyResolver {
private List<String> loadFromMvn(String artifact, Collection<String> excludes,
boolean addSparkContext) throws Exception {
List<String> loadedLibs = new LinkedList<String>();
Collection<String> allExclusions = new LinkedList<String>();
List<String> loadedLibs = new LinkedList<>();
Collection<String> allExclusions = new LinkedList<>();
allExclusions.addAll(excludes);
allExclusions.addAll(Arrays.asList(exclusions));
@ -244,8 +244,8 @@ public class SparkDependencyResolver extends AbstractDependencyResolver {
}
}
List<URL> newClassPathList = new LinkedList<URL>();
List<File> files = new LinkedList<File>();
List<URL> newClassPathList = new LinkedList<>();
List<File> files = new LinkedList<>();
for (ArtifactResult artifactResult : listOfArtifact) {
logger.info("Load " + artifactResult.getArtifact().getGroupId() + ":"
+ artifactResult.getArtifact().getArtifactId() + ":"
@ -302,7 +302,7 @@ public class SparkDependencyResolver extends AbstractDependencyResolver {
}
public static Collection<String> inferScalaVersion(Collection<String> artifact) {
List<String> list = new LinkedList<String>();
List<String> list = new LinkedList<>();
for (String a : artifact) {
list.add(inferScalaVersion(a));
}

View file

@ -23,18 +23,12 @@ Apache Zeppelin is distributed as a single gzip archive with the following struc
Zeppelin
├── bin
│ ├── zeppelin.sh
│ └── seppelin-deamon.sh
│ └── zeppelin-daemon.sh
├── conf
├── interpreter
├── lib
├── licenses
├── zan-repo
│ ├── txt.wordcount
│ ├── vis.bubble
│ ├── vis.gchart
│ ├── ml.something
│ └── ...
├── zeppelin-server-<verion>.jar
├── notebook
└── zeppelin-web-<verion>.war
```
@ -42,4 +36,4 @@ Zeppelin
We use `maven-assembly-plugin` to build it, see `zeppelin-distribution/src/assemble/distribution.xml ` for details.
>**IMPORTANT:** `_/lib_` subdirectory contains all transitive dependencies of the `zeppelin-distribution` module,
automatically resolved by maven, except for explicitly excluded `_server_` and `_web_` Zeppelin sub-modules.
automatically resolved by maven, except for explicitly excluded `_web_` Zeppelin sub-modules.

View file

@ -33,7 +33,6 @@
<useAllReactorProjects>true</useAllReactorProjects> -->
<!-- Now, select which projects to include in this module-set. -->
<includes>
<include>org.apache.zeppelin:zeppelin-server</include>
<include>org.apache.zeppelin:zeppelin-web</include>
</includes>
<useProjectArtifact>false</useProjectArtifact>
@ -44,7 +43,6 @@
<useProjectArtifact>false</useProjectArtifact>
<excludes>
<exclude>${project.groupId}:zeppelin-web</exclude>
<exclude>${project.groupId}:zeppelin-server</exclude>
</excludes>
</dependencySet>
</dependencySets>

View file

@ -37,7 +37,7 @@ import org.sonatype.aether.resolution.ArtifactResult;
*/
public abstract class AbstractDependencyResolver {
protected RepositorySystem system = Booter.newRepositorySystem();
protected List<RemoteRepository> repos = new LinkedList<RemoteRepository>();
protected List<RemoteRepository> repos = new LinkedList<>();
protected RepositorySystemSession session;
public AbstractDependencyResolver(String localRepoPath) {

View file

@ -31,7 +31,7 @@ public class Dependency {
public Dependency(String groupArtifactVersion) {
this.groupArtifactVersion = groupArtifactVersion;
exclusions = new LinkedList<String>();
exclusions = new LinkedList<>();
}
@Override

View file

@ -42,11 +42,11 @@ import org.sonatype.aether.util.filter.PatternExclusionsDependencyFilter;
*
*/
public class DependencyContext {
List<Dependency> dependencies = new LinkedList<Dependency>();
List<Repository> repositories = new LinkedList<Repository>();
List<Dependency> dependencies = new LinkedList<>();
List<Repository> repositories = new LinkedList<>();
List<File> files = new LinkedList<File>();
List<File> filesDist = new LinkedList<File>();
List<File> files = new LinkedList<>();
List<File> filesDist = new LinkedList<>();
private RepositorySystem system = Booter.newRepositorySystem();
private RepositorySystemSession session;
private RemoteRepository mavenCentral = Booter.newCentralRepository();
@ -73,11 +73,11 @@ public class DependencyContext {
}
public void reset() {
dependencies = new LinkedList<Dependency>();
repositories = new LinkedList<Repository>();
dependencies = new LinkedList<>();
repositories = new LinkedList<>();
files = new LinkedList<File>();
filesDist = new LinkedList<File>();
files = new LinkedList<>();
filesDist = new LinkedList<>();
}

View file

@ -70,7 +70,7 @@ public class DependencyResolver extends AbstractDependencyResolver {
throws RepositoryException, IOException {
if (StringUtils.isBlank(artifact)) {
// Skip dependency loading if artifact is empty
return new LinkedList<File>();
return new LinkedList<>();
}
// <groupId>:<artifactId>[:<extension>[:<classifier>]]:<version>
@ -78,7 +78,7 @@ public class DependencyResolver extends AbstractDependencyResolver {
if (numSplits >= 3 && numSplits <= 6) {
return loadFromMvn(artifact, excludes);
} else {
LinkedList<File> libs = new LinkedList<File>();
LinkedList<File> libs = new LinkedList<>();
libs.add(new File(artifact));
return libs;
}
@ -90,7 +90,7 @@ public class DependencyResolver extends AbstractDependencyResolver {
public List<File> load(String artifact, Collection<String> excludes, File destPath)
throws RepositoryException, IOException {
List<File> libs = new LinkedList<File>();
List<File> libs = new LinkedList<>();
if (StringUtils.isNotBlank(artifact)) {
libs = load(artifact, excludes);
@ -123,7 +123,7 @@ public class DependencyResolver extends AbstractDependencyResolver {
private List<File> loadFromMvn(String artifact, Collection<String> excludes)
throws RepositoryException {
Collection<String> allExclusions = new LinkedList<String>();
Collection<String> allExclusions = new LinkedList<>();
allExclusions.addAll(excludes);
allExclusions.addAll(Arrays.asList(exclusions));
@ -142,7 +142,7 @@ public class DependencyResolver extends AbstractDependencyResolver {
}
}
List<File> files = new LinkedList<File>();
List<File> files = new LinkedList<>();
for (ArtifactResult artifactResult : listOfArtifact) {
files.add(artifactResult.getArtifact().getFile());
logger.info("load {}", artifactResult.getArtifact().getFile().getAbsolutePath());

View file

@ -37,7 +37,7 @@ public class TransferListener extends AbstractTransferListener {
Logger logger = LoggerFactory.getLogger(TransferListener.class);
private PrintStream out;
private Map<TransferResource, Long> downloads = new ConcurrentHashMap<TransferResource, Long>();
private Map<TransferResource, Long> downloads = new ConcurrentHashMap<>();
private int lastLength;

View file

@ -38,8 +38,7 @@ public class AngularObject<T> {
private T object;
private transient AngularObjectListener listener;
private transient List<AngularObjectWatcher> watchers
= new LinkedList<AngularObjectWatcher>();
private transient List<AngularObjectWatcher> watchers = new LinkedList<>();
private String noteId; // noteId belonging to. null for global scope
private String paragraphId; // paragraphId belongs to. null for notebook scope
@ -175,7 +174,7 @@ public class AngularObject<T> {
}
final Logger logger = LoggerFactory.getLogger(AngularObject.class);
List<AngularObjectWatcher> ws = new LinkedList<AngularObjectWatcher>();
List<AngularObjectWatcher> ws = new LinkedList<>();
synchronized (watchers) {
ws.addAll(watchers);
}

View file

@ -32,8 +32,7 @@ import java.util.Map;
* - Global scope : Shared to all notebook that uses the same interpreter group
*/
public class AngularObjectRegistry {
Map<String, Map<String, AngularObject>> registry =
new HashMap<String, Map<String, AngularObject>>();
Map<String, Map<String, AngularObject>> registry = new HashMap<>();
private final String GLOBAL_KEY = "_GLOBAL_";
private AngularObjectRegistryListener listener;
private String interpreterId;
@ -209,7 +208,7 @@ public class AngularObjectRegistry {
* @return all angularobject in the scope
*/
public List<AngularObject> getAll(String noteId, String paragraphId) {
List<AngularObject> all = new LinkedList<AngularObject>();
List<AngularObject> all = new LinkedList<>();
synchronized (registry) {
Map<String, AngularObject> r = getRegistryForKey(noteId, paragraphId);
if (r != null) {
@ -228,7 +227,7 @@ public class AngularObjectRegistry {
* @return
*/
public List<AngularObject> getAllWithGlobal(String noteId) {
List<AngularObject> all = new LinkedList<AngularObject>();
List<AngularObject> all = new LinkedList<>();
synchronized (registry) {
Map<String, AngularObject> global = getRegistryForKey(null, null);
if (global != null) {

View file

@ -32,8 +32,8 @@ import org.apache.zeppelin.display.Input.ParamOption;
*/
public class GUI implements Serializable {
Map<String, Object> params = new HashMap<String, Object>(); // form parameters from client
Map<String, Input> forms = new TreeMap<String, Input>(); // form configuration
Map<String, Object> params = new HashMap<>(); // form parameters from client
Map<String, Input> forms = new TreeMap<>(); // form configuration
public GUI() {
@ -86,7 +86,7 @@ public class GUI implements Serializable {
checked = defaultChecked;
}
forms.put(id, new Input(id, defaultChecked, "checkbox", options));
Collection<Object> filtered = new LinkedList<Object>();
Collection<Object> filtered = new LinkedList<>();
for (Object o : checked) {
if (isValidOption(o, options)) {
filtered.add(o);
@ -105,6 +105,6 @@ public class GUI implements Serializable {
}
public void clear() {
this.forms = new TreeMap<String, Input>();
this.forms = new TreeMap<>();
}
}

View file

@ -292,7 +292,7 @@ public class Input implements Serializable {
}
public static Map<String, Input> extractSimpleQueryParam(String script) {
Map<String, Input> params = new HashMap<String, Input>();
Map<String, Input> params = new HashMap<>();
if (script == null) {
return params;
}
@ -331,7 +331,7 @@ public class Input implements Serializable {
}
Collection<Object> checked = value instanceof Collection ? (Collection<Object>) value
: Arrays.asList((Object[]) value);
List<Object> validChecked = new LinkedList<Object>();
List<Object> validChecked = new LinkedList<>();
for (Object o : checked) { // filter out obsolete checked values
for (ParamOption option : input.getOptions()) {
if (option.getValue().equals(o)) {
@ -387,14 +387,14 @@ public class Input implements Serializable {
public static String[] split(String str, String escapeSeq, char escapeChar, String[] blockStart,
String[] blockEnd, String[] splitters, boolean includeSplitter) {
List<String> splits = new ArrayList<String>();
List<String> splits = new ArrayList<>();
String curString = "";
boolean escape = false; // true when escape char is found
int lastEscapeOffset = -1;
int blockStartPos = -1;
List<Integer> blockStack = new LinkedList<Integer>();
List<Integer> blockStack = new LinkedList<>();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);

View file

@ -200,7 +200,7 @@ public class ApplicationLoader {
}
// Create Application classloader
List<URL> urlList = new LinkedList<URL>();
List<URL> urlList = new LinkedList<>();
// load artifact
if (packageInfo.getArtifact() != null) {

View file

@ -30,8 +30,7 @@ import org.apache.zeppelin.resource.ResourcePool;
* Interpreter context
*/
public class InterpreterContext {
private static final ThreadLocal<InterpreterContext> threadIC =
new ThreadLocal<InterpreterContext>();
private static final ThreadLocal<InterpreterContext> threadIC = new ThreadLocal<>();
public final InterpreterOutput out;

View file

@ -55,7 +55,7 @@ public class InterpreterGroup extends ConcurrentHashMap<String, List<Interpreter
// List<Interpreter>>();
private static final Map<String, InterpreterGroup> allInterpreterGroups =
new ConcurrentHashMap<String, InterpreterGroup>();
new ConcurrentHashMap<>();
public static InterpreterGroup getByInterpreterGroupId(String id) {
return allInterpreterGroups.get(id);
@ -147,7 +147,7 @@ public class InterpreterGroup extends ConcurrentHashMap<String, List<Interpreter
*/
public void close() {
LOGGER.info("Close interpreter group " + getId());
List<Interpreter> intpToClose = new LinkedList<Interpreter>();
List<Interpreter> intpToClose = new LinkedList<>();
for (List<Interpreter> intpGroupForNote : this.values()) {
intpToClose.addAll(intpGroupForNote);
}
@ -168,7 +168,7 @@ public class InterpreterGroup extends ConcurrentHashMap<String, List<Interpreter
if (intpToClose == null) {
return;
}
List<Thread> closeThreads = new LinkedList<Thread>();
List<Thread> closeThreads = new LinkedList<>();
for (final Interpreter intp : intpToClose) {
Thread t = new Thread() {
@ -219,7 +219,7 @@ public class InterpreterGroup extends ConcurrentHashMap<String, List<Interpreter
*/
public void destroy() {
LOGGER.info("Destroy interpreter group " + getId());
List<Interpreter> intpToDestroy = new LinkedList<Interpreter>();
List<Interpreter> intpToDestroy = new LinkedList<>();
for (List<Interpreter> intpGroupForNote : this.values()) {
intpToDestroy.addAll(intpGroupForNote);
}
@ -241,7 +241,7 @@ public class InterpreterGroup extends ConcurrentHashMap<String, List<Interpreter
return;
}
List<Thread> destroyThreads = new LinkedList<Thread>();
List<Thread> destroyThreads = new LinkedList<>();
for (final Interpreter intp : intpToDestroy) {
Thread t = new Thread() {

View file

@ -29,8 +29,7 @@ import java.util.Map;
public class InterpreterHookRegistry {
public static final String GLOBAL_KEY = "_GLOBAL_";
private String interpreterId;
private Map<String, Map<String, Map<String, String>>> registry =
new HashMap<String, Map<String, Map<String, String>>>();
private Map<String, Map<String, Map<String, String>>> registry = new HashMap<>();
/**
* hookRegistry constructor.

View file

@ -39,7 +39,7 @@ public class InterpreterOutput extends OutputStream {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
private final List<Object> outList = new LinkedList<Object>();
private final List<Object> outList = new LinkedList<>();
private InterpreterOutputChangeWatcher watcher;
private final InterpreterOutputListener flushListener;
private InterpreterResult.Type type = InterpreterResult.Type.TEXT;
@ -185,7 +185,7 @@ public class InterpreterOutput extends OutputStream {
public byte[] toByteArray() throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
List<Object> all = new LinkedList<Object>();
List<Object> all = new LinkedList<>();
synchronized (outList) {
all.addAll(outList);

View file

@ -44,8 +44,8 @@ public class InterpreterOutputChangeWatcher extends Thread {
Logger logger = LoggerFactory.getLogger(InterpreterOutputChangeWatcher.class);
private WatchService watcher;
private final List<File> watchFiles = new LinkedList<File>();
private final Map<WatchKey, File> watchKeys = new HashMap<WatchKey, File>();
private final List<File> watchFiles = new LinkedList<>();
private final Map<WatchKey, File> watchKeys = new HashMap<>();
private InterpreterOutputChangeListener listener;
private boolean stop;

View file

@ -24,7 +24,7 @@ import java.util.Map;
* InterpreterPropertyBuilder
*/
public class InterpreterPropertyBuilder {
Map<String, InterpreterProperty> properties = new HashMap<String, InterpreterProperty>();
Map<String, InterpreterProperty> properties = new HashMap<>();
public InterpreterPropertyBuilder add(String name, String defaultValue, String description){
properties.put(name, new InterpreterProperty(defaultValue, description));

View file

@ -119,7 +119,7 @@ public class InterpreterResult implements Serializable {
private TreeMap<Integer, Type> buildIndexMap(String msg) {
int lastIndexOftypes = 0;
TreeMap<Integer, Type> typesLastIndexInMsg = new TreeMap<Integer, Type>();
TreeMap<Integer, Type> typesLastIndexInMsg = new TreeMap<>();
Type[] types = Type.values();
for (Type t : types) {
lastIndexOftypes = getIndexOfType(msg, t);

View file

@ -105,7 +105,7 @@ public class DevInterpreter extends Interpreter {
@Override
public List<InterpreterCompletion> completion(String buf, int cursor) {
return new LinkedList<InterpreterCompletion>();
return new LinkedList<>();
}
public InterpreterContext getLastInterpretContext() {

View file

@ -37,7 +37,7 @@ import org.apache.zeppelin.interpreter.thrift.RemoteInterpreterService.Client;
public class ClientFactory extends BasePooledObjectFactory<Client>{
private String host;
private int port;
Map<Client, TSocket> clientSocketMap = new HashMap<Client, TSocket>();
Map<Client, TSocket> clientSocketMap = new HashMap<>();
public ClientFactory(String host, int port) {
this.host = host;
@ -64,7 +64,7 @@ public class ClientFactory extends BasePooledObjectFactory<Client>{
@Override
public PooledObject<Client> wrap(Client client) {
return new DefaultPooledObject<Client>(client);
return new DefaultPooledObject<>(client);
}
@Override

View file

@ -35,7 +35,7 @@ public class InterpreterContextRunnerPool {
private Map<String, List<InterpreterContextRunner>> interpreterContextRunners;
public InterpreterContextRunnerPool() {
interpreterContextRunners = new HashMap<String, List<InterpreterContextRunner>>();
interpreterContextRunners = new HashMap<>();
}

View file

@ -141,7 +141,7 @@ public class RemoteInterpreter extends Interpreter {
}
private Map<String, String> getEnvFromInterpreterProperty(Properties property) {
Map<String, String> env = new HashMap<String, String>();
Map<String, String> env = new HashMap<>();
for (Object key : property.keySet()) {
if (isEnvString((String) key)) {
env.put((String) key, property.getProperty((String) key));

View file

@ -43,9 +43,9 @@ import java.util.Map;
*/
public class RemoteInterpreterEventClient implements ResourcePoolConnector {
private final Logger logger = LoggerFactory.getLogger(RemoteInterpreterEvent.class);
private final List<RemoteInterpreterEvent> eventQueue = new LinkedList<RemoteInterpreterEvent>();
private final List<ResourceSet> getAllResourceResponse = new LinkedList<ResourceSet>();
private final Map<ResourceId, Object> getResourceResponse = new HashMap<ResourceId, Object>();
private final List<RemoteInterpreterEvent> eventQueue = new LinkedList<>();
private final List<ResourceSet> getAllResourceResponse = new LinkedList<>();
private final Map<ResourceId, Object> getResourceResponse = new HashMap<>();
private final Gson gson = new Gson();
/**
@ -79,7 +79,7 @@ public class RemoteInterpreterEventClient implements ResourcePoolConnector {
* notify angularObject removal
*/
public void angularObjectRemove(String name, String noteId, String paragraphId) {
Map<String, String> removeObject = new HashMap<String, String>();
Map<String, String> removeObject = new HashMap<>();
removeObject.put("name", name);
removeObject.put("noteId", noteId);
removeObject.put("paragraphId", paragraphId);
@ -213,7 +213,7 @@ public class RemoteInterpreterEventClient implements ResourcePoolConnector {
}
public void onInterpreterOutputAppend(String noteId, String paragraphId, String output) {
Map<String, String> appendOutput = new HashMap<String, String>();
Map<String, String> appendOutput = new HashMap<>();
appendOutput.put("noteId", noteId);
appendOutput.put("paragraphId", paragraphId);
appendOutput.put("data", output);
@ -224,7 +224,7 @@ public class RemoteInterpreterEventClient implements ResourcePoolConnector {
}
public void onInterpreterOutputUpdate(String noteId, String paragraphId, String output) {
Map<String, String> appendOutput = new HashMap<String, String>();
Map<String, String> appendOutput = new HashMap<>();
appendOutput.put("noteId", noteId);
appendOutput.put("paragraphId", paragraphId);
appendOutput.put("data", output);
@ -243,7 +243,7 @@ public class RemoteInterpreterEventClient implements ResourcePoolConnector {
}
public void onAppOutputAppend(String noteId, String paragraphId, String appId, String output) {
Map<String, String> appendOutput = new HashMap<String, String>();
Map<String, String> appendOutput = new HashMap<>();
appendOutput.put("noteId", noteId);
appendOutput.put("paragraphId", paragraphId);
appendOutput.put("appId", appId);
@ -256,7 +256,7 @@ public class RemoteInterpreterEventClient implements ResourcePoolConnector {
public void onAppOutputUpdate(String noteId, String paragraphId, String appId, String output) {
Map<String, String> appendOutput = new HashMap<String, String>();
Map<String, String> appendOutput = new HashMap<>();
appendOutput.put("noteId", noteId);
appendOutput.put("paragraphId", paragraphId);
appendOutput.put("appId", appId);
@ -268,7 +268,7 @@ public class RemoteInterpreterEventClient implements ResourcePoolConnector {
}
public void onAppStatusUpdate(String noteId, String paragraphId, String appId, String status) {
Map<String, String> appendOutput = new HashMap<String, String>();
Map<String, String> appendOutput = new HashMap<>();
appendOutput.put("noteId", noteId);
appendOutput.put("paragraphId", paragraphId);
appendOutput.put("appId", appId);

View file

@ -211,7 +211,7 @@ public class RemoteInterpreterEventPoller extends Thread {
boolean broken = false;
try {
client = interpreterProcess.getClient();
List<String> resourceList = new LinkedList<String>();
List<String> resourceList = new LinkedList<>();
Gson gson = new Gson();
for (Resource r : resourceSet) {
resourceList.add(gson.toJson(r));

View file

@ -78,7 +78,7 @@ public abstract class RemoteInterpreterProcess {
}
if (clientPool == null) {
clientPool = new GenericObjectPool<Client>(new ClientFactory(getHost(), getPort()));
clientPool = new GenericObjectPool<>(new ClientFactory(getHost(), getPort()));
clientPool.setTestOnBorrow(true);
remoteInterpreterEventPoller.setInterpreterGroup(interpreterGroup);

View file

@ -82,7 +82,7 @@ public class RemoteInterpreterServer
public RemoteInterpreterServer(int port) throws TTransportException {
this.port = port;
processor = new RemoteInterpreterService.Processor<RemoteInterpreterServer>(this);
processor = new RemoteInterpreterService.Processor<>(this);
TServerSocket serverTransport = new TServerSocket(port);
server = new TThreadPoolServer(
new TThreadPoolServer.Args(serverTransport).processor(processor));
@ -181,7 +181,7 @@ public class RemoteInterpreterServer
synchronized (interpreterGroup) {
List<Interpreter> interpreters = interpreterGroup.get(noteId);
if (interpreters == null) {
interpreters = new LinkedList<Interpreter>();
interpreters = new LinkedList<>();
interpreterGroup.put(noteId, interpreters);
}
@ -532,7 +532,7 @@ public class RemoteInterpreterServer
}
private InterpreterContext convert(RemoteInterpreterContext ric, InterpreterOutput output) {
List<InterpreterContextRunner> contextRunners = new LinkedList<InterpreterContextRunner>();
List<InterpreterContextRunner> contextRunners = new LinkedList<>();
List<InterpreterContextRunner> runners = gson.fromJson(ric.getRunners(),
new TypeToken<List<RemoteInterpreterContextRunner>>() {
}.getType());
@ -774,7 +774,7 @@ public class RemoteInterpreterServer
@Override
public List<String> resourcePoolGetAll() throws TException {
logger.debug("Request getAll from ZeppelinServer");
List<String> result = new LinkedList<String>();
List<String> result = new LinkedList<>();
if (resourcePool == null) {
return result;

View file

@ -28,7 +28,7 @@ public class ExecutorFactory {
private static ExecutorFactory _executor;
private static Long _executorLock = new Long(0);
Map<String, ExecutorService> executor = new HashMap<String, ExecutorService>();
Map<String, ExecutorService> executor = new HashMap<>();
public ExecutorFactory() {

View file

@ -31,7 +31,7 @@ import org.slf4j.LoggerFactory;
* FIFOScheduler runs submitted job sequentially
*/
public class FIFOScheduler implements Scheduler {
List<Job> queue = new LinkedList<Job>();
List<Job> queue = new LinkedList<>();
private ExecutorService executor;
private SchedulerListener listener;
boolean terminate = false;
@ -53,7 +53,7 @@ public class FIFOScheduler implements Scheduler {
@Override
public Collection<Job> getJobsWaiting() {
List<Job> ret = new LinkedList<Job>();
List<Job> ret = new LinkedList<>();
synchronized (queue) {
for (Job job : queue) {
ret.add(job);
@ -64,7 +64,7 @@ public class FIFOScheduler implements Scheduler {
@Override
public Collection<Job> getJobsRunning() {
List<Job> ret = new LinkedList<Job>();
List<Job> ret = new LinkedList<>();
Job job = runningJob;
if (job != null) {

View file

@ -31,8 +31,8 @@ import org.slf4j.LoggerFactory;
* Parallel scheduler runs submitted job concurrently.
*/
public class ParallelScheduler implements Scheduler {
List<Job> queue = new LinkedList<Job>();
List<Job> running = new LinkedList<Job>();
List<Job> queue = new LinkedList<>();
List<Job> running = new LinkedList<>();
private ExecutorService executor;
private SchedulerListener listener;
boolean terminate = false;
@ -56,7 +56,7 @@ public class ParallelScheduler implements Scheduler {
@Override
public Collection<Job> getJobsWaiting() {
List<Job> ret = new LinkedList<Job>();
List<Job> ret = new LinkedList<>();
synchronized (queue) {
for (Job job : queue) {
ret.add(job);
@ -82,7 +82,7 @@ public class ParallelScheduler implements Scheduler {
@Override
public Collection<Job> getJobsRunning() {
List<Job> ret = new LinkedList<Job>();
List<Job> ret = new LinkedList<>();
synchronized (queue) {
for (Job job : running) {
ret.add(job);

View file

@ -39,8 +39,8 @@ import java.util.concurrent.ExecutorService;
public class RemoteScheduler implements Scheduler {
Logger logger = LoggerFactory.getLogger(RemoteScheduler.class);
List<Job> queue = new LinkedList<Job>();
List<Job> running = new LinkedList<Job>();
List<Job> queue = new LinkedList<>();
List<Job> running = new LinkedList<>();
private ExecutorService executor;
private SchedulerListener listener;
boolean terminate = false;
@ -105,7 +105,7 @@ public class RemoteScheduler implements Scheduler {
@Override
public Collection<Job> getJobsWaiting() {
List<Job> ret = new LinkedList<Job>();
List<Job> ret = new LinkedList<>();
synchronized (queue) {
for (Job job : queue) {
ret.add(job);
@ -131,7 +131,7 @@ public class RemoteScheduler implements Scheduler {
@Override
public Collection<Job> getJobsRunning() {
List<Job> ret = new LinkedList<Job>();
List<Job> ret = new LinkedList<>();
synchronized (queue) {
for (Job job : running) {
ret.add(job);

View file

@ -34,7 +34,7 @@ import org.slf4j.LoggerFactory;
public class SchedulerFactory implements SchedulerListener {
private static final Logger logger = LoggerFactory.getLogger(SchedulerFactory.class);
ExecutorService executor;
Map<String, Scheduler> schedulers = new LinkedHashMap<String, Scheduler>();
Map<String, Scheduler> schedulers = new LinkedHashMap<>();
private static SchedulerFactory singleton;
private static Long singletonLock = new Long(0);
@ -117,7 +117,7 @@ public class SchedulerFactory implements SchedulerListener {
}
public Collection<Scheduler> listScheduler(String name) {
List<Scheduler> s = new LinkedList<Scheduler>();
List<Scheduler> s = new LinkedList<>();
synchronized (schedulers) {
for (Scheduler ss : schedulers.values()) {
s.add(ss);

View file

@ -102,7 +102,7 @@ public class InputTest {
// test form substitution without new forms
String script = "INPUT=${input_form=}SELECTED=${select_form(Selection Form)=,s_op1|s_op2|s_op3}\n" +
"CHECKED=${checkbox:checkbox_form=c_op1|c_op2,c_op1|c_op2|c_op3}";
Map<String, Object> params = new HashMap<String, Object>();
Map<String, Object> params = new HashMap<>();
params.put("input_form", "some_input");
params.put("select_form", "s_op2");
params.put("checkbox_form", new String[]{"c_op1", "c_op3"});

View file

@ -59,7 +59,7 @@ public class RemoteAngularObjectTest implements AngularObjectRegistryListener {
intpGroup = new InterpreterGroup("intpId");
localRegistry = new RemoteAngularObjectRegistry("intpId", this, intpGroup);
intpGroup.setAngularObjectRegistry(localRegistry);
env = new HashMap<String, String>();
env = new HashMap<>();
env.put("ZEPPELIN_CLASSPATH", new File("./target/test-classes").getAbsolutePath());
Properties p = new Properties();

View file

@ -50,7 +50,7 @@ public class RemoteInterpreterOutputTestStream implements RemoteInterpreterProce
intpGroup = new InterpreterGroup();
intpGroup.put("note", new LinkedList<Interpreter>());
env = new HashMap<String, String>();
env = new HashMap<>();
env.put("ZEPPELIN_CLASSPATH", new File("./target/test-classes").getAbsolutePath());
}

View file

@ -65,7 +65,7 @@ public class RemoteInterpreterTest {
@Before
public void setUp() throws Exception {
intpGroup = new InterpreterGroup();
env = new HashMap<String, String>();
env = new HashMap<>();
env.put("ZEPPELIN_CLASSPATH", new File("./target/test-classes").getAbsolutePath());
}
@ -384,7 +384,7 @@ public class RemoteInterpreterTest {
intpA.open();
int concurrency = 3;
final List<String> results = new LinkedList<String>();
final List<String> results = new LinkedList<>();
Scheduler scheduler = intpA.getScheduler();
for (int i = 0; i < concurrency; i++) {
@ -462,7 +462,7 @@ public class RemoteInterpreterTest {
int concurrency = 4;
final int timeToSleep = 1000;
final List<String> results = new LinkedList<String>();
final List<String> results = new LinkedList<>();
long start = System.currentTimeMillis();
Scheduler scheduler = intpA.getScheduler();

View file

@ -55,7 +55,7 @@ public class DistributedResourcePoolTest {
@Before
public void setUp() throws Exception {
env = new HashMap<String, String>();
env = new HashMap<>();
env.put("ZEPPELIN_CLASSPATH", new File("./target/test-classes").getAbsolutePath());
Properties p = new Properties();

View file

@ -68,7 +68,7 @@ public class RemoteSchedulerTest implements RemoteInterpreterProcessListener {
public void test() throws Exception {
Properties p = new Properties();
final InterpreterGroup intpGroup = new InterpreterGroup();
Map<String, String> env = new HashMap<String, String>();
Map<String, String> env = new HashMap<>();
env.put("ZEPPELIN_CLASSPATH", new File("./target/test-classes").getAbsolutePath());
final RemoteInterpreter intpA = new RemoteInterpreter(
@ -157,7 +157,7 @@ public class RemoteSchedulerTest implements RemoteInterpreterProcessListener {
public void testAbortOnPending() throws Exception {
Properties p = new Properties();
final InterpreterGroup intpGroup = new InterpreterGroup();
Map<String, String> env = new HashMap<String, String>();
Map<String, String> env = new HashMap<>();
env.put("ZEPPELIN_CLASSPATH", new File("./target/test-classes").getAbsolutePath());
final RemoteInterpreter intpA = new RemoteInterpreter(

View file

@ -71,7 +71,7 @@ public class SleepingJob extends Job{
@Override
public Map<String, Object> info() {
Map<String, Object> i = new HashMap<String, Object>();
Map<String, Object> i = new HashMap<>();
i.put("LoopCount", Integer.toString(count));
return i;
}

View file

@ -33,7 +33,7 @@
<name>Zeppelin: Server</name>
<properties>
<cxf.version>2.7.7</cxf.version>
<cxf.version>2.7.8</cxf.version>
<commons.httpclient.version>4.3.6</commons.httpclient.version>
<hadoop-common.version>2.6.0</hadoop-common.version>
</properties>

View file

@ -23,6 +23,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
@ -34,31 +35,33 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import com.google.common.collect.Sets;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import org.apache.commons.lang3.StringUtils;
import org.apache.zeppelin.interpreter.InterpreterResult;
import org.apache.zeppelin.utils.InterpreterBindingUtils;
import org.quartz.CronExpression;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.zeppelin.annotation.ZeppelinApi;
import org.apache.zeppelin.interpreter.InterpreterResult;
import org.apache.zeppelin.notebook.Note;
import org.apache.zeppelin.notebook.Notebook;
import org.apache.zeppelin.notebook.NotebookAuthorization;
import org.apache.zeppelin.notebook.Paragraph;
import org.apache.zeppelin.rest.exception.NotFoundException;
import org.apache.zeppelin.rest.exception.UnauthorizedException;
import org.apache.zeppelin.rest.message.CronRequest;
import org.apache.zeppelin.types.InterpreterSettingsList;
import org.apache.zeppelin.rest.message.NewNoteRequest;
import org.apache.zeppelin.rest.message.NewParagraphRequest;
import org.apache.zeppelin.rest.message.RunParagraphWithParametersRequest;
import org.apache.zeppelin.search.SearchService;
import org.apache.zeppelin.server.JsonResponse;
import org.apache.zeppelin.socket.NotebookServer;
import org.apache.zeppelin.types.InterpreterSettingsList;
import org.apache.zeppelin.user.AuthenticationInfo;
import org.apache.zeppelin.utils.InterpreterBindingUtils;
import org.apache.zeppelin.utils.SecurityUtils;
import org.quartz.CronExpression;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Sets;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
/**
* Rest api endpoint for the notebook.
@ -90,6 +93,8 @@ public class NotebookRestApi {
@Path("{noteId}/permissions")
@ZeppelinApi
public Response getNotePermissions(@PathParam("noteId") String noteId) {
checkIfUserCanRead(noteId,
"Insufficient privileges you cannot get the list of permissions for this note");
HashMap<String, Set<String>> permissionsMap = new HashMap<>();
permissionsMap.put("owners", notebookAuthorization.getOwners(noteId));
permissionsMap.put("readers", notebookAuthorization.getReaders(noteId));
@ -105,6 +110,60 @@ public class NotebookRestApi {
"User belongs to: " + current.toString();
}
/**
* Set of utils method to check if current user can perform action to the note.
* Since we only have security on notebook level, from now we keep this logic in this class.
* In the future we might want to generalize this for the rest of the api enmdpoints.
*/
/**
* Check if the current user own the given note.
*/
private void checkIfUserIsOwner(String noteId, String errorMsg) {
Set<String> userAndRoles = Sets.newHashSet();
userAndRoles.add(SecurityUtils.getPrincipal());
userAndRoles.addAll(SecurityUtils.getRoles());
if (!notebookAuthorization.isOwner(userAndRoles, noteId)) {
throw new UnauthorizedException(errorMsg);
}
}
/**
* Check if the current user is either Owner or Writer for the given note.
*/
private void checkIfUserCanWrite(String noteId, String errorMsg) {
Set<String> userAndRoles = Sets.newHashSet();
userAndRoles.add(SecurityUtils.getPrincipal());
userAndRoles.addAll(SecurityUtils.getRoles());
if (!notebookAuthorization.hasWriteAuthorization(userAndRoles, noteId)) {
throw new UnauthorizedException(errorMsg);
}
}
/**
* Check if the current user can access (at least he have to be reader) the given note.
*/
private void checkIfUserCanRead(String noteId, String errorMsg) {
Set<String> userAndRoles = Sets.newHashSet();
userAndRoles.add(SecurityUtils.getPrincipal());
userAndRoles.addAll(SecurityUtils.getRoles());
if (!notebookAuthorization.hasReadAuthorization(userAndRoles, noteId)) {
throw new UnauthorizedException(errorMsg);
}
}
private void checkIfNoteIsNotNull(Note note) {
if (note == null) {
throw new NotFoundException("note not found");
}
}
private void checkIfParagraphIsNotNull(Paragraph paragraph) {
if (paragraph == null) {
throw new NotFoundException("paragraph not found");
}
}
/**
* set note authorization information
*/
@ -113,22 +172,21 @@ public class NotebookRestApi {
@ZeppelinApi
public Response putNotePermissions(@PathParam("noteId") String noteId, String req)
throws IOException {
HashMap<String, HashSet<String>> permMap =
gson.fromJson(req, new TypeToken<HashMap<String, HashSet<String>>>() {
}.getType());
Note note = notebook.getNote(noteId);
String principal = SecurityUtils.getPrincipal();
HashSet<String> roles = SecurityUtils.getRoles();
LOG.info("Set permissions {} {} {} {} {}", noteId, principal, permMap.get("owners"),
permMap.get("readers"), permMap.get("writers"));
HashSet<String> userAndRoles = new HashSet<>();
userAndRoles.add(principal);
userAndRoles.addAll(roles);
if (!notebookAuthorization.isOwner(noteId, userAndRoles)) {
return new JsonResponse<>(Status.FORBIDDEN,
ownerPermissionError(userAndRoles, notebookAuthorization.getOwners(noteId))).build();
}
checkIfUserIsOwner(noteId,
ownerPermissionError(userAndRoles, notebookAuthorization.getOwners(noteId)));
HashMap<String, HashSet<String>> permMap =
gson.fromJson(req, new TypeToken<HashMap<String, HashSet<String>>>() {}.getType());
Note note = notebook.getNote(noteId);
LOG.info("Set permissions {} {} {} {} {}", noteId, principal, permMap.get("owners"),
permMap.get("readers"), permMap.get("writers"));
HashSet<String> readers = permMap.get("readers");
HashSet<String> owners = permMap.get("owners");
@ -170,6 +228,9 @@ public class NotebookRestApi {
@Path("interpreter/bind/{noteId}")
@ZeppelinApi
public Response bind(@PathParam("noteId") String noteId, String req) throws IOException {
checkIfUserCanWrite(noteId,
"Insufficient privileges you cannot bind any interpreters to this note");
List<String> settingIdList = gson.fromJson(req, new TypeToken<List<String>>() {
}.getType());
notebook.bindInterpretersToNote(SecurityUtils.getPrincipal(), noteId, settingIdList);
@ -183,6 +244,8 @@ public class NotebookRestApi {
@Path("interpreter/bind/{noteId}")
@ZeppelinApi
public Response bind(@PathParam("noteId") String noteId) {
checkIfUserCanRead(noteId, "Insufficient privileges you cannot get any interpreters settings");
List<InterpreterSettingsList> settingList =
InterpreterBindingUtils.getInterpreterBindings(notebook, noteId);
notebookServer.broadcastInterpreterBindings(noteId, settingList);
@ -204,9 +267,8 @@ public class NotebookRestApi {
@ZeppelinApi
public Response getNote(@PathParam("noteId") String noteId) throws IOException {
Note note = notebook.getNote(noteId);
if (note == null) {
return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build();
}
checkIfNoteIsNotNull(note);
checkIfUserCanRead(noteId, "Insufficient privileges you cannot get this note");
return new JsonResponse<>(Status.OK, "", note).build();
}
@ -222,6 +284,7 @@ public class NotebookRestApi {
@Path("export/{noteId}")
@ZeppelinApi
public Response exportNote(@PathParam("noteId") String noteId) throws IOException {
checkIfUserCanRead(noteId, "Insufficient privileges you cannot export this note");
String exportJson = notebook.exportNote(noteId);
return new JsonResponse<>(Status.OK, "", exportJson).build();
}
@ -290,6 +353,7 @@ public class NotebookRestApi {
@ZeppelinApi
public Response deleteNote(@PathParam("noteId") String noteId) throws IOException {
LOG.info("Delete note {} ", noteId);
checkIfUserIsOwner(noteId, "Insufficient privileges you cannot delete this note");
AuthenticationInfo subject = new AuthenticationInfo(SecurityUtils.getPrincipal());
if (!(noteId.isEmpty())) {
Note note = notebook.getNote(noteId);
@ -315,6 +379,7 @@ public class NotebookRestApi {
public Response cloneNote(@PathParam("noteId") String noteId, String message)
throws IOException, CloneNotSupportedException, IllegalArgumentException {
LOG.info("clone note by JSON {}", message);
checkIfUserCanWrite(noteId, "Insufficient privileges you cannot clone this note");
NewNoteRequest request = gson.fromJson(message, NewNoteRequest.class);
String newNoteName = null;
if (request != null) {
@ -342,9 +407,8 @@ public class NotebookRestApi {
LOG.info("insert paragraph {} {}", noteId, message);
Note note = notebook.getNote(noteId);
if (note == null) {
return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build();
}
checkIfNoteIsNotNull(note);
checkIfUserCanWrite(noteId, "Insufficient privileges you cannot add paragraph to this note");
NewParagraphRequest request = gson.fromJson(message, NewParagraphRequest.class);
@ -379,14 +443,10 @@ public class NotebookRestApi {
LOG.info("get paragraph {} {}", noteId, paragraphId);
Note note = notebook.getNote(noteId);
if (note == null) {
return new JsonResponse(Status.NOT_FOUND, "note not found.").build();
}
checkIfNoteIsNotNull(note);
checkIfUserCanRead(noteId, "Insufficient privileges you cannot get this paragraph");
Paragraph p = note.getParagraph(paragraphId);
if (p == null) {
return new JsonResponse(Status.NOT_FOUND, "paragraph not found.").build();
}
checkIfParagraphIsNotNull(p);
return new JsonResponse<>(Status.OK, "", p).build();
}
@ -407,14 +467,11 @@ public class NotebookRestApi {
LOG.info("move paragraph {} {} {}", noteId, paragraphId, newIndex);
Note note = notebook.getNote(noteId);
if (note == null) {
return new JsonResponse(Status.NOT_FOUND, "note not found.").build();
}
checkIfNoteIsNotNull(note);
checkIfUserCanWrite(noteId, "Insufficient privileges you cannot move paragraph");
Paragraph p = note.getParagraph(paragraphId);
if (p == null) {
return new JsonResponse(Status.NOT_FOUND, "paragraph not found.").build();
}
checkIfParagraphIsNotNull(p);
try {
note.moveParagraph(paragraphId, Integer.parseInt(newIndex), true);
@ -444,14 +501,12 @@ public class NotebookRestApi {
LOG.info("delete paragraph {} {}", noteId, paragraphId);
Note note = notebook.getNote(noteId);
if (note == null) {
return new JsonResponse(Status.NOT_FOUND, "note not found.").build();
}
checkIfNoteIsNotNull(note);
checkIfUserCanRead(noteId,
"Insufficient privileges you cannot remove paragraph from this note");
Paragraph p = note.getParagraph(paragraphId);
if (p == null) {
return new JsonResponse(Status.NOT_FOUND, "paragraph not found.").build();
}
checkIfParagraphIsNotNull(p);
AuthenticationInfo subject = new AuthenticationInfo(SecurityUtils.getPrincipal());
note.removeParagraph(SecurityUtils.getPrincipal(), paragraphId);
@ -499,9 +554,8 @@ public class NotebookRestApi {
throws IOException, IllegalArgumentException {
LOG.info("run note jobs {} ", noteId);
Note note = notebook.getNote(noteId);
if (note == null) {
return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build();
}
checkIfNoteIsNotNull(note);
checkIfUserCanWrite(noteId, "Insufficient privileges you cannot run job for this note");
try {
note.runAll();
@ -528,9 +582,8 @@ public class NotebookRestApi {
throws IOException, IllegalArgumentException {
LOG.info("stop note jobs {} ", noteId);
Note note = notebook.getNote(noteId);
if (note == null) {
return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build();
}
checkIfNoteIsNotNull(note);
checkIfUserCanWrite(noteId, "Insufficient privileges you cannot stop this job for this note");
for (Paragraph p : note.getParagraphs()) {
if (!p.isTerminated()) {
@ -554,9 +607,8 @@ public class NotebookRestApi {
throws IOException, IllegalArgumentException {
LOG.info("get note job status.");
Note note = notebook.getNote(noteId);
if (note == null) {
return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build();
}
checkIfNoteIsNotNull(note);
checkIfUserCanRead(noteId, "Insufficient privileges you cannot get job status");
return new JsonResponse<>(Status.OK, null, note.generateParagraphsInfo()).build();
}
@ -577,14 +629,11 @@ public class NotebookRestApi {
throws IOException, IllegalArgumentException {
LOG.info("get note paragraph job status.");
Note note = notebook.getNote(noteId);
if (note == null) {
return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build();
}
checkIfNoteIsNotNull(note);
checkIfUserCanRead(noteId, "Insufficient privileges you cannot get job status");
Paragraph paragraph = note.getParagraph(paragraphId);
if (paragraph == null) {
return new JsonResponse<>(Status.NOT_FOUND, "paragraph not found.").build();
}
checkIfParagraphIsNotNull(paragraph);
return new JsonResponse<>(Status.OK, null, note.generateSingleParagraphInfo(paragraphId)).
build();
@ -607,14 +656,10 @@ public class NotebookRestApi {
LOG.info("run paragraph job asynchronously {} {} {}", noteId, paragraphId, message);
Note note = notebook.getNote(noteId);
if (note == null) {
return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build();
}
checkIfNoteIsNotNull(note);
checkIfUserCanWrite(noteId, "Insufficient privileges you cannot run job for this note");
Paragraph paragraph = note.getParagraph(paragraphId);
if (paragraph == null) {
return new JsonResponse<>(Status.NOT_FOUND, "paragraph not found.").build();
}
checkIfParagraphIsNotNull(paragraph);
// handle params if presented
handleParagraphParams(message, note, paragraph);
@ -649,14 +694,10 @@ public class NotebookRestApi {
LOG.info("run paragraph synchronously {} {} {}", noteId, paragraphId, message);
Note note = notebook.getNote(noteId);
if (note == null) {
return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build();
}
checkIfNoteIsNotNull(note);
checkIfUserCanWrite(noteId, "Insufficient privileges you cannot run paragraph");
Paragraph paragraph = note.getParagraph(paragraphId);
if (paragraph == null) {
return new JsonResponse<>(Status.NOT_FOUND, "paragraph not found.").build();
}
checkIfParagraphIsNotNull(paragraph);
// handle params if presented
handleParagraphParams(message, note, paragraph);
@ -691,14 +732,10 @@ public class NotebookRestApi {
@PathParam("paragraphId") String paragraphId) throws IOException, IllegalArgumentException {
LOG.info("stop paragraph job {} ", noteId);
Note note = notebook.getNote(noteId);
if (note == null) {
return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build();
}
checkIfNoteIsNotNull(note);
checkIfUserCanWrite(noteId, "Insufficient privileges you cannot stop paragraph");
Paragraph p = note.getParagraph(paragraphId);
if (p == null) {
return new JsonResponse<>(Status.NOT_FOUND, "paragraph not found.").build();
}
checkIfParagraphIsNotNull(p);
p.abort();
return new JsonResponse<>(Status.OK).build();
}
@ -720,9 +757,8 @@ public class NotebookRestApi {
CronRequest request = gson.fromJson(message, CronRequest.class);
Note note = notebook.getNote(noteId);
if (note == null) {
return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build();
}
checkIfNoteIsNotNull(note);
checkIfUserCanWrite(noteId, "Insufficient privileges you cannot set a cron job for this note");
if (!CronExpression.isValidExpression(request.getCronString())) {
return new JsonResponse<>(Status.BAD_REQUEST, "wrong cron expressions.").build();
@ -751,9 +787,9 @@ public class NotebookRestApi {
LOG.info("Remove cron job note {}", noteId);
Note note = notebook.getNote(noteId);
if (note == null) {
return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build();
}
checkIfNoteIsNotNull(note);
checkIfUserIsOwner(noteId,
"Insufficient privileges you cannot remove this cron job from this note");
Map<String, Object> config = note.getConfig();
config.put("cron", null);
@ -778,9 +814,8 @@ public class NotebookRestApi {
LOG.info("Get cron job note {}", noteId);
Note note = notebook.getNote(noteId);
if (note == null) {
return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build();
}
checkIfNoteIsNotNull(note);
checkIfUserCanRead(noteId, "Insufficient privileges you cannot get cron information");
return new JsonResponse<>(Status.OK, note.getConfig().get("cron")).build();
}

View file

@ -0,0 +1,59 @@
/*
* 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.exception;
import static javax.ws.rs.core.Response.Status.NOT_FOUND;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import org.apache.zeppelin.utils.ExceptionUtils;
/**
* Not Found handler for WebApplicationException.
*
*/
public class NotFoundException extends WebApplicationException {
private static final long serialVersionUID = 2459398393216512293L;
/**
* Create a HTTP 404 (Not Found) exception.
*/
public NotFoundException() {
super(ExceptionUtils.jsonResponse(NOT_FOUND));
}
/**
* Create a HTTP 404 (Not Found) exception.
* @param message the String that is the entity of the 404 response.
*/
public NotFoundException(String message) {
super(notFoundJson(message));
}
private static Response notFoundJson(String message) {
return ExceptionUtils.jsonResponseContent(NOT_FOUND, message);
}
public NotFoundException(Throwable cause) {
super(cause, notFoundJson(cause.getMessage()));
}
public NotFoundException(Throwable cause, String message) {
super(cause, notFoundJson(message));
}
}

View file

@ -0,0 +1,50 @@
/*
* 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.exception;
import static javax.ws.rs.core.Response.Status.FORBIDDEN;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import org.apache.zeppelin.utils.ExceptionUtils;
/**
* UnauthorizedException handler for WebApplicationException.
*
*/
public class UnauthorizedException extends WebApplicationException {
private static final long serialVersionUID = 4394749068760407567L;
private static final String UNAUTHORIZED_MSG = "Authorization required";
public UnauthorizedException() {
super(unauthorizedJson(UNAUTHORIZED_MSG));
}
private static Response unauthorizedJson(String message) {
return ExceptionUtils.jsonResponseContent(FORBIDDEN, message);
}
public UnauthorizedException(Throwable cause, String message) {
super(cause, unauthorizedJson(message));
}
public UnauthorizedException(String message) {
super(unauthorizedJson(message));
}
}

View file

@ -304,7 +304,7 @@ public class ActiveDirectoryGroupRealm extends AbstractLdapRealm {
* @return a collection of roles that are implied by the given role names.
*/
protected Collection<String> getRoleNamesForGroups(Collection<String> groupNames) {
Set<String> roleNames = new HashSet<String>(groupNames.size());
Set<String> roleNames = new HashSet<>(groupNames.size());
if (groupRolesMap != null) {
for (String groupName : groupNames) {

View file

@ -75,7 +75,7 @@ public class JsonResponse<T> {
*/
public JsonResponse<T> addCookie(NewCookie newCookie) {
if (cookies == null) {
cookies = new ArrayList<NewCookie>();
cookies = new ArrayList<>();
}
cookies.add(newCookie);

View file

@ -56,7 +56,7 @@ public class LdapGroupRealm extends JndiLdapRealm {
LdapContext ldapContext,
String userDnTemplate) throws NamingException {
try {
Set<String> roleNames = new LinkedHashSet<String>();
Set<String> roleNames = new LinkedHashSet<>();
SearchControls searchCtls = new SearchControls();
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);

View file

@ -302,7 +302,7 @@ public class ZeppelinServer extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
Set<Class<?>> classes = new HashSet<>();
return classes;
}

View file

@ -16,10 +16,22 @@
*/
package org.apache.zeppelin.socket;
import com.google.common.base.Strings;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.zeppelin.conf.ZeppelinConfiguration;
@ -36,7 +48,13 @@ import org.apache.zeppelin.interpreter.InterpreterSetting;
import org.apache.zeppelin.interpreter.remote.RemoteAngularObjectRegistry;
import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcessListener;
import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion;
import org.apache.zeppelin.notebook.*;
import org.apache.zeppelin.notebook.JobListenerFactory;
import org.apache.zeppelin.notebook.Note;
import org.apache.zeppelin.notebook.Notebook;
import org.apache.zeppelin.notebook.NotebookAuthorization;
import org.apache.zeppelin.notebook.NotebookEventListener;
import org.apache.zeppelin.notebook.Paragraph;
import org.apache.zeppelin.notebook.ParagraphJobListener;
import org.apache.zeppelin.notebook.repo.NotebookRepo.Revision;
import org.apache.zeppelin.notebook.socket.Message;
import org.apache.zeppelin.notebook.socket.Message.OP;
@ -54,13 +72,10 @@ import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import com.google.common.base.Strings;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
/**
* Zeppelin websocket service.
@ -86,8 +101,7 @@ public class NotebookServer extends WebSocketServlet implements
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").create();
final Map<String, List<NotebookSocket>> noteSocketMap = new HashMap<>();
final Queue<NotebookSocket> connectedSockets = new ConcurrentLinkedQueue<>();
final Map<String, Queue<NotebookSocket>> userConnectedSockets =
new ConcurrentHashMap<String, Queue<NotebookSocket>>();
final Map<String, Queue<NotebookSocket>> userConnectedSockets = new ConcurrentHashMap<>();
private Notebook notebook() {
return ZeppelinServer.notebook;
@ -148,13 +162,12 @@ public class NotebookServer extends WebSocketServlet implements
}
ZeppelinConfiguration conf = ZeppelinConfiguration.create();
boolean allowAnonymous = conf.
getBoolean(ZeppelinConfiguration.ConfVars.ZEPPELIN_ANONYMOUS_ALLOWED);
boolean allowAnonymous = conf.isAnonymousAllowed();
if (!allowAnonymous && messagereceived.principal.equals("anonymous")) {
throw new Exception("Anonymous access not allowed ");
}
HashSet<String> userAndRoles = new HashSet<String>();
HashSet<String> userAndRoles = new HashSet<>();
userAndRoles.add(messagereceived.principal);
if (!messagereceived.roles.equals("")) {
HashSet<String> roles = gson.fromJson(messagereceived.roles,
@ -262,6 +275,9 @@ public class NotebookServer extends WebSocketServlet implements
case EDITOR_SETTING:
getEditorSetting(conn, messagereceived);
break;
case GET_INTERPRETER_SETTINGS:
getInterpreterSettings(conn, subject);
break;
default:
break;
}
@ -703,11 +719,27 @@ public class NotebookServer extends WebSocketServlet implements
Notebook notebook, Message message)
throws IOException {
AuthenticationInfo subject = new AuthenticationInfo(message.principal);
Note note = notebook.createNote(subject);
Note note = null;
String defaultInterpreterId = (String) message.get("defaultInterpreterId");
if (!StringUtils.isEmpty(defaultInterpreterId)) {
List<String> interpreterSettingIds = new LinkedList<>();
interpreterSettingIds.add(defaultInterpreterId);
for (String interpreterSettingId : notebook.getInterpreterFactory().
getDefaultInterpreterSettingList()) {
if (!interpreterSettingId.equals(defaultInterpreterId)) {
interpreterSettingIds.add(interpreterSettingId);
}
}
note = notebook.createNote(interpreterSettingIds, subject);
} else {
note = notebook.createNote(subject);
}
note.addParagraph(); // it's an empty note. so add one paragraph
if (message != null) {
String noteName = (String) message.get("name");
if (noteName == null || noteName.isEmpty()){
if (StringUtils.isEmpty(noteName)){
noteName = "Note " + note.getId();
}
note.setName(noteName);
@ -1684,5 +1716,13 @@ public class NotebookServer extends WebSocketServlet implements
conn.send(serializeMessage(resp));
return;
}
private void getInterpreterSettings(NotebookSocket conn, AuthenticationInfo subject)
throws IOException {
List<InterpreterSetting> availableSettings = notebook().getInterpreterFactory().get();
conn.send(serializeMessage(new Message(OP.INTERPRETER_SETTINGS)
.put("interpreterSettings", availableSettings)));
}
}

View file

@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.zeppelin.utils;
import javax.ws.rs.core.Response.Status;
import org.apache.zeppelin.server.JsonResponse;
/**
* Utility method for exception in rest api.
*
*/
public class ExceptionUtils {
public static javax.ws.rs.core.Response jsonResponse(Status status) {
return new JsonResponse<>(status).build();
}
public static javax.ws.rs.core.Response jsonResponseContent(Status status, String message) {
return new JsonResponse<>(status, message).build();
}
}

View file

@ -114,8 +114,8 @@ public class ScreenCaptureHtmlUnitDriver extends HtmlUnitDriver implements Takes
// http://stackoverflow.com/questions/2244272/how-can-i-tell-htmlunits-webclient-to-download-images-and-css
protected byte[] downloadCssAndImages(WebClient webClient, HtmlPage page) throws Exception {
WebWindow currentWindow = webClient.getCurrentWindow();
Map<String, String> urlMapping = new HashMap<String, String>();
Map<String, byte[]> files = new HashMap<String, byte[]>();
Map<String, String> urlMapping = new HashMap<>();
Map<String, byte[]> files = new HashMap<>();
WebWindow window = null;
try {
window = webClient.getWebWindowByName(page.getUrl().toString()+"_screenshot");
@ -199,7 +199,7 @@ public class ScreenCaptureHtmlUnitDriver extends HtmlUnitDriver implements Takes
}
List<String> getLinksFromCss(String css) {
List<String> result = new LinkedList<String>();
List<String> result = new LinkedList<>();
Matcher m = cssUrlPattern.matcher(css);
while (m.find()) { // find next match
result.add( m.group(2));

View file

@ -88,7 +88,7 @@ abstract public class AbstractZeppelinIT {
}
protected WebElement pollingWait(final By locator, final long timeWait) {
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
Wait<WebDriver> wait = new FluentWait<>(driver)
.withTimeout(timeWait, TimeUnit.SECONDS)
.pollingEvery(1, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);

View file

@ -40,7 +40,7 @@ public class CommandExecutor {
private static IGNORE_ERRORS DEFAULT_BEHAVIOUR_ON_ERRORS = IGNORE_ERRORS.TRUE;
public static Object executeCommandLocalHost(String[] command, boolean printToConsole, ProcessData.Types_Of_Data type, IGNORE_ERRORS ignore_errors) {
List<String> subCommandsAsList = new ArrayList<String>(Arrays.asList(command));
List<String> subCommandsAsList = new ArrayList<>(Arrays.asList(command));
String mergedCommand = StringUtils.join(subCommandsAsList, " ");
LOG.info("Sending command \"" + mergedCommand + "\" to localhost");

View file

@ -0,0 +1,82 @@
/*
* 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.integration;
import org.apache.zeppelin.AbstractZeppelinIT;
import org.apache.zeppelin.WebDriverManager;
import org.hamcrest.CoreMatchers;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ErrorCollector;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class InterpreterIT extends AbstractZeppelinIT {
private static final Logger LOG = LoggerFactory.getLogger(InterpreterIT.class);
@Rule
public ErrorCollector collector = new ErrorCollector();
@Before
public void startUp() {
if (!endToEndTestEnabled()) {
return;
}
driver = WebDriverManager.getWebDriver();
}
@After
public void tearDown() {
if (!endToEndTestEnabled()) {
return;
}
driver.quit();
}
@Test
public void testShowDescriptionOnInterpreterCreate() throws Exception {
if (!endToEndTestEnabled()) {
return;
}
try {
// navigate to interpreter page
WebElement settingButton = driver.findElement(By.xpath("//button[@class='nav-btn dropdown-toggle ng-scope']"));
settingButton.click();
WebElement interpreterLink = driver.findElement(By.xpath("//a[@href='#/interpreter']"));
interpreterLink.click();
WebElement createButton = driver.findElement(By.xpath("//button[contains(., 'Create')]"));
createButton.click();
Select select = new Select(driver.findElement(By.xpath("//select[@ng-change='newInterpreterGroupChange()']")));
select.selectByVisibleText("spark");
collector.checkThat("description of interpreter property is displayed",
driver.findElement(By.xpath("//tr/td[contains(text(), 'spark.app.name')]/following-sibling::td[2]")).getText(),
CoreMatchers.equalTo("The name of spark application."));
} catch (Exception e) {
handleException("Exception in InterpreterIT while testShowDescriptionOnInterpreterCreate ", e);
}
}
}

View file

@ -29,7 +29,7 @@ import org.apache.zeppelin.scheduler.Scheduler;
import org.apache.zeppelin.scheduler.SchedulerFactory;
public class MockInterpreter1 extends Interpreter{
Map<String, Object> vars = new HashMap<String, Object>();
Map<String, Object> vars = new HashMap<>();
public MockInterpreter1(Properties property) {
super(property);

View file

@ -23,20 +23,25 @@ import java.lang.ref.WeakReference;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Pattern;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.PumpStreamHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.zeppelin.conf.ZeppelinConfiguration;
import org.apache.zeppelin.interpreter.InterpreterSetting;
import org.apache.zeppelin.server.ZeppelinServer;
@ -46,6 +51,7 @@ import org.hamcrest.TypeSafeMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
@ -59,6 +65,29 @@ public abstract class AbstractTestRestApi {
protected static final boolean wasRunning = checkIfServerIsRunning();
static boolean pySpark = false;
static boolean sparkR = false;
static Gson gson = new Gson();
static boolean isRunningWithAuth = false;
private static File shiroIni = null;
private static String zeppelinShiro =
"[users]\n" +
"admin = password1, admin\n" +
"user1 = password2, role1, role2\n" +
"user2 = password3, role3\n" +
"user3 = password4, role2\n" +
"[main]\n" +
"sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager\n" +
"securityManager.sessionManager = $sessionManager\n" +
"securityManager.sessionManager.globalSessionTimeout = 86400000\n" +
"shiro.loginUrl = /api/login\n" +
"[roles]\n" +
"role1 = *\n" +
"role2 = *\n" +
"role3 = *\n" +
"admin = *" +
"[urls]\n" +
"/api/version = anon\n" +
"/** = authc";
private String getUrl(String path) {
String url;
@ -94,15 +123,27 @@ public abstract class AbstractTestRestApi {
}
};
protected static void startUp() throws Exception {
private static void start(boolean withAuth) throws Exception {
if (!wasRunning) {
System.setProperty(ZeppelinConfiguration.ConfVars.ZEPPELIN_HOME.getVarName(), "../");
System.setProperty(ZeppelinConfiguration.ConfVars.ZEPPELIN_WAR.getVarName(), "../zeppelin-web/dist");
LOG.info("Staring test Zeppelin up...");
ZeppelinConfiguration conf = ZeppelinConfiguration.create();
if (withAuth) {
isRunningWithAuth = true;
// Set Anonymous session to false.
System.setProperty(ZeppelinConfiguration.ConfVars.ZEPPELIN_ANONYMOUS_ALLOWED.getVarName(), "false");
// Create a shiro env test.
shiroIni = new File("../conf/shiro.ini");
if (!shiroIni.exists()) {
shiroIni.createNewFile();
}
FileUtils.writeStringToFile(shiroIni, zeppelinShiro);
}
// exclude org.apache.zeppelin.rinterpreter.* for scala 2.11 test
ZeppelinConfiguration conf = ZeppelinConfiguration.create();
String interpreters = conf.getString(ZeppelinConfiguration.ConfVars.ZEPPELIN_INTERPRETERS);
String interpretersCompatibleWithScala211Test = null;
@ -140,47 +181,41 @@ public abstract class AbstractTestRestApi {
LOG.info("Test Zeppelin stared.");
// assume first one is spark
InterpreterSetting sparkIntpSetting = null;
for(InterpreterSetting intpSetting : ZeppelinServer.notebook.getInterpreterFactory().get()) {
if (intpSetting.getName().equals("spark")) {
sparkIntpSetting = intpSetting;
}
}
Properties sparkProperties = (Properties) sparkIntpSetting.getProperties();
// ci environment runs spark cluster for testing
// so configure zeppelin use spark cluster
if ("true".equals(System.getenv("CI"))) {
// assume first one is spark
InterpreterSetting sparkIntpSetting = null;
for(InterpreterSetting intpSetting : ZeppelinServer.notebook.getInterpreterFactory().get()) {
if (intpSetting.getName().equals("spark")) {
sparkIntpSetting = intpSetting;
}
}
// set spark master and other properties
sparkIntpSetting.getProperties().setProperty("master", "local[2]");
sparkIntpSetting.getProperties().setProperty("spark.cores.max", "2");
sparkIntpSetting.getProperties().setProperty("zeppelin.spark.useHiveContext", "false");
sparkProperties.setProperty("master", "local[2]");
sparkProperties.setProperty("spark.cores.max", "2");
sparkProperties.setProperty("zeppelin.spark.useHiveContext", "false");
// set spark home for pyspark
sparkIntpSetting.getProperties().setProperty("spark.home", getSparkHome());
sparkProperties.setProperty("spark.home", getSparkHome());
sparkIntpSetting.setProperties(sparkProperties);
pySpark = true;
sparkR = true;
ZeppelinServer.notebook.getInterpreterFactory().restart(sparkIntpSetting.getId());
} else {
// assume first one is spark
InterpreterSetting sparkIntpSetting = null;
for(InterpreterSetting intpSetting : ZeppelinServer.notebook.getInterpreterFactory().get()) {
if (intpSetting.getName().equals("spark")) {
sparkIntpSetting = intpSetting;
}
}
String sparkHome = getSparkHome();
if (sparkHome != null) {
if (System.getenv("SPARK_MASTER") != null) {
sparkIntpSetting.getProperties().setProperty("master", System.getenv("SPARK_MASTER"));
sparkProperties.setProperty("master", System.getenv("SPARK_MASTER"));
} else {
sparkIntpSetting.getProperties()
.setProperty("master", "local[2]");
sparkProperties.setProperty("master", "local[2]");
}
sparkIntpSetting.getProperties().setProperty("spark.cores.max", "2");
sparkProperties.setProperty("spark.cores.max", "2");
// set spark home for pyspark
sparkIntpSetting.getProperties().setProperty("spark.home", sparkHome);
sparkIntpSetting.getProperties().setProperty("zeppelin.spark.useHiveContext", "false");
sparkProperties.setProperty("spark.home", sparkHome);
sparkProperties.setProperty("zeppelin.spark.useHiveContext", "false");
pySpark = true;
sparkR = true;
}
@ -189,6 +224,14 @@ public abstract class AbstractTestRestApi {
}
}
}
protected static void startUpWithAuthenticationEnable() throws Exception {
start(true);
}
protected static void startUp() throws Exception {
start(false);
}
private static String getHostname() {
try {
@ -249,7 +292,9 @@ public abstract class AbstractTestRestApi {
for (String setting : settingList) {
ZeppelinServer.notebook.getInterpreterFactory().restart(setting);
}
if (shiroIni != null) {
FileUtils.deleteQuietly(shiroIni);
}
LOG.info("Terminating test Zeppelin...");
ZeppelinServer.jettyWebServer.stop();
executor.shutdown();
@ -270,6 +315,11 @@ public abstract class AbstractTestRestApi {
LOG.info("Test Zeppelin terminated.");
System.clearProperty(ZeppelinConfiguration.ConfVars.ZEPPELIN_INTERPRETERS.getVarName());
if (isRunningWithAuth) {
isRunningWithAuth = false;
System
.clearProperty(ZeppelinConfiguration.ConfVars.ZEPPELIN_ANONYMOUS_ALLOWED.getVarName());
}
}
}
@ -291,56 +341,104 @@ public abstract class AbstractTestRestApi {
}
protected static GetMethod httpGet(String path) throws IOException {
return httpGet(path, StringUtils.EMPTY, StringUtils.EMPTY);
}
protected static GetMethod httpGet(String path, String user, String pwd) throws IOException {
LOG.info("Connecting to {}", url + path);
HttpClient httpClient = new HttpClient();
GetMethod getMethod = new GetMethod(url + path);
getMethod.addRequestHeader("Origin", url);
if (userAndPasswordAreNotBlank(user, pwd)) {
getMethod.setRequestHeader("Cookie", "JSESSIONID="+ getCookie(user, pwd));
}
httpClient.executeMethod(getMethod);
LOG.info("{} - {}", getMethod.getStatusCode(), getMethod.getStatusText());
return getMethod;
}
protected static DeleteMethod httpDelete(String path) throws IOException {
return httpDelete(path, StringUtils.EMPTY, StringUtils.EMPTY);
}
protected static DeleteMethod httpDelete(String path, String user, String pwd) throws IOException {
LOG.info("Connecting to {}", url + path);
HttpClient httpClient = new HttpClient();
DeleteMethod deleteMethod = new DeleteMethod(url + path);
deleteMethod.addRequestHeader("Origin", url);
if (userAndPasswordAreNotBlank(user, pwd)) {
deleteMethod.setRequestHeader("Cookie", "JSESSIONID="+ getCookie(user, pwd));
}
httpClient.executeMethod(deleteMethod);
LOG.info("{} - {}", deleteMethod.getStatusCode(), deleteMethod.getStatusText());
return deleteMethod;
}
protected static PostMethod httpPost(String path, String body) throws IOException {
return httpPost(path, body, StringUtils.EMPTY, StringUtils.EMPTY);
}
protected static PostMethod httpPost(String path, String request, String user, String pwd)
throws IOException {
LOG.info("Connecting to {}", url + path);
HttpClient httpClient = new HttpClient();
PostMethod postMethod = new PostMethod(url + path);
postMethod.addRequestHeader("Origin", url);
RequestEntity entity = new ByteArrayRequestEntity(body.getBytes("UTF-8"));
postMethod.setRequestEntity(entity);
postMethod.setRequestBody(request);
postMethod.getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
if (userAndPasswordAreNotBlank(user, pwd)) {
postMethod.setRequestHeader("Cookie", "JSESSIONID="+ getCookie(user, pwd));
}
httpClient.executeMethod(postMethod);
LOG.info("{} - {}", postMethod.getStatusCode(), postMethod.getStatusText());
return postMethod;
}
protected static PutMethod httpPut(String path, String body) throws IOException {
return httpPut(path, body, StringUtils.EMPTY, StringUtils.EMPTY);
}
protected static PutMethod httpPut(String path, String body, String user, String pwd) throws IOException {
LOG.info("Connecting to {}", url + path);
HttpClient httpClient = new HttpClient();
PutMethod putMethod = new PutMethod(url + path);
putMethod.addRequestHeader("Origin", url);
RequestEntity entity = new ByteArrayRequestEntity(body.getBytes("UTF-8"));
putMethod.setRequestEntity(entity);
if (userAndPasswordAreNotBlank(user, pwd)) {
putMethod.setRequestHeader("Cookie", "JSESSIONID="+ getCookie(user, pwd));
}
httpClient.executeMethod(putMethod);
LOG.info("{} - {}", putMethod.getStatusCode(), putMethod.getStatusText());
return putMethod;
}
private static String getCookie(String user, String password) throws IOException {
HttpClient httpClient = new HttpClient();
PostMethod postMethod = new PostMethod(url + "/login");
postMethod.addRequestHeader("Origin", url);
postMethod.setParameter("password", password);
postMethod.setParameter("userName", user);
httpClient.executeMethod(postMethod);
LOG.info("{} - {}", postMethod.getStatusCode(), postMethod.getStatusText());
Pattern pattern = Pattern.compile("JSESSIONID=([a-zA-Z0-9-]*)");
java.util.regex.Matcher matcher = pattern.matcher(postMethod.getResponseHeaders("Set-Cookie")[0].toString());
return matcher.find()? matcher.group(1) : StringUtils.EMPTY;
}
protected static boolean userAndPasswordAreNotBlank(String user, String pwd) {
if (StringUtils.isBlank(user) && StringUtils.isBlank(pwd)) {
return false;
}
return true;
}
protected Matcher<HttpMethodBase> responsesWith(final int expectedStatusCode) {
return new TypeSafeMatcher<HttpMethodBase>() {
WeakReference<HttpMethodBase> method;
@Override
public boolean matchesSafely(HttpMethodBase httpMethodBase) {
method = (method == null) ? new WeakReference<HttpMethodBase>(httpMethodBase) : method;
method = (method == null) ? new WeakReference<>(httpMethodBase) : method;
return httpMethodBase.getStatusCode() == expectedStatusCode;
}

View file

@ -0,0 +1,156 @@
/*
* 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 static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import java.io.IOException;
import java.util.Map;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.zeppelin.notebook.Note;
import org.apache.zeppelin.server.ZeppelinServer;
import org.hamcrest.Matcher;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class NotebookSecurityRestApiTest extends AbstractTestRestApi {
Gson gson = new Gson();
@BeforeClass
public static void init() throws Exception {
AbstractTestRestApi.startUpWithAuthenticationEnable();
}
@AfterClass
public static void destroy() throws Exception {
AbstractTestRestApi.shutDown();
}
@Before
public void setUp() {}
@Test
public void testThatUserCanCreateAndRemoveNote() throws IOException {
String noteId = createNoteForUser("test", "admin", "password1");
assertNotNull(noteId);
String id = getNoteIdForUser(noteId, "admin", "password1");
assertThat(id, is(noteId));
deleteNoteForUser(noteId, "admin", "password1");
}
@Test
public void testThatOtherUserCanAccessNoteIfPermissionNotSet() throws IOException {
String noteId = createNoteForUser("test", "admin", "password1");
userTryGetNote(noteId, "user1", "password2", isAllowed());
deleteNoteForUser(noteId, "admin", "password1");
}
@Test
public void testThatOtherUserCannotAccessNoteIfPermissionSet() throws IOException {
String noteId = createNoteForUser("test", "admin", "password1");
//set permission
String payload = "{ \"owners\": [\"admin\"], \"readers\": [\"user2\"], \"writers\": [\"user2\"] }";
PutMethod put = httpPut("/notebook/" + noteId + "/permissions", payload , "admin", "password1");
assertThat("test set note premission method:", put, isAllowed());
put.releaseConnection();
userTryGetNote(noteId, "user1", "password2", isForbiden());
userTryGetNote(noteId, "user2", "password3", isAllowed());
deleteNoteForUser(noteId, "admin", "password1");
}
@Test
public void testThatWriterCannotRemoveNote() throws IOException {
String noteId = createNoteForUser("test", "admin", "password1");
//set permission
String payload = "{ \"owners\": [\"admin\", \"user1\"], \"readers\": [\"user2\"], \"writers\": [\"user2\"] }";
PutMethod put = httpPut("/notebook/" + noteId + "/permissions", payload , "admin", "password1");
assertThat("test set note premission method:", put, isAllowed());
put.releaseConnection();
userTryRemoveNote(noteId, "user2", "password3", isForbiden());
userTryRemoveNote(noteId, "user1", "password2", isAllowed());
Note deletedNote = ZeppelinServer.notebook.getNote(noteId);
assertNull("Deleted note should be null", deletedNote);
}
private void userTryRemoveNote(String noteId, String user, String pwd, Matcher<? super HttpMethodBase> m) throws IOException {
DeleteMethod delete = httpDelete(("/notebook/" + noteId), user, pwd);
assertThat(delete, m);
delete.releaseConnection();
}
private void userTryGetNote(String noteId, String user, String pwd, Matcher<? super HttpMethodBase> m) throws IOException {
GetMethod get = httpGet("/notebook/" + noteId, user, pwd);
assertThat(get, m);
get.releaseConnection();
}
private String getNoteIdForUser(String noteId, String user, String pwd) throws IOException {
GetMethod get = httpGet("/notebook/" + noteId, user, pwd);
assertThat("test note create method:", get, isAllowed());
Map<String, Object> resp = gson.fromJson(get.getResponseBodyAsString(), new TypeToken<Map<String, Object>>() {
}.getType());
get.releaseConnection();
return (String) ((Map<String, Object>)resp.get("body")).get("id");
}
private String createNoteForUser(String noteName, String user, String pwd) throws IOException {
String jsonRequest = "{\"name\":\"" + noteName + "\"}";
PostMethod post = httpPost("/notebook/", jsonRequest, user, pwd);
assertThat("test note create method:", post, isCreated());
Map<String, Object> resp = gson.fromJson(post.getResponseBodyAsString(), new TypeToken<Map<String, Object>>() {
}.getType());
post.releaseConnection();
String newNoteId = (String) resp.get("body");
Note newNote = ZeppelinServer.notebook.getNote(newNoteId);
assertNotNull("Can not find new note by id", newNote);
return newNoteId;
}
private void deleteNoteForUser(String noteId, String user, String pwd) throws IOException {
DeleteMethod delete = httpDelete(("/notebook/" + noteId), user, pwd);
assertThat("Test delete method:", delete, isAllowed());
delete.releaseConnection();
// make sure note is deleted
if (!noteId.isEmpty()) {
Note deletedNote = ZeppelinServer.notebook.getNote(noteId);
assertNull("Deleted note should be null", deletedNote);
}
}
}

View file

@ -360,6 +360,48 @@ public class NotebookServerTest extends AbstractTestRestApi {
verify(otherConn).send(mdMsg1);
}
@Test
public void testCreateNoteWithDefaultInterpreterId() throws IOException {
// create two sockets and open it
NotebookSocket sock1 = createWebSocket();
NotebookSocket sock2 = createWebSocket();
assertEquals(sock1, sock1);
assertNotEquals(sock1, sock2);
notebookServer.onOpen(sock1);
notebookServer.onOpen(sock2);
String noteName = "Note with millis " + System.currentTimeMillis();
String defaultInterpreterId = "";
List<InterpreterSetting> settings = notebook.getInterpreterFactory().get();
if (settings.size() > 1) {
defaultInterpreterId = settings.get(1).getId();
}
// create note from sock1
notebookServer.onMessage(sock1, gson.toJson(
new Message(OP.NEW_NOTE)
.put("name", noteName)
.put("defaultInterpreterId", defaultInterpreterId)));
// expect the events are broadcasted properly
verify(sock1, times(2)).send(anyString());
Note createdNote = null;
for (Note note : notebook.getAllNotes()) {
if (note.getName().equals(noteName)) {
createdNote = note;
break;
}
}
if (settings.size() > 1) {
assertEquals(notebook.getInterpreterFactory().getDefaultInterpreterSetting(
createdNote.getId()).getId(), defaultInterpreterId);
}
notebook.removeNote(createdNote.getId(), anonymous);
}
private NotebookSocket createWebSocket() {
NotebookSocket sock = mock(NotebookSocket.class);
when(sock.getRequest()).thenReturn(mockRequest);

View file

@ -263,10 +263,10 @@ limitations under the License.
<th>description</th>
<th>action</th>
</tr>
<tr ng-repeat="(key, value) in newInterpreterSetting.properties">
<tr ng-repeat="key in newInterpreterSetting.properties | sortByKey">
<td>{{key}}</td>
<td><textarea msd-elastic ng-model="value.value"></textarea></td>
<td>{{value.description}}</td>
<td><textarea msd-elastic ng-model="newInterpreterSetting.properties[key].value"></textarea></td>
<td>{{newInterpreterSetting.properties[key].description}}</td>
<td>
<button class="btn btn-default btn-sm fa fa-remove" ng-click="removeInterpreterProperty(key)">
</button>

View file

@ -399,12 +399,11 @@
var intpInfo = el[i];
for (var key in intpInfo) {
properties[key] = {
value: intpInfo[key],
value: intpInfo[key].defaultValue,
description: intpInfo[key].description
};
}
}
$scope.newInterpreterSetting.properties = properties;
};

View file

@ -26,7 +26,17 @@ limitations under the License.
<div class="form-group">
<label for="noteName">Note Name</label> <input
placeholder="Note name" type="text" class="form-control"
id="noteName" ng-model="note.notename" ng-enter="notenamectrl.handleNameEnter()"/>
id="noteName" ng-model="note.notename" ng-enter="notenamectrl.handleNameEnter()"/><br/>
<div ng-show="!notenamectrl.clone">
<label for="defaultInterpreter">Default Interpreter </label>
<select ng-model="note.defaultInterpreter"
class="selectpicker"
name="defaultInterpreter"
id="defaultInterpreter"
ng-options="option.name for option in interpreterSettings">
<option value="">--Select--</option>
</select>
</div>
</div>
Use '/' to create folders. Example: /NoteDirA/Notebook1
</div>

View file

@ -29,10 +29,17 @@
vm.notes = noteListDataFactory;
vm.websocketMsgSrv = websocketMsgSrv;
$scope.note = {};
$scope.interpreterSettings = {};
$scope.note.defaultInterpreter = null;
vm.createNote = function() {
if (!vm.clone) {
vm.websocketMsgSrv.createNote($scope.note.notename);
var defaultInterpreterId = '';
if ($scope.note.defaultInterpreter !== null) {
defaultInterpreterId = $scope.note.defaultInterpreter.id;
}
vm.websocketMsgSrv.createNotebook($scope.note.notename, defaultInterpreterId);
$scope.note.defaultInterpreter = null;
} else {
var noteId = $routeParams.noteId;
vm.websocketMsgSrv.cloneNote(noteId, $scope.note.notename);
@ -90,6 +97,22 @@
}
return newCloneName + ' ' + copyCount;
};
vm.getInterpreterSettings = function() {
vm.websocketMsgSrv.getInterpreterSettings();
};
$scope.$on('interpreterSettings', function(event, data) {
$scope.interpreterSettings = data.interpreterSettings;
});
var init = function() {
if (!vm.clone) {
vm.getInterpreterSettings();
}
};
init();
}
})();

View file

@ -138,6 +138,8 @@
});
} else if (op === 'CONFIGURATIONS_INFO') {
$rootScope.$broadcast('configurationsInfo', data);
} else if (op === 'INTERPRETER_SETTINGS') {
$rootScope.$broadcast('interpreterSettings', data);
}
});

View file

@ -25,8 +25,14 @@
websocketEvents.sendNewEvent({op: 'GET_HOME_NOTE'});
},
createNote: function(noteName) {
websocketEvents.sendNewEvent({op: 'NEW_NOTE',data: {name: noteName}});
createNotebook: function(noteName, defaultInterpreterId) {
websocketEvents.sendNewEvent({
op: 'NEW_NOTE',
data: {
name: noteName,
defaultInterpreterId: defaultInterpreterId
}
});
},
deleteNote: function(noteId) {
@ -227,6 +233,10 @@
listConfigurations: function() {
websocketEvents.sendNewEvent({op: 'LIST_CONFIGURATIONS'});
},
getInterpreterSettings: function() {
websocketEvents.sendNewEvent({op: 'GET_INTERPRETER_SETTINGS'});
}
};

View file

@ -344,7 +344,7 @@ public class ZeppelinConfiguration extends XMLConfiguration {
public String getNotebookDir() {
return getString(ConfVars.ZEPPELIN_NOTEBOOK_DIR);
}
public String getUser() {
return getString(ConfVars.ZEPPELIN_NOTEBOOK_S3_USER);
}
@ -430,6 +430,10 @@ public class ZeppelinConfiguration extends XMLConfiguration {
public boolean isWindowsPath(String path){
return path.matches("^[A-Za-z]:\\\\.*");
}
public boolean isAnonymousAllowed() {
return getBoolean(ConfVars.ZEPPELIN_ANONYMOUS_ALLOWED);
}
public String getConfDir() {
return getString(ConfVars.ZEPPELIN_CONF_DIR);

View file

@ -42,7 +42,7 @@ import java.util.Map;
*/
public class Helium {
Logger logger = LoggerFactory.getLogger(Helium.class);
private List<HeliumRegistry> registry = new LinkedList<HeliumRegistry>();
private List<HeliumRegistry> registry = new LinkedList<>();
private final HeliumConf heliumConf;
private final String heliumConfPath;
@ -75,7 +75,7 @@ public class Helium {
public List<HeliumRegistry> getAllRegistry() {
synchronized (this.registry) {
List list = new LinkedList<HeliumRegistry>();
List list = new LinkedList<>();
for (HeliumRegistry r : registry) {
list.add(r);
}
@ -88,7 +88,7 @@ public class Helium {
if (!heliumConfFile.isFile()) {
logger.warn("{} does not exists", path);
HeliumConf conf = new HeliumConf();
LinkedList<HeliumRegistry> defaultRegistry = new LinkedList<HeliumRegistry>();
LinkedList<HeliumRegistry> defaultRegistry = new LinkedList<>();
defaultRegistry.add(new HeliumLocalRegistry("local", defaultLocalRegistryPath));
conf.setRegistry(defaultRegistry);
this.registry = conf.getRegistry();
@ -117,7 +117,7 @@ public class Helium {
}
public List<HeliumPackageSearchResult> getAllPackageInfo() {
List<HeliumPackageSearchResult> list = new LinkedList<HeliumPackageSearchResult>();
List<HeliumPackageSearchResult> list = new LinkedList<>();
synchronized (registry) {
for (HeliumRegistry r : registry) {
try {

View file

@ -23,7 +23,7 @@ import java.util.List;
* Helium config. This object will be persisted to conf/heliumc.conf
*/
public class HeliumConf {
List<HeliumRegistry> registry = new LinkedList<HeliumRegistry>();
List<HeliumRegistry> registry = new LinkedList<>();
public List<HeliumRegistry> getRegistry() {
return registry;

View file

@ -46,7 +46,7 @@ public class HeliumLocalRegistry extends HeliumRegistry {
@Override
public synchronized List<HeliumPackage> getAll() throws IOException {
List<HeliumPackage> result = new LinkedList<HeliumPackage>();
List<HeliumPackage> result = new LinkedList<>();
File file = new File(uri());
File [] files = file.listFiles();

View file

@ -25,8 +25,7 @@ import java.util.List;
* Suggested apps
*/
public class HeliumPackageSuggestion {
private final List<HeliumPackageSearchResult> available =
new LinkedList<HeliumPackageSearchResult>();
private final List<HeliumPackageSearchResult> available = new LinkedList<>();
/*
* possible future improvement

View file

@ -53,6 +53,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.internal.StringMap;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.ArrayUtils;
@ -237,8 +238,7 @@ public class InterpreterFactory implements InterpreterGroupFactory {
interpreterInfo =
new InterpreterInfo(r.getClassName(), r.getName(), r.isDefaultInterpreter(),
r.getEditor());
add(r.getGroup(), interpreterInfo, convertInterpreterProperties(r.getProperties()),
r.getPath());
add(r.getGroup(), interpreterInfo, r.getProperties(), r.getPath());
}
for (String settingId : interpreterSettingsRef.keySet()) {
@ -286,7 +286,8 @@ public class InterpreterFactory implements InterpreterGroupFactory {
private InterpreterSetting createFromInterpreterSettingRef(InterpreterSetting o) {
InterpreterSetting setting =
new InterpreterSetting(o.getName(), o.getName(), o.getInterpreterInfos(), o.getProperties(),
new InterpreterSetting(o.getName(), o.getName(), o.getInterpreterInfos(),
convertInterpreterProperties((Map<String, InterpreterProperty>) o.getProperties()),
o.getDependencies(), o.getOption(), o.getPath());
setting.setInterpreterGroupFactory(this);
return setting;
@ -349,16 +350,9 @@ public class InterpreterFactory implements InterpreterGroupFactory {
InterpreterInfo interpreterInfo =
new InterpreterInfo(registeredInterpreter.getClassName(), registeredInterpreter.getName(),
registeredInterpreter.isDefaultInterpreter(), registeredInterpreter.getEditor());
Properties properties = new Properties();
Map<String, InterpreterProperty> p = registeredInterpreter.getProperties();
if (null != p) {
for (String key : p.keySet()) {
properties.setProperty(key, p.get(key).getValue());
}
}
add(registeredInterpreter.getGroup(), interpreterInfo, properties, absolutePath);
add(registeredInterpreter.getGroup(), interpreterInfo, registeredInterpreter.getProperties(),
absolutePath);
}
}
@ -389,6 +383,14 @@ public class InterpreterFactory implements InterpreterGroupFactory {
InterpreterSetting setting = infoSaving.interpreterSettings.get(k);
List<InterpreterInfo> infos = setting.getInterpreterInfos();
// Convert json StringMap to Properties
StringMap<String> p = (StringMap<String>) setting.getProperties();
Properties properties = new Properties();
for (String key : p.keySet()) {
properties.put(key, p.get(key));
}
setting.setProperties(properties);
// Always use separate interpreter process
// While we decided to turn this feature on always (without providing
// enable/disable option on GUI).
@ -615,11 +617,12 @@ public class InterpreterFactory implements InterpreterGroupFactory {
}
private InterpreterSetting add(String group, InterpreterInfo interpreterInfo,
Properties properties, String path)
Map<String, InterpreterProperty> interpreterProperties, String path)
throws InterpreterException, IOException, RepositoryException {
ArrayList<InterpreterInfo> infos = new ArrayList<>();
infos.add(interpreterInfo);
return add(group, infos, new ArrayList<Dependency>(), defaultOption, properties, path);
return add(group, infos, new ArrayList<Dependency>(), defaultOption,
interpreterProperties, path);
}
/**
@ -627,12 +630,13 @@ public class InterpreterFactory implements InterpreterGroupFactory {
* @return
*/
public InterpreterSetting add(String group, ArrayList<InterpreterInfo> interpreterInfos,
List<Dependency> dependencies, InterpreterOption option, Properties properties, String path) {
List<Dependency> dependencies, InterpreterOption option,
Map<String, InterpreterProperty> interpreterProperties, String path) {
Preconditions.checkNotNull(group, "name should not be null");
Preconditions.checkNotNull(interpreterInfos, "interpreterInfos should not be null");
Preconditions.checkNotNull(dependencies, "dependencies should not be null");
Preconditions.checkNotNull(option, "option should not be null");
Preconditions.checkNotNull(properties, "properties should not be null");
Preconditions.checkNotNull(interpreterProperties, "properties should not be null");
InterpreterSetting interpreterSetting;
@ -663,17 +667,18 @@ public class InterpreterFactory implements InterpreterGroupFactory {
}
// Append properties
Properties interpreterProperties = interpreterSetting.getProperties();
for (String key : properties.stringPropertyNames()) {
if (!interpreterProperties.containsKey(key)) {
interpreterProperties.setProperty(key, properties.getProperty(key));
Map<String, InterpreterProperty> properties =
(Map<String, InterpreterProperty>) interpreterSetting.getProperties();
for (String key : interpreterProperties.keySet()) {
if (!properties.containsKey(key)) {
properties.put(key, interpreterProperties.get(key));
}
}
} else {
interpreterSetting =
new InterpreterSetting(group, null, interpreterInfos, properties, dependencies, option,
path);
new InterpreterSetting(group, null, interpreterInfos, interpreterProperties,
dependencies, option, path);
interpreterSettingsRef.put(group, interpreterSetting);
}
}
@ -734,7 +739,7 @@ public class InterpreterFactory implements InterpreterGroupFactory {
String noteId, String key) {
InterpreterGroup interpreterGroup = interpreterSetting.getInterpreterGroup(user, noteId);
InterpreterOption option = interpreterSetting.getOption();
Properties properties = interpreterSetting.getProperties();
Properties properties = (Properties) interpreterSetting.getProperties();
if (option.isExistingProcess) {
properties.put(Constants.ZEPPELIN_INTERPRETER_HOST, option.getHost());
properties.put(Constants.ZEPPELIN_INTERPRETER_PORT, option.getPort());
@ -932,16 +937,16 @@ public class InterpreterFactory implements InterpreterGroupFactory {
public void setPropertyAndRestart(String id, InterpreterOption option, Properties properties,
List<Dependency> dependencies) throws IOException {
synchronized (interpreterSettings) {
InterpreterSetting intpsetting = interpreterSettings.get(id);
if (intpsetting != null) {
InterpreterSetting intpSetting = interpreterSettings.get(id);
if (intpSetting != null) {
try {
stopJobAllInterpreter(intpsetting);
stopJobAllInterpreter(intpSetting);
intpsetting.closeAndRmoveAllInterpreterGroups();
intpsetting.setOption(option);
intpsetting.setProperties(properties);
intpsetting.setDependencies(dependencies);
loadInterpreterDependencies(intpsetting);
intpSetting.closeAndRmoveAllInterpreterGroups();
intpSetting.setOption(option);
intpSetting.setProperties(properties);
intpSetting.setDependencies(dependencies);
loadInterpreterDependencies(intpSetting);
saveToFile();
} catch (Exception e) {
@ -960,12 +965,11 @@ public class InterpreterFactory implements InterpreterGroupFactory {
}
public void restart(String settingId, String noteId) {
InterpreterSetting intpsetting = interpreterSettings.get(settingId);
Preconditions.checkNotNull(intpsetting);
InterpreterSetting intpSetting = interpreterSettings.get(settingId);
Preconditions.checkNotNull(intpSetting);
if (noteIdIsExist(noteId) &&
intpsetting.getOption().isProcess()) {
intpsetting.closeAndRemoveInterpreterGroup(noteId);
if (noteIdIsExist(noteId) && intpSetting.getOption().isProcess()) {
intpSetting.closeAndRemoveInterpreterGroup(noteId);
return;
}
restart(settingId);
@ -973,15 +977,15 @@ public class InterpreterFactory implements InterpreterGroupFactory {
public void restart(String id) {
synchronized (interpreterSettings) {
InterpreterSetting intpsetting = interpreterSettings.get(id);
InterpreterSetting intpSetting = interpreterSettings.get(id);
// Check if dependency in specified path is changed
// If it did, overwrite old dependency jar with new one
if (intpsetting != null) {
copyDependenciesFromLocalPath(intpsetting);
if (intpSetting != null) {
copyDependenciesFromLocalPath(intpSetting);
stopJobAllInterpreter(intpsetting);
stopJobAllInterpreter(intpSetting);
intpsetting.closeAndRmoveAllInterpreterGroups();
intpSetting.closeAndRmoveAllInterpreterGroups();
} else {
throw new InterpreterException("Interpreter setting id " + id + " not found");
@ -989,9 +993,9 @@ public class InterpreterFactory implements InterpreterGroupFactory {
}
}
private void stopJobAllInterpreter(InterpreterSetting intpsetting) {
if (intpsetting != null) {
for (InterpreterGroup intpGroup : intpsetting.getAllInterpreterGroups()) {
private void stopJobAllInterpreter(InterpreterSetting intpSetting) {
if (intpSetting != null) {
for (InterpreterGroup intpGroup : intpSetting.getAllInterpreterGroups()) {
for (List<Interpreter> interpreters : intpGroup.values()) {
for (Interpreter intp : interpreters) {
for (Job job : intp.getScheduler().getJobsRunning()) {
@ -1013,11 +1017,11 @@ public class InterpreterFactory implements InterpreterGroupFactory {
public void close() {
List<Thread> closeThreads = new LinkedList<>();
synchronized (interpreterSettings) {
Collection<InterpreterSetting> intpsettings = interpreterSettings.values();
for (final InterpreterSetting intpsetting : intpsettings) {
Collection<InterpreterSetting> intpSettings = interpreterSettings.values();
for (final InterpreterSetting intpSetting : intpSettings) {
Thread t = new Thread() {
public void run() {
intpsetting.closeAndRmoveAllInterpreterGroups();
intpSetting.closeAndRmoveAllInterpreterGroups();
}
};
t.start();

View file

@ -42,8 +42,19 @@ public class InterpreterSetting {
private static final String SHARED_PROCESS = "shared_process";
private String id;
private String name;
private String group; // always be null in case of InterpreterSettingRef
private Properties properties;
// always be null in case of InterpreterSettingRef
private String group;
/**
* properties can be either Properties or Map<String, InterpreterProperty>
* properties should be:
* - Properties when Interpreter instances are saved to `conf/interpreter.json` file
* - Map<String, InterpreterProperty> when Interpreters are registered
* : this is needed after https://github.com/apache/zeppelin/pull/1145
* which changed the way of getting default interpreter setting AKA interpreterSettingsRef
* Note(mina): In order to simplify the implementation, I chose to change properties
* from Properties to Object instead of creating new classes.
*/
private Object properties;
private Status status;
private String errorReason;
@ -65,7 +76,7 @@ public class InterpreterSetting {
}
public InterpreterSetting(String id, String name, String group,
List<InterpreterInfo> interpreterInfos, Properties properties, List<Dependency> dependencies,
List<InterpreterInfo> interpreterInfos, Object properties, List<Dependency> dependencies,
InterpreterOption option, String path) {
this();
this.id = id;
@ -80,7 +91,7 @@ public class InterpreterSetting {
}
public InterpreterSetting(String name, String group, List<InterpreterInfo> interpreterInfos,
Properties properties, List<Dependency> dependencies, InterpreterOption option, String path) {
Object properties, List<Dependency> dependencies, InterpreterOption option, String path) {
this(generateId(), name, group, interpreterInfos, properties, dependencies, option, path);
}
@ -174,7 +185,7 @@ public class InterpreterSetting {
}
}
public Properties getProperties() {
public Object getProperties() {
return properties;
}
@ -229,11 +240,7 @@ public class InterpreterSetting {
this.option = interpreterOption;
}
void updateProperties(Properties p) {
this.properties.putAll(p);
}
void setProperties(Properties p) {
public void setProperties(Properties p) {
this.properties = p;
}

View file

@ -56,7 +56,7 @@ public class InstallInterpreter {
this.interpreterListFile = interpreterListFile;
this.interpreterBaseDir = interpreterBaseDir;
this.localRepoDir = localRepoDir;
availableInterpreters = new LinkedList<AvailableInterpreterInfo>();
availableInterpreters = new LinkedList<>();
readAvailableInterpreters();
}

View file

@ -26,7 +26,7 @@ import java.util.Map;
public class NoteInfo {
String id;
String name;
private Map<String, Object> config = new HashMap<String, Object>();
private Map<String, Object> config = new HashMap<>();
public NoteInfo(String id, String name, Map<String, Object> config) {
super();

View file

@ -166,7 +166,7 @@ public class Notebook implements NoteEventListener {
}
if (subject != null && !"anonymous".equals(subject.getUser())) {
Set<String> owners = new HashSet<String>();
Set<String> owners = new HashSet<>();
owners.add(subject.getUser());
notebookAuthorization.setOwners(note.getId(), owners);
}

View file

@ -17,18 +17,31 @@
package org.apache.zeppelin.notebook;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.zeppelin.conf.ZeppelinConfiguration;
import org.apache.zeppelin.user.AuthenticationInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.*;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
/**
* Contains authorization information for notes
@ -180,11 +193,11 @@ public class NotebookAuthorization {
Map<String, Set<String>> noteAuthInfo = authInfo.get(noteId);
Set<String> entities = null;
if (noteAuthInfo == null) {
entities = new HashSet<String>();
entities = new HashSet<>();
} else {
entities = noteAuthInfo.get("owners");
if (entities == null) {
entities = new HashSet<String>();
entities = new HashSet<>();
}
}
return entities;
@ -194,11 +207,11 @@ public class NotebookAuthorization {
Map<String, Set<String>> noteAuthInfo = authInfo.get(noteId);
Set<String> entities = null;
if (noteAuthInfo == null) {
entities = new HashSet<String>();
entities = new HashSet<>();
} else {
entities = noteAuthInfo.get("readers");
if (entities == null) {
entities = new HashSet<String>();
entities = new HashSet<>();
}
}
return entities;
@ -208,11 +221,11 @@ public class NotebookAuthorization {
Map<String, Set<String>> noteAuthInfo = authInfo.get(noteId);
Set<String> entities = null;
if (noteAuthInfo == null) {
entities = new HashSet<String>();
entities = new HashSet<>();
} else {
entities = noteAuthInfo.get("writers");
if (entities == null) {
entities = new HashSet<String>();
entities = new HashSet<>();
}
}
return entities;
@ -234,11 +247,44 @@ public class NotebookAuthorization {
// return true if b is empty or if (a intersection b) is non-empty
private boolean isMember(Set<String> a, Set<String> b) {
Set<String> intersection = new HashSet<String>(b);
Set<String> intersection = new HashSet<>(b);
intersection.retainAll(a);
return (b.isEmpty() || (intersection.size() > 0));
}
public boolean isOwner(Set<String> userAndRoles, String noteId) {
if (conf.isAnonymousAllowed()) {
LOG.debug("Zeppelin runs in anonymous mode, everybody is owner");
return true;
}
if (userAndRoles == null) {
return false;
}
return isOwner(noteId, userAndRoles);
}
public boolean hasWriteAuthorization(Set<String> userAndRoles, String noteId) {
if (conf.isAnonymousAllowed()) {
LOG.debug("Zeppelin runs in anonymous mode, everybody is writer");
return true;
}
if (userAndRoles == null) {
return false;
}
return isWriter(noteId, userAndRoles);
}
public boolean hasReadAuthorization(Set<String> userAndRoles, String noteId) {
if (conf.isAnonymousAllowed()) {
LOG.debug("Zeppelin runs in anonymous mode, everybody is reader");
return true;
}
if (userAndRoles == null) {
return false;
}
return isReader(noteId, userAndRoles);
}
public void removeNote(String noteId) {
authInfo.remove(noteId);
saveToFile();

View file

@ -65,7 +65,7 @@ public class Paragraph extends Job implements Serializable, Cloneable {
/**
* Applicaiton states in this paragraph
*/
private final List<ApplicationState> apps = new LinkedList<ApplicationState>();
private final List<ApplicationState> apps = new LinkedList<>();
@VisibleForTesting
Paragraph() {
@ -85,7 +85,7 @@ public class Paragraph extends Job implements Serializable, Cloneable {
user = null;
dateUpdated = null;
settings = new GUI();
config = new HashMap<String, Object>();
config = new HashMap<>();
}
public Paragraph(Note note, JobListener listener, InterpreterFactory factory) {
@ -97,7 +97,7 @@ public class Paragraph extends Job implements Serializable, Cloneable {
authenticationInfo = null;
dateUpdated = null;
settings = new GUI();
config = new HashMap<String, Object>();
config = new HashMap<>();
}
private static String generateId() {
@ -453,7 +453,7 @@ public class Paragraph extends Job implements Serializable, Cloneable {
resourcePool = intpGroup.getInterpreterGroup(getUser(), note.getId()).getResourcePool();
}
List<InterpreterContextRunner> runners = new LinkedList<InterpreterContextRunner>();
List<InterpreterContextRunner> runners = new LinkedList<>();
for (Paragraph p : note.getParagraphs()) {
runners.add(new ParagraphRunner(note, note.getId(), p.getId()));
}
@ -549,7 +549,7 @@ public class Paragraph extends Job implements Serializable, Cloneable {
public List<ApplicationState> getAllApplicationStates() {
synchronized (apps) {
return new LinkedList<ApplicationState>(apps);
return new LinkedList<>(apps);
}
}

View file

@ -86,7 +86,7 @@ public class AzureNotebookRepo implements NotebookRepo {
@Override
public List<NoteInfo> list(AuthenticationInfo subject) throws IOException {
List<NoteInfo> infos = new LinkedList<NoteInfo>();
List<NoteInfo> infos = new LinkedList<>();
NoteInfo info = null;
for (ListFileItem item : rootDir.listFilesAndDirectories()) {

View file

@ -53,7 +53,7 @@ public class NotebookRepoSync implements NotebookRepo {
private static ZeppelinConfiguration config;
private static final String defaultStorage = "org.apache.zeppelin.notebook.repo.VFSNotebookRepo";
private List<NotebookRepo> repos = new ArrayList<NotebookRepo>();
private List<NotebookRepo> repos = new ArrayList<>();
private final boolean oneWaySync;
/**
@ -324,9 +324,9 @@ public class NotebookRepoSync implements NotebookRepo {
NotebookRepo sourceRepo, List<NoteInfo> destNotes, NotebookRepo destRepo,
AuthenticationInfo subject)
throws IOException {
List <String> pushIDs = new ArrayList<String>();
List <String> pullIDs = new ArrayList<String>();
List <String> delDstIDs = new ArrayList<String>();
List <String> pushIDs = new ArrayList<>();
List <String> pullIDs = new ArrayList<>();
List <String> delDstIDs = new ArrayList<>();
NoteInfo dnote;
Date sdate, ddate;
@ -373,7 +373,7 @@ public class NotebookRepoSync implements NotebookRepo {
}
}
Map<String, List<String>> map = new HashMap<String, List<String>>();
Map<String, List<String>> map = new HashMap<>();
map.put(pushKey, pushIDs);
map.put(pullKey, pullIDs);
map.put(delDstKey, delDstIDs);
@ -430,7 +430,7 @@ public class NotebookRepoSync implements NotebookRepo {
int repoBound = Math.min(repoCount, getMaxRepoNum());
int errorCount = 0;
String errorMessage = "";
List<Revision> allRepoCheckpoints = new ArrayList<Revision>();
List<Revision> allRepoCheckpoints = new ArrayList<>();
Revision rev = null;
for (int i = 0; i < repoBound; i++) {
try {

View file

@ -127,7 +127,7 @@ public class VFSNotebookRepo implements NotebookRepo {
FileObject[] children = rootDir.getChildren();
List<NoteInfo> infos = new LinkedList<NoteInfo>();
List<NoteInfo> infos = new LinkedList<>();
for (FileObject f : children) {
String fileName = f.getName().getBaseName();
if (f.isHidden()

View file

@ -185,7 +185,7 @@ public class ZeppelinClient {
private Message zeppelinGetNoteMsg(String noteId) {
Message getNoteMsg = new Message(Message.OP.GET_NOTE);
HashMap<String, Object> data = new HashMap<String, Object>();
HashMap<String, Object> data = new HashMap<>();
data.put("id", noteId);
getNoteMsg.data = data;
return getNoteMsg;
@ -227,7 +227,7 @@ public class ZeppelinClient {
}
public void handleMsgFromZeppelin(String message, String noteId) {
Map<String, String> meta = new HashMap<String, String>();
Map<String, String> meta = new HashMap<>();
meta.put("token", zeppelinhubToken);
meta.put("noteId", noteId);
Message zeppelinMsg = deserialize(message);

Some files were not shown because too many files have changed in this diff Show more