blob: dc5e564aaec79f3453110f4de4f171109f96baf8 [file] [log] [blame]
Sean Condonafe47c22019-12-19 14:28:06 +00001/*
2 * Copyright 2018-present Open Networking Foundation
3 *
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 */
16
17import {ChangeDetectorRef, Component, OnDestroy, OnInit} from '@angular/core';
18import {
19 FnService,
20 LogService, SortDir,
21 TableBaseImpl,
22 WebSocketService
Sean Condon3dd062f2020-04-14 09:25:00 +010023} from 'org_onosproject_onos/web/gui2-fw-lib/public_api';
Sean Condonafe47c22019-12-19 14:28:06 +000024import {ActivatedRoute, Router} from '@angular/router';
25
26const pipeconfReq = 'pipeconfRequest';
27const pipeconfResp = 'pipeConfResponse';
28
29export interface PipeconfHeader {
30 id: string;
31 behaviors: string[];
32 extensions: string[];
33}
34
35export interface ActionParam {
36 name: string;
37 bitWidth: number;
38}
39
40export interface PipeconfAction {
41 name: string;
42 params: ActionParam[];
43}
44
45export interface MatchFields {
46 matchType: string;
47 bitWidth: number;
48 field: string;
49}
50
51export interface PipeconfTable {
52 name: string;
53 maxSize: number;
54 hasCounters: boolean;
55 supportAging: boolean;
56 matchFields: MatchFields[];
57 actions: string[];
58}
59
60export interface PipelineModel {
61 actions: PipeconfAction[];
62 tables: PipeconfTable[];
63}
64
65export interface PipeconfData {
66 pipeconf: PipeconfHeader;
67 pipelineModel: PipelineModel;
68}
69
70
71export interface TableStat {
72 table: string;
73 active: number;
74 haslookedup: boolean;
75 lookedup: number;
76 matched: number;
77 hasmaxsize: boolean;
78 maxsize: number;
79}
80
81export interface TableStats {
82 tableStats: TableStat[];
83}
84
85/**
86 * ONOS GUI -- Pipeconf View Component
87 */
88@Component({
89 selector: 'onos-pipeconf',
90 templateUrl: './pipeconf.component.html',
Sean Condon98b6ddb2019-12-24 08:07:40 +000091 styleUrls: ['./pipeconf.component.css', '../../../../../../../../gui2-fw-lib/lib/widget/table.css', '../../../../../../../../gui2-fw-lib/lib/widget/table.theme.css']
Sean Condonafe47c22019-12-19 14:28:06 +000092})
93export class PipeconfComponent extends TableBaseImpl implements OnInit, OnDestroy {
94 devId: string;
95 pipeconfData: PipeconfData;
96 selectedTable: PipeconfTable;
97 parentSelCb = this.updateSelected; // Func
98
99 // TODO: Update for LION
100 flowTip = 'Show flow view for selected device';
101 portTip = 'Show port view for selected device';
102 groupTip = 'Show group view for selected device';
103 meterTip = 'Show meter view for selected device';
104 pipeconfTip = 'Show pipeconf view for selected device';
105 na = 'N/A';
106
107 constructor(
108 protected fs: FnService,
109 protected log: LogService,
110 protected ar: ActivatedRoute,
111 protected router: Router,
112 protected wss: WebSocketService,
113 private ref: ChangeDetectorRef,
114 ) {
115 super(fs, log, wss, 'tableStat', 'table');
116 this.ar.queryParams.subscribe(params => {
117 this.devId = params['devId'];
118
119 });
120
121 this.payloadParams = {
122 devId: this.devId
123 };
124
125 this.responseCallback = this.tableStatsResponseCb;
126
127 this.sortParams = {
128 firstCol: 'table',
129 firstDir: SortDir.desc,
130 secondCol: 'active',
131 secondDir: SortDir.asc,
132 };
133 }
134
135 ngOnInit() {
136 // Also make a once off call to get the Pipeconf Static information
137 this.wss.bindHandlers(new Map<string, (data) => void>([
138 [pipeconfResp, (data) => {
139 this.pipeconfData = data;
140 this.ref.markForCheck();
141 this.log.debug('Pipeconf static data received', this.pipeconfData);
142 }]
143 ]));
144
Sean Condon98b6ddb2019-12-24 08:07:40 +0000145 const p = (<any>Object).assign({}, this.sortParams, this.payloadParams);
Sean Condonafe47c22019-12-19 14:28:06 +0000146
147 // Allow it to sit in pending events
148 if (this.wss.isConnected()) {
149 this.wss.sendEvent(pipeconfReq, p);
150 }
151
152 this.init();
153
154 this.log.debug('PipeconfComponent initialized');
155 }
156
157 ngOnDestroy() {
158 this.destroy();
159 this.wss.unbindHandlers([pipeconfResp]);
160
161 this.log.debug('PipeconfComponent destroyed');
162 }
163
164 tableStatsResponseCb(newTableData: TableStats) {
165 // checks if data changed for row flashing
166 }
167
168 /**
169 * There's nothing to navigate down further to for Pipeconf - instead we can
170 * navigate for the Device that was passed in
171 * @param path
172 */
173 navto(path) {
174 this.log.debug('navigate to', path);
175 this.router.navigate([path], { queryParams: { devId: this.devId } });
176 }
177
178 pipeconfModelTable(table: string): PipeconfTable {
179 if (this.pipeconfData === undefined) {
180 return; // Not loaded yet
181 }
182 for (const t of this.pipeconfData.pipelineModel.tables) {
183 if (t.name === table) {
184 return t;
185 }
186 }
187 this.log.warn('Could not find table', table, 'in PipelineModel');
188 }
189
190 updateSelected(event: any, selRow: any): void {
191 if (this.selId === undefined) {
192 this.selectedTable = undefined;
193 } else {
194 this.selectedTable = this.pipeconfModelTable(this.selId);
195 }
196 }
197}