mirror of
https://github.com/apache/zeppelin
synced 2026-05-24 09:38:26 +00:00
Enable adding interpreter dependency via GUI
This commit is contained in:
parent
d5c931b919
commit
fe9cb92f57
21 changed files with 455 additions and 158 deletions
|
|
@ -165,7 +165,7 @@ public class SparkDependencyContext {
|
|||
collectRequest.addRepository(repo);
|
||||
}
|
||||
for (Repository repo : repositories) {
|
||||
RemoteRepository rr = new RemoteRepository(repo.getName(), "default", repo.getUrl());
|
||||
RemoteRepository rr = new RemoteRepository(repo.getId(), "default", repo.getUrl());
|
||||
rr.setPolicy(repo.isSnapshot(), null);
|
||||
Authentication auth = repo.getAuthentication();
|
||||
if (auth != null) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import java.util.List;
|
|||
|
||||
import org.sonatype.aether.RepositorySystem;
|
||||
import org.sonatype.aether.RepositorySystemSession;
|
||||
import org.sonatype.aether.repository.Authentication;
|
||||
import org.sonatype.aether.repository.RemoteRepository;
|
||||
import org.sonatype.aether.resolution.ArtifactResult;
|
||||
|
||||
|
|
@ -51,6 +52,16 @@ public abstract class AbstractDependencyResolver {
|
|||
}
|
||||
}
|
||||
|
||||
public void addRepo(String id, String url, boolean snapshot, Authentication auth) {
|
||||
synchronized (repos) {
|
||||
delRepo(id);
|
||||
RemoteRepository rr = new RemoteRepository(id, "default", url);
|
||||
rr.setPolicy(snapshot, null);
|
||||
rr.setAuthentication(auth);
|
||||
repos.add(rr);
|
||||
}
|
||||
}
|
||||
|
||||
public RemoteRepository delRepo(String id) {
|
||||
synchronized (repos) {
|
||||
Iterator<RemoteRepository> it = repos.iterator();
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ public class DependencyContext {
|
|||
collectRequest.addRepository(mavenCentral);
|
||||
collectRequest.addRepository(mavenLocal);
|
||||
for (Repository repo : repositories) {
|
||||
RemoteRepository rr = new RemoteRepository(repo.getName(), "default", repo.getUrl());
|
||||
RemoteRepository rr = new RemoteRepository(repo.getId(), "default", repo.getUrl());
|
||||
rr.setPolicy(repo.isSnapshot(), null);
|
||||
collectRequest.addRepository(rr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
package org.apache.zeppelin.dep;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
|
@ -28,6 +29,7 @@ import org.apache.commons.io.FileUtils;
|
|||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.sonatype.aether.RepositoryException;
|
||||
import org.sonatype.aether.artifact.Artifact;
|
||||
import org.sonatype.aether.collection.CollectRequest;
|
||||
import org.sonatype.aether.graph.Dependency;
|
||||
|
|
@ -56,16 +58,18 @@ public class DependencyResolver extends AbstractDependencyResolver {
|
|||
super(localRepoPath);
|
||||
}
|
||||
|
||||
public List<File> load(String artifact) throws Exception {
|
||||
public List<File> load(String artifact)
|
||||
throws RepositoryException, IOException {
|
||||
return load(artifact, new LinkedList<String>());
|
||||
}
|
||||
|
||||
public List<File> load(String artifact, String destPath) throws Exception {
|
||||
public List<File> load(String artifact, String destPath)
|
||||
throws RepositoryException, IOException {
|
||||
return load(artifact, new LinkedList<String>(), destPath);
|
||||
}
|
||||
|
||||
public synchronized List<File> load(String artifact, Collection<String> excludes)
|
||||
throws Exception {
|
||||
throws RepositoryException, IOException {
|
||||
if (StringUtils.isBlank(artifact)) {
|
||||
// Should throw here
|
||||
throw new RuntimeException("Invalid artifact to load");
|
||||
|
|
@ -83,7 +87,7 @@ public class DependencyResolver extends AbstractDependencyResolver {
|
|||
}
|
||||
|
||||
public List<File> load(String artifact, Collection<String> excludes, String destPath)
|
||||
throws Exception {
|
||||
throws RepositoryException, IOException {
|
||||
List<File> libs = load(artifact, excludes);
|
||||
|
||||
// find home dir
|
||||
|
|
@ -105,7 +109,8 @@ public class DependencyResolver extends AbstractDependencyResolver {
|
|||
return libs;
|
||||
}
|
||||
|
||||
private List<File> loadFromMvn(String artifact, Collection<String> excludes) throws Exception {
|
||||
private List<File> loadFromMvn(String artifact, Collection<String> excludes)
|
||||
throws RepositoryException {
|
||||
Collection<String> allExclusions = new LinkedList<String>();
|
||||
allExclusions.addAll(excludes);
|
||||
allExclusions.addAll(Arrays.asList(exclusions));
|
||||
|
|
@ -142,7 +147,7 @@ public class DependencyResolver extends AbstractDependencyResolver {
|
|||
*/
|
||||
@Override
|
||||
public List<ArtifactResult> getArtifactsWithDep(String dependency,
|
||||
Collection<String> excludes) throws Exception {
|
||||
Collection<String> excludes) throws RepositoryException {
|
||||
Artifact artifact = new DefaultArtifact(dependency);
|
||||
DependencyFilter classpathFilter = DependencyFilterUtils.classpathFilter(JavaScopes.COMPILE);
|
||||
PatternExclusionsDependencyFilter exclusionFilter =
|
||||
|
|
|
|||
|
|
@ -23,13 +23,13 @@ import org.sonatype.aether.repository.Authentication;
|
|||
*/
|
||||
public class Repository {
|
||||
private boolean snapshot = false;
|
||||
private String name;
|
||||
private String id;
|
||||
private String url;
|
||||
private String username = null;
|
||||
private String password = null;
|
||||
|
||||
public Repository(String name){
|
||||
this.name = name;
|
||||
public Repository(String id){
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Repository url(String url) {
|
||||
|
|
@ -46,8 +46,8 @@ public class Repository {
|
|||
return snapshot;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
|
|
|
|||
|
|
@ -127,10 +127,6 @@ public abstract class Interpreter {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static Logger logger = LoggerFactory.getLogger(Interpreter.class);
|
||||
private InterpreterGroup interpreterGroup;
|
||||
private URL [] classloaderUrls;
|
||||
|
|
|
|||
|
|
@ -30,9 +30,7 @@ import org.apache.zeppelin.interpreter.InterpreterContextRunner;
|
|||
import org.apache.zeppelin.interpreter.InterpreterException;
|
||||
import org.apache.zeppelin.interpreter.InterpreterGroup;
|
||||
import org.apache.zeppelin.interpreter.InterpreterResult;
|
||||
import org.apache.zeppelin.interpreter.InterpreterResult.Code;
|
||||
import org.apache.zeppelin.interpreter.InterpreterResult.Type;
|
||||
import org.apache.zeppelin.interpreter.WrappedInterpreter;
|
||||
import org.apache.zeppelin.interpreter.thrift.RemoteInterpreterContext;
|
||||
import org.apache.zeppelin.interpreter.thrift.RemoteInterpreterResult;
|
||||
import org.apache.zeppelin.interpreter.thrift.RemoteInterpreterService.Client;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.sonatype.aether.RepositoryException;
|
||||
|
||||
/**
|
||||
* Interpreter Rest API
|
||||
|
|
@ -85,17 +86,40 @@ public class InterpreterRestApi {
|
|||
*/
|
||||
@POST
|
||||
@Path("setting")
|
||||
public Response newSettings(String message) throws InterpreterException, IOException {
|
||||
NewInterpreterSettingRequest request = gson.fromJson(message,
|
||||
NewInterpreterSettingRequest.class);
|
||||
Properties p = new Properties();
|
||||
p.putAll(request.getProperties());
|
||||
// Option is deprecated from API, always use remote = true
|
||||
InterpreterGroup interpreterGroup = interpreterFactory.add(request.getName(),
|
||||
request.getGroup(), new InterpreterOption(true), p);
|
||||
InterpreterSetting setting = interpreterFactory.get(interpreterGroup.getId());
|
||||
logger.info("new setting created with " + setting.id());
|
||||
return new JsonResponse(Status.CREATED, "", setting ).build();
|
||||
public Response newSettings(String message) {
|
||||
try {
|
||||
NewInterpreterSettingRequest request = gson.fromJson(message,
|
||||
NewInterpreterSettingRequest.class);
|
||||
Properties p = new Properties();
|
||||
p.putAll(request.getProperties());
|
||||
// Option is deprecated from API, always use remote = true
|
||||
InterpreterGroup interpreterGroup = interpreterFactory.add(request.getName(),
|
||||
request.getGroup(),
|
||||
request.getDependencies(),
|
||||
new InterpreterOption(true),
|
||||
p);
|
||||
InterpreterSetting setting = interpreterFactory.get(interpreterGroup.getId());
|
||||
logger.info("new setting created with " + setting.id());
|
||||
return new JsonResponse(Status.CREATED, "", setting).build();
|
||||
} catch (InterpreterException e) {
|
||||
logger.error("Exception in InterpreterRestApi while creating ", e);
|
||||
return new JsonResponse(
|
||||
Status.NOT_FOUND,
|
||||
e.getMessage(),
|
||||
ExceptionUtils.getStackTrace(e)).build();
|
||||
} catch (IOException e) {
|
||||
logger.error("Exception in InterpreterRestApi while creating ", e);
|
||||
return new JsonResponse(
|
||||
Status.INTERNAL_SERVER_ERROR,
|
||||
e.getMessage(),
|
||||
ExceptionUtils.getStackTrace(e)).build();
|
||||
} catch (RepositoryException e) {
|
||||
logger.error("Exception in InterpreterRestApi while creating ", e);
|
||||
return new JsonResponse(
|
||||
Status.INTERNAL_SERVER_ERROR,
|
||||
e.getMessage(),
|
||||
ExceptionUtils.getStackTrace(e)).build();
|
||||
}
|
||||
}
|
||||
|
||||
@PUT
|
||||
|
|
@ -104,11 +128,13 @@ public class InterpreterRestApi {
|
|||
logger.info("Update interpreterSetting {}", settingId);
|
||||
|
||||
try {
|
||||
UpdateInterpreterSettingRequest p = gson.fromJson(message,
|
||||
UpdateInterpreterSettingRequest request = gson.fromJson(message,
|
||||
UpdateInterpreterSettingRequest.class);
|
||||
// Option is deprecated from API, always use remote = true
|
||||
interpreterFactory.setPropertyAndRestart(settingId,
|
||||
new InterpreterOption(true), p.getProperties());
|
||||
new InterpreterOption(true),
|
||||
request.getProperties(),
|
||||
request.getDependencies());
|
||||
} catch (InterpreterException e) {
|
||||
logger.error("Exception in InterpreterRestApi while updateSetting ", e);
|
||||
return new JsonResponse(
|
||||
|
|
@ -117,6 +143,10 @@ public class InterpreterRestApi {
|
|||
logger.error("Exception in InterpreterRestApi while updateSetting ", e);
|
||||
return new JsonResponse(
|
||||
Status.INTERNAL_SERVER_ERROR, e.getMessage(), ExceptionUtils.getStackTrace(e)).build();
|
||||
} catch (RepositoryException e) {
|
||||
logger.error("Exception in InterpreterRestApi while updateSetting ", e);
|
||||
return new JsonResponse(
|
||||
Status.INTERNAL_SERVER_ERROR, e.getMessage(), ExceptionUtils.getStackTrace(e)).build();
|
||||
}
|
||||
InterpreterSetting setting = interpreterFactory.get(settingId);
|
||||
if (setting == null) {
|
||||
|
|
|
|||
|
|
@ -17,9 +17,10 @@
|
|||
|
||||
package org.apache.zeppelin.rest.message;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.zeppelin.interpreter.InterpreterOption;
|
||||
import org.apache.zeppelin.dep.Dependency;
|
||||
|
||||
/**
|
||||
* NewInterpreterSetting rest api request message
|
||||
|
|
@ -30,6 +31,7 @@ public class NewInterpreterSettingRequest {
|
|||
String group;
|
||||
// option was deprecated
|
||||
Map<String, String> properties;
|
||||
List<Dependency> dependencies;
|
||||
|
||||
public NewInterpreterSettingRequest() {
|
||||
|
||||
|
|
@ -47,4 +49,7 @@ public class NewInterpreterSettingRequest {
|
|||
return properties;
|
||||
}
|
||||
|
||||
public List<Dependency> getDependencies() {
|
||||
return dependencies;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,27 +17,30 @@
|
|||
|
||||
package org.apache.zeppelin.rest.message;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.zeppelin.interpreter.InterpreterOption;
|
||||
import org.apache.zeppelin.dep.Dependency;
|
||||
|
||||
/**
|
||||
*
|
||||
* UpdateInterpreterSetting rest api request message
|
||||
*/
|
||||
public class UpdateInterpreterSettingRequest {
|
||||
|
||||
// option was deprecated
|
||||
Properties properties;
|
||||
List<Dependency> dependencies;
|
||||
|
||||
public UpdateInterpreterSettingRequest(InterpreterOption option,
|
||||
Properties properties) {
|
||||
super();
|
||||
public UpdateInterpreterSettingRequest(Properties properties,
|
||||
List<Dependency> dependencies) {
|
||||
this.properties = properties;
|
||||
this.dependencies = dependencies;
|
||||
}
|
||||
|
||||
public Properties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
||||
public List<Dependency> getDependencies() {
|
||||
return dependencies;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import java.io.IOException;
|
|||
import java.lang.ref.WeakReference;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
|
@ -35,6 +36,7 @@ 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.zeppelin.dep.Dependency;
|
||||
import org.apache.zeppelin.interpreter.InterpreterGroup;
|
||||
import org.apache.zeppelin.interpreter.InterpreterOption;
|
||||
import org.apache.zeppelin.interpreter.InterpreterSetting;
|
||||
|
|
@ -48,6 +50,7 @@ import org.slf4j.LoggerFactory;
|
|||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.sonatype.aether.RepositoryException;
|
||||
|
||||
public abstract class AbstractTestRestApi {
|
||||
|
||||
|
|
@ -363,10 +366,14 @@ public abstract class AbstractTestRestApi {
|
|||
}
|
||||
|
||||
//Create new Setting and return Setting ID
|
||||
protected String createTempSetting(String tempName) throws IOException {
|
||||
|
||||
InterpreterGroup interpreterGroup = ZeppelinServer.notebook.getInterpreterFactory().add(tempName,"newGroup",
|
||||
new InterpreterOption(false),new Properties());
|
||||
protected String createTempSetting(String tempName)
|
||||
throws IOException, RepositoryException {
|
||||
InterpreterGroup interpreterGroup = ZeppelinServer.notebook.getInterpreterFactory()
|
||||
.add(tempName,
|
||||
"newGroup",
|
||||
new LinkedList<Dependency>(),
|
||||
new InterpreterOption(false),
|
||||
new Properties());
|
||||
return interpreterGroup.getId();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,8 @@
|
|||
ngToastProvider.configure({
|
||||
dismissButton: true,
|
||||
dismissOnClick: false,
|
||||
timeout: 6000
|
||||
timeout: 6000,
|
||||
verticalPosition: 'bottom'
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -275,31 +275,6 @@ kbd {
|
|||
border-radius: 2px;
|
||||
}
|
||||
|
||||
/*
|
||||
ngToast Style
|
||||
*/
|
||||
|
||||
.ng-toast .alert {
|
||||
color: white !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.ng-toast .alert-danger {
|
||||
background: #A94442 !important;
|
||||
}
|
||||
|
||||
.ng-toast .alert-warning {
|
||||
background: #CE9532 !important;
|
||||
}
|
||||
|
||||
.ng-toast .alert-info {
|
||||
background: #589EC1 !important;
|
||||
}
|
||||
|
||||
.ng-toast .alert-success {
|
||||
background: #428443 !important;
|
||||
}
|
||||
|
||||
/*
|
||||
temporary fix for bootstrap issue (https://github.com/twbs/bootstrap/issues/5865)
|
||||
This part should be removed when new version of bootstrap handles this issue.
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
-->
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="row interpreter">
|
||||
<div class="col-md-12">
|
||||
<div class="interpreterSettingAdd" ng-show="showAddNewSetting">
|
||||
<hr />
|
||||
|
|
@ -67,6 +67,50 @@ limitations under the License.
|
|||
</tr>
|
||||
</table>
|
||||
|
||||
<b>Dependencies</b>
|
||||
<table class="table table-striped properties">
|
||||
<tr>
|
||||
<th>artifact</th>
|
||||
<th>exclude</th>
|
||||
<th>action</th>
|
||||
</tr>
|
||||
|
||||
<tr ng-repeat="dep in newInterpreterSetting.dependencies">
|
||||
<td>
|
||||
<input ng-model="dep.groupArtifactVersion" style="width:100%"/>
|
||||
</td>
|
||||
<td>
|
||||
<textarea msd-elastic ng-model="dep.exclusions"
|
||||
ng-list
|
||||
placeholder="(Optional) comma separated groupId:artifactId list">
|
||||
</textarea>
|
||||
</td>
|
||||
<td>
|
||||
<div class="btn btn-default btn-sm fa fa-remove"
|
||||
ng-click="removeInterpreterDependency(dep.groupArtifactVersion)">
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<input ng-model="newInterpreterSetting.depArtifact"
|
||||
placeholder="groupId:artifactId:version or local file path"
|
||||
style="width: 100%"/>
|
||||
</td>
|
||||
<td>
|
||||
<textarea msd-elastic ng-model="newInterpreterSetting.depExclude"
|
||||
ng-list
|
||||
placeholder="(Optional) comma separated groupId:artifactId list">
|
||||
</textarea>
|
||||
</td>
|
||||
<td>
|
||||
<div class="btn btn-default btn-sm fa fa-plus" ng-click="addNewInterpreterDependency()">
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<span class="btn btn-primary" ng-click="addNewInterpreterSetting()">
|
||||
Save
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, $route, $routeParams, $location, $rootScope,
|
||||
$http, baseUrlSrv) {
|
||||
$http, baseUrlSrv, ngToast) {
|
||||
var interpreterSettingsTmp = [];
|
||||
$scope.interpreterSettings = [];
|
||||
$scope.availableInterpreters = {};
|
||||
|
|
@ -24,28 +24,32 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope,
|
|||
|
||||
var getInterpreterSettings = function() {
|
||||
$http.get(baseUrlSrv.getRestApiBase()+'/interpreter/setting').
|
||||
success(function(data, status, headers, config) {
|
||||
$scope.interpreterSettings = data.body;
|
||||
}).
|
||||
error(function(data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
});
|
||||
success(function(data, status, headers, config) {
|
||||
$scope.interpreterSettings = data.body;
|
||||
}).
|
||||
error(function(data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
});
|
||||
};
|
||||
|
||||
var getAvailableInterpreters = function() {
|
||||
$http.get(baseUrlSrv.getRestApiBase()+'/interpreter').
|
||||
success(function(data, status, headers, config) {
|
||||
$scope.availableInterpreters = data.body;
|
||||
}).
|
||||
error(function(data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
});
|
||||
success(function(data, status, headers, config) {
|
||||
$scope.availableInterpreters = data.body;
|
||||
}).
|
||||
error(function(data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
});
|
||||
};
|
||||
|
||||
var emptyNewProperty = function(object) {
|
||||
angular.extend(object, {propertyValue: '', propertyKey: ''});
|
||||
};
|
||||
|
||||
var emptyNewDependency = function(object) {
|
||||
angular.extend(object, {depArtifact: '', depExclude: ''});
|
||||
};
|
||||
|
||||
var removeTMPSettings = function(index) {
|
||||
interpreterSettingsTmp.splice(index, 1);
|
||||
};
|
||||
|
|
@ -55,29 +59,34 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope,
|
|||
interpreterSettingsTmp[index] = angular.copy($scope.interpreterSettings[index]);
|
||||
};
|
||||
|
||||
$scope.updateInterpreterSetting = function(settingId) {
|
||||
BootstrapDialog.confirm({
|
||||
closable: true,
|
||||
title: '',
|
||||
message: 'Do you want to update this interpreter and restart with new settings?',
|
||||
callback: function(result) {
|
||||
if (result) {
|
||||
var index = _.findIndex($scope.interpreterSettings, {'id': settingId});
|
||||
var request = {
|
||||
properties: angular.copy($scope.interpreterSettings[index].properties),
|
||||
};
|
||||
|
||||
$http.put(baseUrlSrv.getRestApiBase() + '/interpreter/setting/' + settingId, request).
|
||||
success(function (data, status, headers, config) {
|
||||
$scope.interpreterSettings[index] = data.body;
|
||||
removeTMPSettings(index);
|
||||
}).
|
||||
error(function (data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
});
|
||||
}
|
||||
$scope.updateInterpreterSetting = function(form, settingId) {
|
||||
var result = confirm('Do you want to update this interpreter and restart with new settings?');
|
||||
if (result) {
|
||||
var index = _.findIndex($scope.interpreterSettings, {'id': settingId});
|
||||
var setting = $scope.interpreterSettings[index];
|
||||
if (setting.propertyKey !== '' || setting.propertyKey) {
|
||||
$scope.addNewInterpreterProperty(settingId);
|
||||
}
|
||||
});
|
||||
if (setting.depArtifact !== '' || setting.depArtifact) {
|
||||
$scope.addNewInterpreterDependency(settingId);
|
||||
}
|
||||
|
||||
var request = {
|
||||
properties: angular.copy(setting.properties),
|
||||
dependencies: angular.copy(setting.dependencies)
|
||||
};
|
||||
|
||||
$http.put(baseUrlSrv.getRestApiBase() + '/interpreter/setting/' + settingId, request).
|
||||
success(function (data, status, headers, config) {
|
||||
$scope.interpreterSettings[index] = data.body;
|
||||
removeTMPSettings(index);
|
||||
}).
|
||||
error(function (data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
ngToast.danger(data.message);
|
||||
form.$show();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$scope.resetInterpreterSetting = function(settingId){
|
||||
|
|
@ -117,8 +126,8 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope,
|
|||
var intpInfo = el[i];
|
||||
for (var key in intpInfo) {
|
||||
properties[key] = {
|
||||
value : intpInfo[key].defaultValue,
|
||||
description : intpInfo[key].description
|
||||
value: intpInfo[key].defaultValue,
|
||||
description: intpInfo[key].description
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -165,32 +174,46 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope,
|
|||
return;
|
||||
}
|
||||
|
||||
var newSetting = angular.copy($scope.newInterpreterSetting);
|
||||
|
||||
for (var p in $scope.newInterpreterSetting.properties) {
|
||||
newSetting.properties[p] = $scope.newInterpreterSetting.properties[p].value;
|
||||
var newSetting = $scope.newInterpreterSetting;
|
||||
if (newSetting.propertyKey !== '' || newSetting.propertyKey) {
|
||||
$scope.addNewInterpreterProperty();
|
||||
}
|
||||
if (newSetting.depArtifact !== '' || newSetting.depArtifact) {
|
||||
$scope.addNewInterpreterDependency();
|
||||
}
|
||||
|
||||
$http.post(baseUrlSrv.getRestApiBase()+'/interpreter/setting', newSetting).
|
||||
success(function(data, status, headers, config) {
|
||||
$scope.resetNewInterpreterSetting();
|
||||
getInterpreterSettings();
|
||||
$scope.showAddNewSetting = false;
|
||||
}).
|
||||
error(function(data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
});
|
||||
var request = angular.copy($scope.newInterpreterSetting);
|
||||
|
||||
// Change properties to proper request format
|
||||
var newProperties = {};
|
||||
for (var p in newSetting.properties) {
|
||||
newProperties[p] = newSetting.properties[p].value;
|
||||
}
|
||||
request.properties = newProperties;
|
||||
|
||||
$http.post(baseUrlSrv.getRestApiBase() + '/interpreter/setting', request).
|
||||
success(function(data, status, headers, config) {
|
||||
$scope.resetNewInterpreterSetting();
|
||||
getInterpreterSettings();
|
||||
$scope.showAddNewSetting = false;
|
||||
}).
|
||||
error(function(data, status, headers, config) {
|
||||
console.log('Error %o %o', status, data.message);
|
||||
ngToast.danger(data.message);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.cancelInterpreterSetting = function() {
|
||||
$scope.showAddNewSetting = false;
|
||||
$scope.resetNewInterpreterSetting();
|
||||
};
|
||||
|
||||
$scope.resetNewInterpreterSetting = function() {
|
||||
$scope.newInterpreterSetting = {
|
||||
name : undefined,
|
||||
group : undefined,
|
||||
properties : {}
|
||||
name: undefined,
|
||||
group: undefined,
|
||||
properties: {},
|
||||
dependencies: []
|
||||
};
|
||||
emptyNewProperty($scope.newInterpreterSetting);
|
||||
};
|
||||
|
|
@ -205,6 +228,21 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope,
|
|||
}
|
||||
};
|
||||
|
||||
$scope.removeInterpreterDependency = function(artifact, settingId) {
|
||||
if (settingId === undefined) {
|
||||
$scope.newInterpreterSetting.dependencies = _.reject($scope.newInterpreterSetting.dependencies,
|
||||
function(el) {
|
||||
return el.groupArtifactVersion === artifact;
|
||||
});
|
||||
} else {
|
||||
var index = _.findIndex($scope.interpreterSettings, {'id': settingId});
|
||||
$scope.interpreterSettings[index].dependencies = _.reject($scope.interpreterSettings[index].dependencies,
|
||||
function(el) {
|
||||
return el.groupArtifactVersion === artifact;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$scope.addNewInterpreterProperty = function(settingId) {
|
||||
if(settingId === undefined) {
|
||||
// Add new property from create form
|
||||
|
|
@ -230,6 +268,58 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope,
|
|||
}
|
||||
};
|
||||
|
||||
$scope.addNewInterpreterDependency = function(settingId) {
|
||||
if(settingId === undefined) {
|
||||
// Add new dependency from create form
|
||||
if (!$scope.newInterpreterSetting.depArtifact || $scope.newInterpreterSetting.depArtifact === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
// overwrite if artifact already exists
|
||||
var newSetting = $scope.newInterpreterSetting;
|
||||
for(var d in newSetting.dependencies) {
|
||||
if (newSetting.dependencies[d].groupArtifactVersion === newSetting.depArtifact) {
|
||||
newSetting.dependencies[d] = {
|
||||
'groupArtifactVersion': newSetting.depArtifact,
|
||||
'exclusions': newSetting.depExclude
|
||||
};
|
||||
newSetting.dependencies.splice(d, 1);
|
||||
}
|
||||
}
|
||||
|
||||
newSetting.dependencies.push({
|
||||
'groupArtifactVersion': newSetting.depArtifact,
|
||||
'exclusions': (newSetting.depExclude === '')? []: newSetting.depExclude
|
||||
});
|
||||
emptyNewDependency(newSetting);
|
||||
}
|
||||
else {
|
||||
// Add new dependency from edit form
|
||||
var index = _.findIndex($scope.interpreterSettings, { 'id': settingId });
|
||||
var setting = $scope.interpreterSettings[index];
|
||||
if (!setting.depArtifact || setting.depArtifact === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
// overwrite if artifact already exists
|
||||
for(var dep in setting.dependencies) {
|
||||
if (setting.dependencies[dep].groupArtifactVersion === setting.depArtifact) {
|
||||
setting.dependencies[dep] = {
|
||||
'groupArtifactVersion': setting.depArtifact,
|
||||
'exclusions': setting.depExclude
|
||||
};
|
||||
setting.dependencies.splice(dep, 1);
|
||||
}
|
||||
}
|
||||
|
||||
setting.dependencies.push({
|
||||
'groupArtifactVersion': setting.depArtifact,
|
||||
'exclusions': (setting.depExclude === '')? []: setting.depExclude
|
||||
});
|
||||
emptyNewDependency(setting);
|
||||
}
|
||||
};
|
||||
|
||||
var init = function() {
|
||||
$scope.resetNewInterpreterSetting();
|
||||
getInterpreterSettings();
|
||||
|
|
|
|||
|
|
@ -34,6 +34,13 @@
|
|||
font-size: 12px;
|
||||
}
|
||||
|
||||
.interpreter input {
|
||||
width: 100%;
|
||||
display: block;
|
||||
height: 23px;
|
||||
border: 1px solid #CCCCCC;
|
||||
}
|
||||
|
||||
.interpreter .interpreter-title {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
|
|
|
|||
|
|
@ -109,18 +109,74 @@ limitations under the License.
|
|||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<form editable-form name="valueform" onaftersave="updateInterpreterSetting(setting.id)" ng-show="valueform.$visible">
|
||||
<button type="submit" class="btn btn-primary"
|
||||
ng-disabled="valueform.$waiting">
|
||||
Save
|
||||
</button>
|
||||
<button type="button" class="btn btn-default"
|
||||
ng-disabled="valueform.$waiting"
|
||||
ng-click="valueform.$cancel(); resetInterpreterSetting(setting.id)">
|
||||
Cancel
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="col-md-12" ng-show="!_.isEmpty(setting.dependencies) || valueform.$visible">
|
||||
<h5>Dependencies</h5>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:40%">artifact</th>
|
||||
<th>exclude</th>
|
||||
<th ng-if="valueform.$visible">action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr ng-repeat="dep in setting.dependencies">
|
||||
<td>
|
||||
<span editable-text="dep.groupArtifactVersion" e-placeholder="groupId:artifactId:version or local file path"
|
||||
e-form="valueform" e-msd-elastic e-style="width:100%">
|
||||
{{dep.groupArtifactVersion | breakFilter}}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<textarea ng-if="valueform.$visible" ng-model="dep.exclusions"
|
||||
placeholder="(Optional) comma separated groupId:artifactId list"
|
||||
form="valueform"
|
||||
e-msd-elastic
|
||||
ng-list="">
|
||||
</textarea>
|
||||
<div ng-if="!valueform.$visible">{{dep.exclusions.join()}}</div>
|
||||
</td>
|
||||
<td ng-if="valueform.$visible">
|
||||
<div class="btn btn-default btn-sm fa fa-remove"
|
||||
ng-click="removeInterpreterDependency(dep.groupArtifactVersion, setting.id)">
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-if="valueform.$visible">
|
||||
<td>
|
||||
<input ng-model="setting.depArtifact"
|
||||
placeholder="groupId:artifactId:version or local file path"
|
||||
style="width: 100%">
|
||||
</input>
|
||||
</td>
|
||||
<td>
|
||||
<textarea ng-model="setting.depExclude"
|
||||
placeholder="(Optional) comma separated groupId:artifactId list"
|
||||
msd-elastic
|
||||
ng-list="">
|
||||
</textarea>
|
||||
</td>
|
||||
<td>
|
||||
<div class="btn btn-default btn-sm fa fa-plus"
|
||||
ng-click="addNewInterpreterDependency(setting.id)">
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<form editable-form name="valueform"
|
||||
onaftersave="updateInterpreterSetting(valueform, setting.id)"
|
||||
ng-show="valueform.$visible">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
Save
|
||||
</button>
|
||||
<button type="button" class="btn btn-default"
|
||||
ng-disabled="valueform.$waiting"
|
||||
ng-click="valueform.$cancel(); resetInterpreterSetting(setting.id)">
|
||||
Cancel
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -19,10 +19,13 @@ package org.apache.zeppelin.interpreter;
|
|||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import org.apache.commons.lang.NullArgumentException;
|
||||
import org.apache.zeppelin.conf.ZeppelinConfiguration;
|
||||
import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
|
||||
import org.apache.zeppelin.dep.Dependency;
|
||||
import org.apache.zeppelin.dep.DependencyResolver;
|
||||
import org.apache.zeppelin.display.AngularObjectRegistry;
|
||||
import org.apache.zeppelin.display.AngularObjectRegistryListener;
|
||||
|
|
@ -34,6 +37,7 @@ import org.apache.zeppelin.scheduler.Job;
|
|||
import org.apache.zeppelin.scheduler.Job.Status;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.sonatype.aether.RepositoryException;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Constructor;
|
||||
|
|
@ -68,13 +72,13 @@ public class InterpreterFactory {
|
|||
AngularObjectRegistryListener angularObjectRegistryListener;
|
||||
private final RemoteInterpreterProcessListener remoteInterpreterProcessListener;
|
||||
|
||||
DependencyResolver depResolver;
|
||||
private DependencyResolver depResolver;
|
||||
|
||||
public InterpreterFactory(ZeppelinConfiguration conf,
|
||||
AngularObjectRegistryListener angularObjectRegistryListener,
|
||||
RemoteInterpreterProcessListener remoteInterpreterProcessListener,
|
||||
DependencyResolver depResolver)
|
||||
throws InterpreterException, IOException {
|
||||
throws InterpreterException, IOException, RepositoryException {
|
||||
this(conf, new InterpreterOption(true), angularObjectRegistryListener,
|
||||
remoteInterpreterProcessListener, depResolver);
|
||||
}
|
||||
|
|
@ -84,7 +88,7 @@ public class InterpreterFactory {
|
|||
AngularObjectRegistryListener angularObjectRegistryListener,
|
||||
RemoteInterpreterProcessListener remoteInterpreterProcessListener,
|
||||
DependencyResolver depResolver)
|
||||
throws InterpreterException, IOException {
|
||||
throws InterpreterException, IOException, RepositoryException {
|
||||
this.conf = conf;
|
||||
this.defaultOption = defaultOption;
|
||||
this.angularObjectRegistryListener = angularObjectRegistryListener;
|
||||
|
|
@ -101,7 +105,7 @@ public class InterpreterFactory {
|
|||
init();
|
||||
}
|
||||
|
||||
private void init() throws InterpreterException, IOException {
|
||||
private void init() throws InterpreterException, IOException, RepositoryException {
|
||||
ClassLoader oldcl = Thread.currentThread().getContextClassLoader();
|
||||
|
||||
// Load classes
|
||||
|
|
@ -172,7 +176,11 @@ public class InterpreterFactory {
|
|||
|
||||
if (found) {
|
||||
// add all interpreters in group
|
||||
add(groupName, groupName, defaultOption, p);
|
||||
add(groupName,
|
||||
groupName,
|
||||
new LinkedList<Dependency>(),
|
||||
defaultOption,
|
||||
p);
|
||||
groupClassNameMap.remove(groupName);
|
||||
break;
|
||||
}
|
||||
|
|
@ -225,12 +233,11 @@ public class InterpreterFactory {
|
|||
// previously created setting should turn this feature on here.
|
||||
setting.getOption().setRemote(true);
|
||||
|
||||
|
||||
|
||||
InterpreterSetting intpSetting = new InterpreterSetting(
|
||||
setting.id(),
|
||||
setting.getName(),
|
||||
setting.getGroup(),
|
||||
setting.getDependencies(),
|
||||
setting.getOption());
|
||||
|
||||
InterpreterGroup interpreterGroup = createInterpreterGroup(
|
||||
|
|
@ -246,6 +253,31 @@ public class InterpreterFactory {
|
|||
this.interpreterBindings = info.interpreterBindings;
|
||||
}
|
||||
|
||||
private void loadInterpreterDependencies(InterpreterSetting intSetting)
|
||||
throws IOException, RepositoryException {
|
||||
// dependencies to prevent library conflict
|
||||
File localRepoDir = new File(conf.getInterpreterLocalRepoPath() + "/" + intSetting.id());
|
||||
if (localRepoDir.exists()) {
|
||||
FileUtils.cleanDirectory(localRepoDir);
|
||||
}
|
||||
|
||||
// load dependencies
|
||||
List<Dependency> deps = intSetting.getDependencies();
|
||||
if (deps != null) {
|
||||
for (Dependency d: deps) {
|
||||
if (d.getExclusions() != null) {
|
||||
depResolver.load(
|
||||
d.getGroupArtifactVersion(),
|
||||
d.getExclusions(),
|
||||
conf.getString(ConfVars.ZEPPELIN_DEP_LOCALREPO) + "/" + intSetting.id());
|
||||
} else {
|
||||
depResolver.load(
|
||||
d.getGroupArtifactVersion(),
|
||||
conf.getString(ConfVars.ZEPPELIN_DEP_LOCALREPO) + "/" + intSetting.id());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void saveToFile() throws IOException {
|
||||
String jsonString;
|
||||
|
|
@ -330,15 +362,21 @@ public class InterpreterFactory {
|
|||
* @throws IOException
|
||||
*/
|
||||
public InterpreterGroup add(String name, String groupName,
|
||||
List<Dependency> dependencies,
|
||||
InterpreterOption option, Properties properties)
|
||||
throws InterpreterException, IOException {
|
||||
throws InterpreterException, IOException, RepositoryException {
|
||||
synchronized (interpreterSettings) {
|
||||
|
||||
InterpreterSetting intpSetting = new InterpreterSetting(
|
||||
name,
|
||||
groupName,
|
||||
dependencies,
|
||||
option);
|
||||
|
||||
if (dependencies.size() > 0) {
|
||||
loadInterpreterDependencies(intpSetting);
|
||||
}
|
||||
|
||||
InterpreterGroup interpreterGroup = createInterpreterGroup(
|
||||
intpSetting.id(), groupName, option, properties);
|
||||
|
||||
|
|
@ -354,13 +392,13 @@ public class InterpreterFactory {
|
|||
String groupName,
|
||||
InterpreterOption option,
|
||||
Properties properties)
|
||||
throws InterpreterException , NullArgumentException {
|
||||
throws InterpreterException, NullArgumentException {
|
||||
|
||||
//When called from REST API without option we receive NPE
|
||||
if (option == null )
|
||||
if (option == null)
|
||||
throw new NullArgumentException("option");
|
||||
//When called from REST API without option we receive NPE
|
||||
if (properties == null )
|
||||
if (properties == null)
|
||||
throw new NullArgumentException("properties");
|
||||
|
||||
AngularObjectRegistry angularObjectRegistry;
|
||||
|
|
@ -429,6 +467,9 @@ public class InterpreterFactory {
|
|||
saveToFile();
|
||||
}
|
||||
}
|
||||
|
||||
File localRepoDir = new File(conf.getInterpreterLocalRepoPath() + "/" + id);
|
||||
FileUtils.deleteDirectory(localRepoDir);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -512,8 +553,10 @@ public class InterpreterFactory {
|
|||
* @param properties
|
||||
* @throws IOException
|
||||
*/
|
||||
public void setPropertyAndRestart(String id, InterpreterOption option,
|
||||
Properties properties) throws IOException {
|
||||
public void setPropertyAndRestart(String id,
|
||||
InterpreterOption option,
|
||||
Properties properties,
|
||||
List<Dependency> dependencies) throws IOException, RepositoryException {
|
||||
synchronized (interpreterSettings) {
|
||||
InterpreterSetting intpsetting = interpreterSettings.get(id);
|
||||
if (intpsetting != null) {
|
||||
|
|
@ -524,11 +567,14 @@ public class InterpreterFactory {
|
|||
intpsetting.getInterpreterGroup().destroy();
|
||||
|
||||
intpsetting.setOption(option);
|
||||
intpsetting.setDependencies(dependencies);
|
||||
|
||||
InterpreterGroup interpreterGroup = createInterpreterGroup(
|
||||
intpsetting.id(),
|
||||
intpsetting.getGroup(), option, properties);
|
||||
intpsetting.setInterpreterGroup(interpreterGroup);
|
||||
|
||||
loadInterpreterDependencies(intpsetting);
|
||||
saveToFile();
|
||||
} else {
|
||||
throw new InterpreterException("Interpreter setting id " + id
|
||||
|
|
|
|||
|
|
@ -17,9 +17,12 @@
|
|||
|
||||
package org.apache.zeppelin.interpreter;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
|
||||
import org.apache.zeppelin.dep.Dependency;
|
||||
import org.apache.zeppelin.notebook.utility.IdHashes;
|
||||
|
||||
/**
|
||||
|
|
@ -32,21 +35,26 @@ public class InterpreterSetting {
|
|||
private String description;
|
||||
private Properties properties;
|
||||
private InterpreterGroup interpreterGroup;
|
||||
private List<Dependency> dependencies;
|
||||
private InterpreterOption option;
|
||||
|
||||
public InterpreterSetting(String id, String name,
|
||||
public InterpreterSetting(String id,
|
||||
String name,
|
||||
String group,
|
||||
List<Dependency> dependencies,
|
||||
InterpreterOption option) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.group = group;
|
||||
this.dependencies = dependencies;
|
||||
this.option = option;
|
||||
}
|
||||
|
||||
public InterpreterSetting(String name,
|
||||
String group,
|
||||
List<Dependency> dependencies,
|
||||
InterpreterOption option) {
|
||||
this(generateId(), name, group, option);
|
||||
this(generateId(), name, group, dependencies, option);
|
||||
}
|
||||
|
||||
public String id() {
|
||||
|
|
@ -90,6 +98,17 @@ public class InterpreterSetting {
|
|||
return properties;
|
||||
}
|
||||
|
||||
public List<Dependency> getDependencies() {
|
||||
if (dependencies == null) {
|
||||
return new LinkedList<Dependency>();
|
||||
}
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
public void setDependencies(List<Dependency> dependencies) {
|
||||
this.dependencies = dependencies;
|
||||
}
|
||||
|
||||
public InterpreterOption getOption() {
|
||||
if (option == null) {
|
||||
option = new InterpreterOption();
|
||||
|
|
|
|||
|
|
@ -24,17 +24,20 @@ import static org.junit.Assert.assertTrue;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.lang.NullArgumentException;
|
||||
import org.apache.zeppelin.conf.ZeppelinConfiguration;
|
||||
import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
|
||||
import org.apache.zeppelin.dep.Dependency;
|
||||
import org.apache.zeppelin.interpreter.mock.MockInterpreter1;
|
||||
import org.apache.zeppelin.interpreter.mock.MockInterpreter2;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.sonatype.aether.RepositoryException;
|
||||
|
||||
public class InterpreterFactoryTest {
|
||||
|
||||
|
|
@ -98,14 +101,14 @@ public class InterpreterFactoryTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testFactoryDefaultList() throws IOException {
|
||||
public void testFactoryDefaultList() throws IOException, RepositoryException {
|
||||
// get default list from default setting
|
||||
List<String> all = factory.getDefaultInterpreterSettingList();
|
||||
assertEquals(2, all.size());
|
||||
assertEquals(factory.get(all.get(0)).getInterpreterGroup().getFirst().getClassName(), "org.apache.zeppelin.interpreter.mock.MockInterpreter1");
|
||||
|
||||
// add setting
|
||||
factory.add("a mock", "mock2", new InterpreterOption(false), new Properties());
|
||||
factory.add("a mock", "mock2", new LinkedList<Dependency>(), new InterpreterOption(false), new Properties());
|
||||
all = factory.getDefaultInterpreterSettingList();
|
||||
assertEquals(2, all.size());
|
||||
assertEquals("mock1", factory.get(all.get(0)).getName());
|
||||
|
|
@ -113,16 +116,16 @@ public class InterpreterFactoryTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testExceptions() throws IOException {
|
||||
public void testExceptions() throws InterpreterException, IOException, RepositoryException {
|
||||
List<String> all = factory.getDefaultInterpreterSettingList();
|
||||
// add setting with null option & properties expected nullArgumentException.class
|
||||
try {
|
||||
factory.add("a mock", "mock2", null, new Properties());
|
||||
factory.add("a mock", "mock2", new LinkedList<Dependency>(), null, new Properties());
|
||||
} catch(NullArgumentException e) {
|
||||
assertEquals("Test null option" , e.getMessage(),new NullArgumentException("option").getMessage());
|
||||
}
|
||||
try {
|
||||
factory.add("a mock" , "mock2" , new InterpreterOption(false),null);
|
||||
factory.add("a mock", "mock2", new LinkedList<Dependency>(), new InterpreterOption(false), null);
|
||||
} catch (NullArgumentException e){
|
||||
assertEquals("Test null properties" , e.getMessage(),new NullArgumentException("properties").getMessage());
|
||||
}
|
||||
|
|
@ -130,14 +133,14 @@ public class InterpreterFactoryTest {
|
|||
|
||||
|
||||
@Test
|
||||
public void testSaveLoad() throws InterpreterException, IOException {
|
||||
public void testSaveLoad() throws IOException, RepositoryException {
|
||||
// interpreter settings
|
||||
assertEquals(2, factory.get().size());
|
||||
|
||||
// check if file saved
|
||||
assertTrue(new File(conf.getInterpreterSettingPath()).exists());
|
||||
|
||||
factory.add("newsetting", "mock1", new InterpreterOption(false), new Properties());
|
||||
factory.add("newsetting", "mock1", new LinkedList<Dependency>(), new InterpreterOption(false), new Properties());
|
||||
assertEquals(3, factory.get().size());
|
||||
|
||||
InterpreterFactory factory2 = new InterpreterFactory(conf, null, null, null);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ import org.junit.Test;
|
|||
import org.quartz.SchedulerException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.sonatype.aether.RepositoryException;
|
||||
|
||||
public class NotebookTest implements JobListenerFactory{
|
||||
private static final Logger logger = LoggerFactory.getLogger(NotebookTest.class);
|
||||
|
|
@ -161,7 +162,7 @@ public class NotebookTest implements JobListenerFactory{
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testPersist() throws IOException, SchedulerException{
|
||||
public void testPersist() throws IOException, SchedulerException, RepositoryException {
|
||||
Note note = notebook.createNote();
|
||||
|
||||
// run with default repl
|
||||
|
|
|
|||
Loading…
Reference in a new issue