blob: 1c2716e889d218bab5322d82277af1c3a1bdec52 [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;
Ray Milkey0068fd02018-10-11 15:45:39 -070022import org.apache.karaf.shell.api.action.Completion;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070023import org.apache.karaf.shell.api.action.lifecycle.Service;
24import org.apache.karaf.shell.api.action.Option;
Yuta HIGUCHIfadb9a32017-01-13 09:33:10 -080025import org.onlab.util.Tools;
26import org.onosproject.cli.AbstractShellCommand;
Ray Milkey0068fd02018-10-11 15:45:39 -070027import org.onosproject.cli.net.completer.IntentIdCompleter;
Yuta HIGUCHIfadb9a32017-01-13 09:33:10 -080028import org.onosproject.net.Link;
29import org.onosproject.net.LinkKey;
30import org.onosproject.net.intent.Intent;
31import org.onosproject.net.intent.IntentData;
32import org.onosproject.net.intent.IntentId;
33import org.onosproject.net.intent.IntentService;
34
35/**
36 * Displays details about an Intent in the system.
37 */
Ray Milkeyd84f89b2018-08-17 14:54:17 -070038@Service
Yuta HIGUCHIfadb9a32017-01-13 09:33:10 -080039@Command(scope = "onos", name = "intent-details",
40 description = "Displays intent details")
41public class IntentDetailsCommand extends AbstractShellCommand {
42
43 @Option(name = "--id",
44 description = "Filter intent by specific Id", multiValued = true)
Ray Milkey0068fd02018-10-11 15:45:39 -070045 @Completion(IntentIdCompleter.class)
Yuta HIGUCHIfadb9a32017-01-13 09:33:10 -080046 private List<String> idsStr;
47
48 private Set<IntentId> ids = null;
49
50
51 @Override
Ray Milkeyd84f89b2018-08-17 14:54:17 -070052 protected void doExecute() {
Carolina Fernandez0b1449d2016-12-04 13:30:36 +010053 detailIntents(idsStr);
54 }
55
56 /**
57 * Print detailed data for intents, given a list of IDs.
58 *
59 * @param intentsIds List of intent IDs
60 */
61 public void detailIntents(List<String> intentsIds) {
62 if (intentsIds != null) {
63 ids = intentsIds.stream()
Yuta HIGUCHIfadb9a32017-01-13 09:33:10 -080064 .map(IntentId::valueOf)
65 .collect(Collectors.toSet());
66 }
67
68 IntentService service = get(IntentService.class);
69
70 Tools.stream(service.getIntentData())
Carolina Fernandez0b1449d2016-12-04 13:30:36 +010071 .filter(this::filter)
72 .forEach(this::printIntentData);
Yuta HIGUCHIfadb9a32017-01-13 09:33:10 -080073 }
74
75 private boolean filter(IntentData data) {
76 if (ids != null && !ids.contains(data.intent().id())) {
77 return false;
78 }
79
80 return true;
81 }
82
83 private void printIntentData(IntentData data) {
84 print("Key: %s ID: %s", data.key(), data.intent().id());
85
86 print(" Request: %s Current: %s", data.request(), data.state());
87
88 print(" intent: %s", s(data.intent()));
89
90 data.installables().stream()
91 .forEach(this::printInstallable);
92
93 // empty line
94 print("");
95 }
96
97 private void printInstallable(Intent installable) {
98 print(" installable: %s %s", installable.getClass().getSimpleName(),
99 installable.id());
100
101 print(" resources: %s", installable.resources().stream()
102 .filter(r -> !(r instanceof Link))
103 .map(this::s)
104 .collect(Collectors.joining(", ")));
105
106 print(" links: %s", installable.resources().stream()
107 .filter(Link.class::isInstance)
108 .map(Link.class::cast)
109 .map(LinkKey::linkKey)
110 .map(l -> String.format("%s -> %s", l.src(), l.dst()))
111 .collect(Collectors.joining(", ")));
112 }
113
114 protected String s(Object o) {
115 return simplify(String.valueOf(o));
116 }
117
118 /**
119 * Simplify toString result for CLI.
120 *
121 * @param input String
122 * @return simplified String
123 */
124 public static String simplify(String input) {
125 String after = input
126 // omit redundant info
127 .replaceAll("treatment=DefaultTrafficTreatment", "treatment=")
128 .replaceAll("selector=DefaultTrafficSelector", "selector=")
129 // shorten AppId
130 .replaceAll("DefaultApplicationId\\{id=(\\d+), name=([.\\w]+)\\}", "$2($1)")
131 // omit empty list/array attribute
132 .replaceAll("(, )?\\w+=\\[\\]", "")
133 // omit empty map attribute
134 .replaceAll("(, )?\\w+=\\{\\}", "")
135 // omit Object which became empty
136 .replaceAll("(, )?\\w+\\{\\}", "\\{\\}")
137 // shorten FilteredConnectPoint
138 .replaceAll("FilteredConnectPoint", "")
139 // trim prefix Default
140 .replaceAll("Default(\\w+)\\{", "$1\\{")
141 .replaceAll(", , ", ", ");
142
143 return after.equals(input) ? input : simplify(after);
144 }
145
146}