From 6ff68dd180d6f38adfd229e9dd83760c62edcfde Mon Sep 17 00:00:00 2001 From: Mina Lee Date: Thu, 5 Feb 2015 21:32:15 +0900 Subject: [PATCH 1/4] Follow jshint rules --- .../app/scripts/controllers/interpreter.js | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/zeppelin-web/app/scripts/controllers/interpreter.js b/zeppelin-web/app/scripts/controllers/interpreter.js index a9cdaca2..67832b8c 100644 --- a/zeppelin-web/app/scripts/controllers/interpreter.js +++ b/zeppelin-web/app/scripts/controllers/interpreter.js @@ -32,11 +32,11 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, group : setting.group, properties : setting.properties, interpreters : setting.interpreterGroup - } + }; }; var getInterpreterSettings = function() { - $http.get(getRestApiBase()+"/interpreter/setting"). + $http.get(getRestApiBase()+'/interpreter/setting'). success(function(data, status, headers, config) { var interpreterSettings = []; //console.log("getInterpreterSettings=%o", data); @@ -48,13 +48,13 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, $scope.interpreterSettings = interpreterSettings; }). error(function(data, status, headers, config) { - console.log("Error %o %o", status, data.message); + console.log('Error %o %o', status, data.message); }); }; var getAvailableInterpreters = function() { - $http.get(getRestApiBase()+"/interpreter"). + $http.get(getRestApiBase()+'/interpreter'). success(function(data, status, headers, config) { var groupedInfo = {}; var info; @@ -74,7 +74,7 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, //console.log("getAvailableInterpreters=%o", data); }). error(function(data, status, headers, config) { - console.log("Error %o %o", status, data.message); + console.log('Error %o %o', status, data.message); }); }; @@ -84,8 +84,8 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, return; } - console.log("Delete setting %o", settingId); - $http.delete(getRestApiBase()+"/interpreter/setting/"+settingId). + console.log('Delete setting %o', settingId); + $http.delete(getRestApiBase()+'/interpreter/setting/'+settingId). success(function(data, status, headers, config) { for (var i=0; i < $scope.interpreterSettings.length; i++) { var setting = $scope.interpreterSettings[i]; @@ -96,7 +96,7 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, } }). error(function(data, status, headers, config) { - console.log("Error %o %o", status, data.message); + console.log('Error %o %o', status, data.message); }); }; @@ -109,7 +109,7 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, property[key] = { value : intpInfo.properties[key].defaultValue, description : intpInfo.properties[key].description - } + }; } } $scope.newInterpreterSetting.properties = property; @@ -121,7 +121,7 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, return; } - $http.put(getRestApiBase()+"/interpreter/setting/restart/"+settingId). + $http.put(getRestApiBase()+'/interpreter/setting/restart/'+settingId). success(function(data, status, headers, config) { for (var i=0; i < $scope.interpreterSettings.length; i++) { var setting = $scope.interpreterSettings[i]; @@ -133,21 +133,21 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, } }). error(function(data, status, headers, config) { - console.log("Error %o %o", status, data.message); + console.log('Error %o %o', status, data.message); }); }; $scope.addNewInterpreterSetting = function() { if (!$scope.newInterpreterSetting.name || !$scope.newInterpreterSetting.group) { - alert("Please determine name and interpreter"); + alert('Please determine name and interpreter'); return; } for (var i=0; i<$scope.interpreterSettings.length; i++) { var setting = $scope.interpreterSettings[i]; if (setting.name === $scope.newInterpreterSetting.name) { - alert("Name '"+setting.name+"' already exists"); + alert('Name ' + setting.name + ' already exists'); return; } } @@ -162,16 +162,16 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, for (var p in $scope.newInterpreterSetting.properties) { newSetting.properties[p] = $scope.newInterpreterSetting.properties[p].value; - }; + } - $http.post(getRestApiBase()+"/interpreter/setting", newSetting). + $http.post(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); + console.log('Error %o %o', status, data.message); }); }; @@ -182,22 +182,22 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, group : undefined, properties : {} }; - $scope.newInterpreterSetting.propertyValue = ""; - $scope.newInterpreterSetting.propertyKey = ""; - } + $scope.newInterpreterSetting.propertyValue = ''; + $scope.newInterpreterSetting.propertyKey = ''; + }; $scope.removeNewInterpreterProperty = function(key) { delete $scope.newInterpreterSetting.properties[key]; - } + }; $scope.addNewInterpreterProperty = function() { - if (!$scope.newInterpreterSetting.propertyKey || $scope.newInterpreterSetting.propertyKey === "") { + if (!$scope.newInterpreterSetting.propertyKey || $scope.newInterpreterSetting.propertyKey === '') { return; } $scope.newInterpreterSetting.properties[$scope.newInterpreterSetting.propertyKey] = { value : $scope.newInterpreterSetting.propertyValue}; - $scope.newInterpreterSetting.propertyValue = ""; - $scope.newInterpreterSetting.propertyKey = ""; + $scope.newInterpreterSetting.propertyValue = ''; + $scope.newInterpreterSetting.propertyKey = ''; }; var init = function() { From 284ad826aeb75940f251632cdd1a58467064b37b Mon Sep 17 00:00:00 2001 From: Mina Lee Date: Sun, 8 Feb 2015 17:53:34 +0900 Subject: [PATCH 2/4] Add interpreter setting edit function --- .../zeppelin/rest/InterpreterRestApi.java | 17 +++ zeppelin-web/app/index.html | 2 + zeppelin-web/app/scripts/app.js | 3 +- .../app/scripts/controllers/interpreter.js | 109 ++++++++++++++++-- zeppelin-web/app/styles/interpreter.css | 10 +- zeppelin-web/app/views/interpreter.html | 53 ++++++++- zeppelin-web/bower.json | 3 +- 7 files changed, 177 insertions(+), 20 deletions(-) diff --git a/zeppelin-server/src/main/java/com/nflabs/zeppelin/rest/InterpreterRestApi.java b/zeppelin-server/src/main/java/com/nflabs/zeppelin/rest/InterpreterRestApi.java index 38ec9c5a..0bdbfb0c 100644 --- a/zeppelin-server/src/main/java/com/nflabs/zeppelin/rest/InterpreterRestApi.java +++ b/zeppelin-server/src/main/java/com/nflabs/zeppelin/rest/InterpreterRestApi.java @@ -87,6 +87,23 @@ public Response newSettings(String message) throws InterpreterException, IOExcep return new JsonResponse(Status.CREATED, "").build(); } + @PUT + @Path("setting/{settingId}") + public Response updateSetting(String message, @PathParam("settingId") String settingId) { + logger.info("Update interpreterSetting {}", settingId); + try { + Properties p = gson.fromJson(message, Properties.class); + interpreterFactory.setPropertyAndRestart(settingId, p); + } catch (InterpreterException e) { + return new JsonResponse(Status.NOT_FOUND, e.getMessage(), e).build(); + } + InterpreterSetting setting = interpreterFactory.get(settingId); + if (setting == null) { + return new JsonResponse(Status.NOT_FOUND, "", settingId).build(); + } + return new JsonResponse(Status.OK, "", setting).build(); + } + @DELETE @Path("setting/{settingId}") @ApiOperation(httpMethod = "GET", value = "Remove interpreter setting") diff --git a/zeppelin-web/app/index.html b/zeppelin-web/app/index.html index 8fff6047..d4a7aef6 100644 --- a/zeppelin-web/app/index.html +++ b/zeppelin-web/app/index.html @@ -35,6 +35,7 @@ + @@ -132,6 +133,7 @@ + diff --git a/zeppelin-web/app/scripts/app.js b/zeppelin-web/app/scripts/app.js index b11be914..55dc9b4c 100644 --- a/zeppelin-web/app/scripts/app.js +++ b/zeppelin-web/app/scripts/app.js @@ -87,7 +87,8 @@ angular 'ngTouch', 'ngDragDrop', 'monospaced.elastic', - 'puElasticInput' + 'puElasticInput', + 'xeditable' ]) .filter('breakFilter', function() { return function (text) { diff --git a/zeppelin-web/app/scripts/controllers/interpreter.js b/zeppelin-web/app/scripts/controllers/interpreter.js index 67832b8c..05bcd924 100644 --- a/zeppelin-web/app/scripts/controllers/interpreter.js +++ b/zeppelin-web/app/scripts/controllers/interpreter.js @@ -26,11 +26,17 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, $route, $routeParams, $location, $rootScope, $http) { var remoteSettingToLocalSetting = function(settingId, setting) { + var property = {}; + for (var key in setting.properties) { + property[key] = { + value : setting.properties[key] + }; + } return { id : settingId, name : setting.name, group : setting.group, - properties : setting.properties, + properties : property, interpreters : setting.interpreterGroup }; }; @@ -52,7 +58,6 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, }); }; - var getAvailableInterpreters = function() { $http.get(getRestApiBase()+'/interpreter'). success(function(data, status, headers, config) { @@ -78,6 +83,61 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, }); }; + $scope.copyOriginInterpreterSettingProperties = function(settingId) { + $scope.interpreterSettingProperties = {}; + for (var i=0; i < $scope.interpreterSettings.length; i++) { + var setting = $scope.interpreterSettings[i]; + if(setting.id === settingId) { + angular.copy(setting.properties, $scope.interpreterSettingProperties); + break; + } + } + console.log('%o, %o', $scope.interpreterSettings[i], $scope.interpreterSettingProperties); + }; + + $scope.updateInterpreterSetting = function(settingId) { + var result = confirm('Do you want to update this interpreter and restart with new settings?'); + if (!result) { + return; + } + + var properties = {}; + for (var i=0; i < $scope.interpreterSettings.length; i++) { + var setting = $scope.interpreterSettings[i]; + if(setting.id === settingId) { + for (var p in setting.properties) { + properties[p] = setting.properties[p].value; + } + break; + } + } + + $http.put(getRestApiBase()+'/interpreter/setting/'+settingId, properties). + success(function(data, status, headers, config) { + for (var i=0; i < $scope.interpreterSettings.length; i++) { + var setting = $scope.interpreterSettings[i]; + if (setting.id === settingId) { + $scope.interpreterSettings.splice(i, 1); + $scope.interpreterSettings.splice(i, 0, remoteSettingToLocalSetting(settingId, data.body)); + break; + } + } + }). + error(function(data, status, headers, config) { + console.log('Error %o %o', status, data.message); + }); + }; + + $scope.resetInterpreterSetting = function(settingId){ + for (var i=0; i<$scope.interpreterSettings.length; i++) { + var setting = $scope.interpreterSettings[i]; + if (setting.id ===settingId) { + angular.copy($scope.interpreterSettingProperties, setting.properties); + break; + } + } + }; + $scope.removeInterpreterSetting = function(settingId) { var result = confirm('Do you want to delete this interpreter setting?'); if (!result) { @@ -135,7 +195,6 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, error(function(data, status, headers, config) { console.log('Error %o %o', status, data.message); }); - }; $scope.addNewInterpreterSetting = function() { @@ -186,18 +245,44 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, $scope.newInterpreterSetting.propertyKey = ''; }; - $scope.removeNewInterpreterProperty = function(key) { - delete $scope.newInterpreterSetting.properties[key]; + $scope.removeInterpreterProperty = function(key, settingId) { + if (settingId === undefined) { + delete $scope.newInterpreterSetting.properties[key]; + } + else { + for (var i=0; i < $scope.interpreterSettings.length; i++) { + var setting = $scope.interpreterSettings[i]; + if (setting.id === settingId) { + delete $scope.interpreterSettings[i].properties[key] + break; + } + } + } }; - $scope.addNewInterpreterProperty = function() { - if (!$scope.newInterpreterSetting.propertyKey || $scope.newInterpreterSetting.propertyKey === '') { - return; + $scope.addNewInterpreterProperty = function(settingId) { + if(settingId === undefined) { + if (!$scope.newInterpreterSetting.propertyKey || $scope.newInterpreterSetting.propertyKey === '') { + return; + } + $scope.newInterpreterSetting.properties[$scope.newInterpreterSetting.propertyKey] = { value : $scope.newInterpreterSetting.propertyValue}; + $scope.newInterpreterSetting.propertyValue = ''; + $scope.newInterpreterSetting.propertyKey = ''; + } + else { + for (var i=0; i < $scope.interpreterSettings.length; i++) { + var setting = $scope.interpreterSettings[i]; + if (setting.id === settingId){ + if (!setting.propertyKey || setting.propertyKey === '') { + return; + } + setting.properties[setting.propertyKey] = { value : setting.propertyValue }; + setting.propertyValue = ''; + setting.propertyKey = ''; + break; + } + } } - - $scope.newInterpreterSetting.properties[$scope.newInterpreterSetting.propertyKey] = { value : $scope.newInterpreterSetting.propertyValue}; - $scope.newInterpreterSetting.propertyValue = ''; - $scope.newInterpreterSetting.propertyKey = ''; }; var init = function() { diff --git a/zeppelin-web/app/styles/interpreter.css b/zeppelin-web/app/styles/interpreter.css index b11eff01..41704c70 100644 --- a/zeppelin-web/app/styles/interpreter.css +++ b/zeppelin-web/app/styles/interpreter.css @@ -13,7 +13,7 @@ font-family: 'Roboto', sans-serif; } -.interpreterHead textarea { +.interpreterHead textarea, .interpreter textarea { width: 100%; display: block; height: 20px; @@ -51,7 +51,15 @@ overflow-y: auto; } +.interpreter table tr { + height : 45px; +} + .interpreterSettingAdd { margin : 5px 5px 5px 5px; padding : 10px 10px 10px 10px; +} + +.editable-wrap { + width : 100%; } \ No newline at end of file diff --git a/zeppelin-web/app/views/interpreter.html b/zeppelin-web/app/views/interpreter.html index 154de977..dbc3a821 100644 --- a/zeppelin-web/app/views/interpreter.html +++ b/zeppelin-web/app/views/interpreter.html @@ -76,7 +76,7 @@

Create new interpreter

{{value.description}}
+ ng-click="removeInterpreterProperty(key)">
@@ -128,9 +128,15 @@

{{setting.name}}

+ ng-click="valueform.$show(); + copyOriginInterpreterSettingProperties(setting.id)"> + edit + ng-click="restartInterpreterSetting(setting.id)"> + restart + @@ -140,14 +146,51 @@

{{setting.name}} Properties - + + - + + + + + + +
namename valueaction
{{key}} + + {{value.value | breakFilter}} + + +
+
+
+ + + + + +
+
+
+
+ + +
diff --git a/zeppelin-web/bower.json b/zeppelin-web/bower.json index 856ad973..fe94c922 100644 --- a/zeppelin-web/bower.json +++ b/zeppelin-web/bower.json @@ -21,7 +21,8 @@ "perfect-scrollbar": "~0.5.4", "ng-sortable": "~1.1.9", "angular-elastic": "~2.4.2", - "angular-elastic-input": "~2.0.1" + "angular-elastic-input": "~2.0.1", + "angular-xeditable" : "0.1.8" }, "devDependencies": { "angular-mocks": "1.3.8", From 556e665874450fddb6aff505f958918c7b9762cb Mon Sep 17 00:00:00 2001 From: Mina Lee Date: Sun, 8 Feb 2015 17:59:31 +0900 Subject: [PATCH 3/4] Consistent capitalization for interpreter setting description --- .../java/com/nflabs/zeppelin/spark/SparkInterpreter.java | 8 ++++---- .../com/nflabs/zeppelin/spark/SparkSqlInterpreter.java | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/spark/src/main/java/com/nflabs/zeppelin/spark/SparkInterpreter.java b/spark/src/main/java/com/nflabs/zeppelin/spark/SparkInterpreter.java index dfd3e5fd..c83a70ce 100644 --- a/spark/src/main/java/com/nflabs/zeppelin/spark/SparkInterpreter.java +++ b/spark/src/main/java/com/nflabs/zeppelin/spark/SparkInterpreter.java @@ -68,16 +68,16 @@ public class SparkInterpreter extends Interpreter { "spark", SparkInterpreter.class.getName(), new InterpreterPropertyBuilder() - .add("spark.app.name", "Zeppelin", "The name of spark application") + .add("spark.app.name", "Zeppelin", "The name of spark application.") .add("master", getSystemDefault("MASTER", "spark.master", "local[*]"), - "spark master uri. ex) spark://masterhost:7077") + "Spark master uri. ex) spark://masterhost:7077") .add("spark.executor.memory", getSystemDefault(null, "spark.executor.memory", "512m"), - "executor memory per worker instance. ex) 512m, 32g") + "Executor memory per worker instance. ex) 512m, 32g") .add("spark.cores.max", getSystemDefault(null, "spark.cores.max", ""), - "total number of cores to use. Empty value uses all available core") + "Total number of cores to use. Empty value uses all available core.") .add("args", "", "spark commandline args").build()); } diff --git a/spark/src/main/java/com/nflabs/zeppelin/spark/SparkSqlInterpreter.java b/spark/src/main/java/com/nflabs/zeppelin/spark/SparkSqlInterpreter.java index 402f0ff7..484c1349 100644 --- a/spark/src/main/java/com/nflabs/zeppelin/spark/SparkSqlInterpreter.java +++ b/spark/src/main/java/com/nflabs/zeppelin/spark/SparkSqlInterpreter.java @@ -51,9 +51,9 @@ public class SparkSqlInterpreter extends Interpreter { "spark", SparkSqlInterpreter.class.getName(), new InterpreterPropertyBuilder() - .add("zeppelin.spark.maxResult", "10000", "Max number of SparkSQL result to display") + .add("zeppelin.spark.maxResult", "10000", "Max number of SparkSQL result to display.") .add("zeppelin.spark.useHiveContext", "false", - "use HiveContext instead of SQLContext if it is true") + "Use HiveContext instead of SQLContext if it is true.") .build()); } From 83b65cc21a22a396b76b67d5da2375c12727a51c Mon Sep 17 00:00:00 2001 From: Mina Lee Date: Sun, 8 Feb 2015 19:54:15 +0900 Subject: [PATCH 4/4] Make new properties be added without clicking plus button --- zeppelin-web/app/scripts/controllers/interpreter.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/zeppelin-web/app/scripts/controllers/interpreter.js b/zeppelin-web/app/scripts/controllers/interpreter.js index 05bcd924..aeb1f9a4 100644 --- a/zeppelin-web/app/scripts/controllers/interpreter.js +++ b/zeppelin-web/app/scripts/controllers/interpreter.js @@ -101,6 +101,8 @@ angular.module('zeppelinWebApp').controller('InterpreterCtrl', function($scope, return; } + $scope.addNewInterpreterProperty(settingId); + var properties = {}; for (var i=0; i < $scope.interpreterSettings.length; i++) { var setting = $scope.interpreterSettings[i];