blob: e80623b298668ccb0794d0865776760d44ecfb69 [file] [log] [blame]
Yuta HIGUCHIfadb9a32017-01-13 09:33:10 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Yuta HIGUCHIfadb9a32017-01-13 09:33:10 -08003 *
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 */
16package org.onosproject.cli.net;
17
18import java.util.List;
19import java.util.Set;
20import java.util.stream.Collectors;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070021import org.apache.karaf.shell.api.action.Command;
22import org.apache.karaf.shell.api.action.lifecycle.Service;
23import org.apache.karaf.shell.api.action.Option;
Yuta HIGUCHIfadb9a32017-01-13 09:33:10 -080024import org.onlab.util.Tools;
25import org.onosproject.cli.AbstractShellCommand;
26import org.onosproject.net.Link;
27import org.onosproject.net.LinkKey;
28import org.onosproject.net.intent.Intent;
29import org.onosproject.net.intent.IntentData;
30import org.onosproject.net.intent.IntentId;
31import org.onosproject.net.intent.IntentService;
32
33/**
34 * Displays details about an Intent in the system.
35 */
Ray Milkeyd84f89b2018-08-17 14:54:17 -070036@Service
Yuta HIGUCHIfadb9a32017-01-13 09:33:10 -080037@Command(scope = "onos", name = "intent-details",
38 description = "Displays intent details")
39public class IntentDetailsCommand extends AbstractShellCommand {
40
41 @Option(name = "--id",
42 description = "Filter intent by specific Id", multiValued = true)
43 private List<String> idsStr;
44
45 private Set<IntentId> ids = null;
46
47
48 @Override
Ray Milkeyd84f89b2018-08-17 14:54:17 -070049 protected void doExecute() {
Carolina Fernandez0b1449d2016-12-04 13:30:36 +010050 detailIntents(idsStr);
51 }
52
53 /**
54 * Print detailed data for intents, given a list of IDs.
55 *
56 * @param intentsIds List of intent IDs
57 */
58 public void detailIntents(List<String> intentsIds) {
59 if (intentsIds != null) {
60 ids = intentsIds.stream()
Yuta HIGUCHIfadb9a32017-01-13 09:33:10 -080061 .map(IntentId::valueOf)
62 .collect(Collectors.toSet());
63 }
64
65 IntentService service = get(IntentService.class);
66
67 Tools.stream(service.getIntentData())
Carolina Fernandez0b1449d2016-12-04 13:30:36 +010068 .filter(this::filter)
69 .forEach(this::printIntentData);
Yuta HIGUCHIfadb9a32017-01-13 09:33:10 -080070 }
71
72 private boolean filter(IntentData data) {
73 if (ids != null && !ids.contains(data.intent().id())) {
74 return false;
75 }
76
77 return true;
78 }
79
80 private void printIntentData(IntentData data) {
81 print("Key: %s ID: %s", data.key(), data.intent().id());
82
83 print(" Request: %s Current: %s", data.request(), data.state());
84
85 print(" intent: %s", s(data.intent()));
86
87 data.installables().stream()
88 .forEach(this::printInstallable);
89
90 // empty line
91 print("");
92 }
93
94 private void printInstallable(Intent installable) {
95 print(" installable: %s %s", installable.getClass().getSimpleName(),
96 installable.id());
97
98 print(" resources: %s", installable.resources().stream()
99 .filter(r -> !(r instanceof Link))
100 .map(this::s)
101 .collect(Collectors.joining(", ")));
102
103 print(" links: %s", installable.resources().stream()
104 .filter(Link.class::isInstance)
105 .map(Link.class::cast)
106 .map(LinkKey::linkKey)
107 .map(l -> String.format("%s -> %s", l.src(), l.dst()))
108 .collect(Collectors.joining(", ")));
109 }
110
111 protected String s(Object o) {
112 return simplify(String.valueOf(o));
113 }
114
115 /**
116 * Simplify toString result for CLI.
117 *
118 * @param input String
119 * @return simplified String
120 */
121 public static String simplify(String input) {
122 String after = input
123 // omit redundant info
124 .replaceAll("treatment=DefaultTrafficTreatment", "treatment=")
125 .replaceAll("selector=DefaultTrafficSelector", "selector=")
126 // shorten AppId
127 .replaceAll("DefaultApplicationId\\{id=(\\d+), name=([.\\w]+)\\}", "$2($1)")
128 // omit empty list/array attribute
129 .replaceAll("(, )?\\w+=\\[\\]", "")
130 // omit empty map attribute
131 .replaceAll("(, )?\\w+=\\{\\}", "")
132 // omit Object which became empty
133 .replaceAll("(, )?\\w+\\{\\}", "\\{\\}")
134 // shorten FilteredConnectPoint
135 .replaceAll("FilteredConnectPoint", "")
136 // trim prefix Default
137 .replaceAll("Default(\\w+)\\{", "$1\\{")
138 .replaceAll(", , ", ", ");
139
140 return after.equals(input) ? input : simplify(after);
141 }
142
143}