From d04cfb35342cdc998e89a7060e7b19baee129209 Mon Sep 17 00:00:00 2001 From: Fabio Buso Date: Sat, 11 Nov 2023 16:47:26 -0800 Subject: [PATCH] [HWORKS-803] Remove airflow from old UI (#1613) --- hopsworks-web/yo/app/index.html | 3 - hopsworks-web/yo/app/scripts/app.js | 20 -- .../scripts/controllers/dagComposerCtrl.js | 182 --------------- .../controllers/dagComposerModalsCtrl.js | 92 -------- .../yo/app/scripts/controllers/mainCtrl.js | 7 +- .../yo/app/scripts/controllers/projectCtrl.js | 24 +- .../yo/app/scripts/services/AirflowService.js | 51 ----- .../yo/app/scripts/services/ModalService.js | 30 --- hopsworks-web/yo/app/views/airflow.html | 74 ------- .../views/airflowDagOperatorProperties.html | 111 ---------- hopsworks-web/yo/app/views/dagComposer.html | 208 ------------------ 11 files changed, 8 insertions(+), 794 deletions(-) delete mode 100644 hopsworks-web/yo/app/scripts/controllers/dagComposerCtrl.js delete mode 100644 hopsworks-web/yo/app/scripts/controllers/dagComposerModalsCtrl.js delete mode 100644 hopsworks-web/yo/app/scripts/services/AirflowService.js delete mode 100644 hopsworks-web/yo/app/views/airflow.html delete mode 100644 hopsworks-web/yo/app/views/airflowDagOperatorProperties.html delete mode 100644 hopsworks-web/yo/app/views/dagComposer.html diff --git a/hopsworks-web/yo/app/index.html b/hopsworks-web/yo/app/index.html index 204fc3d3bf..fc8a82e7c0 100644 --- a/hopsworks-web/yo/app/index.html +++ b/hopsworks-web/yo/app/index.html @@ -273,8 +273,6 @@ - - @@ -292,7 +290,6 @@ - diff --git a/hopsworks-web/yo/app/scripts/app.js b/hopsworks-web/yo/app/scripts/app.js index cb6e930f6f..5b92535431 100644 --- a/hopsworks-web/yo/app/scripts/app.js +++ b/hopsworks-web/yo/app/scripts/app.js @@ -312,26 +312,6 @@ angular.module('hopsWorksApp', [ }] } }) - .when('/project/:projectID/airflow', { - templateUrl: 'views/airflow.html', - controller: 'ProjectCtrl as projectCtrl', - resolve: { - auth: ['$q', '$route', 'AuthGuardService', - function ($q, $route, AuthGuardService) { - return AuthGuardService.guardProject($q, $route.current.params.projectID); - }] - } - }) - .when('/project/:projectID/airflow/dagcomposer', { - templateUrl: 'views/dagComposer.html', - controller: 'ProjectCtrl as projectCtrl', - resolve: { - auth: ['$q', '$route', 'AuthGuardService', - function ($q, $route, AuthGuardService) { - return AuthGuardService.guardProject($q, $route.current.params.projectID); - }] - } - }) .when('/project/:projectID/newjob', { templateUrl: 'views/newJob.html', controller: 'ProjectCtrl as projectCtrl', diff --git a/hopsworks-web/yo/app/scripts/controllers/dagComposerCtrl.js b/hopsworks-web/yo/app/scripts/controllers/dagComposerCtrl.js deleted file mode 100644 index f94df91017..0000000000 --- a/hopsworks-web/yo/app/scripts/controllers/dagComposerCtrl.js +++ /dev/null @@ -1,182 +0,0 @@ -/* - * This file is part of Hopsworks - * Copyright (C) 2019, Logical Clocks AB. All rights reserved - * - * Hopsworks is free software: you can redistribute it and/or modify it under the terms of - * the GNU Affero General Public License as published by the Free Software Foundation, - * either version 3 of the License, or (at your option) any later version. - * - * Hopsworks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License along with this program. - * If not, see . - */ -'use strict'; - -angular.module('hopsWorksApp') - .controller('DagComposerCtrl', ['$routeParams', 'growl', '$location', 'ModalService', 'AirflowService', - 'JobService', - function($routeParams, growl, $location, ModalService, AirflowService, JobService) { - self = this; - self.projectId = $routeParams.projectID; - - self.jobs; - self.newDagDefined = false; - // DAG properties - self.dag = { - name: "", - scheduleInterval: "@once", - operators: [] - }; - var getJobsPromise; - - self.showCart = true; - self.toggleCart = function() { - self.showCart = !self.showCart; - } - - self.showAdvanced = false; - self.toggleAdvanced = function() { - self.showAdvanced = !self.showAdvanced; - } - - self.removeOperatorFromDag = function(index) { - self.dag.operators.splice(index, 1); - } - - self.returnToFileManager = function() { - $location.path("project/" + self.projectId + "/airflow"); - } - - self.init = function() { - self.getJobsPromise = JobService.getJobs(self.projectId, 0, 0, ""); - } - - self.isUndefined = function(input) { - return typeof input === "undefined"; - } - - // Operators - // Attributes mask [hasJobName, hasWait2Finish, hasFeatureGroupsName] - var Operator = function(type, name, description, attributesMask) { - // Do NOT change the attributes order! - this.HAS_JOB_NAME_ATTR = 0; - this.HAS_WAIT_2_FINISH_ATTR = 1; - this.HAS_FEATURE_GROUPS_NAME_ATTR = 2; - this.CAN_REQUIRE_JOB_ARGUMENTS = 3 - - this.type = type; - this.name = name; - this.description = description; - this.attributesMask = attributesMask; - this.jobArgs = ""; - } - - Operator.prototype.hasAttribute = function(attribute) { - if (this.attributesMask.length < attribute || attribute < 0) { - return false; - } - return this.attributesMask[attribute]; - } - - var launchJobOperator = new Operator(0, "HopsworksLaunchOperator", - "Operator to launch a Job in Hopsworks. Job should already be defined in Jobs UI " - + "and job name in operator must match the job name in Jobs UI.", [true, true, false, true]); - - var jobSensor = new Operator(1, "HopsworksJobSuccessSensor", - "Operator which waits for the completion of a specific job. Job must be defined " - + "in Jobs UI and job name in operator must match the job name in Jobs UI. " - + "The task will fail too if the job which is waiting for fails.", [true, false]); - - self.availableOperators = [launchJobOperator, jobSensor]; - - self.finishedDagDefinition = function() { - if (self.isUndefined(self.dag.name) || self.dag.name == "") { - var errorMsg = "DAG name is required"; - } else if (self.isUndefined(self.dag.scheduleInterval) || self.dag.scheduleInterval == "") { - var errorMsg = "DAG schedule interval is required"; - } - if (self.isUndefined(errorMsg)) { - growl.info("You can continue adding Operators", - {title: "Created new DAG definition", ttl: 3000, referenceId: 'dag_comp_growl'}); - self.newDagDefined = true; - } else { - growl.error(errorMsg, - {title: 'Failed to create new DAG definition', ttl: 5000, referenceId: 'dag_comp_growl'}); - self.newDagDefined = false; - } - } - - self.addOperator = function(operator) { - if (!self.newDagDefined) { - growl.error("You should define DAG properties before start adding operators", - {title: "Failed to add operator", ttl: 5000, referenceId: "dag_comp_growl"}); - return; - } - - var thisthis = self; - var newOperator = new Operator(operator.type, operator.name, operator.description, operator.attributesMask); - if (newOperator.hasAttribute(newOperator.HAS_WAIT_2_FINISH_ATTR)) { - newOperator.wait = true; - } - - self.getJobsPromise.then( - function(success) { - if (self.isUndefined(self.jobs)) { - var idx = 0; - self.jobs = []; - success.data.items.forEach(function(value, key) { - self.jobs[idx] = value - idx++; - }) - } - ModalService.addOperator2AirflowDag('lg', newOperator, self.jobs, self.dag.operators).then( - function(operator) { - thisthis.dag.operators.push(operator); - self = thisthis; - }, function(error) { - self = thisthis; - } - ) - }, function(error) { - growl.error("Could not fetch Project's jobs. Please try again", - {title: "Failed to add operator", ttl: 5000, referenceId: "dag_comp_growl"}); - } - ) - } - - self.generateAirflowDag = function() { - if (self.dag.operators.length == 0) { - growl.error("No tasks have been added to workflow", - {title: "Could not create workflow", ttl: 5000, referenceId: "dag_comp_growl"}); - return; - } - - //Construct new dag to send, backend does not accept sending unknown fields such as HAS_JOB_NAME_ATTR or attributesMask - var newDag = {'name': self.dag.name, 'scheduleInterval': self.dag.scheduleInterval, 'operators': []}; - for (var i = 0; i < self.dag.operators.length; i++) { - var operator = self.dag.operators[i]; - newDag.operators.push({'name': operator.name, - 'wait': operator.wait, - 'id': operator.id, - 'jobName': operator.jobName, - 'dependsOn': operator.dependsOn, - 'jobArgs': operator.jobArgs}); - } - - AirflowService.generateDag(self.projectId, newDag).then( - function(success) { - growl.info("Generated DAG " + self.dag.name, - {title: "Success", ttl: 3000, referenceId: "dag_comp_growl"}); - self.returnToFileManager(); - }, function(error) { - growl.error(error.data.usrMsg, - {title: "Could not generate DAG file", ttl: 5000, referenceId: "dag_comp_growl"}); - } - ) - } - self.init(); - } -]); \ No newline at end of file diff --git a/hopsworks-web/yo/app/scripts/controllers/dagComposerModalsCtrl.js b/hopsworks-web/yo/app/scripts/controllers/dagComposerModalsCtrl.js deleted file mode 100644 index f1c482b19c..0000000000 --- a/hopsworks-web/yo/app/scripts/controllers/dagComposerModalsCtrl.js +++ /dev/null @@ -1,92 +0,0 @@ -/* - * This file is part of Hopsworks - * Copyright (C) 2019, Logical Clocks AB. All rights reserved - * - * Hopsworks is free software: you can redistribute it and/or modify it under the terms of - * the GNU Affero General Public License as published by the Free Software Foundation, - * either version 3 of the License, or (at your option) any later version. - * - * Hopsworks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License along with this program. - * If not, see . - */ -'use strict'; -angular.module('hopsWorksApp') - .controller('DagComposerModalsCtrl', ['$uibModalInstance', 'growl', 'operator', 'jobs', 'addedOperators', - function($uibModalInstance, growl, operator, jobs, addedOperators) { - self = this; - self.operator = operator; - self.jobs = jobs; - self.jobNames = []; - self.addedOperators = addedOperators; - self.jobCanTakeArguments = false; - - self.tmpDagDefinition = { - dependsOn: [] - }; - - self.addOperator2Dag = function() { - if (!self.operator.hasAttribute(self.operator.HAS_JOB_NAME_ATTR) - && (self.isUndefined(self.operator.id) || self.operator.id == "")) { - var errorMsg = "Operator name is required"; - } else if (self.operator.hasAttribute(self.operator.HAS_JOB_NAME_ATTR) - && (self.isUndefined(self.operator.jobName) || self.operator.jobName == "")) { - var errorMsg = "Job name to operate is required"; - } else if (self.operator.hasAttribute(self.operator.HAS_WAIT_2_FINISH_ATTR) - && self.isUndefined(self.operator.wait)) { - var errorMsg = "Wait for job to finish flag is required"; - } else if (self.operator.hasAttribute(self.operator.HAS_FEATURE_GROUPS_NAME_ATTR) - && (self.isUndefined(self.operator.featureGroupName) || self.operator.featureGroupName == "")) { - var errorMsg = "Feature group name is required"; - } - if (self.isUndefined(errorMsg)) { - if (self.operator.type == 0) { - self.operator.id = "launch_" + self.operator.jobName; - } else if (self.operator.type == 1) { - self.operator.id = "wait_" + self.operator.jobName; - } - growl.info("Operator " + self.operator.id + " successfully added to DAG", - {title: "Added operator", ttl: 2000, referenceId: "dag_comp_growl"}); - self.operator.dependsOn = []; - for (var idx = 0; idx < self.tmpDagDefinition.dependsOn.length; idx++) { - self.operator.dependsOn[idx] = self.tmpDagDefinition.dependsOn[idx].id; - } - $uibModalInstance.close(self.operator); - } else { - growl.error(errorMsg, - {title: "Failed to add operator", ttl: 5000, referenceId: "dag_comp_growl"}); - $uibModalInstance.dismiss('cancel'); - } - } - - self.init = function () { - self.jobs.forEach(function (j) { - self.jobNames.push(j.name); - }); - } - - self.isUndefined = function(input) { - return typeof input === "undefined"; - } - - self.close = function() { - $uibModalInstance.dismiss('cancel'); - } - - self.checkIfJobCanTakeArguments = function () { - var selectedJob = self.jobs.find(function (j) { - return j.name == self.operator.jobName; - }); - if(selectedJob != null) { - if(selectedJob.jobType.toUpperCase() !== 'FLINK') { - self.jobCanTakeArguments = true; - } - } - } - - self.init(); - } - ]); \ No newline at end of file diff --git a/hopsworks-web/yo/app/scripts/controllers/mainCtrl.js b/hopsworks-web/yo/app/scripts/controllers/mainCtrl.js index c3eb5de580..f82e2890f7 100644 --- a/hopsworks-web/yo/app/scripts/controllers/mainCtrl.js +++ b/hopsworks-web/yo/app/scripts/controllers/mainCtrl.js @@ -47,16 +47,15 @@ angular.module('hopsWorksApp') '$http', 'AuthService', 'UtilsService', 'ElasticService', 'DelaProjectService', 'DelaService', 'md5', 'ModalService', 'ProjectService', 'growl', 'MessageService', '$routeParams', '$window', 'HopssiteService', 'BannerService', - 'AirflowService', 'PaginationService', 'VariablesService', 'StorageService', + 'PaginationService', 'VariablesService', 'StorageService', function ($q, $interval, $location, $scope, $rootScope, $http, AuthService, UtilsService, ElasticService, DelaProjectService, DelaService, md5, ModalService, ProjectService, growl, MessageService, $routeParams, $window, HopssiteService, BannerService, - AirflowService, PaginationService, VariablesService, StorageService) { + PaginationService, VariablesService, StorageService) { var self = this; const MAX_IN_MEMORY_ITEMS = 1000; - self.ui = "/hopsworks-api/airflow/login?q=username="; self.email = StorageService.get('email'); self.emailHash = md5.createHash(self.email || ''); @@ -86,8 +85,6 @@ angular.module('hopsWorksApp') }; self.logout = function () { - AirflowService.logout(); - AuthService.logout(self.user).then( function (success) { AuthService.cleanSession(); diff --git a/hopsworks-web/yo/app/scripts/controllers/projectCtrl.js b/hopsworks-web/yo/app/scripts/controllers/projectCtrl.js index 2d9488f642..6681393282 100644 --- a/hopsworks-web/yo/app/scripts/controllers/projectCtrl.js +++ b/hopsworks-web/yo/app/scripts/controllers/projectCtrl.js @@ -46,10 +46,10 @@ angular.module('hopsWorksApp') .controller('ProjectCtrl', ['$scope', '$rootScope', '$location', '$routeParams', '$route', '$timeout', '$window', 'UtilsService', 'growl', 'ProjectService', 'ModalService', 'ActivityService', 'DataSetService', 'UserService', 'TourService', 'PythonService', 'StorageService', 'CertService', 'VariablesService', 'FileSaver', 'Blob', - 'AirflowService', '$http', + '$http', function ($scope, $rootScope, $location, $routeParams, $route, $timeout, $window, UtilsService, growl, ProjectService, ModalService, ActivityService, DataSetService, UserService, TourService, PythonService, - StorageService, CertService, VariablesService, FileSaver, Blob, AirflowService, $http) { + StorageService, CertService, VariablesService, FileSaver, Blob, $http) { var self = this; self.loadedView = false; @@ -325,14 +325,6 @@ angular.module('hopsWorksApp') self.goToUrl('rstudio'); }; - self.goToDagComposer = function() { - self.goToUrl('airflow/dagcomposer'); - }; - - self.goToAirflow = function () { - self.goToUrl('airflow'); - }; - self.goToJobs = function () { self.toggleKibanaNavBar(); self.goToUrl('jobs'); @@ -386,6 +378,10 @@ angular.module('hopsWorksApp') $window.location.href = '/p/' + self.projectId; }; + self.goToAirflow = function () { + $window.location.href = '/p/' + self.projectId + '/airflow'; + }; + self.goToPython = function () { self.goToUrl('python'); }; @@ -768,14 +764,6 @@ angular.module('hopsWorksApp') $window.open(self.ui, '_blank'); }; - self.connectToAirflow = function () { - // Open airlfow - var newTab = $window.open('about:blank', '_blank'); - $http.get(getApiLocationBase() + "/airflow").then ( function (response) { - newTab.location.href = getApiLocationBase() + "/airflow/admin"; - }) - }; - var kibanaNavVarInitKey = "hopsworks.kibana.navbar.set"; self.toggleKibanaNavBar = function () { var kibanaNavBarInit = StorageService.get(kibanaNavVarInitKey); diff --git a/hopsworks-web/yo/app/scripts/services/AirflowService.js b/hopsworks-web/yo/app/scripts/services/AirflowService.js deleted file mode 100644 index 698e294ca8..0000000000 --- a/hopsworks-web/yo/app/scripts/services/AirflowService.js +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * This file is part of Hopsworks - * Copyright (C) 2018, Logical Clocks AB. All rights reserved - * - * Hopsworks is free software: you can redistribute it and/or modify it under the terms of - * the GNU Affero General Public License as published by the Free Software Foundation, - * either version 3 of the License, or (at your option) any later version. - * - * Hopsworks is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License along with this program. - * If not, see . - * - */ - -/*global angular: false */ - -'use strict'; - -angular.module('hopsWorksApp') - .factory('AirflowService', ['$http', function ($http) { - return { - logout: function() { - $http.get(getApiLocationBase() + '/airflow/admin/airflow/logout').then( - function successCallback(response) { - // Do nothing - }, function errorCallback(response) { - // I wish http module had a way not to follow redirects!!! - // When Airflow logs out a user, it sends a redirect - // which in browser console will appear as 403 or 500 INTERNAL ERROR - // - // Both status codes are normal. - console.info("Logged out from Airflow successfully"); - }); - }, - generateDag: function(projectId, dagDefinition) { - var request = { - method: 'POST', - url: '/api/project/' + projectId + '/airflow/dag', - headers: { - 'Content-Type': 'application/json' - }, - data: dagDefinition - }; - return $http(request); - } - }; - }]); diff --git a/hopsworks-web/yo/app/scripts/services/ModalService.js b/hopsworks-web/yo/app/scripts/services/ModalService.js index 6ef147d632..7189d266f8 100644 --- a/hopsworks-web/yo/app/scripts/services/ModalService.js +++ b/hopsworks-web/yo/app/scripts/services/ModalService.js @@ -1170,36 +1170,6 @@ angular.module('hopsWorksApp') }); return modalInstance.result; }, - addOperator2AirflowDag: function(size, operator, jobs, addedOperators) { - var modalInstance = $uibModal.open({ - templateUrl: 'views/airflowDagOperatorProperties.html', - controller: 'DagComposerModalsCtrl as dagComposerModalsCtrl', - size: size, - resolve: { - auth: ['$q', '$location', 'AuthService', - function ($q, $location, AuthService) { - return AuthService.session().then( - function (success) { - }, - function (err) { - $location.path('/login'); - $location.replace(); - return $q.reject(err); - }); - }], - operator: function() { - return operator; - }, - jobs: function() { - return jobs; - }, - addedOperators: function() { - return addedOperators; - } - } - }); - return modalInstance.result; - }, selectFromList: function(size, msg, list) { var modalInstance = $uibModal.open({ templateUrl: 'views/selectFromList.html', diff --git a/hopsworks-web/yo/app/views/airflow.html b/hopsworks-web/yo/app/views/airflow.html deleted file mode 100644 index fc6565bbf7..0000000000 --- a/hopsworks-web/yo/app/views/airflow.html +++ /dev/null @@ -1,74 +0,0 @@ - - - -
-
- - -
-
- -
-
-
-
-
-
- - -
-

-
-
- - -
-
-
-
- -
diff --git a/hopsworks-web/yo/app/views/airflowDagOperatorProperties.html b/hopsworks-web/yo/app/views/airflowDagOperatorProperties.html deleted file mode 100644 index 5a9ea34e0f..0000000000 --- a/hopsworks-web/yo/app/views/airflowDagOperatorProperties.html +++ /dev/null @@ -1,111 +0,0 @@ - - - - \ No newline at end of file diff --git a/hopsworks-web/yo/app/views/dagComposer.html b/hopsworks-web/yo/app/views/dagComposer.html deleted file mode 100644 index 6b66c6e5f5..0000000000 --- a/hopsworks-web/yo/app/views/dagComposer.html +++ /dev/null @@ -1,208 +0,0 @@ - -
-
- -
-
-
-
-
- -
-
-
-
-
-

Workflow properties

-
- -
- -
-
Name -
-
- -
-
- -
-
Scheduler interval -
-
- -
-
- -
-
- -
- -
- -
- -
-
API key -
-
- -
-
-
-
- -
-
-
-
- -
-
-
-
-

-
-
-

{{dagComposerCtrl.dag.name}}

-
-
- - -
-
-
-
-

-
-
-

{{dagComposerCtrl.dag.scheduleInterval}}

-
-
-
-
-

-
-
-

{{dagComposerCtrl.dag.apiKey}}

-
-
-
-
- -
-
-
-
-
-
-
-

{{operator.name}}

-

{{operator.description}}

- - Add - -
-
-
-
-
- -
- -
- -
-
- {{dagComposerCtrl.dag.operators.length}} -
- Total: - {{dagComposerCtrl.dag.operators.length}} - -
-
- - - - -
    -
  • - - {{operator.id}} - Type: {{operator.name}} -
  • -
- Generate Airflow - DAG -
-
-
-
- - -
-
- -
-
-
\ No newline at end of file