discovery

This commit is contained in:
insanity 2018-06-01 20:25:51 +09:00
parent fd369d3519
commit 54f5a61901
5 changed files with 152 additions and 34 deletions

View File

@ -24,11 +24,11 @@ export const Anim = [
trigger('discoveryResultAnim', [ trigger('discoveryResultAnim', [
transition('void => *', [ transition('void => *', [
query('*', style({ opacity: 0 }), { optional: true }), query('*', style({ opacity: 0 }), { optional: true }),
query('*', stagger('500ms', [ query('*', stagger('30ms', [
animate('0.08s ease-in', keyframes([ animate('0.08s ease-in', keyframes([
style({ opacity: 0, transform: 'translateX(-75%)', offset: 0 }), style({ opacity: 0, transform: 'translateX(-95%)', offset: 0 }),
style({ opacity: .5, transform: 'translateX(35px)', offset: 0.3 }), style({ opacity: .5, transform: 'translateX(95px)', offset: 0.3 }),
style({ opacity: 1, transform: 'translateY(0)', offset: 1.0 }), style({ opacity: 1, transform: 'translateX(0)', offset: 1.0 }),
]))]), { optional: true }), ]))]), { optional: true }),
]), ]),
]), ]),

View File

@ -16,13 +16,16 @@
<div class="ui-g-12 ui-md-9"> <div class="ui-g-12 ui-md-9">
<p-panel> <p-panel>
<of-discovery-result *ngIf="requested else info" [started]="requested" (stop)="onRequestDiscoveryStop($event)"></of-discovery-result> <button class="ui-button-danger ui-button-width-fit" type="button" label="Stop" icon="ui-icon-close" pButton (click)="onStop()"
[disabled]="!started"></button>
<!-- <of-discovery-result *ngIf="requested else info" [started]="requested" (stop)="onRequestDiscoveryStop($event)"></of-discovery-result> -->
<of-discovery-result #discoveryResult *ngIf="requested else info" [probeHost]="selectedProbe" [started]="requested"></of-discovery-result>
</p-panel> </p-panel>
</div> </div>
</div> </div>
<ng-template #info> <ng-template #info>
<div style="min-height: 100vh "> <div style="min-height: 100vh">
Network Discovery 설명 페이지 Network Discovery 설명 페이지
</div> </div>
</ng-template> </ng-template>

View File

@ -1,5 +1,5 @@
import { import {
Component, Input, Output, EventEmitter, OnDestroy, Component, Input, Output, EventEmitter, OnDestroy, ViewChild,
} from '@angular/core'; } from '@angular/core';
import { Probe, ProbeHost } from '@overflow/commons-typescript/model/probe'; import { Probe, ProbeHost } from '@overflow/commons-typescript/model/probe';
import { Anim } from './animation'; import { Anim } from './animation';
@ -9,6 +9,7 @@ import { DiscoveryService } from '../service/discovery.service';
import { catchError, exhaustMap, map, tap } from 'rxjs/operators'; import { catchError, exhaustMap, map, tap } from 'rxjs/operators';
import { DiscoverZone, Zone, Host, Port, Service } from '@overflow/commons-typescript/model/discovery'; import { DiscoverZone, Zone, Host, Port, Service } from '@overflow/commons-typescript/model/discovery';
import { DiscoverySubscriber, DiscoveryNotify } from '../subscriber/discovery.subscriber'; import { DiscoverySubscriber, DiscoveryNotify } from '../subscriber/discovery.subscriber';
import { SearchResultComponent } from './search-result.component';
@Component({ @Component({
selector: 'of-discovery', selector: 'of-discovery',
@ -26,6 +27,8 @@ export class DiscoveryComponent implements OnDestroy {
requested: boolean; requested: boolean;
discoverZone: DiscoverZone; discoverZone: DiscoverZone;
@ViewChild('discoveryResult') discoveryResult: SearchResultComponent;
constructor( constructor(
private discoveryService: DiscoveryService, private discoveryService: DiscoveryService,
private discoverySubscriber: DiscoverySubscriber, private discoverySubscriber: DiscoverySubscriber,
@ -58,6 +61,7 @@ export class DiscoveryComponent implements OnDestroy {
this.discoverySubscription.unsubscribe(); this.discoverySubscription.unsubscribe();
this.discoverySubscription = null; this.discoverySubscription = null;
break; break;
} }
case 'DiscoveryService.discoveredZone': { case 'DiscoveryService.discoveredZone': {

View File

@ -1,14 +1,32 @@
<button class="ui-button-danger ui-button-width-fit" type="button" label="Stop" icon="ui-icon-close" pButton (click)="onStop()"
[disabled]="!started"></button>
<div> <div>
<button pButton type="button" label="Click" (click)="addHostNode()"></button> <button pButton type="button" label="TestHost" (click)="tempHost()"></button>
<button pButton type="button" label="Click" (click)="addServiceNode()"></button> <button pButton type="button" label="TestService" (click)="tempService()"></button>
<p-tree [value]="zoneNode" layout="horizontal">
<ng-template let-node pTemplate="default"> <p-tree [value]="zoneNode" layout="vertical">
<div @discoveryResultAnim>
<input [(ngModel)]="node.label" type="text" style="width:100%"> <!-- ZONE node template -->
<ng-template let-node pTemplate="ZONE">
<div>
{{node.label}}
</div> </div>
</ng-template> </ng-template>
<!-- HOST node template -->
<ng-template let-node pTemplate="HOST">
<div @discoveryResultAnim>
<p-toggleButton onLabel="{{node.label}}" offLabel="{{node.label}}" onIcon="fa-check" offIcon="fa-square" [style]="{'width':'150px'}"
(onChange)="onTargetSelect($event, node.data)"></p-toggleButton>
</div>
</ng-template>
<!-- SERVICE node template -->
<ng-template let-node pTemplate="SERVICE">
<div @discoveryResultAnim>
<p-toggleButton onLabel="{{node.label}} {{node.data.portType}} {{node.data.portNumber}}" offLabel="{{node.label}} {{node.data.portType}} {{node.data.portNumber}}"
onIcon="fa-check" offIcon="fa-square" [style]="{'width':'300px'}" (onChange)="onTargetSelect($event, node.data)"></p-toggleButton>
</div>
</ng-template>
</p-tree> </p-tree>
</div> </div>

View File

@ -2,56 +2,149 @@ import {
AfterContentInit, Component, Input, AfterContentInit, Component, Input,
EventEmitter, EventEmitter,
Output, Output,
OnChanges, SimpleChanges,
SimpleChanges OnInit,
} from '@angular/core'; } from '@angular/core';
import { Anim } from './animation'; import { Anim } from './animation';
import { TreeNode } from 'primeng/primeng'; import { TreeNode } from 'primeng/primeng';
import { DiscoveryNotify } from '../subscriber/discovery.subscriber';
import { DiscoverZone, Zone, Host, Port, Service } from '@overflow/commons-typescript/model/discovery';
import { Subscription } from 'rxjs';
import { ProbeHost } from '@overflow/commons-typescript/model/probe';
@Component({ @Component({
selector: 'of-discovery-result', selector: 'of-discovery-result',
templateUrl: './search-result.component.html', templateUrl: './search-result.component.html',
animations: Anim animations: Anim
}) })
export class SearchResultComponent implements OnChanges { export class SearchResultComponent implements OnInit {
@Input() probeHost: ProbeHost;
@Output() stop = new EventEmitter(); @Output() stop = new EventEmitter();
@Input() started: boolean; @Input() started: boolean; // Temporary
discoverySubscription: Subscription;
zoneNode: TreeNode[] = []; zoneNode: TreeNode[] = [];
hostNode: TreeNode[] = []; hostNode: TreeNode[] = [];
selectedItems = [];
tempHostId = 0; // Temporary
constructor( constructor(
) { ) {
}
ngOnInit(): void {
this.zoneNode.push({ this.zoneNode.push({
label: 'zone', label: this.probeHost.probe.cidr,
type: 'ZONE',
data: {
},
children: this.hostNode, children: this.hostNode,
expanded: true expanded: true
}); });
} }
ngOnChanges(changes: SimpleChanges): void { tempHost() {
const idx = Math.floor(Math.random() * (255));
const host: Host = {
id: this.tempHostId++,
ipv4: '192.168.1.' + idx,
};
this.addHostNode(host);
} }
onStop() { tempService() {
this.stop.emit(); const idx = Math.floor(Math.random() * (255));
const hostId = Math.floor(Math.random() * (this.tempHostId - 1));
const service: Service = {
id: idx,
serviceName: 'Service',
port: {
portNumber: idx,
portType: idx % 2 === 0 ? 'TCP' : 'UDP',
host: {
id: hostId
}
}
};
this.addServiceNode(service);
} }
test() { addHostNode(host: Host) {
} const idx = this.findHostIndex(host);
addHostNode() {
const idx = Math.floor(Math.random() * (this.hostNode.length - 1));
this.hostNode.splice(idx, 0, { this.hostNode.splice(idx, 0, {
label: 'host', type: 'HOST',
label: host.ipv4,
data: {
id: host.id,
ip: this.convertIPtoNumber(host.ipv4),
},
expanded: true, expanded: true,
children: [] children: []
}); });
} }
addServiceNode() { addServiceNode(service: Service) {
const idx = Math.floor(Math.random() * (this.hostNode.length - 1)); const targetHostNode = this.findHostNodeByService(service);
this.hostNode[idx].children.push({ const idx = this.findServiceIndex(targetHostNode.children, service);
label: 'service', targetHostNode.children[idx] = {
type: 'SERVICE',
label: service.serviceName,
data: {
id: service.id,
portType: service.port.portType,
portNumber: service.port.portNumber,
},
};
}
onTargetSelect(e, data) {
if (e.checked) {
this.selectedItems.push(data);
} else {
const index = this.selectedItems.indexOf(data);
this.selectedItems.splice(index, 1);
}
}
findHostIndex(host: Host): number {
let index = 0;
this.hostNode.forEach(node => {
if (node.data.ip < this.convertIPtoNumber(host.ipv4)) {
index++;
}
});
return index;
}
findServiceIndex(serviceNodes: TreeNode[], service: Service) {
let index = 0;
serviceNodes.forEach(node => {
if (node.data.portNumber < service.port.portNumber) {
index++;
}
});
return index;
}
findHostNodeByService(service: Service) {
let targetHost = null;
this.hostNode.forEach((value, i) => {
if (value.data.id === service.port.host.id) {
targetHost = this.hostNode[i];
}
});
return targetHost;
}
convertIPtoNumber(ip: string) {
return ip.split('.').map((octet, index, array) => {
// tslint:disable-next-line:radix
return parseInt(octet) * Math.pow(256, (array.length - index - 1));
}).reduce((prev, curr) => {
return prev + curr;
}); });
} }
} }