This commit is contained in:
crusader 2018-10-12 19:36:02 +09:00
parent 4c630efc84
commit fcd7d9f1b8
3 changed files with 203 additions and 54 deletions

View File

@ -1,5 +1,6 @@
import { Host } from './Host';
import { MetaPortType, MetaDiscovererType } from '../meta';
import { Service } from './Service';
export interface Port {
metaPortType?: MetaPortType;
@ -10,5 +11,5 @@ export interface Port {
discoveredDate?: Date;
host?: Host;
// serviceList?: Service[];
serviceList?: Service[];
}

View File

@ -96,4 +96,10 @@ export class DisplayComponent implements OnInit, AfterContentInit, OnDestroy {
this.store.dispatch(new InfraStore.ChangeSelectedInfra(null));
}
otherHostSelected(host: Host) {
this.store.dispatch(new InfraStore.ChangeSelectedInfra({
group: 'host',
infra: host,
}));
}
}

View File

@ -29,6 +29,7 @@ import * as UILayoutStore from '../../../store/ui/layout';
import { DiscoverySession } from '../../../core/discovery/discovery-session';
import { DiscoveryMessageType } from 'src/app/core/type';
import { ConfirmationService } from 'primeng/primeng';
import { MetaServiceTypeEnum, toMetaServiceTypeEnum } from '@overflow/model/meta/MetaServiceType';
export class DisplaySummary {
totalHosts: number;
@ -91,6 +92,8 @@ export class DisplaySummary {
}
}
const FIRE_CLICK_DETAIL = -99999;
@Component({
selector: 'app-infra-display-map',
templateUrl: './map.component.html',
@ -106,6 +109,7 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
zoneNode: Node | null = null;
nodes: Node[];
links: Link[];
nodeElements: Map<string, Element>;
selectedNode: Node | null = null;
@ -209,6 +213,26 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
}
break;
case DiscoveryMessageType.DiscoveryStop: {
__this.zone.hostList = [];
__this.hosts.forEach(_host => {
if (_host.zone.network === __this.zone.network) {
__this.zone.hostList.push(_host);
}
_host.portList = [];
if (__this.ports.has(_host.address)) {
__this.ports.get(_host.address).forEach(_port => {
_host.portList.push(_port);
_port.serviceList = [];
if (__this.services.has(_host.address) && __this.services.get(_host.address).has(_port.portNumber)) {
__this.services.get(_host.address).get(_port.portNumber).forEach(_service => {
_port.serviceList.push(_service);
});
}
});
}
});
__this.simulationRestart(true);
__this.zoomToFit(0.95, 500);
@ -265,7 +289,7 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
__this.onHideDetail();
return;
} else {
__this.onInfraSelected(selectedInfra);
}
}),
).subscribe();
@ -325,6 +349,7 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
}
this.nodes = [];
this.links = [];
this.nodeElements = new Map();
this.hosts = new Map();
this.ports = new Map();
this.services = new Map();
@ -406,7 +431,8 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
function getNodeFromElement(element: Element): Node | null {
const container = d3.select(element);
const nodeId = container.attr('nodeId');
return __this.getNode(nodeId);
const { node } = __this.getNode(nodeId);
return node;
}
// drag
@ -474,13 +500,22 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
return false;
}
nodeElements.each(function (d) {
const nodeElement = this as Element;
const node = getNodeFromElement(nodeElement);
__this.nodeElements.set(node.id, nodeElement);
});
nodeElements.on('click', function () {
d3.event.stopPropagation();
const nodeElement = this as Element;
const node = getNodeFromElement(nodeElement);
if (null === node || 'zone' === node.group) {
clearSelection();
if (FIRE_CLICK_DETAIL !== d3.event.detail) {
__this.onInfraClick(node);
}
return;
}
@ -535,16 +570,13 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
}
});
if (FIRE_CLICK_DETAIL !== d3.event.detail) {
__this.onInfraClick(node);
}
});
// Highlight
const displayInfra = d3.select(this.displayInfraRef.nativeElement);
displayInfra.on('click', function () {
__this.selectedNode = null;
__this.store.dispatch(new InfraStore.ChangeSelectedInfra(null));
function clearSelection() {
nodeElements.each(function () {
const _thisElement = this as Element;
d3.select(_thisElement).classed('semi-unselected', false);
@ -556,6 +588,14 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
d3.select(_thisElement).classed('semi-unselected', false);
d3.select(_thisElement).classed('unselected', false);
});
}
const displayInfra = d3.select(this.displayInfraRef.nativeElement);
displayInfra.on('click', function () {
__this.selectedNode = null;
__this.store.dispatch(new InfraStore.ChangeSelectedInfra(null));
clearSelection();
});
nodeElements
@ -681,33 +721,63 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
.call(this.zoomBehavior.transform, d3.zoomIdentity.translate(translate[0], translate[1]).scale(scale));
}
onInfraClick(node: Node) {
console.log(node);
switch (node.group) {
case 'zone':
const zone: Zone = node.target;
zone.hostList = [];
this.hosts.forEach(_host => {
if (_host.zone.network === zone.network) {
zone.hostList.push(_host);
onInfraSelected({ group, infra }: { group: string, infra: Host | Port | Service }) {
switch (group) {
case 'zone': {
const id = this.getZoneId(infra);
this.fireClickOnNodeElement(id);
}
});
break;
case 'host':
const host: Host = node.target;
host.portList = [];
if (this.ports.has(host.address)) {
this.ports.get(host.address).forEach(port => {
host.portList.push(port);
});
case 'host': {
const id = this.getHostId(infra);
this.fireClickOnNodeElement(id);
}
break;
case 'service': {
const id = this.getServiceId(infra);
this.fireClickOnNodeElement(id);
}
break;
default:
break;
}
}
fireClickOnNodeElement(nodeId: string) {
const nodeElement = this.nodeElements.get(nodeId);
if (null === nodeElement || (null !== this.selectedNode && nodeId === this.selectedNode.id)) {
return;
}
nodeElement.dispatchEvent(new CustomEvent('click', { detail: FIRE_CLICK_DETAIL }));
}
onInfraClick(node: Node) {
// switch (node.group) {
// case 'zone':
// const zone: Zone = node.target;
// zone.hostList = [];
// this.hosts.forEach(_host => {
// if (_host.zone.network === zone.network) {
// zone.hostList.push(_host);
// }
// });
// break;
// case 'host':
// const host: Host = node.target;
// host.portList = [];
// if (this.ports.has(host.address)) {
// this.ports.get(host.address).forEach(port => {
// host.portList.push(port);
// });
// }
// break;
// default:
// break;
// }
this.store.dispatch(new InfraStore.ChangeSelectedInfra({
group: node.group,
@ -739,29 +809,60 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
}
private getNode(id: string): Node | null {
private getNode(id: string): { index: number, node: Node } {
let _n: Node = null;
let _idx = -1;
this.nodes.some((node): boolean => {
_idx++;
if (node.id === id) {
_n = node;
return true;
}
return false;
});
return _n;
return { index: null === _n ? -1 : _idx, node: _n };
}
private getLink(source: Node, target: Node): { index: number, link: Link } | null {
let _l: Link = null;
let _idx = -1;
this.links.some((link): boolean => {
_idx++;
if (link.source.id === source.id && link.target.id === target.id) {
_l = link;
return true;
}
return false;
});
return { index: null === _l ? -1 : _idx, link: _l };
}
refreshInfraDisplay(zone: Zone, hosts: Host[], services: Service[]) {
}
getZoneId(zone: Zone): string {
return `${zone.network}`;
}
getHostId(host: Host): string {
return `${this.getZoneId(host.zone)}-${host.address}`;
}
getPortId(port: Port): string {
return `${this.getHostId(port.host)}-${port.portNumber}-${port.metaPortType.key}`;
}
getServiceId(service: Service): string {
return `${this.getPortId(service.port)}-${service.serviceType}`;
}
getUnknownServiceId(service: Service): string {
return `${this.getPortId(service.port)}-${MetaServiceTypeEnum.UNKNOWN}`;
}
setZone(zone: Zone, requireRefresh: boolean = false) {
if (null === zone) {
return;
}
this.zone = zone;
this.zoneNode = new Node(zone.network);
this.zoneNode = new Node(this.getZoneId(zone));
this.zoneNode.group = 'zone';
this.zoneNode.target = zone;
this.zoneNode.fx = this.displayInfraWidth / 2;
@ -783,21 +884,21 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
}
this.hosts.set(host.address, host);
const hostId = `${host.address}`;
const hostId = this.getHostId(host);
let hostNode = this.getNode(hostId);
if (null !== hostNode) {
hostNode.target = host;
let { node } = this.getNode(hostId);
if (null !== node) {
node.target = host;
} else {
hostNode = new Node(hostId);
hostNode.target = host;
hostNode.group = 'host';
hostNode.r = 40;
hostNode.x = this.zoneNode.x;
hostNode.y = this.zoneNode.y;
node = new Node(hostId);
node.target = host;
node.group = 'host';
node.r = 40;
node.x = this.zoneNode.x;
node.y = this.zoneNode.y;
this.nodes.push(hostNode);
this.links.push(new Link(this.zoneNode, hostNode));
this.nodes.push(node);
this.links.push(new Link(this.zoneNode, node));
this.displaySummary.increaseHost();
@ -837,14 +938,55 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
return;
}
const hostId = `${service.port.host.address}`;
const serviceId = `${service.port.host.address}-${service.port.portNumber}-${service.port.metaPortType.key}`;
const hostId = this.getHostId(service.port.host);
const { node: hostNode } = this.getNode(hostId);
const hostNode = this.getNode(hostId);
let serviceNode = this.getNode(serviceId);
const unknownServiceId = this.getUnknownServiceId(service);
const { index: unknownServiceNodeIdx, node: unknownServiceNode } = this.getNode(unknownServiceId);
const serviceId = this.getServiceId(service);
let { node: serviceNode } = this.getNode(serviceId);
let newNode = false;
if (MetaServiceTypeEnum.UNKNOWN === MetaServiceTypeEnum[service.serviceType]) {
if (null !== unknownServiceNode) {
unknownServiceNode.target = service;
} else {
newNode = true;
}
} else {
if (null !== serviceNode) {
serviceNode.target = service;
} else {
if (null !== unknownServiceNode) {
const { index: linkIdx } = this.getLink(hostNode, unknownServiceNode);
delete this.links[linkIdx];
delete this.nodes[unknownServiceNodeIdx];
}
newNode = true;
}
}
let _servicesMap: Map<number, Map<string, Service>>;
if (!this.services.has(service.port.host.address)) {
_servicesMap = new Map();
this.services.set(service.port.host.address, _servicesMap);
} else {
_servicesMap = this.services.get(service.port.host.address);
}
let _services: Map<string, Service>;
if (!_servicesMap.has(service.port.portNumber)) {
_services = new Map();
_servicesMap.set(service.port.portNumber, _services);
} else {
_services = _servicesMap.get(service.port.portNumber);
}
_services.set(service.serviceType, service);
if (newNode) {
serviceNode = new Node(serviceId);
serviceNode.target = service;
serviceNode.group = 'service';