ing
This commit is contained in:
parent
4c630efc84
commit
fcd7d9f1b8
|
@ -1,5 +1,6 @@
|
||||||
import { Host } from './Host';
|
import { Host } from './Host';
|
||||||
import { MetaPortType, MetaDiscovererType } from '../meta';
|
import { MetaPortType, MetaDiscovererType } from '../meta';
|
||||||
|
import { Service } from './Service';
|
||||||
|
|
||||||
export interface Port {
|
export interface Port {
|
||||||
metaPortType?: MetaPortType;
|
metaPortType?: MetaPortType;
|
||||||
|
@ -10,5 +11,5 @@ export interface Port {
|
||||||
discoveredDate?: Date;
|
discoveredDate?: Date;
|
||||||
|
|
||||||
host?: Host;
|
host?: Host;
|
||||||
// serviceList?: Service[];
|
serviceList?: Service[];
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,4 +96,10 @@ export class DisplayComponent implements OnInit, AfterContentInit, OnDestroy {
|
||||||
this.store.dispatch(new InfraStore.ChangeSelectedInfra(null));
|
this.store.dispatch(new InfraStore.ChangeSelectedInfra(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
otherHostSelected(host: Host) {
|
||||||
|
this.store.dispatch(new InfraStore.ChangeSelectedInfra({
|
||||||
|
group: 'host',
|
||||||
|
infra: host,
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import * as UILayoutStore from '../../../store/ui/layout';
|
||||||
import { DiscoverySession } from '../../../core/discovery/discovery-session';
|
import { DiscoverySession } from '../../../core/discovery/discovery-session';
|
||||||
import { DiscoveryMessageType } from 'src/app/core/type';
|
import { DiscoveryMessageType } from 'src/app/core/type';
|
||||||
import { ConfirmationService } from 'primeng/primeng';
|
import { ConfirmationService } from 'primeng/primeng';
|
||||||
|
import { MetaServiceTypeEnum, toMetaServiceTypeEnum } from '@overflow/model/meta/MetaServiceType';
|
||||||
|
|
||||||
export class DisplaySummary {
|
export class DisplaySummary {
|
||||||
totalHosts: number;
|
totalHosts: number;
|
||||||
|
@ -91,6 +92,8 @@ export class DisplaySummary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const FIRE_CLICK_DETAIL = -99999;
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-infra-display-map',
|
selector: 'app-infra-display-map',
|
||||||
templateUrl: './map.component.html',
|
templateUrl: './map.component.html',
|
||||||
|
@ -106,6 +109,7 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
|
||||||
zoneNode: Node | null = null;
|
zoneNode: Node | null = null;
|
||||||
nodes: Node[];
|
nodes: Node[];
|
||||||
links: Link[];
|
links: Link[];
|
||||||
|
nodeElements: Map<string, Element>;
|
||||||
|
|
||||||
selectedNode: Node | null = null;
|
selectedNode: Node | null = null;
|
||||||
|
|
||||||
|
@ -209,6 +213,26 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DiscoveryMessageType.DiscoveryStop: {
|
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.simulationRestart(true);
|
||||||
__this.zoomToFit(0.95, 500);
|
__this.zoomToFit(0.95, 500);
|
||||||
|
|
||||||
|
@ -265,7 +289,7 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
|
||||||
__this.onHideDetail();
|
__this.onHideDetail();
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
__this.onInfraSelected(selectedInfra);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
).subscribe();
|
).subscribe();
|
||||||
|
@ -325,6 +349,7 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
|
||||||
}
|
}
|
||||||
this.nodes = [];
|
this.nodes = [];
|
||||||
this.links = [];
|
this.links = [];
|
||||||
|
this.nodeElements = new Map();
|
||||||
this.hosts = new Map();
|
this.hosts = new Map();
|
||||||
this.ports = new Map();
|
this.ports = new Map();
|
||||||
this.services = new Map();
|
this.services = new Map();
|
||||||
|
@ -406,7 +431,8 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
|
||||||
function getNodeFromElement(element: Element): Node | null {
|
function getNodeFromElement(element: Element): Node | null {
|
||||||
const container = d3.select(element);
|
const container = d3.select(element);
|
||||||
const nodeId = container.attr('nodeId');
|
const nodeId = container.attr('nodeId');
|
||||||
return __this.getNode(nodeId);
|
const { node } = __this.getNode(nodeId);
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
// drag
|
// drag
|
||||||
|
@ -474,13 +500,22 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
|
||||||
return false;
|
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 () {
|
nodeElements.on('click', function () {
|
||||||
d3.event.stopPropagation();
|
d3.event.stopPropagation();
|
||||||
|
|
||||||
const nodeElement = this as Element;
|
const nodeElement = this as Element;
|
||||||
const node = getNodeFromElement(nodeElement);
|
const node = getNodeFromElement(nodeElement);
|
||||||
if (null === node || 'zone' === node.group) {
|
if (null === node || 'zone' === node.group) {
|
||||||
|
clearSelection();
|
||||||
|
if (FIRE_CLICK_DETAIL !== d3.event.detail) {
|
||||||
__this.onInfraClick(node);
|
__this.onInfraClick(node);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,16 +570,13 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (FIRE_CLICK_DETAIL !== d3.event.detail) {
|
||||||
__this.onInfraClick(node);
|
__this.onInfraClick(node);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Highlight
|
// Highlight
|
||||||
const displayInfra = d3.select(this.displayInfraRef.nativeElement);
|
function clearSelection() {
|
||||||
displayInfra.on('click', function () {
|
|
||||||
__this.selectedNode = null;
|
|
||||||
__this.store.dispatch(new InfraStore.ChangeSelectedInfra(null));
|
|
||||||
|
|
||||||
nodeElements.each(function () {
|
nodeElements.each(function () {
|
||||||
const _thisElement = this as Element;
|
const _thisElement = this as Element;
|
||||||
d3.select(_thisElement).classed('semi-unselected', false);
|
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('semi-unselected', false);
|
||||||
d3.select(_thisElement).classed('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
|
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));
|
.call(this.zoomBehavior.transform, d3.zoomIdentity.translate(translate[0], translate[1]).scale(scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
onInfraClick(node: Node) {
|
onInfraSelected({ group, infra }: { group: string, infra: Host | Port | Service }) {
|
||||||
console.log(node);
|
switch (group) {
|
||||||
|
case 'zone': {
|
||||||
switch (node.group) {
|
const id = this.getZoneId(infra);
|
||||||
case 'zone':
|
this.fireClickOnNodeElement(id);
|
||||||
const zone: Zone = node.target;
|
|
||||||
zone.hostList = [];
|
|
||||||
|
|
||||||
this.hosts.forEach(_host => {
|
|
||||||
if (_host.zone.network === zone.network) {
|
|
||||||
zone.hostList.push(_host);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'host':
|
case 'host': {
|
||||||
const host: Host = node.target;
|
const id = this.getHostId(infra);
|
||||||
host.portList = [];
|
this.fireClickOnNodeElement(id);
|
||||||
if (this.ports.has(host.address)) {
|
|
||||||
this.ports.get(host.address).forEach(port => {
|
|
||||||
host.portList.push(port);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case 'service': {
|
||||||
|
const id = this.getServiceId(infra);
|
||||||
|
this.fireClickOnNodeElement(id);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
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({
|
this.store.dispatch(new InfraStore.ChangeSelectedInfra({
|
||||||
group: node.group,
|
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 _n: Node = null;
|
||||||
|
let _idx = -1;
|
||||||
this.nodes.some((node): boolean => {
|
this.nodes.some((node): boolean => {
|
||||||
|
_idx++;
|
||||||
if (node.id === id) {
|
if (node.id === id) {
|
||||||
_n = node;
|
_n = node;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
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[]) {
|
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) {
|
setZone(zone: Zone, requireRefresh: boolean = false) {
|
||||||
if (null === zone) {
|
if (null === zone) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.zone = zone;
|
this.zone = zone;
|
||||||
this.zoneNode = new Node(zone.network);
|
this.zoneNode = new Node(this.getZoneId(zone));
|
||||||
this.zoneNode.group = 'zone';
|
this.zoneNode.group = 'zone';
|
||||||
this.zoneNode.target = zone;
|
this.zoneNode.target = zone;
|
||||||
this.zoneNode.fx = this.displayInfraWidth / 2;
|
this.zoneNode.fx = this.displayInfraWidth / 2;
|
||||||
|
@ -783,21 +884,21 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
|
||||||
}
|
}
|
||||||
this.hosts.set(host.address, host);
|
this.hosts.set(host.address, host);
|
||||||
|
|
||||||
const hostId = `${host.address}`;
|
const hostId = this.getHostId(host);
|
||||||
|
|
||||||
let hostNode = this.getNode(hostId);
|
let { node } = this.getNode(hostId);
|
||||||
if (null !== hostNode) {
|
if (null !== node) {
|
||||||
hostNode.target = host;
|
node.target = host;
|
||||||
} else {
|
} else {
|
||||||
hostNode = new Node(hostId);
|
node = new Node(hostId);
|
||||||
hostNode.target = host;
|
node.target = host;
|
||||||
hostNode.group = 'host';
|
node.group = 'host';
|
||||||
hostNode.r = 40;
|
node.r = 40;
|
||||||
hostNode.x = this.zoneNode.x;
|
node.x = this.zoneNode.x;
|
||||||
hostNode.y = this.zoneNode.y;
|
node.y = this.zoneNode.y;
|
||||||
|
|
||||||
this.nodes.push(hostNode);
|
this.nodes.push(node);
|
||||||
this.links.push(new Link(this.zoneNode, hostNode));
|
this.links.push(new Link(this.zoneNode, node));
|
||||||
|
|
||||||
this.displaySummary.increaseHost();
|
this.displaySummary.increaseHost();
|
||||||
|
|
||||||
|
@ -837,14 +938,55 @@ export class MapComponent implements OnInit, AfterContentInit, OnDestroy {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hostId = `${service.port.host.address}`;
|
const hostId = this.getHostId(service.port.host);
|
||||||
const serviceId = `${service.port.host.address}-${service.port.portNumber}-${service.port.metaPortType.key}`;
|
const { node: hostNode } = this.getNode(hostId);
|
||||||
|
|
||||||
const hostNode = this.getNode(hostId);
|
const unknownServiceId = this.getUnknownServiceId(service);
|
||||||
let serviceNode = this.getNode(serviceId);
|
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) {
|
if (null !== serviceNode) {
|
||||||
serviceNode.target = service;
|
serviceNode.target = service;
|
||||||
} else {
|
} 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 = new Node(serviceId);
|
||||||
serviceNode.target = service;
|
serviceNode.target = service;
|
||||||
serviceNode.group = 'service';
|
serviceNode.group = 'service';
|
||||||
|
|
Loading…
Reference in New Issue
Block a user