blob: bba7f1486d26670ae3d5342e06d1ed9063e73a87 [file] [log] [blame]
Yi Tsenga87b40c2017-09-10 00:59:03 -07001/*
2 * Copyright 2017-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
17package org.onosproject.ui.impl;
18
19import com.fasterxml.jackson.databind.node.ObjectNode;
Sean Condonafe47c22019-12-19 14:28:06 +000020import com.google.common.base.Strings;
Yi Tsenga87b40c2017-09-10 00:59:03 -070021import com.google.common.collect.ImmutableSet;
Yi Tsenga87b40c2017-09-10 00:59:03 -070022import org.onosproject.codec.CodecContext;
23import org.onosproject.net.Device;
24import org.onosproject.net.DeviceId;
25import org.onosproject.net.device.DeviceService;
Sean Condonafe47c22019-12-19 14:28:06 +000026import org.onosproject.net.flow.FlowRuleService;
27import org.onosproject.net.flow.TableStatisticsEntry;
Yi Tsenga87b40c2017-09-10 00:59:03 -070028import org.onosproject.net.pi.model.PiPipeconf;
29import org.onosproject.net.pi.model.PiPipeconfId;
Yi Tsenga87b40c2017-09-10 00:59:03 -070030import org.onosproject.net.pi.model.PiPipelineModel;
Carmelo Cascone39c28ca2017-11-15 13:03:57 -080031import org.onosproject.net.pi.service.PiPipeconfService;
Yi Tsenga87b40c2017-09-10 00:59:03 -070032import org.onosproject.ui.RequestHandler;
33import org.onosproject.ui.UiMessageHandler;
Sean Condonafe47c22019-12-19 14:28:06 +000034import org.onosproject.ui.table.TableModel;
35import org.onosproject.ui.table.TableRequestHandler;
36
37import org.onosproject.ui.table.cell.DefaultCellFormatter;
38import org.onosproject.ui.table.cell.NumberFormatter;
Yi Tsenga87b40c2017-09-10 00:59:03 -070039import org.slf4j.Logger;
40import org.slf4j.LoggerFactory;
41
42import java.util.Collection;
43import java.util.Optional;
Yi Tsenga87b40c2017-09-10 00:59:03 -070044
45public class PipeconfViewMessageHandler extends UiMessageHandler {
46 private static final Logger log =
47 LoggerFactory.getLogger(PipeconfViewMessageHandler.class);
48 private static final String PIPECONF_REQUEST = "pipeconfRequest";
49 private static final String PIPECONF_RESP = "pipeConfResponse";
50 private static final String DEVICE_ID = "devId";
51 private static final String PIPECONF = "pipeconf";
52 private static final String PIPELINE_MODEL = "pipelineModel";
53 private static final String NO_PIPECONF_RESP = "noPipeconfResp";
54
Sean Condonafe47c22019-12-19 14:28:06 +000055 private static final String TABLESTAT_DATA_REQ = "tableStatDataRequest";
56 private static final String TABLESTAT_DATA_RESP = "tableStatDataResponse";
57 private static final String TABLESTATS = "tableStats";
58 private static final String TABLE_NAME = "table";
59 private static final String ACTIVE = "active";
60 private static final String LOOKEDUP = "lookedup";
61 private static final String HASLOOKEDUP = "haslookedup";
62 private static final String MATCHED = "matched";
63 private static final String HASMAXSIZE = "hasmaxsize";
64 private static final String MAXSIZE = "maxsize";
65
66 private static final String[] COL_IDS = {
67 TABLE_NAME, ACTIVE, HASLOOKEDUP, LOOKEDUP, MATCHED, HASMAXSIZE, MAXSIZE
68 };
69
70
Yi Tsenga87b40c2017-09-10 00:59:03 -070071 @Override
72 protected Collection<RequestHandler> createRequestHandlers() {
Sean Condonafe47c22019-12-19 14:28:06 +000073 return ImmutableSet.of(new PipeconfRequestHandler(), new TableStatsHandler());
Yi Tsenga87b40c2017-09-10 00:59:03 -070074 }
75
76 private class PipeconfRequestHandler extends RequestHandler {
77
Carmelo Cascone87892e22017-11-13 16:01:29 -080078 PipeconfRequestHandler() {
Yi Tsenga87b40c2017-09-10 00:59:03 -070079 super(PIPECONF_REQUEST);
80 }
81
82 @Override
83 public void process(ObjectNode payload) {
84 PiPipeconfService piPipeconfService = get(PiPipeconfService.class);
85 DeviceService deviceService = get(DeviceService.class);
86 ObjectNode responseData = objectNode();
87 String devId = string(payload, DEVICE_ID);
88 if (devId == null || devId.isEmpty()) {
89 log.warn("{}: Invalid device id", PIPECONF_REQUEST);
90 sendMessage(NO_PIPECONF_RESP, null);
91 return;
92 }
93 DeviceId deviceId = DeviceId.deviceId(devId);
94 Optional<PiPipeconfId> pipeconfId = piPipeconfService.ofDevice(deviceId);
95 if (!pipeconfId.isPresent()) {
96 log.warn("{}: Can't find pipeconf id for device {}", PIPECONF_REQUEST, deviceId);
97 sendMessage(NO_PIPECONF_RESP, null);
98 return;
99 }
100
101 Optional<PiPipeconf> pipeconf = piPipeconfService.getPipeconf(pipeconfId.get());
102 if (!pipeconf.isPresent()) {
103 log.warn("{}: Can't find pipeconf {}", PIPECONF_REQUEST, pipeconfId);
104 sendMessage(NO_PIPECONF_RESP, null);
105 return;
106 }
107 CodecContext codecContext = getJsonCodecContext();
108
109 ObjectNode pipeconfData = codecContext.encode(pipeconf.get(), PiPipeconf.class);
110 responseData.set(PIPECONF, pipeconfData);
111
112 // Filtered out models not exists in interpreter
113 // usually they generated by compiler automatically
114 Device device = deviceService.getDevice(deviceId);
115 if (device == null || !deviceService.isAvailable(deviceId)) {
116 log.warn("{}: Device {} is not available", PIPECONF_REQUEST, deviceId);
117 sendMessage(NO_PIPECONF_RESP, null);
118 return;
119 }
Carmelo Cascone87892e22017-11-13 16:01:29 -0800120 PiPipelineModel pipelineModel = pipeconf.get().pipelineModel();
Yi Tsenga87b40c2017-09-10 00:59:03 -0700121
122 ObjectNode pipelineModelData =
123 codecContext.encode(pipelineModel, PiPipelineModel.class);
124 responseData.set(PIPELINE_MODEL, pipelineModelData);
125
126 sendMessage(PIPECONF_RESP, responseData);
127 }
128 }
Sean Condonafe47c22019-12-19 14:28:06 +0000129
130 private class TableStatsHandler extends TableRequestHandler {
131
132 TableStatsHandler() {
133 super(TABLESTAT_DATA_REQ, TABLESTAT_DATA_RESP, TABLESTATS);
134 }
135
136 @Override
137 protected String noRowsMessage(ObjectNode payload) {
138 return NO_PIPECONF_RESP;
139 }
140
141 @Override
142 protected String defaultColumnId() {
143 return TABLE_NAME;
144 }
145
146 @Override
147 protected String[] getColumnIds() {
148 return COL_IDS;
149 }
150
151 @Override
152 protected TableModel createTableModel() {
153 TableModel tm = super.createTableModel();
154 tm.setFormatter(TABLE_NAME, DefaultCellFormatter.INSTANCE);
155 tm.setFormatter(ACTIVE, NumberFormatter.INTEGER);
156 tm.setFormatter(HASLOOKEDUP, DefaultCellFormatter.INSTANCE);
157 tm.setFormatter(LOOKEDUP, NumberFormatter.INTEGER);
158 tm.setFormatter(MATCHED, NumberFormatter.INTEGER);
159 tm.setFormatter(HASMAXSIZE, DefaultCellFormatter.INSTANCE);
160 tm.setFormatter(MAXSIZE, NumberFormatter.INTEGER);
161 return tm;
162 }
163
164 @Override
165 protected void populateTable(TableModel tm, ObjectNode payload) {
166 String uri = string(payload, "devId");
167 if (!Strings.isNullOrEmpty(uri)) {
168 DeviceId deviceId = DeviceId.deviceId(uri);
169 DeviceService ds = get(DeviceService.class);
170 FlowRuleService flowService = get(FlowRuleService.class);
171
172 Iterable<TableStatisticsEntry> stats = flowService.getFlowTableStatistics(deviceId);
173 for (TableStatisticsEntry stat : stats) {
174 populateRow(tm.addRow(), stat);
175 }
176 }
177 }
178
179 private void populateRow(TableModel.Row row, TableStatisticsEntry tableStat) {
180 row.cell(TABLE_NAME, tableStat.table())
181 .cell(ACTIVE, tableStat.activeFlowEntries())
182 .cell(HASLOOKEDUP, tableStat.hasPacketsLookedup())
183 .cell(LOOKEDUP, tableStat.packetsLookedup())
184 .cell(MATCHED, tableStat.packetsMatched())
185 .cell(HASMAXSIZE, tableStat.hasMaxSize())
186 .cell(MAXSIZE, tableStat.maxSize());
187 }
188 }
Yi Tsenga87b40c2017-09-10 00:59:03 -0700189}