blob: c2beae7857dc786088153a322f76a5abc11adff2 [file] [log] [blame]
Sean Condon83fc39f2018-04-19 18:56:13 +01001/*
Sean Condon91481822019-01-01 13:56:14 +00002 * Copyright 2019-present Open Networking Foundation
Sean Condon83fc39f2018-04-19 18:56:13 +01003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Sean Condon50855cf2018-12-23 15:37:42 +000016import {Injectable, SimpleChange} from '@angular/core';
Sean Condonf4f54a12018-10-10 23:25:46 +010017import {
Sean Condonaa4366d2018-11-02 14:29:01 +000018 LogService, WebSocketService,
Sean Condona3ad7792020-01-04 19:26:34 +000019} from 'gui2-fw-lib/public_api';
Sean Condon058804c2019-04-16 09:41:52 +010020import {Instance, InstanceComponent} from './panel/instance/instance.component';
Sean Condonaa4366d2018-11-02 14:29:01 +000021import { BackgroundSvgComponent } from './layer/backgroundsvg/backgroundsvg.component';
22import { ForceSvgComponent } from './layer/forcesvg/forcesvg.component';
Sean Condon50855cf2018-12-23 15:37:42 +000023import {
24 ModelEventMemo,
25 ModelEventType,
26 Region
27} from './layer/forcesvg/models';
Sean Condon83fc39f2018-04-19 18:56:13 +010028
29/**
Sean Condon4e55c802019-12-03 22:13:34 +000030 * Model of the Intent to be displayed
31 */
32export interface Intent {
33 appId: string;
34 appName: string;
35 key: string;
36 type: string;
37}
38
39export interface RelatedIntent {
40 ids: string[];
41 hover: string;
42}
43
44/**
Sean Condonf4f54a12018-10-10 23:25:46 +010045 * ONOS GUI -- Topology Service Module.
Sean Condon83fc39f2018-04-19 18:56:13 +010046 */
Sean Condonf4f54a12018-10-10 23:25:46 +010047@Injectable()
48export class TopologyService {
Sean Condon83fc39f2018-04-19 18:56:13 +010049
Sean Condonaa4366d2018-11-02 14:29:01 +000050 private handlers: string[] = [];
51 private openListener: any;
Sean Condon058804c2019-04-16 09:41:52 +010052 public instancesIndex: Map<string, number>;
Sean Condonaa4366d2018-11-02 14:29:01 +000053
Sean Condonf4f54a12018-10-10 23:25:46 +010054 constructor(
55 protected log: LogService,
Sean Condonaa4366d2018-11-02 14:29:01 +000056 protected wss: WebSocketService
Sean Condonf4f54a12018-10-10 23:25:46 +010057 ) {
Sean Condon058804c2019-04-16 09:41:52 +010058 this.instancesIndex = new Map();
Sean Condonaa4366d2018-11-02 14:29:01 +000059 this.log.debug('TopologyService constructed');
Sean Condonf4f54a12018-10-10 23:25:46 +010060 }
61
Sean Condonaa4366d2018-11-02 14:29:01 +000062 /**
63 * bind our event handlers to the web socket service, so that our
64 * callbacks get invoked for incoming events
65 */
66 init(instance: InstanceComponent, background: BackgroundSvgComponent, force: ForceSvgComponent) {
67 this.wss.bindHandlers(new Map<string, (data) => void>([
68 ['topo2AllInstances', (data) => {
Sean Condon91481822019-01-01 13:56:14 +000069 this.log.debug('Instances updated through WSS as topo2AllInstances', data);
Sean Condon058804c2019-04-16 09:41:52 +010070 instance.ngOnChanges(
71 {'onosInstances': new SimpleChange({}, data.members, true)});
72
73 // Also generate an index locally of the instances
74 // needed so that devices can be coloured by instance
75 this.instancesIndex.clear();
76 (<Instance[]>data.members).forEach((inst, idx) => this.instancesIndex.set(inst.id, idx));
77 this.log.debug('Created local index of instances', this.instancesIndex);
Sean Condonaa4366d2018-11-02 14:29:01 +000078 }
79 ],
80 ['topo2CurrentLayout', (data) => {
Sean Condon91481822019-01-01 13:56:14 +000081 this.log.debug('Background Data updated from WSS as topo2CurrentLayout', data);
Sean Condon50855cf2018-12-23 15:37:42 +000082 if (background) {
83 background.layoutData = data;
84 }
Sean Condonaa4366d2018-11-02 14:29:01 +000085 }
86 ],
87 ['topo2CurrentRegion', (data) => {
Sean Condonaa4366d2018-11-02 14:29:01 +000088 force.regionData = data;
Sean Condon0c577f62018-11-18 22:40:05 +000089 force.ngOnChanges({
90 'regionData' : new SimpleChange(<Region>{}, data, true)
91 });
Sean Condon91481822019-01-01 13:56:14 +000092 this.log.debug('Region Data replaced from WSS as topo2CurrentRegion', force.regionData);
Sean Condonaa4366d2018-11-02 14:29:01 +000093 }
94 ],
95 ['topo2PeerRegions', (data) => { this.log.warn('Add fn for topo2PeerRegions callback', data); } ],
Sean Condon50855cf2018-12-23 15:37:42 +000096 ['topo2UiModelEvent', (event) => {
97 // this.log.debug('Handling', event);
98 force.handleModelEvent(
Sean Condon91481822019-01-01 13:56:14 +000099 <ModelEventType><unknown>(ModelEventType[event.type]), // Number based enum
100 <ModelEventMemo>(event.memo), // String based enum
Sean Condon50855cf2018-12-23 15:37:42 +0000101 event.subject, event.data);
102 }
103 ],
Sean Condon64ea7d22019-04-12 19:39:13 +0100104 ['showHighlights', (event) => {
Sean Condon4e55c802019-12-03 22:13:34 +0000105 this.log.debug('Handling showHighlights', event);
106 force.handleHighlights(event.devices, event.hosts, event.links, 5000);
Sean Condon64ea7d22019-04-12 19:39:13 +0100107 }]
Sean Condon91481822019-01-01 13:56:14 +0000108 // topo2Highlights is handled by TrafficService
Sean Condonaa4366d2018-11-02 14:29:01 +0000109 ]));
110 this.handlers.push('topo2AllInstances');
111 this.handlers.push('topo2CurrentLayout');
112 this.handlers.push('topo2CurrentRegion');
113 this.handlers.push('topo2PeerRegions');
114 this.handlers.push('topo2UiModelEvent');
Sean Condon4e55c802019-12-03 22:13:34 +0000115 this.handlers.push('showHighlights');
Sean Condon50855cf2018-12-23 15:37:42 +0000116 // this.handlers.push('topo2Highlights');
Sean Condonf4f54a12018-10-10 23:25:46 +0100117
Sean Condonaa4366d2018-11-02 14:29:01 +0000118 // in case we fail over to a new server,
119 // listen for wsock-open events
120 this.openListener = this.wss.addOpenListener(() => this.wsOpen);
Sean Condonf4f54a12018-10-10 23:25:46 +0100121
Sean Condonaa4366d2018-11-02 14:29:01 +0000122 // tell the server we are ready to receive topology events
123 this.wss.sendEvent('topo2Start', {});
124 this.log.debug('TopologyService initialized');
Sean Condonf4f54a12018-10-10 23:25:46 +0100125 }
126
Sean Condonaa4366d2018-11-02 14:29:01 +0000127 /**
128 * tell the server we no longer wish to receive topology events
129 */
Sean Condonf4f54a12018-10-10 23:25:46 +0100130 destroy() {
Sean Condonaa4366d2018-11-02 14:29:01 +0000131 this.wss.sendEvent('topo2Stop', {});
132 this.wss.unbindHandlers(this.handlers);
133 this.wss.removeOpenListener(this.openListener);
134 this.openListener = null;
135 this.log.debug('TopologyService destroyed');
136 }
Sean Condonf4f54a12018-10-10 23:25:46 +0100137
138
Sean Condonaa4366d2018-11-02 14:29:01 +0000139 wsOpen(host: string, url: string) {
140 this.log.debug('topo2Event: WSopen - cluster node:', host, 'URL:', url);
141 // tell the server we are ready to receive topo events
142 this.wss.sendEvent('topo2Start', {});
Sean Condonf4f54a12018-10-10 23:25:46 +0100143 }
Sean Condon4e55c802019-12-03 22:13:34 +0000144
145 /*
146 * Result will be handled by showHighlights handler (set up in topology service)
147 * which will call handleHighlights() in Force Component
148 */
149 setSelectedIntent(selectedIntent: Intent): void {
150 this.log.debug('Selected intent changed to', selectedIntent);
151 this.wss.sendEvent('selectIntent', selectedIntent);
152 }
153
154 selectRelatedIntent(ids: string[]): void {
155 this.log.debug('Select next intent');
156 this.wss.sendEvent('requestNextRelatedIntent', <RelatedIntent>{
157 ids: ids,
158 hover: undefined,
159 });
160 }
161
162 /*
163 * Tell the backend to stop sending highlights - any present will fade after 5 seconds
164 * There is also a cancel traffic for Topo 2 in Traffic Service
165 */
166 cancelHighlights(): void {
167 this.wss.sendEvent('cancelTraffic', {});
168 this.log.debug('Highlights canceled');
169 }
Sean Condonf4f54a12018-10-10 23:25:46 +0100170}