blob: 29ec446e4d7eef14915e2acf0e56d4a5386c8760 [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;
Simon Hunt36b658d2017-07-14 16:20:11 -070022import org.onosproject.app.ApplicationService;
23import org.onosproject.core.Application;
Viswanath KSPd1212c72016-10-21 01:03:35 +053024import org.onosproject.core.ApplicationId;
25import org.onosproject.core.DefaultApplicationId;
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070026import org.onosproject.net.DeviceId;
27import org.onosproject.net.flow.FlowEntry;
Viswanath KSPd1212c72016-10-21 01:03:35 +053028import org.onosproject.net.flow.FlowRule;
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070029import org.onosproject.net.flow.FlowRuleService;
Deepa Vaddireddyf3932c02017-02-09 17:32:28 +053030import org.onosproject.net.flow.TrafficTreatment;
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070031import org.onosproject.net.flow.criteria.Criterion;
32import org.onosproject.net.flow.instructions.Instruction;
Simon Huntd2747a02015-04-30 22:41:16 -070033import org.onosproject.ui.RequestHandler;
Simon Hunta0ddb022015-05-01 09:53:01 -070034import org.onosproject.ui.UiMessageHandler;
Bri Prebilic Cole9467a232015-05-06 16:59:05 -070035import org.onosproject.ui.table.CellFormatter;
Simon Hunt3d1b0652015-05-05 17:27:24 -070036import org.onosproject.ui.table.TableModel;
Simon Huntabd16f62015-05-01 13:14:40 -070037import org.onosproject.ui.table.TableRequestHandler;
Bri Prebilic Cole9467a232015-05-06 16:59:05 -070038import org.onosproject.ui.table.cell.EnumFormatter;
Simon Hunt3e4ccaf2016-01-12 19:59:54 -080039import org.onosproject.ui.table.cell.HexLongFormatter;
Simon Huntbe60dde2016-01-13 12:26:56 -080040import org.onosproject.ui.table.cell.NumberFormatter;
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070041
Simon Huntd2747a02015-04-30 22:41:16 -070042import java.util.Collection;
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070043import java.util.List;
Simon Hunt36b658d2017-07-14 16:20:11 -070044import java.util.Map;
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070045import java.util.Set;
Simon Hunt36b658d2017-07-14 16:20:11 -070046import java.util.stream.Collectors;
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070047
Deepa Vaddireddyf3932c02017-02-09 17:32:28 +053048
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070049/**
50 * Message handler for flow view related messages.
51 */
Simon Hunta0ddb022015-05-01 09:53:01 -070052public class FlowViewMessageHandler extends UiMessageHandler {
Simon Huntd2747a02015-04-30 22:41:16 -070053
54 private static final String FLOW_DATA_REQ = "flowDataRequest";
Simon Huntabd16f62015-05-01 13:14:40 -070055 private static final String FLOW_DATA_RESP = "flowDataResponse";
56 private static final String FLOWS = "flows";
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070057
Viswanath KSPd1212c72016-10-21 01:03:35 +053058 private static final String FLOW_DETAILS_REQ = "flowDetailsRequest";
59 private static final String FLOW_DETAILS_RESP = "flowDetailsResponse";
60 private static final String DETAILS = "details";
61 private static final String FLOW_PRIORITY = "priority";
62
Simon Huntabd16f62015-05-01 13:14:40 -070063 private static final String ID = "id";
Viswanath KSPd1212c72016-10-21 01:03:35 +053064 private static final String FLOW_ID = "flowId";
Simon Huntabd16f62015-05-01 13:14:40 -070065 private static final String APP_ID = "appId";
Simon Hunt36b658d2017-07-14 16:20:11 -070066 private static final String APP_NAME = "appName";
Simon Huntabd16f62015-05-01 13:14:40 -070067 private static final String GROUP_ID = "groupId";
68 private static final String TABLE_ID = "tableId";
69 private static final String PRIORITY = "priority";
Simon Hunt9bff5952017-07-13 14:05:09 -070070 private static final String SELECTOR_C = "selector_c"; // for table column
Simon Huntabd16f62015-05-01 13:14:40 -070071 private static final String SELECTOR = "selector";
Simon Hunt9bff5952017-07-13 14:05:09 -070072 private static final String TREATMENT_C = "treatment_c"; // for table column
Simon Huntabd16f62015-05-01 13:14:40 -070073 private static final String TREATMENT = "treatment";
74 private static final String TIMEOUT = "timeout";
75 private static final String PERMANENT = "permanent";
76 private static final String STATE = "state";
Bri Prebilic Cole641b97b2015-05-05 14:47:40 -070077 private static final String PACKETS = "packets";
Simon Hunt9bff5952017-07-13 14:05:09 -070078 private static final String DURATION = "duration";
Bri Prebilic Cole641b97b2015-05-05 14:47:40 -070079 private static final String BYTES = "bytes";
Simon Huntabd16f62015-05-01 13:14:40 -070080
81 private static final String COMMA = ", ";
Viswanath KSP70e0d142016-10-28 21:58:32 +053082 private static final String OX = "0x";
83 private static final String EMPTY = "";
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070084
Simon Hunt36b658d2017-07-14 16:20:11 -070085 private static final String ONOS_PREFIX = "org.onosproject.";
86 private static final String ONOS_MARKER = "*";
87
Simon Hunt3d1b0652015-05-05 17:27:24 -070088 private static final String[] COL_IDS = {
Simon Hunt9bff5952017-07-13 14:05:09 -070089 ID,
90 STATE,
91 BYTES,
92 PACKETS,
93 DURATION,
94 PRIORITY,
95 TABLE_ID,
96 APP_ID,
Simon Hunt36b658d2017-07-14 16:20:11 -070097 APP_NAME,
Simon Hunt9bff5952017-07-13 14:05:09 -070098
99 GROUP_ID,
100 TIMEOUT,
101 PERMANENT,
102
103 SELECTOR_C,
104 SELECTOR,
105 TREATMENT_C,
106 TREATMENT,
Simon Hunt3d1b0652015-05-05 17:27:24 -0700107 };
108
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700109 @Override
Simon Huntda580882015-05-12 20:58:18 -0700110 protected Collection<RequestHandler> createRequestHandlers() {
Viswanath KSPd1212c72016-10-21 01:03:35 +0530111 return ImmutableSet.of(
112 new FlowDataRequest(),
113 new DetailRequestHandler()
114 );
Simon Huntd2747a02015-04-30 22:41:16 -0700115 }
116
Deepa Vaddireddyf3932c02017-02-09 17:32:28 +0530117 private StringBuilder removeTrailingComma(StringBuilder sb) {
118 int pos = sb.lastIndexOf(COMMA);
119 sb.delete(pos, sb.length());
120 return sb;
121 }
122
Simon Hunt36b658d2017-07-14 16:20:11 -0700123 // Generate a map of shorts->application IDs
124 // (working around deficiency(?) in Application Service API)
125 private Map<Short, ApplicationId> appShortMap() {
126 Set<Application> apps =
127 get(ApplicationService.class).getApplications();
128
129 return apps.stream()
130 .collect(Collectors.toMap(a -> a.id().id(), Application::id));
131 }
132
133 // Return an application name, based on a lookup of the internal short ID
134 private String makeAppName(short id, Map<Short, ApplicationId> lookup) {
135 ApplicationId appId = lookup.get(id);
136 if (appId == null) {
137 return "Unknown <" + id + ">";
138 }
139 String appName = appId.name();
140 return appName.startsWith(ONOS_PREFIX)
141 ? appName.replaceFirst(ONOS_PREFIX, ONOS_MARKER) : appName;
142 }
143
Simon Huntabd16f62015-05-01 13:14:40 -0700144 // handler for flow table requests
145 private final class FlowDataRequest extends TableRequestHandler {
Simon Huntd2747a02015-04-30 22:41:16 -0700146
Jian Li69f66632016-01-15 12:27:42 -0800147 private static final String NO_ROWS_MESSAGE = "No flows found";
148
Simon Huntd2747a02015-04-30 22:41:16 -0700149 private FlowDataRequest() {
Simon Huntabd16f62015-05-01 13:14:40 -0700150 super(FLOW_DATA_REQ, FLOW_DATA_RESP, FLOWS);
Simon Huntd2747a02015-04-30 22:41:16 -0700151 }
152
153 @Override
Simon Hunt3d1b0652015-05-05 17:27:24 -0700154 protected String[] getColumnIds() {
155 return COL_IDS;
Simon Hunt44aa2f82015-04-30 15:01:35 -0700156 }
Simon Hunt44aa2f82015-04-30 15:01:35 -0700157
Simon Hunt3d1b0652015-05-05 17:27:24 -0700158 @Override
Jian Li8baf4472016-01-15 15:08:09 -0800159 protected String noRowsMessage(ObjectNode payload) {
Jian Li69f66632016-01-15 12:27:42 -0800160 return NO_ROWS_MESSAGE;
161 }
162
163 @Override
Simon Hunt3d1b0652015-05-05 17:27:24 -0700164 protected TableModel createTableModel() {
165 TableModel tm = super.createTableModel();
Simon Hunt3e4ccaf2016-01-12 19:59:54 -0800166 tm.setFormatter(ID, HexLongFormatter.INSTANCE);
Simon Huntbe60dde2016-01-13 12:26:56 -0800167 tm.setFormatter(STATE, EnumFormatter.INSTANCE);
Simon Huntbe60dde2016-01-13 12:26:56 -0800168 tm.setFormatter(BYTES, NumberFormatter.INTEGER);
Simon Hunt9bff5952017-07-13 14:05:09 -0700169 tm.setFormatter(PACKETS, NumberFormatter.INTEGER);
170 tm.setFormatter(DURATION, NumberFormatter.INTEGER);
171
172 tm.setFormatter(SELECTOR_C, new SelectorShortFormatter());
Bri Prebilic Cole9467a232015-05-06 16:59:05 -0700173 tm.setFormatter(SELECTOR, new SelectorFormatter());
Simon Hunt9bff5952017-07-13 14:05:09 -0700174 tm.setFormatter(TREATMENT_C, new TreatmentShortFormatter());
Bri Prebilic Cole9467a232015-05-06 16:59:05 -0700175 tm.setFormatter(TREATMENT, new TreatmentFormatter());
Simon Hunt3d1b0652015-05-05 17:27:24 -0700176 return tm;
177 }
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700178
Simon Hunt3d1b0652015-05-05 17:27:24 -0700179 @Override
180 protected void populateTable(TableModel tm, ObjectNode payload) {
181 String uri = string(payload, "devId");
182 if (!Strings.isNullOrEmpty(uri)) {
183 DeviceId deviceId = DeviceId.deviceId(uri);
Simon Hunt36b658d2017-07-14 16:20:11 -0700184 Map<Short, ApplicationId> lookup = appShortMap();
Simon Hunt3d1b0652015-05-05 17:27:24 -0700185 FlowRuleService frs = get(FlowRuleService.class);
Simon Hunt36b658d2017-07-14 16:20:11 -0700186
Simon Hunt3d1b0652015-05-05 17:27:24 -0700187 for (FlowEntry flow : frs.getFlowEntries(deviceId)) {
Simon Hunt36b658d2017-07-14 16:20:11 -0700188 populateRow(tm.addRow(), flow, lookup);
Simon Hunt3d1b0652015-05-05 17:27:24 -0700189 }
190 }
191 }
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700192
Simon Hunt36b658d2017-07-14 16:20:11 -0700193 private void populateRow(TableModel.Row row, FlowEntry flow,
194 Map<Short, ApplicationId> lookup) {
Simon Hunt3d1b0652015-05-05 17:27:24 -0700195 row.cell(ID, flow.id().value())
Simon Hunt9bff5952017-07-13 14:05:09 -0700196 .cell(STATE, flow.state())
197 .cell(BYTES, flow.bytes())
198 .cell(PACKETS, flow.packets())
199 .cell(DURATION, flow.life())
Simon Hunt8a0429a2017-01-06 16:52:47 -0800200 .cell(PRIORITY, flow.priority())
Simon Hunt9bff5952017-07-13 14:05:09 -0700201 .cell(TABLE_ID, flow.tableId())
202 .cell(APP_ID, flow.appId())
Simon Hunt36b658d2017-07-14 16:20:11 -0700203 .cell(APP_NAME, makeAppName(flow.appId(), lookup))
Simon Hunt9bff5952017-07-13 14:05:09 -0700204
205 .cell(GROUP_ID, flow.groupId().id())
Simon Hunt8a0429a2017-01-06 16:52:47 -0800206 .cell(TIMEOUT, flow.timeout())
207 .cell(PERMANENT, flow.isPermanent())
Simon Hunt9bff5952017-07-13 14:05:09 -0700208
209 .cell(SELECTOR_C, flow)
Simon Hunt8a0429a2017-01-06 16:52:47 -0800210 .cell(SELECTOR, flow)
Simon Hunt9bff5952017-07-13 14:05:09 -0700211 .cell(TREATMENT_C, flow)
Simon Hunt8a0429a2017-01-06 16:52:47 -0800212 .cell(TREATMENT, flow);
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700213 }
214
Simon Hunt9bff5952017-07-13 14:05:09 -0700215 private class InternalSelectorFormatter implements CellFormatter {
216 private final boolean shortFormat;
217
218 InternalSelectorFormatter(boolean shortFormat) {
219 this.shortFormat = shortFormat;
220 }
221
Bri Prebilic Cole9467a232015-05-06 16:59:05 -0700222 @Override
223 public String format(Object value) {
224 FlowEntry flow = (FlowEntry) value;
225 Set<Criterion> criteria = flow.selector().criteria();
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700226
Bri Prebilic Cole9467a232015-05-06 16:59:05 -0700227 if (criteria.isEmpty()) {
228 return "(No traffic selector criteria for this flow)";
229 }
Simon Hunt9bff5952017-07-13 14:05:09 -0700230
231 StringBuilder sb = new StringBuilder();
232 if (!shortFormat) {
233 sb.append("Criteria: ");
234 }
235
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700236 for (Criterion c : criteria) {
Bri Prebilic Cole9467a232015-05-06 16:59:05 -0700237 sb.append(c).append(COMMA);
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700238 }
239 removeTrailingComma(sb);
Bri Prebilic Cole9467a232015-05-06 16:59:05 -0700240
241 return sb.toString();
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700242 }
243 }
244
Simon Hunt9bff5952017-07-13 14:05:09 -0700245 private final class SelectorShortFormatter extends InternalSelectorFormatter {
246 SelectorShortFormatter() {
247 super(true);
248 }
249 }
250
251 private final class SelectorFormatter extends InternalSelectorFormatter {
252 SelectorFormatter() {
253 super(false);
254 }
255 }
256
257 private class InternalTreatmentFormatter implements CellFormatter {
258 private final boolean shortFormat;
259
260 InternalTreatmentFormatter(boolean shortFormat) {
261 this.shortFormat = shortFormat;
262 }
263
Bri Prebilic Cole9467a232015-05-06 16:59:05 -0700264 @Override
265 public String format(Object value) {
266 FlowEntry flow = (FlowEntry) value;
Deepa Vaddireddyf3932c02017-02-09 17:32:28 +0530267 TrafficTreatment treatment = flow.treatment();
268 List<Instruction> imm = treatment.immediate();
269 List<Instruction> def = treatment.deferred();
270 if (imm.isEmpty() &&
271 def.isEmpty() &&
272 treatment.metered() == null &&
273 treatment.tableTransition() == null) {
Bri Prebilic Cole9467a232015-05-06 16:59:05 -0700274 return "(No traffic treatment instructions for this flow)";
275 }
Deepa Vaddireddyf3932c02017-02-09 17:32:28 +0530276
Simon Hunt9bff5952017-07-13 14:05:09 -0700277 StringBuilder sb = new StringBuilder();
278
279 if (!shortFormat) {
280 sb.append("Treatment Instructions: ");
281 }
282
Deepa Vaddireddyf3932c02017-02-09 17:32:28 +0530283 formatInstructs(sb, imm, "immediate:");
284 formatInstructs(sb, def, "deferred:");
285
286 if (treatment.metered() != null) {
287 sb.append("metered:")
288 .append(treatment.metered())
289 .append(COMMA);
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700290 }
Deepa Vaddireddyf3932c02017-02-09 17:32:28 +0530291
292 if (treatment.tableTransition() != null) {
293 sb.append("transition:")
294 .append(treatment.tableTransition())
295 .append(COMMA);
Konstantinos Kanonakis845c3282016-04-01 17:34:20 -0500296 }
Deepa Vaddireddyf3932c02017-02-09 17:32:28 +0530297
298 if (treatment.writeMetadata() != null) {
299 sb.append("metadata:")
300 .append(treatment.writeMetadata())
301 .append(COMMA);
Konstantinos Kanonakis845c3282016-04-01 17:34:20 -0500302 }
Deepa Vaddireddyf3932c02017-02-09 17:32:28 +0530303
304 sb.append("cleared:").append(treatment.clearedDeferred());
Bri Prebilic Cole9467a232015-05-06 16:59:05 -0700305
306 return sb.toString();
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700307 }
308 }
309
Simon Hunt9bff5952017-07-13 14:05:09 -0700310 private final class TreatmentShortFormatter extends InternalTreatmentFormatter {
311 TreatmentShortFormatter() {
312 super(true);
313 }
314 }
315
316 private final class TreatmentFormatter extends InternalTreatmentFormatter {
317 TreatmentFormatter() {
318 super(false);
319 }
320 }
321
Deepa Vaddireddyf3932c02017-02-09 17:32:28 +0530322 private void formatInstructs(StringBuilder sb,
323 List<Instruction> instructs,
324 String type) {
325 if (!instructs.isEmpty()) {
326 sb.append(type);
327 for (Instruction i : instructs) {
328 sb.append(i).append(COMMA);
329 }
330 }
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700331 }
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700332 }
Viswanath KSPd1212c72016-10-21 01:03:35 +0530333
334 private final class DetailRequestHandler extends RequestHandler {
335 private DetailRequestHandler() {
336 super(FLOW_DETAILS_REQ);
337 }
338
Bharath Thiruveedula99849dc2016-11-17 22:04:38 +0530339 private FlowEntry findFlowById(String appIdText, String flowId) {
Viswanath KSP70e0d142016-10-28 21:58:32 +0530340 String strippedFlowId = flowId.replaceAll(OX, EMPTY);
Viswanath KSPd1212c72016-10-21 01:03:35 +0530341 FlowRuleService fs = get(FlowRuleService.class);
342 int appIdInt = Integer.parseInt(appIdText);
Viswanath KSP70e0d142016-10-28 21:58:32 +0530343 ApplicationId appId = new DefaultApplicationId(appIdInt, DETAILS);
Bharath Thiruveedula99849dc2016-11-17 22:04:38 +0530344 Iterable<FlowEntry> entries = fs.getFlowEntriesById(appId);
Viswanath KSPd1212c72016-10-21 01:03:35 +0530345
Bharath Thiruveedula99849dc2016-11-17 22:04:38 +0530346 for (FlowEntry entry : entries) {
347 if (entry.id().toString().equals(strippedFlowId)) {
348 return entry;
Viswanath KSPd1212c72016-10-21 01:03:35 +0530349 }
350 }
351
352 return null;
353 }
354
Viswanath KSP70e0d142016-10-28 21:58:32 +0530355 private String decorateFlowId(FlowRule flow) {
356 return OX + flow.id();
357 }
358
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530359 private String decorateGroupId(FlowRule flow) {
360 return OX + flow.groupId().id();
361 }
362
363 private String getCriteriaString(FlowRule flow) {
364 Set<Criterion> criteria = flow.selector().criteria();
365 StringBuilder sb = new StringBuilder();
366 for (Criterion c : criteria) {
367 sb.append(c).append(COMMA);
368 }
Deepa Vaddireddyf3932c02017-02-09 17:32:28 +0530369 removeTrailingComma(sb);
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530370 return sb.toString();
371 }
372
373 private String getTreatmentString(FlowRule flow) {
374 List<Instruction> instructions = flow.treatment().allInstructions();
375 StringBuilder sb = new StringBuilder();
376 for (Instruction inst : instructions) {
377 sb.append(inst).append(COMMA);
378 }
379 if (flow.treatment().metered() != null) {
Deepa Vaddireddyf3932c02017-02-09 17:32:28 +0530380 sb.append(flow.treatment().metered()).append(COMMA);
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530381 }
382 if (flow.treatment().tableTransition() != null) {
Deepa Vaddireddyf3932c02017-02-09 17:32:28 +0530383 sb.append(flow.treatment().tableTransition()).append(COMMA);
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530384 }
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530385
Deepa Vaddireddyf3932c02017-02-09 17:32:28 +0530386 removeTrailingComma(sb);
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530387 return sb.toString();
388 }
389
Viswanath KSPd1212c72016-10-21 01:03:35 +0530390 @Override
Simon Hunt8a0429a2017-01-06 16:52:47 -0800391 public void process(ObjectNode payload) {
Viswanath KSPd1212c72016-10-21 01:03:35 +0530392
393 String flowId = string(payload, FLOW_ID);
394 String appId = string(payload, APP_ID);
Simon Hunt9bff5952017-07-13 14:05:09 -0700395
396 FlowEntry flow = findFlowById(appId, flowId);
Viswanath KSP70e0d142016-10-28 21:58:32 +0530397 if (flow != null) {
398 ObjectNode data = objectNode();
Viswanath KSPd1212c72016-10-21 01:03:35 +0530399
Viswanath KSP70e0d142016-10-28 21:58:32 +0530400 data.put(FLOW_ID, decorateFlowId(flow));
Simon Hunt9bff5952017-07-13 14:05:09 -0700401
402 // TODO: use formatters for these values..
403 data.put(STATE, flow.state().toString());
404 data.put(BYTES, flow.bytes());
405 data.put(PACKETS, flow.packets());
406 data.put(DURATION, flow.life());
407
Viswanath KSP70e0d142016-10-28 21:58:32 +0530408 data.put(FLOW_PRIORITY, flow.priority());
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530409 data.put(TABLE_ID, flow.tableId());
Simon Hunt9bff5952017-07-13 14:05:09 -0700410 data.put(APP_ID, flow.appId());
Simon Hunt36b658d2017-07-14 16:20:11 -0700411 // NOTE: horribly inefficient... make a map and retrieve a single value...
412 data.put(APP_NAME, makeAppName(flow.appId(), appShortMap()));
Simon Hunt9bff5952017-07-13 14:05:09 -0700413
414 data.put(GROUP_ID, decorateGroupId(flow));
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530415 data.put(TIMEOUT, flow.hardTimeout());
416 data.put(PERMANENT, Boolean.toString(flow.isPermanent()));
Simon Hunt9bff5952017-07-13 14:05:09 -0700417
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530418 data.put(SELECTOR, getCriteriaString(flow));
419 data.put(TREATMENT, getTreatmentString(flow));
420
Viswanath KSP70e0d142016-10-28 21:58:32 +0530421 ObjectNode rootNode = objectNode();
422 rootNode.set(DETAILS, data);
423 sendMessage(FLOW_DETAILS_RESP, rootNode);
424 }
Viswanath KSPd1212c72016-10-21 01:03:35 +0530425 }
426 }
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700427}