blob: e15845c964610b771f6a6db441325feeeb89a05d [file] [log] [blame]
Thomas Vachuska7d693f52014-10-21 19:17:57 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2014-present Open Networking Laboratory
Thomas Vachuska7d693f52014-10-21 19:17:57 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska7d693f52014-10-21 19:17:57 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska7d693f52014-10-21 19:17:57 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.cli.net;
tomf5c9d922014-10-03 15:22:03 -070017
Luca Prete5db2e872016-12-07 18:31:00 -080018import com.fasterxml.jackson.databind.JsonNode;
19import com.fasterxml.jackson.databind.ObjectMapper;
20import com.fasterxml.jackson.databind.node.ArrayNode;
21import com.fasterxml.jackson.databind.node.ObjectNode;
22import com.google.common.base.Strings;
23import com.google.common.collect.Lists;
24import com.google.common.collect.Sets;
25import org.apache.commons.lang.StringUtils;
tomf5c9d922014-10-03 15:22:03 -070026import org.apache.karaf.shell.commands.Command;
Brian O'Connorfe0f4b12014-10-30 21:19:02 -070027import org.apache.karaf.shell.commands.Option;
Carolina Fernandezfa56d142016-11-14 01:13:26 +010028import org.onlab.util.StringFilter;
Brian O'Connorabafb502014-12-02 22:26:20 -080029import org.onosproject.cli.AbstractShellCommand;
Luca Prete5db2e872016-12-07 18:31:00 -080030import org.onosproject.net.ConnectPoint;
31import org.onosproject.net.FilteredConnectPoint;
32import org.onosproject.net.flow.TrafficSelector;
33import org.onosproject.net.flow.criteria.Criterion;
Brian O'Connorabafb502014-12-02 22:26:20 -080034import org.onosproject.net.intent.ConnectivityIntent;
Pavlin Radoslavovaab51a32014-12-08 11:07:38 -080035import org.onosproject.net.intent.HostToHostIntent;
Brian O'Connorabafb502014-12-02 22:26:20 -080036import org.onosproject.net.intent.Intent;
37import org.onosproject.net.intent.IntentService;
38import org.onosproject.net.intent.IntentState;
39import org.onosproject.net.intent.LinkCollectionIntent;
40import org.onosproject.net.intent.MultiPointToSinglePointIntent;
Rimon Ashkenazyf0699702016-01-17 19:28:49 +020041import org.onosproject.net.intent.OpticalCircuitIntent;
42import org.onosproject.net.intent.OpticalConnectivityIntent;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020043import org.onosproject.net.intent.OpticalOduIntent;
Brian O'Connorabafb502014-12-02 22:26:20 -080044import org.onosproject.net.intent.PathIntent;
45import org.onosproject.net.intent.PointToPointIntent;
46import org.onosproject.net.intent.SinglePointToMultiPointIntent;
Thomas Vachuska6ce73042014-10-21 10:01:49 -070047
Luca Prete5db2e872016-12-07 18:31:00 -080048import java.util.ArrayList;
49import java.util.List;
50import java.util.Set;
51import java.util.stream.StreamSupport;
tomf5c9d922014-10-03 15:22:03 -070052
53/**
54 * Lists the inventory of intents and their states.
55 */
56@Command(scope = "onos", name = "intents",
57 description = "Lists the inventory of intents and their states")
58public class IntentsListCommand extends AbstractShellCommand {
59
Luca Prete5db2e872016-12-07 18:31:00 -080060 // Color codes and style
61 private static final String BOLD = "\u001B[1m";
62 private static final String RESET = "\u001B[0m";
63
64 // Messages and string formatter
65 private static final String APP_ID = BOLD + "Application Id:" + RESET + " %s";
66
67 private static final String COMMON_SELECTOR = BOLD + "Common ingress " +
68 "selector:" + RESET + " %s";
69
70 private static final String CP = BOLD + "Connect Point:" + RESET + " %s";
71
72 private static final String CONSTRAINTS = BOLD + "Constraints:" + RESET + " %s";
73
74 private static final String DST = BOLD + "Destination " + RESET;
75
76 private static final String EGRESS = BOLD + "Egress ";
77
78 private static final String FILTERED_CPS = "connect points and individual selectors" + RESET;
79
80 private static final String HOST = "host:" + RESET + " %s";
81
82 private static final String ID = BOLD + "Id:" + RESET + " %s";
83
84 private static final String INHERITED = "Inherited";
85
86 private static final String INGRESS = BOLD + "Ingress ";
87
88 private static final String INDENTATION = " -> ";
89
90 private static final String INSTALLABLE = BOLD + "Installable:" + RESET + " %s";
91
92 private static final String KEY = BOLD + "Key:" + RESET + " %s";
93
94 private static final String RESOURCES = BOLD + "Resources:" + RESET + " %s";
95
96 private static final String SELECTOR = BOLD + "Selector:" + RESET + " %s";
97
98 private static final String SEPARATOR = StringUtils.repeat("-", 172);;
99
100 private static final String SPACE = " ";
101
102 private static final String SRC = BOLD + "Source ";
103
104 private static final String STATE = BOLD + "State:" + RESET + " %s";
105
106 private static final String TREATMENT = BOLD + "Treatment:" + RESET + " %s";
107
108 private static final String TYPE = BOLD + "Intent type:" + RESET + " %s";
109
110 private static final String SUMMARY_TITLES =
111 BOLD + String.format(
112 "\n%1s%21s%14s%14s%14s%14s%14s%14s%14s%14s%14s%14s",
113 "Intent type",
114 "Total",
115 "Installed",
116 "Withdrawn",
117 "Failed",
118 "InstallReq",
119 "Compiling",
120 "Installing",
121 "Recompiling",
122 "WithdrawReq",
123 "Withdrawing",
124 "UnknownState") +
125 RESET;
126
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800127 @Option(name = "-i", aliases = "--installable",
128 description = "Output Installable Intents",
Brian O'Connorfe0f4b12014-10-30 21:19:02 -0700129 required = false, multiValued = false)
130 private boolean showInstallable = false;
131
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800132 @Option(name = "-s", aliases = "--summary",
133 description = "Intents summary",
134 required = false, multiValued = false)
135 private boolean intentsSummary = false;
Brian O'Connorfe0f4b12014-10-30 21:19:02 -0700136
Jonathan Hart34f1e382015-02-24 16:52:23 -0800137 @Option(name = "-p", aliases = "--pending",
Carolina Fernandezfa56d142016-11-14 01:13:26 +0100138 description = "Show information about pending intents",
Jonathan Hart34f1e382015-02-24 16:52:23 -0800139 required = false, multiValued = false)
140 private boolean pending = false;
141
Carolina Fernandezfa56d142016-11-14 01:13:26 +0100142 @Option(name = "-f", aliases = "--filter",
Yuta HIGUCHIfadb9a32017-01-13 09:33:10 -0800143 description = "Filter intents by specific keyword",
Carolina Fernandezfa56d142016-11-14 01:13:26 +0100144 required = false, multiValued = true)
145 private List<String> filter = new ArrayList<>();
146
147 private StringFilter contentFilter;
148
tomf5c9d922014-10-03 15:22:03 -0700149 @Override
150 protected void execute() {
151 IntentService service = get(IntentService.class);
Carolina Fernandezfa56d142016-11-14 01:13:26 +0100152 contentFilter = new StringFilter(filter, StringFilter.Strategy.AND);
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800153
154 if (intentsSummary) {
155 IntentSummaries intentSummaries = new IntentSummaries();
156 intentSummaries.collectIntentSummary(service,
157 service.getIntents());
158 if (outputJson()) {
159 print("%s", intentSummaries.json());
160 } else {
Luca Prete5db2e872016-12-07 18:31:00 -0800161 print(intentSummaries.summary());
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800162 }
163 return;
Jonathan Hart34f1e382015-02-24 16:52:23 -0800164 } else if (pending) {
Ray Milkey740c8a32015-03-17 13:41:03 -0700165 if (outputJson()) {
Luca Prete5db2e872016-12-07 18:31:00 -0800166 print("%s", json(service.getPending()));
Ray Milkey740c8a32015-03-17 13:41:03 -0700167 } else {
Carolina Fernandezfa56d142016-11-14 01:13:26 +0100168 StreamSupport.stream(service.getPending().spliterator(), false)
169 .filter(intent -> contentFilter.filter(intent))
170 .forEach(intent -> print(fullFormat(intent)));
Ray Milkey740c8a32015-03-17 13:41:03 -0700171 }
Jonathan Hart34f1e382015-02-24 16:52:23 -0800172 return;
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800173 }
174
Thomas Vachuska6ce73042014-10-21 10:01:49 -0700175 if (outputJson()) {
Luca Prete5db2e872016-12-07 18:31:00 -0800176 print("%s", json(service.getIntents()));
Thomas Vachuska6ce73042014-10-21 10:01:49 -0700177 } else {
Carolina Fernandezfa56d142016-11-14 01:13:26 +0100178 printIntents(service);
tomf5c9d922014-10-03 15:22:03 -0700179 }
180 }
181
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800182 /**
183 * Internal local class to keep track of all intent summaries.
184 */
185 private class IntentSummaries {
186 private IntentSummary summaryAll;
187 private IntentSummary summaryConnectivity;
Pavlin Radoslavovaab51a32014-12-08 11:07:38 -0800188 private IntentSummary summaryHostToHost;
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800189 private IntentSummary summaryPointToPoint;
190 private IntentSummary summaryMultiPointToSinglePoint;
191 private IntentSummary summarySinglePointToMultiPoint;
192 private IntentSummary summaryPath;
193 private IntentSummary summaryLinkCollection;
Rimon Ashkenazyf0699702016-01-17 19:28:49 +0200194 private IntentSummary summaryOpticalCircuit;
195 private IntentSummary summaryOpticalConnectivity;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200196 private IntentSummary summaryOpticalOdu;
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800197 private IntentSummary summaryUnknownType;
198
199 /**
Luca Prete5db2e872016-12-07 18:31:00 -0800200 * Initializes the internal summary.
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800201 */
202 private void init() {
203 summaryAll = new IntentSummary("All");
204 summaryConnectivity = new IntentSummary("Connectivity");
Pavlin Radoslavovaab51a32014-12-08 11:07:38 -0800205 summaryHostToHost = new IntentSummary("HostToHost");
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800206 summaryPointToPoint = new IntentSummary("PointToPoint");
207 summaryMultiPointToSinglePoint =
208 new IntentSummary("MultiPointToSinglePoint");
209 summarySinglePointToMultiPoint =
210 new IntentSummary("SinglePointToMultiPoint");
211 summaryPath = new IntentSummary("Path");
212 summaryLinkCollection = new IntentSummary("LinkCollection");
Rimon Ashkenazyf0699702016-01-17 19:28:49 +0200213 summaryOpticalCircuit = new IntentSummary("OpticalCircuit");
214 summaryOpticalConnectivity = new IntentSummary("OpticalConnectivity");
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200215 summaryOpticalOdu = new IntentSummary("OpticalOdu");
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800216 summaryUnknownType = new IntentSummary("UnknownType");
217 }
218
219 /**
220 * Collects summary of all intents.
221 *
222 * @param service the Intent Service to use
223 * @param intents the intents
224 */
225 private void collectIntentSummary(IntentService service,
226 Iterable<Intent> intents) {
227 init();
228
229 // Collect the summary for each intent type intents
230 for (Intent intent : intents) {
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800231 IntentState intentState = service.getIntentState(intent.key());
Pavlin Radoslavovdeb8a102014-11-26 13:31:36 -0800232 if (intentState == null) {
233 continue;
234 }
Carolina Fernandezfa56d142016-11-14 01:13:26 +0100235 if (!contentFilter.filter(intent)) {
236 break;
237 }
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800238
239 // Update the summary for all Intents
240 summaryAll.update(intentState);
241
242 if (intent instanceof ConnectivityIntent) {
243 summaryConnectivity.update(intentState);
244 // NOTE: ConnectivityIntent is a base type Intent
245 // continue;
246 }
Pavlin Radoslavovaab51a32014-12-08 11:07:38 -0800247 if (intent instanceof HostToHostIntent) {
248 summaryHostToHost.update(intentState);
249 continue;
250 }
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800251 if (intent instanceof PointToPointIntent) {
252 summaryPointToPoint.update(intentState);
253 continue;
254 }
255 if (intent instanceof MultiPointToSinglePointIntent) {
256 summaryMultiPointToSinglePoint.update(intentState);
257 continue;
258 }
259 if (intent instanceof SinglePointToMultiPointIntent) {
260 summarySinglePointToMultiPoint.update(intentState);
261 continue;
262 }
263 if (intent instanceof PathIntent) {
264 summaryPath.update(intentState);
265 continue;
266 }
267 if (intent instanceof LinkCollectionIntent) {
268 summaryLinkCollection.update(intentState);
269 continue;
270 }
Rimon Ashkenazyf0699702016-01-17 19:28:49 +0200271 if (intent instanceof OpticalCircuitIntent) {
272 summaryOpticalCircuit.update(intentState);
273 continue;
274 }
275 if (intent instanceof OpticalConnectivityIntent) {
276 summaryOpticalConnectivity.update(intentState);
277 continue;
278 }
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200279 if (intent instanceof OpticalOduIntent) {
280 summaryOpticalOdu.update(intentState);
281 continue;
282 }
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800283 summaryUnknownType.update(intentState);
284 }
285 }
286
287 /**
288 * Gets JSON representation of all Intents summary.
289 *
290 * @return JSON representation of all Intents summary
291 */
292 ObjectNode json() {
293 ObjectMapper mapper = new ObjectMapper();
294 ObjectNode result = mapper.createObjectNode();
Ray Milkey9d810f62015-02-13 11:20:58 -0800295 result.set("connectivity", summaryConnectivity.json(mapper));
296 result.set("hostToHost", summaryHostToHost.json(mapper));
297 result.set("pointToPoint", summaryPointToPoint.json(mapper));
298 result.set("multiPointToSinglePoint",
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800299 summaryMultiPointToSinglePoint.json(mapper));
Ray Milkey9d810f62015-02-13 11:20:58 -0800300 result.set("singlePointToMultiPoint",
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800301 summarySinglePointToMultiPoint.json(mapper));
Ray Milkey9d810f62015-02-13 11:20:58 -0800302 result.set("path", summaryPath.json(mapper));
303 result.set("linkCollection", summaryLinkCollection.json(mapper));
Rimon Ashkenazyf0699702016-01-17 19:28:49 +0200304 result.set("opticalCircuit", summaryOpticalCircuit.json(mapper));
305 result.set("opticalConnectivity", summaryOpticalConnectivity.json(mapper));
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200306 result.set("opticalOdu", summaryOpticalOdu.json(mapper));
Ray Milkey9d810f62015-02-13 11:20:58 -0800307 result.set("unknownType", summaryUnknownType.json(mapper));
308 result.set("all", summaryAll.json(mapper));
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800309 return result;
310 }
311
312 /**
313 * Prints summary of the intents.
314 */
Luca Prete5db2e872016-12-07 18:31:00 -0800315 private String summary() {
316 StringBuilder builder = new StringBuilder();
317 builder.append(SUMMARY_TITLES);
318 builder.append("\n" + SEPARATOR);
319 builder.append(summaryAll.summary());
320 builder.append(summaryPointToPoint.summary());
321 builder.append(summarySinglePointToMultiPoint.summary());
322 builder.append(summaryMultiPointToSinglePoint.summary());
323 builder.append(summaryHostToHost.summary());
324 builder.append(summaryLinkCollection.summary());
325 builder.append(summaryConnectivity.summary());
326 builder.append(summaryPath.summary());
327 builder.append(summaryOpticalCircuit.summary());
328 builder.append(summaryOpticalConnectivity.summary());
329 builder.append(summaryOpticalOdu.summary());
330 builder.append(summaryUnknownType.summary());
331
332 return builder.toString();
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800333 }
334
335 /**
336 * Internal local class to keep track of a single type Intent summary.
337 */
338 private class IntentSummary {
339 private final String intentType;
340 private int total = 0;
Pavlin Radoslavov67c05142014-12-02 13:04:08 -0800341 private int installReq = 0;
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800342 private int compiling = 0;
343 private int installing = 0;
344 private int installed = 0;
345 private int recompiling = 0;
Pavlin Radoslavov67c05142014-12-02 13:04:08 -0800346 private int withdrawReq = 0;
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800347 private int withdrawing = 0;
348 private int withdrawn = 0;
349 private int failed = 0;
350 private int unknownState = 0;
351
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800352 /**
353 * Constructor.
354 *
355 * @param intentType the scring describing the Intent type
356 */
357 IntentSummary(String intentType) {
358 this.intentType = intentType;
359 }
360
361 /**
362 * Updates the Intent Summary.
363 *
Luca Prete5db2e872016-12-07 18:31:00 -0800364 * @param intentState the state of the intent
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800365 */
366 void update(IntentState intentState) {
367 total++;
368 switch (intentState) {
Brian O'Connor7a71d5d2014-12-02 00:12:27 -0800369 case INSTALL_REQ:
Pavlin Radoslavov67c05142014-12-02 13:04:08 -0800370 installReq++;
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800371 break;
372 case COMPILING:
373 compiling++;
374 break;
375 case INSTALLING:
376 installing++;
377 break;
378 case INSTALLED:
379 installed++;
380 break;
381 case RECOMPILING:
382 recompiling++;
383 break;
Pavlin Radoslavov67c05142014-12-02 13:04:08 -0800384 case WITHDRAW_REQ:
385 withdrawReq++;
386 break;
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800387 case WITHDRAWING:
388 withdrawing++;
389 break;
390 case WITHDRAWN:
391 withdrawn++;
392 break;
393 case FAILED:
394 failed++;
395 break;
396 default:
397 unknownState++;
398 break;
399 }
400 }
401
402 /**
403 * Prints the Intent Summary.
Luca Prete5db2e872016-12-07 18:31:00 -0800404 *
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800405 */
Luca Prete5db2e872016-12-07 18:31:00 -0800406 String summary() {
407 StringBuilder builder = new StringBuilder();
408
409 builder.append(String.format(
410 "\n%1s%s%14d%14d%14d%14d%14d%14d%14d%14d%14d%14d",
411 BOLD + intentType + RESET,
412 Strings.padStart(String.valueOf(total),
413 (32 - intentType.length()),
414 ' '),
415 installed,
416 withdrawn,
417 failed,
418 installReq,
419 compiling,
420 installing,
421 recompiling,
422 withdrawReq,
423 withdrawing,
424 unknownState));
425 builder.append("\n" + SEPARATOR);
426
427 return builder.toString();
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800428 }
429
430 /**
431 * Gets the JSON representation of the Intent Summary.
432 *
Luca Prete5db2e872016-12-07 18:31:00 -0800433 * @param mapper the object mapper
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800434 * @return the JSON representation of the Intent Summary
435 */
436 JsonNode json(ObjectMapper mapper) {
437 ObjectNode result = mapper.createObjectNode()
438 .put("total", total)
439 .put("installed", installed)
440 .put("failed", failed)
Pavlin Radoslavov67c05142014-12-02 13:04:08 -0800441 .put("installReq", installReq)
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800442 .put("installing", installing)
Luca Prete5db2e872016-12-07 18:31:00 -0800443 .put("compiling", compiling)
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800444 .put("recompiling", recompiling)
Pavlin Radoslavov67c05142014-12-02 13:04:08 -0800445 .put("withdrawReq", withdrawReq)
Pavlin Radoslavov708e8202014-11-14 17:18:37 -0800446 .put("withdrawing", withdrawing)
447 .put("withdrawn", withdrawn)
448 .put("unknownState", unknownState);
449
450 return result;
451 }
452 }
453 }
454
Luca Prete5db2e872016-12-07 18:31:00 -0800455 /*
456 * Prints detailed information about a specific intent.
457 */
Carolina Fernandezfa56d142016-11-14 01:13:26 +0100458 private String detailsFormat(IntentService service, Intent intent) {
459 StringBuilder builder = new StringBuilder();
Sho SHIMIZUd7d18002015-01-21 14:37:14 -0800460 if (!intent.resources().isEmpty()) {
Luca Prete5db2e872016-12-07 18:31:00 -0800461 builder.append("\n" + String.format(RESOURCES, intent.resources()));
Thomas Vachuska6ce73042014-10-21 10:01:49 -0700462 }
463 if (intent instanceof ConnectivityIntent) {
464 ConnectivityIntent ci = (ConnectivityIntent) intent;
Thomas Vachuska10d4abc2014-10-21 12:47:26 -0700465 if (!ci.selector().criteria().isEmpty()) {
Luca Prete5db2e872016-12-07 18:31:00 -0800466 builder.append("\n" + String.format(COMMON_SELECTOR, formatSelector(ci.selector())));
Thomas Vachuska10d4abc2014-10-21 12:47:26 -0700467 }
Ray Milkey42507352015-03-20 15:16:10 -0700468 if (!ci.treatment().allInstructions().isEmpty()) {
Luca Prete5db2e872016-12-07 18:31:00 -0800469 builder.append("\n" + String.format(TREATMENT, ci.treatment().allInstructions()));
Thomas Vachuska10d4abc2014-10-21 12:47:26 -0700470 }
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800471 if (ci.constraints() != null && !ci.constraints().isEmpty()) {
Luca Prete5db2e872016-12-07 18:31:00 -0800472 builder.append("\n" + String.format(CONSTRAINTS, ci.constraints()));
Thomas Vachuskaedc944c2014-11-04 15:42:25 -0800473 }
Thomas Vachuska6ce73042014-10-21 10:01:49 -0700474 }
475
Pavlin Radoslavovaab51a32014-12-08 11:07:38 -0800476 if (intent instanceof HostToHostIntent) {
477 HostToHostIntent pi = (HostToHostIntent) intent;
Luca Prete5db2e872016-12-07 18:31:00 -0800478 builder.append("\n" + String.format(SRC + HOST, pi.one()));
479 builder.append("\n" + String.format(DST + HOST, pi.two()));
Pavlin Radoslavovaab51a32014-12-08 11:07:38 -0800480 } else if (intent instanceof PointToPointIntent) {
Thomas Vachuska6ce73042014-10-21 10:01:49 -0700481 PointToPointIntent pi = (PointToPointIntent) intent;
Luca Prete5db2e872016-12-07 18:31:00 -0800482 builder.append("\n" + formatFilteredCps(Sets.newHashSet(pi.filteredIngressPoint()), INGRESS));
483 builder.append("\n" + formatFilteredCps(Sets.newHashSet(pi.filteredEgressPoint()), EGRESS));
Thomas Vachuska6ce73042014-10-21 10:01:49 -0700484 } else if (intent instanceof MultiPointToSinglePointIntent) {
485 MultiPointToSinglePointIntent pi = (MultiPointToSinglePointIntent) intent;
Luca Prete5db2e872016-12-07 18:31:00 -0800486 builder.append("\n" + formatFilteredCps(pi.filteredIngressPoints(), INGRESS));
487 builder.append("\n" + formatFilteredCps(Sets.newHashSet(pi.filteredEgressPoint()), EGRESS));
Thomas Vachuska6ce73042014-10-21 10:01:49 -0700488 } else if (intent instanceof SinglePointToMultiPointIntent) {
489 SinglePointToMultiPointIntent pi = (SinglePointToMultiPointIntent) intent;
Luca Prete5db2e872016-12-07 18:31:00 -0800490 builder.append("\n" + formatFilteredCps(Sets.newHashSet(pi.filteredIngressPoint()), INGRESS));
491 builder.append("\n" + formatFilteredCps(pi.filteredEgressPoints(), EGRESS));
Thomas Vachuska6ce73042014-10-21 10:01:49 -0700492 } else if (intent instanceof PathIntent) {
493 PathIntent pi = (PathIntent) intent;
Luca Prete5db2e872016-12-07 18:31:00 -0800494 builder.append(String.format("path=%s, cost=%f", pi.path().links(), pi.path().cost()));
Thomas Vachuska6ce73042014-10-21 10:01:49 -0700495 } else if (intent instanceof LinkCollectionIntent) {
496 LinkCollectionIntent li = (LinkCollectionIntent) intent;
Luca Prete5db2e872016-12-07 18:31:00 -0800497 builder.append("\n" + String.format("links=%s", li.links()));
498 builder.append("\n" + String.format(CP, li.egressPoints()));
Rimon Ashkenazyf0699702016-01-17 19:28:49 +0200499 } else if (intent instanceof OpticalCircuitIntent) {
500 OpticalCircuitIntent ci = (OpticalCircuitIntent) intent;
Luca Prete5db2e872016-12-07 18:31:00 -0800501 builder.append("\n" + String.format("src=%s, dst=%s", ci.getSrc(), ci.getDst()));
Rimon Ashkenazyf0699702016-01-17 19:28:49 +0200502 } else if (intent instanceof OpticalConnectivityIntent) {
503 OpticalConnectivityIntent ci = (OpticalConnectivityIntent) intent;
Luca Prete5db2e872016-12-07 18:31:00 -0800504 builder.append("\n" + String.format("src=%s, dst=%s", ci.getSrc(), ci.getDst()));
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200505 } else if (intent instanceof OpticalOduIntent) {
506 OpticalOduIntent ci = (OpticalOduIntent) intent;
Luca Prete5db2e872016-12-07 18:31:00 -0800507 builder.append("\n" + String.format("src=%s, dst=%s", ci.getSrc(), ci.getDst()));
Thomas Vachuska6ce73042014-10-21 10:01:49 -0700508 }
Thomas Vachuska10d4abc2014-10-21 12:47:26 -0700509
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800510 List<Intent> installable = service.getInstallableIntents(intent.key());
Carolina Fernandezfa56d142016-11-14 01:13:26 +0100511 installable.stream().filter(i -> contentFilter.filter(i));
Brian O'Connorfe0f4b12014-10-30 21:19:02 -0700512 if (showInstallable && installable != null && !installable.isEmpty()) {
Luca Prete5db2e872016-12-07 18:31:00 -0800513 builder.append("\n" + String.format(INSTALLABLE, installable));
Carolina Fernandezfa56d142016-11-14 01:13:26 +0100514 }
515 return builder.toString();
516 }
517
Luca Prete5db2e872016-12-07 18:31:00 -0800518 /*
519 * Prints out a formatted string, given a list of connect points.
520 */
521 private String formatFilteredCps(Set<FilteredConnectPoint> fCps, String prefix) {
522 StringBuilder builder = new StringBuilder();
523 builder.append(prefix);
524 builder.append(FILTERED_CPS);
525 fCps.forEach(fCp -> builder.append("\n" + String.format(formatFilteredCp(fCp))));
526
527 return builder.toString();
528 }
529
530 /*
531 * Prints out a formatted string, given a filtered connect point.
532 */
533 private String formatFilteredCp(FilteredConnectPoint fCp) {
534 ConnectPoint connectPoint = fCp.connectPoint();
535 TrafficSelector selector = fCp.trafficSelector();
536 StringBuilder builder = new StringBuilder();
537 builder.append(INDENTATION + String.format(CP, connectPoint));
538 builder.append(SPACE + String.format(SELECTOR, formatSelector(selector)));
539
540 return builder.toString();
541 }
542
543 /*
544 * Prints out a formatted string, given a traffic selector
545 */
546 private String formatSelector(TrafficSelector ts) {
547 StringBuilder builder = new StringBuilder();
548 List<Criterion> criteria = Lists.newArrayList(ts.criteria());
549
550 if (criteria == null || criteria.isEmpty()) {
551 builder.append(INHERITED);
552 return builder.toString();
553 }
554
555 criteria.forEach(c -> {
556 builder.append(c.toString());
557 if (criteria.indexOf(c) < criteria.size() - 1) {
558 builder.append(", ");
559 }
560 });
561
562 return builder.toString();
563 }
564
Carolina Fernandezfa56d142016-11-14 01:13:26 +0100565 private String fullFormat(Intent intent) {
566 return fullFormat(intent, null);
567 }
568
Luca Prete5db2e872016-12-07 18:31:00 -0800569 /*
570 * Prints information about the intent state, given an intent.
571 */
Carolina Fernandezfa56d142016-11-14 01:13:26 +0100572 private String fullFormat(Intent intent, String state) {
573 StringBuilder builder = new StringBuilder();
Luca Prete5db2e872016-12-07 18:31:00 -0800574 builder.append(String.format(ID, intent.id()));
Carolina Fernandezfa56d142016-11-14 01:13:26 +0100575 if (state != null) {
Luca Prete5db2e872016-12-07 18:31:00 -0800576 builder.append("\n" + String.format(STATE, state));
Carolina Fernandezfa56d142016-11-14 01:13:26 +0100577 }
Luca Prete5db2e872016-12-07 18:31:00 -0800578 builder.append("\n" + String.format(KEY, intent.key()));
579 builder.append("\n" + String.format(TYPE, intent.getClass().getSimpleName()));
580 builder.append("\n" + String.format(APP_ID, intent.appId().name()));
581
Carolina Fernandezfa56d142016-11-14 01:13:26 +0100582 return builder.toString();
583 }
584
Luca Prete5db2e872016-12-07 18:31:00 -0800585 /*
586 * Prints a detailed information about intents.
587 */
Carolina Fernandezfa56d142016-11-14 01:13:26 +0100588 private void printIntents(IntentService service) {
589 for (Intent intent : service.getIntents()) {
590 IntentState state = service.getIntentState(intent.key());
591 String intentFormat = fullFormat(intent, state.toString());
592 String detailsIntentFormat = detailsFormat(service, intent);
593 if (state != null && (contentFilter.filter(
594 intentFormat + detailsIntentFormat))) {
Luca Prete5db2e872016-12-07 18:31:00 -0800595 StringBuilder builder = new StringBuilder();
596 builder.append(intentFormat)
597 .append(detailsIntentFormat)
598 .append("\n");
599 print(builder.toString());
Carolina Fernandezfa56d142016-11-14 01:13:26 +0100600 }
Thomas Vachuska10d4abc2014-10-21 12:47:26 -0700601 }
Thomas Vachuska6ce73042014-10-21 10:01:49 -0700602 }
603
Luca Prete5db2e872016-12-07 18:31:00 -0800604 /*
605 * Produces a JSON array from the intents specified.
606 */
607 private JsonNode json(Iterable<Intent> intents) {
Thomas Vachuska6ce73042014-10-21 10:01:49 -0700608 ObjectMapper mapper = new ObjectMapper();
609 ArrayNode result = mapper.createArrayNode();
Carolina Fernandezfa56d142016-11-14 01:13:26 +0100610 StreamSupport.stream(intents.spliterator(), false)
611 .filter(intent -> contentFilter.filter(jsonForEntity(intent, Intent.class).toString()))
612 .forEach(intent -> result.add(jsonForEntity(intent, Intent.class)));
Thomas Vachuska6ce73042014-10-21 10:01:49 -0700613 return result;
614 }
615
tomf5c9d922014-10-03 15:22:03 -0700616}