blob: 4e0c939c55f2f8e77fd4f20589c4c93e5e805fdc [file] [log] [blame]
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -07003 *
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
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070019import com.fasterxml.jackson.databind.node.ObjectNode;
Simon Huntabd16f62015-05-01 13:14:40 -070020import com.google.common.base.Strings;
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070021import com.google.common.collect.ImmutableSet;
Viswanath KSPd1212c72016-10-21 01:03:35 +053022import org.onosproject.core.ApplicationId;
23import org.onosproject.core.DefaultApplicationId;
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070024import org.onosproject.net.DeviceId;
25import org.onosproject.net.flow.FlowEntry;
Viswanath KSPd1212c72016-10-21 01:03:35 +053026import org.onosproject.net.flow.FlowRule;
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070027import org.onosproject.net.flow.FlowRuleService;
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070028import org.onosproject.net.flow.criteria.Criterion;
29import org.onosproject.net.flow.instructions.Instruction;
Simon Huntd2747a02015-04-30 22:41:16 -070030import org.onosproject.ui.RequestHandler;
Simon Hunta0ddb022015-05-01 09:53:01 -070031import org.onosproject.ui.UiMessageHandler;
Bri Prebilic Cole9467a232015-05-06 16:59:05 -070032import org.onosproject.ui.table.CellFormatter;
Simon Hunt3d1b0652015-05-05 17:27:24 -070033import org.onosproject.ui.table.TableModel;
Simon Huntabd16f62015-05-01 13:14:40 -070034import org.onosproject.ui.table.TableRequestHandler;
Bri Prebilic Cole9467a232015-05-06 16:59:05 -070035import org.onosproject.ui.table.cell.EnumFormatter;
Simon Hunt3e4ccaf2016-01-12 19:59:54 -080036import org.onosproject.ui.table.cell.HexFormatter;
37import org.onosproject.ui.table.cell.HexLongFormatter;
Simon Huntbe60dde2016-01-13 12:26:56 -080038import org.onosproject.ui.table.cell.NumberFormatter;
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070039
Simon Huntd2747a02015-04-30 22:41:16 -070040import java.util.Collection;
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070041import java.util.List;
42import java.util.Set;
43
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070044/**
45 * Message handler for flow view related messages.
46 */
Simon Hunta0ddb022015-05-01 09:53:01 -070047public class FlowViewMessageHandler extends UiMessageHandler {
Simon Huntd2747a02015-04-30 22:41:16 -070048
49 private static final String FLOW_DATA_REQ = "flowDataRequest";
Simon Huntabd16f62015-05-01 13:14:40 -070050 private static final String FLOW_DATA_RESP = "flowDataResponse";
51 private static final String FLOWS = "flows";
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070052
Viswanath KSPd1212c72016-10-21 01:03:35 +053053 private static final String FLOW_DETAILS_REQ = "flowDetailsRequest";
54 private static final String FLOW_DETAILS_RESP = "flowDetailsResponse";
55 private static final String DETAILS = "details";
56 private static final String FLOW_PRIORITY = "priority";
57
Simon Huntabd16f62015-05-01 13:14:40 -070058 private static final String ID = "id";
Viswanath KSPd1212c72016-10-21 01:03:35 +053059 private static final String FLOW_ID = "flowId";
Simon Huntabd16f62015-05-01 13:14:40 -070060 private static final String APP_ID = "appId";
61 private static final String GROUP_ID = "groupId";
62 private static final String TABLE_ID = "tableId";
63 private static final String PRIORITY = "priority";
64 private static final String SELECTOR = "selector";
65 private static final String TREATMENT = "treatment";
66 private static final String TIMEOUT = "timeout";
67 private static final String PERMANENT = "permanent";
68 private static final String STATE = "state";
Bri Prebilic Cole641b97b2015-05-05 14:47:40 -070069 private static final String PACKETS = "packets";
70 private static final String BYTES = "bytes";
Simon Huntabd16f62015-05-01 13:14:40 -070071
72 private static final String COMMA = ", ";
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070073
Simon Hunt3d1b0652015-05-05 17:27:24 -070074 private static final String[] COL_IDS = {
75 ID, APP_ID, GROUP_ID, TABLE_ID, PRIORITY, SELECTOR,
76 TREATMENT, TIMEOUT, PERMANENT, STATE, PACKETS, BYTES
77 };
78
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070079 @Override
Simon Huntda580882015-05-12 20:58:18 -070080 protected Collection<RequestHandler> createRequestHandlers() {
Viswanath KSPd1212c72016-10-21 01:03:35 +053081 return ImmutableSet.of(
82 new FlowDataRequest(),
83 new DetailRequestHandler()
84 );
Simon Huntd2747a02015-04-30 22:41:16 -070085 }
86
Simon Huntabd16f62015-05-01 13:14:40 -070087 // handler for flow table requests
88 private final class FlowDataRequest extends TableRequestHandler {
Simon Huntd2747a02015-04-30 22:41:16 -070089
Jian Li69f66632016-01-15 12:27:42 -080090 private static final String NO_ROWS_MESSAGE = "No flows found";
91
Simon Huntd2747a02015-04-30 22:41:16 -070092 private FlowDataRequest() {
Simon Huntabd16f62015-05-01 13:14:40 -070093 super(FLOW_DATA_REQ, FLOW_DATA_RESP, FLOWS);
Simon Huntd2747a02015-04-30 22:41:16 -070094 }
95
96 @Override
Simon Hunt3d1b0652015-05-05 17:27:24 -070097 protected String[] getColumnIds() {
98 return COL_IDS;
Simon Hunt44aa2f82015-04-30 15:01:35 -070099 }
Simon Hunt44aa2f82015-04-30 15:01:35 -0700100
Simon Hunt3d1b0652015-05-05 17:27:24 -0700101 @Override
Jian Li8baf4472016-01-15 15:08:09 -0800102 protected String noRowsMessage(ObjectNode payload) {
Jian Li69f66632016-01-15 12:27:42 -0800103 return NO_ROWS_MESSAGE;
104 }
105
106 @Override
Simon Hunt3d1b0652015-05-05 17:27:24 -0700107 protected TableModel createTableModel() {
108 TableModel tm = super.createTableModel();
Simon Hunt3e4ccaf2016-01-12 19:59:54 -0800109 tm.setFormatter(ID, HexLongFormatter.INSTANCE);
110 tm.setFormatter(GROUP_ID, HexFormatter.INSTANCE);
Simon Huntbe60dde2016-01-13 12:26:56 -0800111 tm.setFormatter(STATE, EnumFormatter.INSTANCE);
112 tm.setFormatter(PACKETS, NumberFormatter.INTEGER);
113 tm.setFormatter(BYTES, NumberFormatter.INTEGER);
Bri Prebilic Cole9467a232015-05-06 16:59:05 -0700114 tm.setFormatter(SELECTOR, new SelectorFormatter());
115 tm.setFormatter(TREATMENT, new TreatmentFormatter());
Simon Hunt3d1b0652015-05-05 17:27:24 -0700116 return tm;
117 }
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700118
Simon Hunt3d1b0652015-05-05 17:27:24 -0700119 @Override
120 protected void populateTable(TableModel tm, ObjectNode payload) {
121 String uri = string(payload, "devId");
122 if (!Strings.isNullOrEmpty(uri)) {
123 DeviceId deviceId = DeviceId.deviceId(uri);
124 FlowRuleService frs = get(FlowRuleService.class);
125 for (FlowEntry flow : frs.getFlowEntries(deviceId)) {
126 populateRow(tm.addRow(), flow);
127 }
128 }
129 }
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700130
Simon Hunt3d1b0652015-05-05 17:27:24 -0700131 private void populateRow(TableModel.Row row, FlowEntry flow) {
132 row.cell(ID, flow.id().value())
133 .cell(APP_ID, flow.appId())
134 .cell(GROUP_ID, flow.groupId().id())
135 .cell(TABLE_ID, flow.tableId())
136 .cell(PRIORITY, flow.priority())
Simon Hunt3d1b0652015-05-05 17:27:24 -0700137 .cell(TIMEOUT, flow.timeout())
138 .cell(PERMANENT, flow.isPermanent())
Bri Prebilic Cole9467a232015-05-06 16:59:05 -0700139 .cell(STATE, flow.state())
Simon Hunt3d1b0652015-05-05 17:27:24 -0700140 .cell(PACKETS, flow.packets())
Simon Huntbe60dde2016-01-13 12:26:56 -0800141 .cell(BYTES, flow.bytes())
142 .cell(SELECTOR, flow)
143 .cell(TREATMENT, flow);
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700144 }
145
Bri Prebilic Cole9467a232015-05-06 16:59:05 -0700146 private final class SelectorFormatter implements CellFormatter {
147 @Override
148 public String format(Object value) {
149 FlowEntry flow = (FlowEntry) value;
150 Set<Criterion> criteria = flow.selector().criteria();
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700151
Bri Prebilic Cole9467a232015-05-06 16:59:05 -0700152 if (criteria.isEmpty()) {
153 return "(No traffic selector criteria for this flow)";
154 }
155 StringBuilder sb = new StringBuilder("Criteria: ");
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700156 for (Criterion c : criteria) {
Bri Prebilic Cole9467a232015-05-06 16:59:05 -0700157 sb.append(c).append(COMMA);
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700158 }
159 removeTrailingComma(sb);
Bri Prebilic Cole9467a232015-05-06 16:59:05 -0700160
161 return sb.toString();
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700162 }
163 }
164
Bri Prebilic Cole9467a232015-05-06 16:59:05 -0700165 private final class TreatmentFormatter implements CellFormatter {
166 @Override
167 public String format(Object value) {
168 FlowEntry flow = (FlowEntry) value;
169 List<Instruction> instructions = flow.treatment().allInstructions();
170
Konstantinos Kanonakisa7592bc2016-04-13 10:24:15 -0500171 if (instructions.isEmpty()
172 && flow.treatment().metered() == null
173 && flow.treatment().tableTransition() == null) {
Bri Prebilic Cole9467a232015-05-06 16:59:05 -0700174 return "(No traffic treatment instructions for this flow)";
175 }
176 StringBuilder sb = new StringBuilder("Treatment Instructions: ");
177 for (Instruction i : instructions) {
178 sb.append(i).append(COMMA);
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700179 }
Konstantinos Kanonakis845c3282016-04-01 17:34:20 -0500180 if (flow.treatment().metered() != null) {
181 sb.append(flow.treatment().metered().toString()).append(COMMA);
182 }
183 if (flow.treatment().tableTransition() != null) {
184 sb.append(flow.treatment().tableTransition().toString()).append(COMMA);
185 }
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700186 removeTrailingComma(sb);
Bri Prebilic Cole9467a232015-05-06 16:59:05 -0700187
188 return sb.toString();
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700189 }
190 }
191
192 private StringBuilder removeTrailingComma(StringBuilder sb) {
193 int pos = sb.lastIndexOf(COMMA);
194 sb.delete(pos, sb.length());
195 return sb;
196 }
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700197 }
Viswanath KSPd1212c72016-10-21 01:03:35 +0530198
199 private final class DetailRequestHandler extends RequestHandler {
200 private DetailRequestHandler() {
201 super(FLOW_DETAILS_REQ);
202 }
203
204 private FlowRule findFlowById(String appIdText, String flowId) {
205 FlowRuleService fs = get(FlowRuleService.class);
206 int appIdInt = Integer.parseInt(appIdText);
207 ApplicationId appId = new DefaultApplicationId(appIdInt, "details");
208 Iterable<FlowRule> flows = fs.getFlowRulesById(appId);
209
210 for (FlowRule flow : flows) {
211 if (flow.id().toString().equals(flowId)) {
212 return flow;
213 }
214 }
215
216 return null;
217 }
218
219 @Override
220 public void process(long sid, ObjectNode payload) {
221
222 String flowId = string(payload, FLOW_ID);
223 String appId = string(payload, APP_ID);
224 FlowRule flow = findFlowById(appId, flowId);
225 ObjectNode data = objectNode();
226
227 data.put(FLOW_ID, flow.id().toString());
228 data.put(FLOW_PRIORITY, flow.priority());
229
230 //TODO put more detail info to data
231
232 ObjectNode rootNode = objectNode();
233 rootNode.set(DETAILS, data);
234 sendMessage(FLOW_DETAILS_RESP, rootNode);
235 }
236 }
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700237}