Skip to content

Commit

Permalink
Merge pull request #427 from Senyoret1/dmsg-info
Browse files Browse the repository at this point in the history
Add DMSG info to the manager

Former-commit-id: f496ad8
  • Loading branch information
jdknives authored Jul 10, 2020
2 parents 3bc4e25 + 270f70f commit 5c017c9
Show file tree
Hide file tree
Showing 9 changed files with 237 additions and 32 deletions.
4 changes: 4 additions & 0 deletions static/skywire-manager-src/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ const routes: Routes = [
path: '',
component: NodeListComponent
},
{
path: 'dmsg',
component: NodeListComponent
},
{
path: ':key',
component: NodeComponent,
Expand Down
2 changes: 2 additions & 0 deletions static/skywire-manager-src/src/app/app.datatypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export class Node {
online?: boolean;
seconds_online?: number;
health?: HealthInfo;
dmsgServerPk?: string;
roundTripPing?: string;
}

export interface Application {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<app-tab-bar
[titleParts]="['start.title']"
[tabsData]="tabsData"
[selectedTabIndex]="0"
[selectedTabIndex]="!showDmsgInfo ? 0 : 1"
[showUpdateButton]="false"
></app-tab-bar>
</div>
Expand All @@ -17,7 +17,7 @@
<app-tab-bar
[titleParts]="['start.title']"
[tabsData]="tabsData"
[selectedTabIndex]="0"
[selectedTabIndex]="!showDmsgInfo ? 0 : 1"
[secondsSinceLastUpdate]="secondsSinceLastUpdate"
[showLoading]="updating"
[showAlert]="errorsUpdating"
Expand All @@ -39,14 +39,22 @@
<span class="dot-outline-gray"></span>
<mat-icon *ngIf="sortBy === sortableColumns.State" [inline]="true">{{ sortingArrow }}</mat-icon>
</th>
<th class="sortable-column" (click)="changeSortingOrder(sortableColumns.Label)">
<th class="sortable-column labels" (click)="changeSortingOrder(sortableColumns.Label)">
{{ 'nodes.label' | translate }}
<mat-icon *ngIf="sortBy === sortableColumns.Label" [inline]="true">{{ sortingArrow }}</mat-icon>
</th>
<th class="sortable-column" (click)="changeSortingOrder(sortableColumns.Key)">
{{ 'nodes.key' | translate }}
<mat-icon *ngIf="sortBy === sortableColumns.Key" [inline]="true">{{ sortingArrow }}</mat-icon>
</th>
<th *ngIf="showDmsgInfo" class="sortable-column" (click)="changeSortingOrder(sortableColumns.DmsgServer)">
{{ 'nodes.dmsg-server' | translate }}
<mat-icon *ngIf="sortBy === sortableColumns.DmsgServer" [inline]="true">{{ sortingArrow }}</mat-icon>
</th>
<th *ngIf="showDmsgInfo" class="sortable-column" (click)="changeSortingOrder(sortableColumns.Ping)">
{{ 'nodes.ping' | translate }}
<mat-icon *ngIf="sortBy === sortableColumns.Ping" [inline]="true">{{ sortingArrow }}</mat-icon>
</th>
<th class="actions"></th>
</tr>

Expand All @@ -60,13 +68,20 @@
</td>
<td>
{{ node.local_pk }}
<!--<app-copy-to-clipboard-text [short]="true" text="{{ node.local_pk }}" shortTextLength="5"></app-copy-to-clipboard-text>-->
</td>
<td *ngIf="showDmsgInfo">
{{ node.dmsgServerPk }}
<!--<app-copy-to-clipboard-text [short]="true" text="{{ node.dmsgServerPk }}" shortTextLength="5"></app-copy-to-clipboard-text>-->
</td>
<td *ngIf="showDmsgInfo">
{{ 'common.time-in-ms' | translate:{ time: node.roundTripPing } }}
</td>
<td (click)="$event.stopPropagation()" class="actions">
<button
[clipboard]="node.local_pk"
(copyEvent)="onCopyToClipboardClicked()"
(click)="copyToClipboard(node)"
mat-icon-button
[matTooltip]="'nodes.copy-key' | translate"
[matTooltip]="(showDmsgInfo ? 'nodes.copy-data' : 'nodes.copy-key') | translate"
class="big-action-button transparent-button"
>
<mat-icon [inline]="true">filter_none</mat-icon>
Expand Down Expand Up @@ -135,7 +150,17 @@
</div>
<div class="list-row long-content">
<span class="title">{{ 'nodes.key' | translate }}</span>:
{{ node.local_pk }}
<app-copy-to-clipboard-text [short]="true" text="{{ node.local_pk }}" shortTextLength="5"></app-copy-to-clipboard-text>
<!--{{ node.local_pk }}-->
</div>
<div class="list-row long-content" *ngIf="showDmsgInfo">
<span class="title">{{ 'nodes.dmsg-server' | translate }}</span>:
<!--{{ node.dmsgServerPk }}-->
<app-copy-to-clipboard-text [short]="true" text="{{ node.dmsgServerPk }}" shortTextLength="5"></app-copy-to-clipboard-text>
</div>
<div class="list-row" *ngIf="showDmsgInfo">
<span class="title">{{ 'nodes.ping' | translate }}</span>:
{{ 'common.time-in-ms' | translate:{ time: node.roundTripPing } }}
</div>
</div>
<div class="margin-part"></div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.labels {
width: 15%;
}

.actions {
text-align: right;
width: 120px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ enum SortableColumns {
State = 'transports.state',
Label = 'nodes.label',
Key = 'nodes.key',
DmsgServer = 'nodes.dmsg-server',
Ping = 'nodes.ping',
}

/**
Expand All @@ -39,7 +41,8 @@ enum SortableColumns {
styleUrls: ['./node-list.component.scss'],
})
export class NodeListComponent implements OnInit, OnDestroy {
private static sortByInternal = SortableColumns.Key;
private static defaultSortableColumn = SortableColumns.Key;
private static sortByInternal = NodeListComponent.defaultSortableColumn;
private static sortReverseInternal = false;

// Vars for keeping track of the column used for sorting the data.
Expand All @@ -55,6 +58,7 @@ export class NodeListComponent implements OnInit, OnDestroy {
loading = true;
dataSource: Node[];
tabsData: TabButtonData[] = [];
showDmsgInfo = false;

private dataSubscription: Subscription;
private updateTimeSubscription: Subscription;
Expand All @@ -79,13 +83,21 @@ export class NodeListComponent implements OnInit, OnDestroy {
private clipboardService: ClipboardService,
private translateService: TranslateService,
) {
// Show the dmsg info if the dmsg url was used.
this.showDmsgInfo = this.router.url.indexOf('dmsg') !== -1;

// Data for populating the tab bar.
this.tabsData = [
{
icon: 'view_headline',
label: 'nodes.title',
linkParts: ['/nodes'],
},
{
icon: 'language',
label: 'nodes.dmsg-title',
linkParts: ['/nodes', 'dmsg'],
},
{
icon: 'settings',
label: 'settings.title',
Expand Down Expand Up @@ -192,12 +204,14 @@ export class NodeListComponent implements OnInit, OnDestroy {
const options: SelectableOption[] = [];
const enumKeys = Object.keys(SortableColumns);
enumKeys.forEach(key => {
options.push({
label: this.translateService.instant(SortableColumns[key]) + ' ' + this.translateService.instant('tables.ascending-order'),
});
options.push({
label: this.translateService.instant(SortableColumns[key]) + ' ' + this.translateService.instant('tables.descending-order'),
});
if (this.showDmsgInfo || (SortableColumns[key] !== SortableColumns.DmsgServer && SortableColumns[key] !== SortableColumns.Ping)) {
options.push({
label: this.translateService.instant(SortableColumns[key]) + ' ' + this.translateService.instant('tables.ascending-order'),
});
options.push({
label: this.translateService.instant(SortableColumns[key]) + ' ' + this.translateService.instant('tables.descending-order'),
});
}
});

// Open the option selection modal window.
Expand Down Expand Up @@ -297,6 +311,11 @@ export class NodeListComponent implements OnInit, OnDestroy {
let response: number;
if (this.sortBy === SortableColumns.Key) {
response = !this.sortReverse ? a.local_pk.localeCompare(b.local_pk) : b.local_pk.localeCompare(a.local_pk);
} else if (this.sortBy === SortableColumns.DmsgServer) {
response = !this.sortReverse ? a.dmsgServerPk.localeCompare(b.dmsgServerPk) : b.dmsgServerPk.localeCompare(a.dmsgServerPk);
} else if (this.sortBy === SortableColumns.Ping) {
response =
!this.sortReverse ? Number(a.roundTripPing) - Number(b.roundTripPing) : Number(b.roundTripPing) - Number(a.roundTripPing);
} else if (this.sortBy === SortableColumns.State) {
if (a.online && !b.online) {
response = -1;
Expand Down Expand Up @@ -499,13 +518,21 @@ export class NodeListComponent implements OnInit, OnDestroy {
{
icon: 'filter_none',
label: 'nodes.copy-key',
},
{
icon: 'short_text',
label: 'edit-label.title',
}
];

if (this.showDmsgInfo) {
options.push({
icon: 'filter_none',
label: 'nodes.copy-dmsg',
});
}

options.push({
icon: 'short_text',
label: 'edit-label.title',
});

if (!node.online) {
options.push({
icon: 'close',
Expand All @@ -515,22 +542,62 @@ export class NodeListComponent implements OnInit, OnDestroy {

SelectOptionComponent.openDialog(this.dialog, options, 'common.options').afterClosed().subscribe((selectedOption: number) => {
if (selectedOption === 1) {
if (this.clipboardService.copy(node.local_pk)) {
this.onCopyToClipboardClicked();
this.copySpecificTextToClipboard(node.local_pk);
} else if (this.showDmsgInfo) {
if (selectedOption === 2) {
this.copySpecificTextToClipboard(node.dmsgServerPk);
} else if (selectedOption === 3) {
this.showEditLabelDialog(node);
} else if (selectedOption === 4) {
this.deleteNode(node);
}
} else {
if (selectedOption === 2) {
this.showEditLabelDialog(node);
} else if (selectedOption === 3) {
this.deleteNode(node);
}
} else if (selectedOption === 2) {
this.showEditLabelDialog(node);
} else if (selectedOption === 3) {
this.deleteNode(node);
}
});
}

/**
* Called after copying the public key of a node.
* Copies the public key of a visor. If the dmsg data is being shown, it allows the user to
* select between copying the public key of the node or the dmsg server.
*/
onCopyToClipboardClicked() {
this.snackbarService.showDone('copy.copied');
copyToClipboard(node: Node) {
if (!this.showDmsgInfo) {
this.copySpecificTextToClipboard(node.local_pk);
} else {
const options: SelectableOption[] = [
{
icon: 'filter_none',
label: 'nodes.key',
},
{
icon: 'filter_none',
label: 'nodes.dmsg-server',
}
];

SelectOptionComponent.openDialog(this.dialog, options, 'common.options').afterClosed().subscribe((selectedOption: number) => {
if (selectedOption === 1) {
this.copySpecificTextToClipboard(node.local_pk);
} else if (selectedOption === 2) {
this.copySpecificTextToClipboard(node.dmsgServerPk);
}
});
}
}

/**
* Copies a text to the clipboard.
* @param text Text to copy.
*/
private copySpecificTextToClipboard(text: string) {
if (this.clipboardService.copy(text)) {
this.snackbarService.showDone('copy.copied');
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@
<span class="title">{{ 'node.details.node-info.port' | translate }}&nbsp;</span>
<app-copy-to-clipboard-text text="{{ node.port }}"></app-copy-to-clipboard-text>
</span>
<span class="info-line">
<span class="title">{{ 'node.details.node-info.dmsg-server' | translate }}&nbsp;</span>
<app-copy-to-clipboard-text text="{{ node.dmsgServerPk }}"></app-copy-to-clipboard-text>
</span>
<span class="info-line">
<span class="title">{{ 'node.details.node-info.ping' | translate }}&nbsp;</span>
{{ 'common.time-in-ms' | translate:{ time: node.roundTripPing } }}
</span>
<span class="info-line">
<span class="title">{{ 'node.details.node-info.node-version' | translate }}</span>
{{ node.build_info.version }}
Expand Down
58 changes: 55 additions & 3 deletions static/skywire-manager-src/src/app/services/node.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { flatMap, map } from 'rxjs/operators';
import { flatMap, map, mergeMap } from 'rxjs/operators';
import BigNumber from 'bignumber.js';

import { StorageService } from './storage.service';
import { Node, Transport, Route, HealthInfo } from '../app.datatypes';
Expand All @@ -26,12 +27,30 @@ export class NodeService {
* Get the list of the nodes connected to the hypervisor.
*/
getNodes(): Observable<Node[]> {
return this.apiService.get('visors').pipe(map((nodes: Node[]) => {
nodes = nodes || [];
let nodes: Node[];

return this.apiService.get('visors').pipe(mergeMap((result: Node[]) => {
// Save the visor list.
nodes = result || [];

// Get the dmsg info.
return this.apiService.get('dmsg');
}), map((dmsgInfo: any[]) => {
// Create a map to associate the dmsg info with the visors.
const dmsgInfoMap = new Map<string, any>();
dmsgInfo.forEach(info => dmsgInfoMap.set(info.public_key, info));

// Process the node data and create a helper map.
const obtainedNodes = new Map<string, Node>();
nodes.forEach(node => {
if (dmsgInfoMap.has(node.local_pk)) {
node.dmsgServerPk = dmsgInfoMap.get(node.local_pk).server_public_key;
node.roundTripPing = this.nsToMs(dmsgInfoMap.get(node.local_pk).round_trip);
} else {
node.dmsgServerPk = '-';
node.roundTripPing = '-1';
}

node.ip = this.getAddressPart(node.tcp_addr, 0);
node.port = this.getAddressPart(node.tcp_addr, 1);
node.label = this.storageService.getNodeLabel(node.local_pk);
Expand Down Expand Up @@ -72,6 +91,22 @@ export class NodeService {
}));
}

/**
* Converts a ns value to a ms string. It includes 2 decimals is the final value is less than 10.
* @param time Value to convert.
*/
private nsToMs(time: number) {
let value = new BigNumber(time).dividedBy(1000000);

if (value.isLessThan(10)) {
value = value.decimalPlaces(2);
} else {
value = value.decimalPlaces(0);
}

return value.toString(10);
}

/**
* Gets the details of a specific node.
*/
Expand All @@ -94,6 +129,23 @@ export class NodeService {
});
}

// Get the dmsg info.
return this.apiService.get('dmsg');
}),
flatMap((dmsgInfo: any[]) => {
for (let i = 0; i < dmsgInfo.length; i++) {
if (dmsgInfo[i].public_key === currentNode.local_pk) {
currentNode.dmsgServerPk = dmsgInfo[i].server_public_key;
currentNode.roundTripPing = this.nsToMs(dmsgInfo[i].round_trip);

// Get the health info.
return this.apiService.get(`visors/${nodeKey}/health`);
}
}

currentNode.dmsgServerPk = '-';
currentNode.roundTripPing = '-1';

// Get the health info.
return this.apiService.get(`visors/${nodeKey}/health`);
}),
Expand Down
Loading

0 comments on commit 5c017c9

Please sign in to comment.