blob: c2beae7857dc786088153a322f76a5abc11adff2 [file] [log] [blame]
/*
* Copyright 2019-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {Injectable, SimpleChange} from '@angular/core';
import {
LogService, WebSocketService,
} from 'gui2-fw-lib/public_api';
import {Instance, InstanceComponent} from './panel/instance/instance.component';
import { BackgroundSvgComponent } from './layer/backgroundsvg/backgroundsvg.component';
import { ForceSvgComponent } from './layer/forcesvg/forcesvg.component';
import {
ModelEventMemo,
ModelEventType,
Region
} from './layer/forcesvg/models';
/**
* Model of the Intent to be displayed
*/
export interface Intent {
appId: string;
appName: string;
key: string;
type: string;
}
export interface RelatedIntent {
ids: string[];
hover: string;
}
/**
* ONOS GUI -- Topology Service Module.
*/
@Injectable()
export class TopologyService {
private handlers: string[] = [];
private openListener: any;
public instancesIndex: Map<string, number>;
constructor(
protected log: LogService,
protected wss: WebSocketService
) {
this.instancesIndex = new Map();
this.log.debug('TopologyService constructed');
}
/**
* bind our event handlers to the web socket service, so that our
* callbacks get invoked for incoming events
*/
init(instance: InstanceComponent, background: BackgroundSvgComponent, force: ForceSvgComponent) {
this.wss.bindHandlers(new Map<string, (data) => void>([
['topo2AllInstances', (data) => {
this.log.debug('Instances updated through WSS as topo2AllInstances', data);
instance.ngOnChanges(
{'onosInstances': new SimpleChange({}, data.members, true)});
// Also generate an index locally of the instances
// needed so that devices can be coloured by instance
this.instancesIndex.clear();
(<Instance[]>data.members).forEach((inst, idx) => this.instancesIndex.set(inst.id, idx));
this.log.debug('Created local index of instances', this.instancesIndex);
}
],
['topo2CurrentLayout', (data) => {
this.log.debug('Background Data updated from WSS as topo2CurrentLayout', data);
if (background) {
background.layoutData = data;
}
}
],
['topo2CurrentRegion', (data) => {
force.regionData = data;
force.ngOnChanges({
'regionData' : new SimpleChange(<Region>{}, data, true)
});
this.log.debug('Region Data replaced from WSS as topo2CurrentRegion', force.regionData);
}
],
['topo2PeerRegions', (data) => { this.log.warn('Add fn for topo2PeerRegions callback', data); } ],
['topo2UiModelEvent', (event) => {
// this.log.debug('Handling', event);
force.handleModelEvent(
<ModelEventType><unknown>(ModelEventType[event.type]), // Number based enum
<ModelEventMemo>(event.memo), // String based enum
event.subject, event.data);
}
],
['showHighlights', (event) => {
this.log.debug('Handling showHighlights', event);
force.handleHighlights(event.devices, event.hosts, event.links, 5000);
}]
// topo2Highlights is handled by TrafficService
]));
this.handlers.push('topo2AllInstances');
this.handlers.push('topo2CurrentLayout');
this.handlers.push('topo2CurrentRegion');
this.handlers.push('topo2PeerRegions');
this.handlers.push('topo2UiModelEvent');
this.handlers.push('showHighlights');
// this.handlers.push('topo2Highlights');
// in case we fail over to a new server,
// listen for wsock-open events
this.openListener = this.wss.addOpenListener(() => this.wsOpen);
// tell the server we are ready to receive topology events
this.wss.sendEvent('topo2Start', {});
this.log.debug('TopologyService initialized');
}
/**
* tell the server we no longer wish to receive topology events
*/
destroy() {
this.wss.sendEvent('topo2Stop', {});
this.wss.unbindHandlers(this.handlers);
this.wss.removeOpenListener(this.openListener);
this.openListener = null;
this.log.debug('TopologyService destroyed');
}
wsOpen(host: string, url: string) {
this.log.debug('topo2Event: WSopen - cluster node:', host, 'URL:', url);
// tell the server we are ready to receive topo events
this.wss.sendEvent('topo2Start', {});
}
/*
* Result will be handled by showHighlights handler (set up in topology service)
* which will call handleHighlights() in Force Component
*/
setSelectedIntent(selectedIntent: Intent): void {
this.log.debug('Selected intent changed to', selectedIntent);
this.wss.sendEvent('selectIntent', selectedIntent);
}
selectRelatedIntent(ids: string[]): void {
this.log.debug('Select next intent');
this.wss.sendEvent('requestNextRelatedIntent', <RelatedIntent>{
ids: ids,
hover: undefined,
});
}
/*
* Tell the backend to stop sending highlights - any present will fade after 5 seconds
* There is also a cancel traffic for Topo 2 in Traffic Service
*/
cancelHighlights(): void {
this.wss.sendEvent('cancelTraffic', {});
this.log.debug('Highlights canceled');
}
}