Added native Bazel build to GUI2. Reduced a lot of the unused Angular CLI structures
Reviewers should look at the changes in WORKSPACE, BUILD, BUILD.bazel, README.md files
This is only possible now as rules_nodejs went to 1.0.0 on December 20
gui2 has now been made the entry point (rather than gui2-fw-lib)
No tests or linting are functional yet for Typescript
Each NgModule now has its own BUILD.bazel file with ng_module
gui2-fw-lib is all one module and has been refactored to simplify the directory structure
gui2-topo-lib is also all one module - its directory structure has had 3 layers removed
The big bash script in web/gui2/BUILD has been removed - all is done through ng_module rules
in web/gui2/src/main/webapp/BUILD.bazel and web/gui2/src/main/webapp/app/BUILD.bazel
Change-Id: Ifcfcc23a87be39fe6d6c8324046cc8ebadb90551
diff --git a/web/gui2-topo-lib/lib/topology.service.ts b/web/gui2-topo-lib/lib/topology.service.ts
new file mode 100644
index 0000000..693a29a
--- /dev/null
+++ b/web/gui2-topo-lib/lib/topology.service.ts
@@ -0,0 +1,170 @@
+/*
+ * 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');
+ }
+}