diff --git a/static/skywire-manager-src/src/app/app.datatypes.ts b/static/skywire-manager-src/src/app/app.datatypes.ts index 826aa05792..d9725ede80 100644 --- a/static/skywire-manager-src/src/app/app.datatypes.ts +++ b/static/skywire-manager-src/src/app/app.datatypes.ts @@ -1,20 +1,16 @@ -// Most classes are based on the responses returned by the API, but -// sometimes with some extra fields which are calculated internally in the app. - export class Node { - tcp_addr: string; + label: string; + localPk: string; + tcpAddr: string; ip: string; port: string; - local_pk: string; - node_version: string; - app_protocol_version: string; + version: string; apps: Application[]; transports: Transport[]; - routes_count: number; + routesCount: number; routes?: Route[]; - label?: string; online?: boolean; - seconds_online?: number; + secondsOnline?: number; health?: HealthInfo; dmsgServerPk?: string; roundTripPing?: string; @@ -26,19 +22,15 @@ export interface Application { autostart: boolean; port: number; status: number; - args?: any[]; + args: any[]; } export interface Transport { + isUp: boolean; id: string; - local_pk: string; - remote_pk: string; + localPk: string; + remotePk: string; type: string; - log?: TransportLog; - is_up: boolean; -} - -export interface TransportLog { recv: number|null; sent: number|null; } @@ -46,15 +38,42 @@ export interface TransportLog { export interface Route { key: number; rule: string; + ruleSummary?: RouteRuleSummary; + appFields?: RouteAppRuleSumary; + forwardFields?: RouteForwardRuleSumary; + intermediaryForwardFields?: RouteForwardRuleSumary; +} + +export interface RouteRuleSummary { + keepAlive: number; + ruleType: number; + keyRouteId: number; +} + +interface RouteAppRuleSumary { + routeDescriptor: RouteDescriptor; +} + +interface RouteForwardRuleSumary { + nextRid: number; + nextTid: string; + routeDescriptor?: RouteDescriptor; +} + +interface RouteDescriptor { + dstPk: string; + srcPk: string; + dstPort: number; + srcPort: number; } export interface HealthInfo { - status?: number; - transport_discovery?: number; - route_finder?: number; - setup_node?: number; - uptime_tracker?: number; - address_resolver?: number; + status: number; + transportDiscovery: number; + routeFinder: number; + setupNode: number; + uptimeTracker: number; + addressResolver: number; } export class ProxyDiscoveryEntry { diff --git a/static/skywire-manager-src/src/app/components/pages/node-list/node-list.component.html b/static/skywire-manager-src/src/app/components/pages/node-list/node-list.component.html index 1fcface6f8..6d964ba4ce 100644 --- a/static/skywire-manager-src/src/app/components/pages/node-list/node-list.component.html +++ b/static/skywire-manager-src/src/app/components/pages/node-list/node-list.component.html @@ -122,7 +122,7 @@ {{ node.label }} - {{ node.local_pk }} + {{ node.localPk }}
{{ 'nodes.key' | translate }}: - {{ node.local_pk }} + {{ node.localPk }}
{{ 'nodes.dmsg-server' | translate }}: diff --git a/static/skywire-manager-src/src/app/components/pages/node-list/node-list.component.ts b/static/skywire-manager-src/src/app/components/pages/node-list/node-list.component.ts index a17693ba0d..666d797178 100644 --- a/static/skywire-manager-src/src/app/components/pages/node-list/node-list.component.ts +++ b/static/skywire-manager-src/src/app/components/pages/node-list/node-list.component.ts @@ -39,7 +39,7 @@ export class NodeListComponent implements OnInit, OnDestroy { hypervisorSortData = new SortingColumn(['isHypervisor'], 'nodes.hypervisor', SortingModes.Boolean); stateSortData = new SortingColumn(['online'], 'nodes.state', SortingModes.Boolean); labelSortData = new SortingColumn(['label'], 'nodes.label', SortingModes.Text); - keySortData = new SortingColumn(['local_pk'], 'nodes.key', SortingModes.Text); + keySortData = new SortingColumn(['localPk'], 'nodes.key', SortingModes.Text); dmsgServerSortData = new SortingColumn(['dmsgServerPk'], 'nodes.dmsg-server', SortingModes.Text, ['dmsgServerPk_label']); pingSortData = new SortingColumn(['roundTripPing'], 'nodes.ping', SortingModes.Number); @@ -95,7 +95,7 @@ export class NodeListComponent implements OnInit, OnDestroy { }, { filterName: 'nodes.filter-dialog.key', - keyNameInElementsArray: 'local_pk', + keyNameInElementsArray: 'localPk', type: FilterFieldTypes.TextInput, maxlength: 66, }, @@ -305,7 +305,7 @@ export class NodeListComponent implements OnInit, OnDestroy { nodeStatusClass(node: Node, forDot: boolean): string { switch (node.online) { case true: - return this.nodesHealthInfo.get(node.local_pk).allServicesOk ? + return this.nodesHealthInfo.get(node.localPk).allServicesOk ? (forDot ? 'dot-green' : 'green-text') : (forDot ? 'dot-yellow online-warning' : 'yellow-text'); default: @@ -321,7 +321,7 @@ export class NodeListComponent implements OnInit, OnDestroy { nodeStatusText(node: Node, forTooltip: boolean): string { switch (node.online) { case true: - return this.nodesHealthInfo.get(node.local_pk).allServicesOk ? + return this.nodesHealthInfo.get(node.localPk).allServicesOk ? ('node.statuses.online' + (forTooltip ? '-tooltip' : '')) : ('node.statuses.partially-online' + (forTooltip ? '-tooltip' : '')); default: @@ -424,13 +424,15 @@ export class NodeListComponent implements OnInit, OnDestroy { this.nodesToShow = null; } - // Get the health status of each node. - this.nodesHealthInfo = new Map(); - this.nodesToShow.forEach(node => { - this.nodesHealthInfo.set(node.local_pk, this.nodeService.getHealthStatus(node)); - }); + if (this.nodesToShow) { + // Get the health status of each node. + this.nodesHealthInfo = new Map(); + this.nodesToShow.forEach(node => { + this.nodesHealthInfo.set(node.localPk, this.nodeService.getHealthStatus(node)); + }); - this.dataSource = this.nodesToShow; + this.dataSource = this.nodesToShow; + } } logout() { @@ -457,7 +459,7 @@ export class NodeListComponent implements OnInit, OnDestroy { const nodesData: NodeData[] = []; this.dataSource.forEach(node => { nodesData.push({ - key: node.local_pk, + key: node.localPk, label: node.label, }); }); @@ -530,7 +532,7 @@ export class NodeListComponent implements OnInit, OnDestroy { SelectOptionComponent.openDialog(this.dialog, options, 'common.options').afterClosed().subscribe((selectedOption: number) => { if (selectedOption === 1) { - this.copySpecificTextToClipboard(node.local_pk); + this.copySpecificTextToClipboard(node.localPk); } else if (this.showDmsgInfo) { if (selectedOption === 2) { this.copySpecificTextToClipboard(node.dmsgServerPk); @@ -555,7 +557,7 @@ export class NodeListComponent implements OnInit, OnDestroy { */ copyToClipboard(node: Node) { if (!this.showDmsgInfo) { - this.copySpecificTextToClipboard(node.local_pk); + this.copySpecificTextToClipboard(node.localPk); } else { const options: SelectableOption[] = [ { @@ -570,7 +572,7 @@ export class NodeListComponent implements OnInit, OnDestroy { SelectOptionComponent.openDialog(this.dialog, options, 'common.options').afterClosed().subscribe((selectedOption: number) => { if (selectedOption === 1) { - this.copySpecificTextToClipboard(node.local_pk); + this.copySpecificTextToClipboard(node.localPk); } else if (selectedOption === 2) { this.copySpecificTextToClipboard(node.dmsgServerPk); } @@ -592,10 +594,10 @@ export class NodeListComponent implements OnInit, OnDestroy { * Opens the modal window for changing the label of a node. */ showEditLabelDialog(node: Node) { - let labelInfo = this.storageService.getLabelInfo(node.local_pk); + let labelInfo = this.storageService.getLabelInfo(node.localPk); if (!labelInfo) { labelInfo = { - id: node.local_pk, + id: node.localPk, label: '', identifiedElementType: LabeledElementTypes.Node, }; @@ -616,7 +618,7 @@ export class NodeListComponent implements OnInit, OnDestroy { confirmationDialog.componentInstance.operationAccepted.subscribe(() => { confirmationDialog.close(); - this.storageService.setLocalNodesAsHidden([node.local_pk]); + this.storageService.setLocalNodesAsHidden([node.localPk]); this.forceDataRefresh(); this.snackbarService.showDone('nodes.deleted'); }); @@ -640,7 +642,7 @@ export class NodeListComponent implements OnInit, OnDestroy { const nodesToRemove: string[] = []; this.filteredNodes.forEach(node => { if (!node.online) { - nodesToRemove.push(node.local_pk); + nodesToRemove.push(node.localPk); } }); @@ -664,7 +666,7 @@ export class NodeListComponent implements OnInit, OnDestroy { */ open(node: Node) { if (node.online) { - this.router.navigate(['nodes', node.local_pk]); + this.router.navigate(['nodes', node.localPk]); } } } diff --git a/static/skywire-manager-src/src/app/components/pages/node/actions/node-actions-helper.ts b/static/skywire-manager-src/src/app/components/pages/node/actions/node-actions-helper.ts index c6b54fbd93..95343f6be7 100644 --- a/static/skywire-manager-src/src/app/components/pages/node/actions/node-actions-helper.ts +++ b/static/skywire-manager-src/src/app/components/pages/node/actions/node-actions-helper.ts @@ -1,5 +1,4 @@ -import { MatDialog, MatDialogConfig } from '@angular/material/dialog'; -import { Component, AfterViewInit, OnDestroy, Input } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; import { Router } from '@angular/router'; import { Subscription } from 'rxjs'; import { TranslateService } from '@ngx-translate/core'; @@ -13,8 +12,6 @@ import { NodeService } from 'src/app/services/node.service'; import { OperationError } from 'src/app/utils/operation-error'; import { processServiceError } from 'src/app/utils/errors'; import { SelectableOption, SelectOptionComponent } from 'src/app/components/layout/select-option/select-option.component'; -import { ConfirmationData, ConfirmationComponent } from 'src/app/components/layout/confirmation/confirmation.component'; -import { AppConfig } from 'src/app/app.config'; import { MenuOptionData } from 'src/app/components/layout/top-bar/top-bar.component'; import { UpdateComponent } from 'src/app/components/layout/update/update.component'; import { StorageService } from 'src/app/services/storage.service'; diff --git a/static/skywire-manager-src/src/app/components/pages/node/apps/all-apps/all-apps.component.ts b/static/skywire-manager-src/src/app/components/pages/node/apps/all-apps/all-apps.component.ts index 298487fa36..d69e6e0969 100644 --- a/static/skywire-manager-src/src/app/components/pages/node/apps/all-apps/all-apps.component.ts +++ b/static/skywire-manager-src/src/app/components/pages/node/apps/all-apps/all-apps.component.ts @@ -21,7 +21,7 @@ export class AllAppsComponent implements OnInit, OnDestroy { ngOnInit() { // Get the node data from the parent page. this.dataSubscription = NodeComponent.currentNode.subscribe((node: Node) => { - this.nodePK = node.local_pk; + this.nodePK = node.localPk; this.apps = node.apps; }); } diff --git a/static/skywire-manager-src/src/app/components/pages/node/apps/apps.component.ts b/static/skywire-manager-src/src/app/components/pages/node/apps/apps.component.ts index c2842939fc..93adc2207a 100644 --- a/static/skywire-manager-src/src/app/components/pages/node/apps/apps.component.ts +++ b/static/skywire-manager-src/src/app/components/pages/node/apps/apps.component.ts @@ -21,7 +21,7 @@ export class AppsComponent implements OnInit, OnDestroy { ngOnInit() { // Get the node data from the parent page. this.dataSubscription = NodeComponent.currentNode.subscribe((node: Node) => { - this.nodePK = node.local_pk; + this.nodePK = node.localPk; this.apps = node.apps; }); } diff --git a/static/skywire-manager-src/src/app/components/pages/node/node-info/node-info-content/node-info-content.component.html b/static/skywire-manager-src/src/app/components/pages/node/node-info/node-info-content/node-info-content.component.html index b87b55d2c5..f277ce6cbc 100644 --- a/static/skywire-manager-src/src/app/components/pages/node/node-info/node-info-content/node-info-content.component.html +++ b/static/skywire-manager-src/src/app/components/pages/node/node-info/node-info-content/node-info-content.component.html @@ -11,7 +11,7 @@ {{ 'node.details.node-info.public-key' | translate }}  - + {{ 'node.details.node-info.port' | translate }}  @@ -27,7 +27,7 @@ {{ 'node.details.node-info.node-version' | translate }} - {{ node.build_info.version ? node.build_info.version : ('common.unknown' | translate) }} + {{ node.version ? node.version : ('common.unknown' | translate) }} {{ 'node.details.node-info.time.title' | translate }} diff --git a/static/skywire-manager-src/src/app/components/pages/node/node-info/node-info-content/node-info-content.component.ts b/static/skywire-manager-src/src/app/components/pages/node/node-info/node-info-content/node-info-content.component.ts index d2665c31dd..c06fc9f975 100644 --- a/static/skywire-manager-src/src/app/components/pages/node/node-info/node-info-content/node-info-content.component.ts +++ b/static/skywire-manager-src/src/app/components/pages/node/node-info/node-info-content/node-info-content.component.ts @@ -20,7 +20,7 @@ export class NodeInfoContentComponent { @Input() set nodeInfo(val: Node) { this.node = val; this.nodeHealthInfo = this.nodeService.getHealthStatus(val); - this.timeOnline = TimeUtils.getElapsedTime(val.seconds_online); + this.timeOnline = TimeUtils.getElapsedTime(val.secondsOnline); } node: Node; @@ -34,10 +34,10 @@ export class NodeInfoContentComponent { ) { } showEditLabelDialog() { - let labelInfo = this.storageService.getLabelInfo(this.node.local_pk); + let labelInfo = this.storageService.getLabelInfo(this.node.localPk); if (!labelInfo) { labelInfo = { - id: this.node.local_pk, + id: this.node.localPk, label: '', identifiedElementType: LabeledElementTypes.Node, }; diff --git a/static/skywire-manager-src/src/app/components/pages/node/routing/all-routes/all-routes.component.ts b/static/skywire-manager-src/src/app/components/pages/node/routing/all-routes/all-routes.component.ts index 11826077f3..98c27a2162 100644 --- a/static/skywire-manager-src/src/app/components/pages/node/routing/all-routes/all-routes.component.ts +++ b/static/skywire-manager-src/src/app/components/pages/node/routing/all-routes/all-routes.component.ts @@ -21,7 +21,7 @@ export class AllRoutesComponent implements OnInit, OnDestroy { ngOnInit() { // Get the node data from the parent page. this.dataSubscription = NodeComponent.currentNode.subscribe((node: Node) => { - this.nodePK = node.local_pk; + this.nodePK = node.localPk; this.routes = node.routes; }); } diff --git a/static/skywire-manager-src/src/app/components/pages/node/routing/all-transports/all-transports.component.ts b/static/skywire-manager-src/src/app/components/pages/node/routing/all-transports/all-transports.component.ts index cfe4581141..77f24aa195 100644 --- a/static/skywire-manager-src/src/app/components/pages/node/routing/all-transports/all-transports.component.ts +++ b/static/skywire-manager-src/src/app/components/pages/node/routing/all-transports/all-transports.component.ts @@ -21,7 +21,7 @@ export class AllTransportsComponent implements OnInit, OnDestroy { ngOnInit() { // Get the node data from the parent page. this.dataSubscription = NodeComponent.currentNode.subscribe((node: Node) => { - this.nodePK = node.local_pk; + this.nodePK = node.localPk; this.transports = node.transports; }); } diff --git a/static/skywire-manager-src/src/app/components/pages/node/routing/route-list/route-details/route-details.component.html b/static/skywire-manager-src/src/app/components/pages/node/routing/route-list/route-details/route-details.component.html index 2f7ba74b58..5f2905e91f 100644 --- a/static/skywire-manager-src/src/app/components/pages/node/routing/route-list/route-details/route-details.component.html +++ b/static/skywire-manager-src/src/app/components/pages/node/routing/route-list/route-details/route-details.component.html @@ -1,6 +1,5 @@ - -
+
list{{ 'routes.details.basic.title' | translate }} @@ -13,89 +12,86 @@
-
+
list{{ 'routes.details.summary.title' | translate }}
- {{ 'routes.details.summary.keep-alive' | translate }} {{ routeRule.rule_summary.keep_alive }} + {{ 'routes.details.summary.keep-alive' | translate }} {{ routeRule.ruleSummary.keepAlive }}
- {{ 'routes.details.summary.type' | translate }} {{ getRuleTypeName(routeRule.rule_summary.rule_type) }} + {{ 'routes.details.summary.type' | translate }} {{ getRuleTypeName(routeRule.ruleSummary.ruleType) }}
- {{ 'routes.details.summary.key-route-id' | translate }} {{ routeRule.rule_summary.key_route_id }} + {{ 'routes.details.summary.key-route-id' | translate }} {{ routeRule.ruleSummary.keyRouteId }}
-
+
settings{{ 'routes.details.specific-fields-titles.app' | translate }}
-
+
swap_horiz{{ 'routes.details.specific-fields-titles.forward' | translate }}
-
+
arrow_forward{{ 'routes.details.specific-fields-titles.intermediary-forward' | translate }}
-
+
{{ 'routes.details.specific-fields.route-id' | translate }} {{ - routeRule.rule_summary.forward_fields ? - routeRule.rule_summary.forward_fields.next_rid : - routeRule.rule_summary.intermediary_forward_fields.next_rid + routeRule.forwardFields ? + routeRule.forwardFields.nextRid : + routeRule.intermediaryForwardFields.nextRid }}
{{ 'routes.details.specific-fields.transport-id' | translate }} {{ - routeRule.rule_summary.forward_fields ? - routeRule.rule_summary.forward_fields.next_tid : - routeRule.rule_summary.intermediary_forward_fields.next_tid + routeRule.forwardFields ? + routeRule.forwardFields.nextTid : + routeRule.intermediaryForwardFields.nextTid }}
{{ 'routes.details.specific-fields.destination-pk' | translate }} {{ - routeRule.rule_summary.app_fields ? - routeRule.rule_summary.app_fields.route_descriptor.dst_pk : - routeRule.rule_summary.forward_fields.route_descriptor.dst_pk + routeRule.appFields ? + routeRule.appFields.routeDescriptor.dstPk : + routeRule.forwardFields.routeDescriptor.dstPk }}
{{ 'routes.details.specific-fields.source-pk' | translate }} {{ - routeRule.rule_summary.app_fields ? - routeRule.rule_summary.app_fields.route_descriptor.src_pk : - routeRule.rule_summary.forward_fields.route_descriptor.src_pk + routeRule.appFields ? + routeRule.appFields.routeDescriptor.srcPk : + routeRule.forwardFields.routeDescriptor.srcPk }}
{{ 'routes.details.specific-fields.destination-port' | translate }} {{ - routeRule.rule_summary.app_fields ? - routeRule.rule_summary.app_fields.route_descriptor.dst_port : - routeRule.rule_summary.forward_fields.route_descriptor.dst_port + routeRule.appFields ? + routeRule.appFields.routeDescriptor.dstPort : + routeRule.forwardFields.routeDescriptor.dstPort }}
{{ 'routes.details.specific-fields.source-port' | translate }} {{ - routeRule.rule_summary.app_fields ? - routeRule.rule_summary.app_fields.route_descriptor.src_port : - routeRule.rule_summary.forward_fields.route_descriptor.src_port + routeRule.appFields ? + routeRule.appFields.routeDescriptor.srcPort : + routeRule.forwardFields.routeDescriptor.srcPort }}
diff --git a/static/skywire-manager-src/src/app/components/pages/node/routing/route-list/route-details/route-details.component.ts b/static/skywire-manager-src/src/app/components/pages/node/routing/route-list/route-details/route-details.component.ts index f114bb0f52..8d1febe809 100644 --- a/static/skywire-manager-src/src/app/components/pages/node/routing/route-list/route-details/route-details.component.ts +++ b/static/skywire-manager-src/src/app/components/pages/node/routing/route-list/route-details/route-details.component.ts @@ -1,45 +1,8 @@ -import { Component, OnInit, Inject, OnDestroy } from '@angular/core'; +import { Component, Inject } from '@angular/core'; import { MatDialogRef, MAT_DIALOG_DATA, MatDialog, MatDialogConfig } from '@angular/material/dialog'; -import { Subscription, of } from 'rxjs'; -import { delay, flatMap } from 'rxjs/operators'; -import { RouteService } from '../../../../../../services/route.service'; -import { NodeComponent } from '../../../node.component'; -import { SnackbarService } from '../../../../../../services/snackbar.service'; import { AppConfig } from 'src/app/app.config'; -import { processServiceError } from 'src/app/utils/errors'; - -// Objects representing the structure of the response returned by the hypervisor. - -class RouteRule { - key: string; - rule: string; - rule_summary?: RuleSumary; -} - -class RuleSumary { - keep_alive: number; - rule_type: number; - key_route_id: number; - app_fields?: AppRuleSumary; - forward_fields?: ForwardRuleSumary; -} - -class AppRuleSumary { - route_descriptor: RouteDescriptor; -} - -class RouteDescriptor { - dst_pk: string; - src_pk: string; - dst_port: number; - src_port: number; -} - -class ForwardRuleSumary { - next_rid: number; - next_tid: string; -} +import { Route } from 'src/app/app.datatypes'; /** * Modal window for showing the details of a route. @@ -49,11 +12,8 @@ class ForwardRuleSumary { templateUrl: './route-details.component.html', styleUrls: ['./route-details.component.scss'] }) -export class RouteDetailsComponent implements OnInit, OnDestroy { - routeRule: RouteRule; - - private shouldShowError = true; - private dataSubscription: Subscription; +export class RouteDetailsComponent { + routeRule: Route; /** * Map with the types of route rules that the hypervisor can return and are known by this app. @@ -67,9 +27,9 @@ export class RouteDetailsComponent implements OnInit, OnDestroy { /** * Opens the modal window. Please use this function instead of opening the window "by hand". */ - public static openDialog(dialog: MatDialog, routeID: string): MatDialogRef { + public static openDialog(dialog: MatDialog, route: Route): MatDialogRef { const config = new MatDialogConfig(); - config.data = routeID; + config.data = route; config.autoFocus = false; config.width = AppConfig.largeModalWidth; @@ -77,18 +37,10 @@ export class RouteDetailsComponent implements OnInit, OnDestroy { } constructor( - @Inject(MAT_DIALOG_DATA) private data: string, - private routeService: RouteService, + @Inject(MAT_DIALOG_DATA) data: Route, private dialogRef: MatDialogRef, - private snackbarService: SnackbarService, - ) { } - - ngOnInit() { - this.loadData(0); - } - - ngOnDestroy() { - this.dataSubscription.unsubscribe(); + ) { + this.routeRule = data; } getRuleTypeName(type: number): string { @@ -102,34 +54,4 @@ export class RouteDetailsComponent implements OnInit, OnDestroy { closePopup() { this.dialogRef.close(); } - - private loadData(delayMilliseconds: number) { - if (this.dataSubscription) { - this.dataSubscription.unsubscribe(); - } - - this.dataSubscription = of(1).pipe( - // Wait the delay. - delay(delayMilliseconds), - // Load the data. The node pk is obtained from the currently openned node page. - flatMap(() => this.routeService.get(NodeComponent.getCurrentNodeKey(), this.data)) - ).subscribe( - (rule: RouteRule) => { - this.snackbarService.closeCurrentIfTemporaryError(); - this.routeRule = rule; - }, - err => { - err = processServiceError(err); - - // Show an error msg if it has not be done before during the current attempt to obtain the data. - if (this.shouldShowError) { - this.snackbarService.showError('common.loading-error', null, true, err); - this.shouldShowError = false; - } - - // Retry after a small delay. - this.loadData(AppConfig.connectionRetryDelay); - }, - ); - } } diff --git a/static/skywire-manager-src/src/app/components/pages/node/routing/route-list/route-list.component.html b/static/skywire-manager-src/src/app/components/pages/node/routing/route-list/route-list.component.html index 7baf58a46c..370b0bb027 100644 --- a/static/skywire-manager-src/src/app/components/pages/node/routing/route-list/route-list.component.html +++ b/static/skywire-manager-src/src/app/components/pages/node/routing/route-list/route-list.component.html @@ -89,7 +89,7 @@
{{ 'transports.details.basic.state' | translate }} -
- {{ ('transports.statuses.' + (data.is_up ? 'online' : 'offline')) | translate }} +
+ {{ ('transports.statuses.' + (data.isUp ? 'online' : 'offline')) | translate }}
{{ 'transports.details.basic.id' | translate }} {{ data.id }}
- {{ 'transports.details.basic.local-pk' | translate }} {{ data.local_pk }} + {{ 'transports.details.basic.local-pk' | translate }} {{ data.localPk }}
- {{ 'transports.details.basic.remote-pk' | translate }} {{ data.remote_pk }} + {{ 'transports.details.basic.remote-pk' | translate }} {{ data.remotePk }}
{{ 'transports.details.basic.type' | translate }} {{ data.type }} @@ -26,10 +26,10 @@ import_export{{ 'transports.details.data.title' | translate }}
- {{ 'transports.details.data.uploaded' | translate }} {{ data.log.sent | autoScale }} + {{ 'transports.details.data.uploaded' | translate }} {{ data.sent | autoScale }}
- {{ 'transports.details.data.downloaded' | translate }} {{ data.log.recv | autoScale }} + {{ 'transports.details.data.downloaded' | translate }} {{ data.recv | autoScale }}
diff --git a/static/skywire-manager-src/src/app/components/pages/node/routing/transport-list/transport-list.component.html b/static/skywire-manager-src/src/app/components/pages/node/routing/transport-list/transport-list.component.html index f9fc427bba..6b88138f81 100644 --- a/static/skywire-manager-src/src/app/components/pages/node/routing/transport-list/transport-list.component.html +++ b/static/skywire-manager-src/src/app/components/pages/node/routing/transport-list/transport-list.component.html @@ -125,7 +125,7 @@ @@ -134,10 +134,10 @@ {{ transport.type }} - {{ transport.log.sent | autoScale }} + {{ transport.sent | autoScale }} - {{ transport.log.recv | autoScale }} + {{ transport.recv | autoScale }}
@@ -216,11 +216,11 @@
{{ 'common.uploaded' | translate }}: - {{ transport.log.sent | autoScale }} + {{ transport.sent | autoScale }}
{{ 'common.downloaded' | translate }}: - {{ transport.log.recv | autoScale }} + {{ transport.recv | autoScale }}
diff --git a/static/skywire-manager-src/src/app/components/pages/node/routing/transport-list/transport-list.component.ts b/static/skywire-manager-src/src/app/components/pages/node/routing/transport-list/transport-list.component.ts index 2ee55c91ff..c217ce6157 100644 --- a/static/skywire-manager-src/src/app/components/pages/node/routing/transport-list/transport-list.component.ts +++ b/static/skywire-manager-src/src/app/components/pages/node/routing/transport-list/transport-list.component.ts @@ -38,12 +38,12 @@ export class TransportListComponent implements OnDestroy { @Input() nodePK: string; // Vars with the data of the columns used for sorting the data. - stateSortData = new SortingColumn(['is_up'], 'transports.state', SortingModes.Boolean); + stateSortData = new SortingColumn(['isUp'], 'transports.state', SortingModes.Boolean); idSortData = new SortingColumn(['id'], 'transports.id', SortingModes.Text, ['id_label']); - remotePkSortData = new SortingColumn(['remote_pk'], 'transports.remote-node', SortingModes.Text, ['remote_pk_label']); + remotePkSortData = new SortingColumn(['remotePk'], 'transports.remote-node', SortingModes.Text, ['remote_pk_label']); typeSortData = new SortingColumn(['type'], 'transports.type', SortingModes.Text); - uploadedSortData = new SortingColumn(['log', 'sent'], 'common.uploaded', SortingModes.NumberReversed); - downloadedSortData = new SortingColumn(['log', 'recv'], 'common.downloaded', SortingModes.NumberReversed); + uploadedSortData = new SortingColumn(['sent'], 'common.uploaded', SortingModes.NumberReversed); + downloadedSortData = new SortingColumn(['recv'], 'common.downloaded', SortingModes.NumberReversed); private dataSortedSubscription: Subscription; private dataFiltererSubscription: Subscription; @@ -86,7 +86,7 @@ export class TransportListComponent implements OnDestroy { LabeledElementTextComponent.getCompleteLabel(this.storageService, this.translateService, transport.id); transport['remote_pk_label'] = - LabeledElementTextComponent.getCompleteLabel(this.storageService, this.translateService, transport.remote_pk); + LabeledElementTextComponent.getCompleteLabel(this.storageService, this.translateService, transport.remotePk); }); this.dataFilterer.setData(this.allTransports); @@ -96,7 +96,7 @@ export class TransportListComponent implements OnDestroy { filterProperties: FilterProperties[] = [ { filterName: 'transports.filter-dialog.online', - keyNameInElementsArray: 'is_up', + keyNameInElementsArray: 'isUp', type: FilterFieldTypes.Select, printableLabelsForValues: [ { @@ -122,7 +122,7 @@ export class TransportListComponent implements OnDestroy { }, { filterName: 'transports.filter-dialog.remote-node', - keyNameInElementsArray: 'remote_pk', + keyNameInElementsArray: 'remotePk', secondaryKeyNameInElementsArray: 'remote_pk_label', type: FilterFieldTypes.TextInput, maxlength: 66, @@ -166,7 +166,7 @@ export class TransportListComponent implements OnDestroy { // Check if there are offline transports. this.hasOfflineTransports = false; this.filteredTransports.forEach(transport => { - if (!transport.is_up) { + if (!transport.isUp) { this.hasOfflineTransports = true; } }); @@ -213,7 +213,7 @@ export class TransportListComponent implements OnDestroy { * returns a class for a colored text. */ transportStatusClass(transport: Transport, forDot: boolean): string { - switch (transport.is_up) { + switch (transport.isUp) { case true: return forDot ? 'dot-green' : 'green-text'; default: @@ -227,7 +227,7 @@ export class TransportListComponent implements OnDestroy { * text for the transport list shown on small screens. */ transportStatusText(transport: Transport, forTooltip: boolean): string { - switch (transport.is_up) { + switch (transport.isUp) { case true: return 'transports.statuses.online' + (forTooltip ? '-tooltip' : ''); default: @@ -309,7 +309,7 @@ export class TransportListComponent implements OnDestroy { // Prepare all offline transports to be removed. const transportsToRemove: string[] = []; this.filteredTransports.forEach(transport => { - if (!transport.is_up) { + if (!transport.isUp) { transportsToRemove.push(transport.id); } }); diff --git a/static/skywire-manager-src/src/app/services/node.service.ts b/static/skywire-manager-src/src/app/services/node.service.ts index 68fa41ade3..a9f3ee2e1e 100644 --- a/static/skywire-manager-src/src/app/services/node.service.ts +++ b/static/skywire-manager-src/src/app/services/node.service.ts @@ -418,8 +418,8 @@ export class NodeService { currentData.totalSent = 0; currentData.totalReceived = 0; if (transports && transports.length > 0) { - currentData.totalSent = transports.reduce((total, transport) => total + transport.log.sent, 0); - currentData.totalReceived = transports.reduce((total, transport) => total + transport.log.recv, 0); + currentData.totalSent = transports.reduce((total, transport) => total + transport.sent, 0); + currentData.totalReceived = transports.reduce((total, transport) => total + transport.recv, 0); } // Update the history. @@ -490,12 +490,29 @@ export class NodeService { * Gets the list of the nodes connected to the hypervisor. */ private getNodes(): Observable { - let nodes: Node[]; + let nodes: Node[] = []; let dmsgInfo: any[]; - return this.apiService.get('visors').pipe(mergeMap((result: Node[]) => { + return this.apiService.get('visors').pipe(mergeMap((result: any[]) => { // Save the visor list. - nodes = result || []; + if (result) { + result.forEach(response => { + const node = new Node(); + + // Basic data. + node.online = response.online; + node.tcpAddr = response.tcp_addr; + node.ip = this.getAddressPart(node.tcpAddr, 0); + node.port = this.getAddressPart(node.tcpAddr, 1); + node.localPk = response.local_pk; + + // Label. + const labelInfo = this.storageService.getLabelInfo(node.localPk); + node.label = labelInfo && labelInfo.label ? labelInfo.label : this.storageService.getDefaultLabel(node.localPk); + + nodes.push(node); + }); + } // Get the dmsg info. return this.apiService.get('dmsg'); @@ -503,10 +520,17 @@ export class NodeService { dmsgInfo = result; // Get the health info of each node. - return forkJoin(nodes.map(node => this.apiService.get(`visors/${node.local_pk}/health`))); + return forkJoin(nodes.map(node => this.apiService.get(`visors/${node.localPk}/health`))); }), mergeMap((result: any[]) => { nodes.forEach((node, i) => { - node.health = result[i]; + node.health = { + status: result[i].status, + addressResolver: result[i].address_resolver, + routeFinder: result[i].route_finder, + setupNode: result[i].setup_node, + transportDiscovery: result[i].transport_discovery, + uptimeTracker: result[i].uptime_tracker, + }; }); // Get the basic info about the hypervisor. @@ -520,25 +544,19 @@ export class NodeService { const obtainedNodes = new Map(); const nodesToRegisterInLocalStorageAsOnline: string[] = []; 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); + if (dmsgInfoMap.has(node.localPk)) { + node.dmsgServerPk = dmsgInfoMap.get(node.localPk).server_public_key; + node.roundTripPing = this.nsToMs(dmsgInfoMap.get(node.localPk).round_trip); } else { node.dmsgServerPk = '-'; node.roundTripPing = '-1'; } - node.isHypervisor = node.local_pk === aboutInfo.public_key; - - node.ip = this.getAddressPart(node.tcp_addr, 0); - node.port = this.getAddressPart(node.tcp_addr, 1); - const labelInfo = this.storageService.getLabelInfo(node.local_pk); - node.label = - labelInfo && labelInfo.label ? labelInfo.label : this.storageService.getDefaultLabel(node.local_pk); + node.isHypervisor = node.localPk === aboutInfo.public_key; - obtainedNodes.set(node.local_pk, node); + obtainedNodes.set(node.localPk, node); if (node.online) { - nodesToRegisterInLocalStorageAsOnline.push(node.local_pk); + nodesToRegisterInLocalStorageAsOnline.push(node.localPk); } }); @@ -549,10 +567,9 @@ export class NodeService { // If the backend did not return a saved node, add it to the response as an offline node. if (!obtainedNodes.has(node.publicKey) && !node.hidden) { const newNode: Node = new Node(); - newNode.local_pk = node.publicKey; + newNode.localPk = node.publicKey; const labelInfo = this.storageService.getLabelInfo(node.publicKey); - newNode.label = - labelInfo && labelInfo.label ? labelInfo.label : this.storageService.getDefaultLabel(node.publicKey); + newNode.label = labelInfo && labelInfo.label ? labelInfo.label : this.storageService.getDefaultLabel(node.publicKey); newNode.online = false; missingSavedNodes.push(newNode); @@ -593,68 +610,139 @@ export class NodeService { * Gets the details of a specific node. */ private getNode(nodeKey: string): Observable { - let currentNode: Node; - - // Get the basic node data. - return this.apiService.get(`visors/${nodeKey}`).pipe( - flatMap((node: Node) => { - node.ip = this.getAddressPart(node.tcp_addr, 0); - node.port = this.getAddressPart(node.tcp_addr, 1); - const labelInfo = this.storageService.getLabelInfo(node.local_pk); - node.label = - labelInfo && labelInfo.label ? labelInfo.label : this.storageService.getDefaultLabel(node.local_pk); - currentNode = node; - - // Needed for a change made to the names on the backend. - if (node.apps) { - node.apps.forEach(app => { - app.name = (app as any).name ? (app as any).name : (app as any).app; - app.autostart = (app as any).auto_start; + // Get the node data. + return this.apiService.get(`visors/${nodeKey}/summary`).pipe( + map((response: any) => { + const node = new Node(); + + // Basic data. + node.online = response.online; + node.tcpAddr = response.tcp_addr; + node.ip = this.getAddressPart(node.tcpAddr, 0); + node.port = this.getAddressPart(node.tcpAddr, 1); + node.localPk = response.summary.local_pk; + node.version = response.summary.build_info.version; + node.secondsOnline = Math.floor(Number.parseFloat(response.uptime)); + + // Label. + const labelInfo = this.storageService.getLabelInfo(node.localPk); + node.label = labelInfo && labelInfo.label ? labelInfo.label : this.storageService.getDefaultLabel(node.localPk); + + // Health info. + node.health = { + status: 200, + addressResolver: response.health.address_resolver, + routeFinder: response.health.route_finder, + setupNode: response.health.setup_node, + transportDiscovery: response.health.transport_discovery, + uptimeTracker: response.health.uptime_tracker, + }; + + // Transports. + node.transports = []; + if (response.summary.transports) { + (response.summary.transports as any[]).forEach(transport => { + node.transports.push({ + isUp: transport.is_up, + id: transport.id, + localPk: transport.local_pk, + remotePk: transport.remote_pk, + type: transport.type, + recv: transport.log.recv, + sent: transport.log.sent, + }); }); } - // 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`); + // Routes. + node.routes = []; + if (response.routes) { + (response.routes as any[]).forEach(route => { + // Basic data. + node.routes.push({ + key: route.key, + rule: route.rule, + }); + + if (route.rule_summary) { + // Rule summary. + node.routes[node.routes.length - 1].ruleSummary = { + keepAlive: route.rule_summary.keep_alive, + ruleType: route.rule_summary.rule_type, + keyRouteId: route.rule_summary.key_route_id, + }; + + // App fields, if any. + if (route.rule_summary.app_fields && route.rule_summary.app_fields.route_descriptor) { + node.routes[node.routes.length - 1].appFields = { + routeDescriptor: { + dstPk: route.rule_summary.app_fields.route_descriptor.dst_pk, + dstPort: route.rule_summary.app_fields.route_descriptor.dst_port, + srcPk: route.rule_summary.app_fields.route_descriptor.src_pk, + srcPort: route.rule_summary.app_fields.route_descriptor.src_port, + }, + }; + } + + // Forward fields, if any. + if (route.rule_summary.forward_fields) { + node.routes[node.routes.length - 1].forwardFields = { + nextRid: route.rule_summary.forward_fields.next_rid, + nextTid: route.rule_summary.forward_fields.next_tid, + }; + + if (route.rule_summary.forward_fields.route_descriptor) { + node.routes[node.routes.length - 1].forwardFields.routeDescriptor = { + dstPk: route.rule_summary.forward_fields.route_descriptor.dst_pk, + dstPort: route.rule_summary.forward_fields.route_descriptor.dst_port, + srcPk: route.rule_summary.forward_fields.route_descriptor.src_pk, + srcPort: route.rule_summary.forward_fields.route_descriptor.src_port, + }; + } + } + + // Intermediary forward fields, if any. + if (route.rule_summary.intermediary_forward_fields) { + node.routes[node.routes.length - 1].intermediaryForwardFields = { + nextRid: route.rule_summary.intermediary_forward_fields.next_rid, + nextTid: route.rule_summary.intermediary_forward_fields.next_tid, + }; + } + } + }); + } + + // Apps. + node.apps = []; + if (response.summary.apps) { + (response.summary.apps as any[]).forEach(app => { + node.apps.push({ + name: app.name, + status: app.status, + port: app.port, + autostart: app.auto_start, + args: app.args, + }); + }); + } + + let dmsgServerFound = false; + for (let i = 0; i < response.dmsg.length; i++) { + if (response.dmsg[i].public_key === node.localPk) { + node.dmsgServerPk = response.dmsg[i].server_public_key; + node.roundTripPing = this.nsToMs(response.dmsg[i].round_trip); + + dmsgServerFound = true; + break; } } - currentNode.dmsgServerPk = '-'; - currentNode.roundTripPing = '-1'; - - // Get the health info. - return this.apiService.get(`visors/${nodeKey}/health`); - }), - flatMap((health: HealthInfo) => { - currentNode.health = health; - - // Get the node uptime. - return this.apiService.get(`visors/${nodeKey}/uptime`); - }), - flatMap((secondsOnline: string) => { - currentNode.seconds_online = Math.floor(Number.parseFloat(secondsOnline)); - - // Get the complete transports info. - return this.transportService.getTransports(nodeKey); - }), - flatMap((transports: Transport[]) => { - currentNode.transports = transports; - - // Get the complete routes info. - return this.routeService.getRoutes(nodeKey); - }), - map((routes: Route[]) => { - currentNode.routes = routes; - - return currentNode; + if (!dmsgServerFound) { + node.dmsgServerPk = '-'; + node.roundTripPing = '-1'; + } + + return node; }) ); } @@ -741,40 +829,40 @@ export class NodeService { // Transport discovery. service = { name: 'node.details.node-health.transport-discovery', - isOk: node.health.transport_discovery && node.health.transport_discovery === 200, - originalValue: node.health.transport_discovery + '' + isOk: node.health.transportDiscovery && node.health.transportDiscovery === 200, + originalValue: node.health.transportDiscovery + '' }; response.services.push(service); // Route finder. service = { name: 'node.details.node-health.route-finder', - isOk: node.health.route_finder && node.health.route_finder === 200, - originalValue: node.health.route_finder + '' + isOk: node.health.routeFinder && node.health.routeFinder === 200, + originalValue: node.health.routeFinder + '' }; response.services.push(service); // Setup node. service = { name: 'node.details.node-health.setup-node', - isOk: node.health.setup_node && node.health.setup_node === 200, - originalValue: node.health.setup_node + '' + isOk: node.health.setupNode && node.health.setupNode === 200, + originalValue: node.health.setupNode + '' }; response.services.push(service); // Uptime tracker. service = { name: 'node.details.node-health.uptime-tracker', - isOk: node.health.uptime_tracker && node.health.uptime_tracker === 200, - originalValue: node.health.uptime_tracker + '' + isOk: node.health.uptimeTracker && node.health.uptimeTracker === 200, + originalValue: node.health.uptimeTracker + '' }; response.services.push(service); // Address resolver. service = { name: 'node.details.node-health.address-resolver', - isOk: node.health.address_resolver && node.health.address_resolver === 200, - originalValue: node.health.address_resolver + '' + isOk: node.health.addressResolver && node.health.addressResolver === 200, + originalValue: node.health.addressResolver + '' }; response.services.push(service); diff --git a/static/skywire-manager-src/src/app/services/route.service.ts b/static/skywire-manager-src/src/app/services/route.service.ts index aa39a2031d..88375e849e 100644 --- a/static/skywire-manager-src/src/app/services/route.service.ts +++ b/static/skywire-manager-src/src/app/services/route.service.ts @@ -1,9 +1,6 @@ import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; import { ApiService } from './api.service'; -import { Route } from '../app.datatypes'; /** * Allows to work with the routes of a node. @@ -16,21 +13,6 @@ export class RouteService { private apiService: ApiService, ) { } - /** - * Get a list with the routes of a node. - */ - getRoutes(nodeKey: string): Observable { - return this.apiService.get(`visors/${nodeKey}/routes`).pipe( - map(val => { - if (!val) { - return []; - } - - return val; - }) - ); - } - /** * Gets the details of a specific route. */ diff --git a/static/skywire-manager-src/src/app/services/transport.service.ts b/static/skywire-manager-src/src/app/services/transport.service.ts index 424128ab9c..203a573905 100644 --- a/static/skywire-manager-src/src/app/services/transport.service.ts +++ b/static/skywire-manager-src/src/app/services/transport.service.ts @@ -1,9 +1,7 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; import { ApiService } from './api.service'; -import { Transport } from '../app.datatypes'; /** * Allows to work with the transports of a node. @@ -16,21 +14,6 @@ export class TransportService { private apiService: ApiService, ) { } - /** - * Get a list with the transports of a node. - */ - getTransports(nodeKey: string): Observable { - return this.apiService.get(`visors/${nodeKey}/transports`).pipe( - map(val => { - if (!val) { - return []; - } - - return val; - }) - ); - } - create(nodeKey: string, remoteKey: string, type: string): Observable { return this.apiService.post(`visors/${nodeKey}/transports`, { remote_pk: remoteKey,