diff --git a/smart-server/src/main/scala/org/smartdata/server/web/ActionService.scala b/smart-server/src/main/scala/org/smartdata/server/web/ActionService.scala new file mode 100644 index 00000000000..06ba0abc039 --- /dev/null +++ b/smart-server/src/main/scala/org/smartdata/server/web/ActionService.scala @@ -0,0 +1,103 @@ +/** + * 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.smartdata.server.web + +import java.util + +import scala.collection.JavaConverters._ +import akka.http.scaladsl.server.Directives.{complete, path, pathPrefix, _} +import akka.http.scaladsl.server.Route +import akka.http.scaladsl.server.directives.ParameterDirectives.ParamMagnet +import akka.stream.Materializer +import com.google.gson.Gson +import org.smartdata.actions.ActionRegistry +import org.smartdata.model._ +import org.smartdata.server.SmartEngine + +import scala.util.Random + +class ActionService(ssmServer: SmartEngine) extends BasicService { + private val gson: Gson = new Gson() + private val actions: util.Collection[ActionInfo] = new util.ArrayList[ActionInfo]() + val builder = new ActionInfo.Builder() + .setActionName("test") + .setCreateTime(1024) + .setFinished(true) + .setFinishTime(2048) + .setResult("this is result") + .setLog("this is log") + .setArgs(CmdletDescriptor.fromCmdletString("test -opt1 val1").getActionArgs(0)) + .setProgress(0.5f) + .setResult("objc[41272]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/bin/java (0x1075fd4c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x1076d94e0). One of the two will be used. Which one is undefined.") + .setLog("objc[41272]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/bin/java (0x1075fd4c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x1076d94e0). One of the two will be used. Which one is undefined.") + actions.add(builder.build()) + + private val actionTypes: util.Collection[ActionDescriptor] = new util.ArrayList[ActionDescriptor]() + actionTypes.add(new ActionDescriptor("ls", "List files", "Comment", "Usage")) + actionTypes.add(new ActionDescriptor("write", "Write files", "Comment", "Usage")) + + override protected def doRoute(implicit mat: Materializer): Route = + pathPrefix("actions" / LongNumber) { actionId => + path("detail") { + complete(gson.toJson(actions.asScala.find(_.getActionId == actionId).get)) +// complete(gson.toJson(ssmServer.getCommandExecutor.getActionInfo(actionId))) + } + } ~ + path("cachedfiles") { + val status = new util.ArrayList[CachedFileStatus]() + status.add(new CachedFileStatus(1, "file1", 1023, 2048, 5)) + status.add(new CachedFileStatus(2, "file2", 1023000, 2048000, 4)) + complete(gson.toJson(status)) +// complete(gson.toJson(ssmServer.getDBAdapter.getCachedFileStatus)) + } ~ + path("hotfiles") { +// val tables = ssmServer.getStatesManager.getTablesInLast(Constants.ONE_HOUR_IN_MILLIS) +// complete(gson.toJson(ssmServer.getDBAdapter.getHotFiles(tables, 20))) + val status = new util.ArrayList[FileAccessInfo]() + status.add(new FileAccessInfo(101L, "file1", 10)) + status.add(new FileAccessInfo(102L, "file2", 20)) + complete(gson.toJson(status)) + } ~ + path("actiontypes") { + complete(gson.toJson(ActionRegistry.supportedActions())) + } ~ + path("actionlist") { + complete(gson.toJson(actions)) + // complete(gson.toJson(ssmServer.getCommandExecutor.listNewCreatedActions(20))) + } ~ + path("submitaction" / Segment) { actionType => + post { + parameters(ParamMagnet("args")) { args: String => + val rule = java.net.URLDecoder.decode(args, "UTF-8") + val action = new ActionInfo.Builder().setActionName(actionType) + .setActionId(Math.abs(Random.nextInt())) + .setArgs(CmdletDescriptor.fromCmdletString(actionType + " " + args).getActionArgs(0)) + .setCreateTime(System.currentTimeMillis()) + .setFinished(false) + .setSuccessful(false).build() + actions.add(action) + try { +// ssmServer.getCommandExecutor.submitCommand(actionType + " " + args) + complete("Success") + } catch { + case e: Exception => failWith(e) + } + } + } + } +} diff --git a/smart-server/src/main/scala/org/smartdata/server/web/RuleService.scala b/smart-server/src/main/scala/org/smartdata/server/web/RuleService.scala new file mode 100644 index 00000000000..b6717f37fc7 --- /dev/null +++ b/smart-server/src/main/scala/org/smartdata/server/web/RuleService.scala @@ -0,0 +1,119 @@ +/** + * 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.smartdata.server.web + +import java.util + +import akka.http.scaladsl.server.Directives.{complete, path, _} +import akka.http.scaladsl.server.Route +import akka.stream.Materializer +import com.google.gson.Gson +import org.smartdata.model.CmdletState +import org.smartdata.model.{CmdletInfo, RuleInfo} +import org.smartdata.model.RuleState +import org.smartdata.server.SmartEngine +import org.smartdata.server.utils.JsonUtil + +import scala.collection.JavaConverters._ +import scala.util.Random + +class RuleService(ssmServer: SmartEngine) extends BasicService { + private val gson: Gson = new Gson() + private val rules: util.Collection[RuleInfo] = new util.ArrayList[RuleInfo]() + + override protected def doRoute(implicit mat: Materializer): Route = pathPrefix("rules" / IntNumber) { ruleId => + path("start") { + post { + try { + // ssmServer.getRuleManager.activateRule(ruleId) + rules.asScala.filter(_.getId == ruleId).foreach(_.setState(RuleState.ACTIVE)) + complete("success") + } catch { + case e: Exception => failWith(e) + } + } + } ~ + path("stop") { + delete { + try { + // ssmServer.getRuleManager.disableRule(ruleId, true) + rules.asScala.filter(_.getId == ruleId).foreach(_.setState(RuleState.DISABLED)) + complete("success") + } catch { + case e: Exception => failWith(e) + } + } + } ~ + path("detail") { + try { + complete(gson.toJson(rules.asScala.find(_.getId == ruleId).get)) +// complete(gson.toJson(ssmServer.getRuleManager.getRuleInfo(ruleId))) + } catch { + case e: Exception => failWith(e) + } + } ~ + path("errors") { + complete("{\"time\" : \"0\", \"error\" : \"\"}") + } ~ + path("cmdlets") { + val smap1 = new util.HashMap[String, String] + smap1.put("_FILE_PATH_", "/testCacheFile") + val cmdlet1 = new CmdletInfo(0, 1, + CmdletState.PENDING, JsonUtil.toJsonString(smap1), 123123333l, 232444444l) + val cmdlet2 = new CmdletInfo(1, 1, CmdletState.PENDING, + JsonUtil.toJsonString(smap1), 123178333l, 232444994l) + try { + complete(gson.toJson(util.Arrays.asList(cmdlet1, cmdlet2))) +// complete(gson.toJson(ssmServer.getCommandExecutor.listCommandsInfo(ruleId, null))) + } catch { + case e: Exception => failWith(e) + } + } + } ~ + path("rulelist") { + try { + complete(gson.toJson(rules)) +// complete(gson.toJson(ssmServer.getRuleManager.listRulesInfo())) + } catch { + case e: Exception => failWith(e) + } + } ~ + path("addrule") { + post { + entity(as[String]) { request => + val rule = java.net.URLDecoder.decode(request, "UTF-8") + System.out.println("Adding rule: " + rule) + try { + addRuleInfo(rule) +// ssmServer.getRuleManager.submitRule(rule, RuleState.DISABLED) + complete("Success") + } catch { + case e: Exception => failWith(e) + } + } + } + } + + private def addRuleInfo(rule: String): RuleInfo = { + val builder = RuleInfo.newBuilder + builder.setRuleText(rule).setId(Math.abs(Random.nextInt())).setState(RuleState.DISABLED) + val ruleInfo = builder.build + rules.add(ruleInfo) + ruleInfo + } +} diff --git a/smart-zeppelin/zeppelin-web/pom.xml b/smart-zeppelin/zeppelin-web/pom.xml index cd53f4e8444..387bdb8c65b 100644 --- a/smart-zeppelin/zeppelin-web/pom.xml +++ b/smart-zeppelin/zeppelin-web/pom.xml @@ -38,8 +38,8 @@ - v6.9.1 - v0.18.1 + v6.11.0 + v0.27.5 4.2.0 UTF-8 @@ -138,7 +138,7 @@ yarn - run build + run build --force diff --git a/smart-zeppelin/zeppelin-web/src/app/app.js b/smart-zeppelin/zeppelin-web/src/app/app.js index 56ffbbfd6de..250ceb436b1 100644 --- a/smart-zeppelin/zeppelin-web/src/app/app.js +++ b/smart-zeppelin/zeppelin-web/src/app/app.js @@ -150,6 +150,36 @@ var zeppelinWebApp = angular.module('zeppelinWebApp', [ }] } }) + .when('/mover', { + templateUrl: 'app/dashboard/views/mover/mover.html', + controller: 'MoverCtrl', + resolve: { + load: ['heliumService', function(heliumService) { + return heliumService.load; + }], + actions0: ['models', function (models) { + return models.$get.actions(); + }], + actionTypes: ['models', function (models) { + return models.$get.actionTypes(); + }] + } + }) + .when('/copy', { + templateUrl: 'app/dashboard/views/copy/copy.html', + controller: 'CopyCtrl', + resolve: { + load: ['heliumService', function(heliumService) { + return heliumService.load; + }], + actions0: ['models', function (models) { + return models.$get.actions(); + }], + actionTypes: ['models', function (models) { + return models.$get.actionTypes(); + }] + } + }) .when('/actions/action/:actionId', { templateUrl: 'app/dashboard/views/actions/action/action.html', controller: 'ActionCtrl', @@ -246,13 +276,13 @@ var zeppelinWebApp = angular.module('zeppelinWebApp', [ // constants .constant('conf', { restapiProtocol: 'v1', - restapiRoot: 'http://localhost:8080/', - // restapiRoot: rootPath, + // restapiRoot: 'http://localhost:8080/', + restapiRoot: rootPath, restapiQueryInterval: 3 * 1000, // in milliseconds restapiQueryTimeout: 30 * 1000, // in milliseconds restapiTaskLevelMetricsQueryLimit: 100, - loginUrl: 'http://localhost:8080/' + 'login' - // loginUrl: rootPath + 'login' + // loginUrl: 'http://localhost:8080/' + 'login' + loginUrl: rootPath + 'login' }) .constant('TRASH_FOLDER_ID', '~Trash'); diff --git a/smart-zeppelin/zeppelin-web/src/app/dashboard/styles/bootstrap-override.css b/smart-zeppelin/zeppelin-web/src/app/dashboard/styles/bootstrap-override.css index 77aa9a28806..f4605b74682 100644 --- a/smart-zeppelin/zeppelin-web/src/app/dashboard/styles/bootstrap-override.css +++ b/smart-zeppelin/zeppelin-web/src/app/dashboard/styles/bootstrap-override.css @@ -6,9 +6,9 @@ * 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 @@ -41,15 +41,6 @@ html, body { margin-left: 30px; } -/* Emphasize active navbar element for dark background (2 rules) */ -.navbar-inverse { - background-color: #373a3c; -} - -.navbar-inverse .navbar-nav > li > a:hover { - background-color: #444; -} - /* A extra small breadcrumb (2 rules) */ .breadcrumb-sm { margin-bottom: 8px; diff --git a/smart-zeppelin/zeppelin-web/src/app/dashboard/views/copy/copy.html b/smart-zeppelin/zeppelin-web/src/app/dashboard/views/copy/copy.html new file mode 100644 index 00000000000..df36730fa34 --- /dev/null +++ b/smart-zeppelin/zeppelin-web/src/app/dashboard/views/copy/copy.html @@ -0,0 +1,48 @@ +
+ + +
+
+ Copy +
+
+ +
+ +
+ +
+ +
+ +
+

+

No copy is running

+
+
+
diff --git a/smart-zeppelin/zeppelin-web/src/app/dashboard/views/copy/copy.js b/smart-zeppelin/zeppelin-web/src/app/dashboard/views/copy/copy.js new file mode 100644 index 00000000000..012d0b6c5ab --- /dev/null +++ b/smart-zeppelin/zeppelin-web/src/app/dashboard/views/copy/copy.js @@ -0,0 +1,84 @@ +/* + * 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. + */ +angular.module('zeppelinWebApp') + + .controller('CopyCtrl', CopyCtrl); + CopyCtrl.$inject = ['$scope', '$modal', '$sortableTableBuilder', '$dialogs', 'actions0', 'actionTypes']; + function CopyCtrl($scope, $modal, $stb, $dialogs, actions0, actionTypes) { + + $scope.actionsTable = { + cols: [ + // group 1/3 (4-col) + $stb.indicator().key('state').canSort('state.condition+"_"+createTime').styleClass('td-no-padding').done(), + $stb.text('ID').key('id').canSort().sortDefaultDescent().done(), + $stb.text('Cmdlet ID').key('cid').canSort().done(), + $stb.datetime('Create Time').key('createTime').canSort().done(), + $stb.datetime('Finish Time').key('finishTime').canSort().done(), + $stb.duration("Running Time").key('runningTime').canSort().done(), + $stb.text('File Path').key('filePath').canSort().styleClass('col-md-1').done(), + $stb.text('Target Path').key('targetPath').canSort().styleClass('col-md-1').done(), + $stb.text('Succeed').key('succeed').canSort().styleClass('col-md-1 hidden-sm hidden-xs').done(), + $stb.progressbar('Progress').key('progress').sortBy('progress.usage').styleClass('col-md-1').done(), + $stb.button('Actions').key(['view']).styleClass('col-md-3').done() + ], + rows: null + }; + + function updateTable(actions) { + $scope.actionsTable.rows = $stb.$update($scope.actionsTable.rows, + _.map(actions, function (action) { + return { + id: action.actionId, + cid: action.cmdletId, + state: {tooltip: action.status, condition: action.finished ? '' : 'good', shape: 'stripe'}, + createTime: action.createTime, + finishTime: action.finished ? action.finishTime : "-", + runningTime: action.uptime, + succeed: action.finished ? action.successful : "-", + view: { + href: action.pageUrl, + icon: function() { + return 'glyphicon glyphicon-info-sign'; + }, + class: 'btn-xs btn-info' + }, + progress: { + current: action.progress, + max: 1, + flag: action.finished ? action.successful : "-" + // usage: action.progress * 100 + }, + filePath: "FilePath", + targetPath: "TargetPath" + }; + })); + } + + updateTable(actions0.$data()); + actions0.$subscribe($scope, function (actions) { + updateTable(actions); + }); +/* + $(function () { + $("[data-toggle='tooltip']").tooltip({ + container: body + }); + });*/ + } + diff --git a/smart-zeppelin/zeppelin-web/src/app/dashboard/views/mover/mover.html b/smart-zeppelin/zeppelin-web/src/app/dashboard/views/mover/mover.html new file mode 100644 index 00000000000..d80bed69f95 --- /dev/null +++ b/smart-zeppelin/zeppelin-web/src/app/dashboard/views/mover/mover.html @@ -0,0 +1,48 @@ +
+ + +
+
+ Mover +
+
+ +
+ +
+ +
+ +
+ +
+

+

No mover is running

+
+
+
diff --git a/smart-zeppelin/zeppelin-web/src/app/dashboard/views/mover/mover.js b/smart-zeppelin/zeppelin-web/src/app/dashboard/views/mover/mover.js new file mode 100644 index 00000000000..8aeb2f6041b --- /dev/null +++ b/smart-zeppelin/zeppelin-web/src/app/dashboard/views/mover/mover.js @@ -0,0 +1,80 @@ +/* + * 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. + */ +angular.module('zeppelinWebApp') + + .controller('MoverCtrl', MoverCtrl); + MoverCtrl.$inject = ['$scope', '$modal', '$sortableTableBuilder', '$dialogs', 'actions0', 'actionTypes']; + function MoverCtrl($scope, $modal, $stb, $dialogs, actions0, actionTypes) { + + $scope.actionsTable = { + cols: [ + // group 1/3 (4-col) + $stb.indicator().key('state').canSort('state.condition+"_"+createTime').styleClass('td-no-padding').done(), + $stb.text('ID').key('id').canSort().sortDefaultDescent().done(), + $stb.text('Cmdlet ID').key('cid').canSort().done(), + $stb.datetime('Create Time').key('createTime').canSort().done(), + $stb.datetime('Finish Time').key('finishTime').canSort().done(), + $stb.duration("Running Time").key('runningTime').canSort().done(), + $stb.text('File').key('file').canSort().styleClass('col-md-1').done(), + $stb.text('Storage Type').key('sourceType').canSort().styleClass('col-md-1').done(), + $stb.text('Target Storage Type').key('targetType').canSort().styleClass('col-md-1').done(), + $stb.text('Succeed').key('succeed').canSort().styleClass('col-md-1 hidden-sm hidden-xs').done(), + $stb.progressbar('Progress').key('progress').sortBy('progress.usage').styleClass('col-md-1').done(), + $stb.button('Actions').key(['view']).styleClass('col-md-3').done() + ], + rows: null + }; + + function updateTable(actions) { + $scope.actionsTable.rows = $stb.$update($scope.actionsTable.rows, + _.map(actions, function (action) { + return { + id: action.actionId, + cid: action.cmdletId, + state: {tooltip: action.status, condition: action.finished ? '' : 'good', shape: 'stripe'}, + createTime: action.createTime, + finishTime: action.finished ? action.finishTime : "-", + runningTime: action.uptime, + succeed: action.finished ? action.successful : "-", + view: { + href: action.pageUrl, + icon: function() { + return 'glyphicon glyphicon-info-sign'; + }, + class: 'btn-xs btn-info' + }, + progress: { + current: action.progress, + max: 1, + flag: action.finished ? action.successful : "-" + // usage: action.progress * 100 + }, + file: "PATH", + sourceType: "COOL", + targetType: "ONESSD" + }; + })); + } + + updateTable(actions0.$data()); + actions0.$subscribe($scope, function (actions) { + updateTable(actions); + }); + } + diff --git a/smart-zeppelin/zeppelin-web/src/app/dashboard/views/rules/submit/submit.html b/smart-zeppelin/zeppelin-web/src/app/dashboard/views/rules/submit/submit.html index c15d56296d5..4d65faac18e 100644 --- a/smart-zeppelin/zeppelin-web/src/app/dashboard/views/rules/submit/submit.html +++ b/smart-zeppelin/zeppelin-web/src/app/dashboard/views/rules/submit/submit.html @@ -47,16 +47,11 @@

- + Rule Spec
diff --git a/smart-zeppelin/zeppelin-web/src/components/navbar/navbar.html b/smart-zeppelin/zeppelin-web/src/components/navbar/navbar.html index 4edbdebd2ae..20b9cbcf701 100644 --- a/smart-zeppelin/zeppelin-web/src/components/navbar/navbar.html +++ b/smart-zeppelin/zeppelin-web/src/components/navbar/navbar.html @@ -37,6 +37,8 @@
  • Rules
  • Actions
  • +
  • Mover
  • +
  • Copy