Skip to content

Commit

Permalink
Use dashboard to restart the workspace (#15180)
Browse files Browse the repository at this point in the history
* Use dashboard to restart the workspace

Signed-off-by: Vitaliy Gulyy <vgulyy@redhat.com>

* Use authorization header instead of query parameter

Signed-off-by: Vitaliy Gulyy <vgulyy@redhat.com>
  • Loading branch information
vitaliy-guliy committed Nov 14, 2019
1 parent 145e7c4 commit bd429a0
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 24 deletions.
128 changes: 104 additions & 24 deletions src/app/ide/ide-iframe/ide-iframe.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
* Red Hat, Inc. - initial API and implementation
*/
'use strict';
import {CheUIElementsInjectorService} from '../../../components/service/injector/che-ui-elements-injector.service';

import { CheWorkspace } from '../../../components/api/workspace/che-workspace.factory';
import IdeSvc from '../ide.service';

/*global $:false */

Expand All @@ -26,53 +28,131 @@ interface IIdeIFrameRootScope extends ng.IRootScopeService {
* @author Florent Benoit
*/
class IdeIFrameSvc {
static $inject = ['$window', '$location', '$rootScope', '$mdSidenav'];

static $inject = ['$window', '$location', '$rootScope', '$mdSidenav', 'cheWorkspace', 'ideSvc'];

private $location: ng.ILocationService;
private $rootScope: IIdeIFrameRootScope;
private $mdSidenav: ng.material.ISidenavService;
private cheWorkspace: CheWorkspace;
private ideSvc: IdeSvc;

/**
* Default constructor that is using resource
*/
constructor($window: ng.IWindowService,
$location: ng.ILocationService,
$rootScope: IIdeIFrameRootScope,
$mdSidenav: ng.material.ISidenavService) {
$mdSidenav: ng.material.ISidenavService,
cheWorkspace: CheWorkspace,
ideSvc: IdeSvc) {
this.$location = $location;
this.$rootScope = $rootScope;
this.$mdSidenav = $mdSidenav;
this.cheWorkspace = cheWorkspace;
this.ideSvc = ideSvc;

$window.addEventListener('message', (event: any) => {
if ('show-ide' === event.data) {
if (this.isWaitingIDE()) {
$rootScope.$apply(() => {
$rootScope.showIDE = true;
$rootScope.hideLoader = true;
});
}
} else if ('show-workspaces' === event.data) {
$rootScope.$apply(() => {
$location.path('/workspaces');
});

} else if ('show-navbar' === event.data) {
$rootScope.hideNavbar = false;
$mdSidenav('left').open();

} else if ('hide-navbar' === event.data) {
if (this.isWaitingIDE()) {
$rootScope.hideNavbar = true;
$mdSidenav('left').close();
}
if (!event || typeof event.data !== "string") {
return;
}

const msg: string = event.data;

if ('show-ide' === msg) {
this.showIDE();
return;
}

if ('show-workspaces' === msg) {
this.showWorkspaces();
return;
}

if ('show-navbar' === msg) {
this.showNavBar();
return;
}

if ('hide-navbar' === msg) {
this.hideNavBar();
return;
}

if (msg.startsWith('restart-workspace:')) {
this.restartWorkspace(msg);
return;
}

}, false);
}

private showIDE(): void {
if (this.isWaitingIDE()) {
this.$rootScope.$apply(() => {
this.$rootScope.showIDE = true;
this.$rootScope.hideLoader = true;
});
}
}

private showWorkspaces(): void {
this.$rootScope.$apply(() => {
this.$location.path('/workspaces');
});
}

private showNavBar(): void {
this.$rootScope.hideNavbar = false;
this.$mdSidenav('left').open();
}

private hideNavBar(): void {
if (this.isWaitingIDE()) {
this.$rootScope.hideNavbar = true;
this.$mdSidenav('left').close();
}
}

/**
* Restarts the workspace
*
* @param message message from Editor in format
* restart-workspace:${workspaceId}:${token}
* Where
* 'restart-workspace' - action name
* ${workspaceId} - workpsace ID
* ${token} - Che machine token to validate
*/
private restartWorkspace(message: string): void {
// cut action name
message = message.substring(message.indexOf(':') + 1);

// get workpsace ID
const workspaceId = message.substring(0, message.indexOf(':'));

// get Che machine token
const token = message.substring(message.indexOf(':') + 1);

this.cheWorkspace.validateMachineToken(workspaceId, token).then(() => {
this.cheWorkspace.stopWorkspace(workspaceId).then(() => {
this.ideSvc.reloadIdeFrame();
}).catch((error) => {
console.error('Unable to stop workspace. ', error);
});
}).catch(() => {
console.error('Unable to stop workspace: token is not valid.');
});
}

/**
* Returns true if the user is waiting for IDE.
* @returns {boolean}
*/
private isWaitingIDE(): boolean {
return /\/ide\//.test(this.$location.path());
}

}

export default IdeIFrameSvc;
11 changes: 11 additions & 0 deletions src/app/ide/ide.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,17 @@ class IdeSvc {
});
}

/**
* Reloads frame with IDE
*/
reloadIdeFrame(): void {
let iframe = angular.element('#ide-application-iframe');
if (iframe) {
const src = iframe.attr('src');
iframe.attr('src', src);
}
}

/**
* Emit event to move workspace immediately
* to top of the recent workspaces list
Expand Down
28 changes: 28 additions & 0 deletions src/components/api/workspace/che-workspace.factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,34 @@ export class CheWorkspace {
return defer.promise;
}

/**
* Validates machine token for the workspace
*
* @param workspaceId workspace ID
* @param token Che machine token
*/
validateMachineToken(workspaceId: string, token: string): ng.IPromise<any> {
const defer = this.$q.defer();

const promise: ng.IHttpPromise<any> = this.$http.get(`/api/workspace/${workspaceId}`, {
headers: {
'Authorization': `Bearer ${token}`
}
});

promise.then((response: ng.IHttpPromiseCallbackArg<che.IWorkspace>) => {
defer.resolve();
}, (error: any) => {
if (error && error.status === 304) {
defer.resolve();
return;
}
defer.reject(error);
});

return defer.promise;
}

/**
* Adds a project on the workspace
* @param workspaceId {string} the workspace ID required to add a project
Expand Down

0 comments on commit bd429a0

Please sign in to comment.