Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UD] Add diagnostic page with ability to check if workspaces can work or not #4207

Merged
merged 2 commits into from
Feb 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions dashboard/src/app/diagnostics/diagnostic-callback-state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (c) 2015-2017 Codenvy, S.A.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Codenvy, S.A. - initial API and implementation
*/

/**
* Defines the state of the diagnostic callback
* @author Florent Benoit
*/
export const enum DiagnosticCallbackState {
OK,
FAILURE,
ERROR,
RUNNING,
HINT
}
300 changes: 300 additions & 0 deletions dashboard/src/app/diagnostics/diagnostic-callback.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
/*
* Copyright (c) 2015-2017 Codenvy, S.A.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Codenvy, S.A. - initial API and implementation
*/
import {DiagnosticItem} from './diagnostic-item';
import {DiagnosticCallbackState} from './diagnostic-callback-state';
import {MessageBus, CheWebsocket} from '../../components/api/che-websocket.factory';
import {DiagnosticPart} from './diagnostic-part';
import {DiagnosticsController} from './diagnostics.controller';

/**
* Defines a callback of diagnostic. Allow to notify/report states, messages, etc.
* @author Florent Benoit
*/
export class DiagnosticCallback {

/**
* Parent item.
*/
private diagnosticPart : DiagnosticPart;

/**
* Promise service handling.
*/
private $q : ng.IQService;

/**
* Websocket API used to deal with websockets.
*/
private cheWebsocket : CheWebsocket;

/**
* Angular Timeout service
*/
private $timeout : ng.ITimeoutService;

/**
* defered object instance from q service
*/
private defered : ng.IDeferred;

/**
* List of all channels on which we're listening for websockets.
*/
private listeningChannels : Array<string>;

/**
* All timeouts that we're starting as part of this callback. They need to be stopped at the end.
*/
private timeoutPromises : Array<ng.IPromise>;

/**
* Map used to send data across different fonctions.
*/
private sharedMap : Map<string, any>;

/**
* Builder when a new sibling callback is required to be added/build.
*/
private builder : DiagnosticsController;

/**
* Allow to override the messagebus (originally it's grabbing it from cheWebsocket service)
*/
private messageBus : MessageBus;

/**
* Name of the callback.
*/
private name : string;

/**
* Content associated to the callback.
*/
private content: string;

/**
* All items attached to this category.
*/
private items : Array<DiagnosticItem>;


/**
* Constructor.
*/
constructor($q : ng.IQService, cheWebsocket : CheWebsocket, $timeout : ng.ITimeoutService, name: string, sharedMap : Map<string, any>, builder : any, diagnosticPart : DiagnosticPart) {
this.$q = $q;
this.cheWebsocket = cheWebsocket;
this.$timeout = $timeout;
this.defered = $q.defer();
this.listeningChannels = new Array<string>();
this.timeoutPromises = new Array<ng.IPromise>();
this.name = name;
this.sharedMap = sharedMap;
this.builder = builder;
this.diagnosticPart = diagnosticPart;
this.items = new Array<DiagnosticItem>();
}

/**
* Add the given value under the given key name.
* @param key the key for the storage (a string)
* @param value the value object
*/
public shared(key:string, value : any) : void {
this.sharedMap.set(key, value);
}

/**
* Allow to retrieved an object based on its key (string)
* @param key the string name
* @returns {undefined|any}
*/
public getShared(key:string) : any {
return this.sharedMap.get(key);
}

/**
* Build a new item instance
* @param message the message to store in the item
* @param hint any hint to add to the item
* @param state the state of this newly item
* @returns {DiagnosticItem} the newly created object
*/
private newItem(message, hint : string, state : DiagnosticCallbackState) {
let diagnosticItem = new DiagnosticItem();
diagnosticItem.title = this.name;
diagnosticItem.message = message;
if (hint) {
diagnosticItem.hint = hint;
}
diagnosticItem.state = state;
diagnosticItem.content = this.content;
this.diagnosticPart.addItem(diagnosticItem);
this.items.push(diagnosticItem);
return diagnosticItem;
}

/**
* Adds a running state item [like a new service that is now running received by server side event]
* @param message the message to display
* @param hint extra hint
*/
public stateRunning(message : string, hint? : string) : void {
this.newItem(message, hint, DiagnosticCallbackState.RUNNING);
this.cleanup();
this.defered.resolve(message);
}


/**
* Adds a success item [like the result of a test]
* @param message the message to display
* @param hint extra hint
*/
public success(message : string, hint? : string) : void {
this.newItem(message, hint, DiagnosticCallbackState.OK);
this.cleanup();
this.defered.resolve(message);
}

/**
* Notify a failure. note: it doesn't stop the execution flow. A success or an error will come after a failure.
* @param message the message to display
* @param hint extra hint
*/
notifyFailure(message : string, hint? : string) : void {
this.newItem(message, hint, DiagnosticCallbackState.FAILURE);
}

/**
* Only notify a hint.
* @param hint the hint to display
*/
notifyHint(hint : string) : void {
this.newItem('', hint, DiagnosticCallbackState.HINT);
}

/**
* Adds an error item [like the result of a test]. Note: it will break the current flow and cancel all existing promises.
* @param message the message to display
* @param hint extra hint
*/
public error(message : string, hint? : string) : void {
this.newItem(message, hint, DiagnosticCallbackState.ERROR);
this.cleanup();
this.defered.reject(message);
}

/**
* Add content to the callback
* @param content the content to add
*/
public addContent(content : string) : void {
if (!this.content) {
this.content = content;
} else {
this.content += '\n' + content;
}
}

/**
* Promise associated to this callback
* @returns {IPromise}
*/
public getPromise() : ng.IPromise {
return this.defered.promise;
}

/**
* MessageBus used to connect with websockets.
* @returns {MessageBus}
*/
public getMessageBus() : MessageBus {
if (this.messageBus) {
return this.messageBus;
} else {
return this.cheWebsocket.getBus();
}
}

/**
* Override the current messagebus
* @param messageBus
*/
public setMessageBus(messageBus : MessageBus) {
this.messageBus = messageBus;
}

/**
* Delay an error after a timeout. Allow to stop a test if there is no answer after some time.
* @param message
* @param delay the number of seconds to wait
*/
delayError(message: string, delay: number) {
let promise = this.$timeout(() => {this.error(message)}, delay);
this.timeoutPromises.push(promise);
}

/**
* Delay a function after a timeout.
* @param funct the callback function
* @param delay the number of seconds to wait
*/
delayFunction(funct: any, delay: number) {
let promise = this.$timeout(funct, delay);
this.timeoutPromises.push(promise);
}

/**
* Subscribe on message bus channel
*/
public subscribeChannel(channel : string, callback : any) : void {
this.getMessageBus().subscribe(channel, callback);
this.listeningChannels.push(channel);
}

/**
* Unsubscribe from message bus channel
*/
public unsubscribeChannel(channel : string) : void {
this.getMessageBus().unsubscribe(channel);
let index : number = this.listeningChannels.indexOf(channel);
if (index >= 0) {
delete this.listeningChannels[index];
}
}

/**
* Cleanup all resources (like current promises)
*/
protected cleanup() : void {
this.timeoutPromises.forEach((promise: ng.IPromise) => {
this.$timeout.cancel(promise);
});
this.timeoutPromises.length = 0;

this.listeningChannels.forEach((channel: string) => {
this.getMessageBus().unsubscribe(channel);
});
this.listeningChannels.length = 0;

}

/**
* Builder of a sibling callback
* @param text
* @returns {DiagnosticCallback}
*/
newCallback(text : string) : DiagnosticCallback{
return this.builder.newItem(text, this.diagnosticPart);
}

}
Loading