blob: 30e1ca063cca71c66238d61ce0360d2da1d31b55 [file] [log] [blame]
Andrea Campanella55c3f422018-02-08 17:10:11 +01001/*
2 * Copyright 2015-present Open Networking Foundation
3 *
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.t3.cli;
18
19import org.onosproject.net.ConnectPoint;
20import org.onosproject.net.flow.TrafficTreatment;
21import org.onosproject.net.group.GroupBucket;
22import org.onosproject.t3.api.GroupsInDevice;
23import org.onosproject.t3.api.StaticPacketTrace;
24
25import java.util.List;
26
27/**
28 * Class containing utility methods for T3 cli.
29 */
30final class T3CliUtils {
31
32 private T3CliUtils() {
33 //banning construction
34 }
35
36 private static final String FLOW_SHORT_FORMAT = " %s, bytes=%s, packets=%s, "
37 + "table=%s, priority=%s, selector=%s, treatment=%s";
38
39 private static final String GROUP_FORMAT =
40 " id=0x%s, state=%s, type=%s, bytes=%s, packets=%s, appId=%s, referenceCount=%s";
41 private static final String GROUP_BUCKET_FORMAT =
42 " id=0x%s, bucket=%s, bytes=%s, packets=%s, actions=%s";
43
44 /**
45 * Builds a string output for the given trace for a specific level of verbosity.
46 *
47 * @param trace the trace
48 * @param verbosity1 middle verbosity level
49 * @param verbosity2 high verbosity level
50 * @return a string representing the trace.
51 */
52 static String printTrace(StaticPacketTrace trace, boolean verbosity1, boolean verbosity2) {
53 StringBuilder tracePrint = new StringBuilder();
54 //Print based on verbosity
55 if (verbosity1) {
56 tracePrint = printTrace(trace, false, tracePrint);
57 } else if (verbosity2) {
58 tracePrint = printTrace(trace, true, tracePrint);
59 } else {
60 tracePrint.append("Paths");
61 tracePrint.append("\n");
62 List<List<ConnectPoint>> paths = trace.getCompletePaths();
63 for (List<ConnectPoint> path : paths) {
64 tracePrint.append(path);
65 tracePrint.append("\n");
66 }
67 }
68 tracePrint.append("Result: \n" + trace.resultMessage());
69 return tracePrint.toString();
70 }
71
72 //prints the trace
73 private static StringBuilder printTrace(StaticPacketTrace trace, boolean verbose, StringBuilder tracePrint) {
74 List<List<ConnectPoint>> paths = trace.getCompletePaths();
75 for (List<ConnectPoint> path : paths) {
76 tracePrint.append("Path " + path);
77 tracePrint.append("\n");
78 ConnectPoint previous = null;
79 if (path.size() == 1) {
80 ConnectPoint connectPoint = path.get(0);
81 tracePrint.append("Device " + connectPoint.deviceId());
82 tracePrint.append("\n");
83 tracePrint.append("Input from " + connectPoint);
84 tracePrint.append("\n");
85 tracePrint = printFlows(trace, verbose, connectPoint, tracePrint);
86 tracePrint = printGroups(trace, verbose, connectPoint, tracePrint);
87 tracePrint.append("Output through " + connectPoint);
88 tracePrint.append("\n");
89 } else {
90 for (ConnectPoint connectPoint : path) {
91 if (previous == null || !previous.deviceId().equals(connectPoint.deviceId())) {
92 tracePrint.append("Device " + connectPoint.deviceId());
93 tracePrint.append("\n");
94 tracePrint.append("Input from " + connectPoint);
95 tracePrint.append("\n");
96 tracePrint = printFlows(trace, verbose, connectPoint, tracePrint);
97 } else {
98 tracePrint = printGroups(trace, verbose, connectPoint, tracePrint);
99 tracePrint.append("Output through " + connectPoint);
100 tracePrint.append("\n");
101 }
102 previous = connectPoint;
103 }
104 }
105 tracePrint.append("---------------------------------------------------------------\n");
106 }
107 return tracePrint;
108 }
109
110
111 //Prints the flows for a given trace and a specified level of verbosity
112 private static StringBuilder printFlows(StaticPacketTrace trace, boolean verbose, ConnectPoint connectPoint,
113 StringBuilder tracePrint) {
Andrea Campanella4c6170a2018-01-17 16:34:51 +0100114 tracePrint.append("Flows ");
115 tracePrint.append(trace.getFlowsForDevice(connectPoint.deviceId()).size());
Andrea Campanella55c3f422018-02-08 17:10:11 +0100116 tracePrint.append("\n");
117 trace.getFlowsForDevice(connectPoint.deviceId()).forEach(f -> {
118 if (verbose) {
119 tracePrint.append(String.format(FLOW_SHORT_FORMAT, f.state(), f.bytes(), f.packets(),
120 f.table(), f.priority(), f.selector().criteria(),
121 printTreatment(f.treatment())));
122 tracePrint.append("\n");
123 } else {
124 tracePrint.append(String.format(" flowId=%s, table=%s, selector=%s", f.id(), f.table(),
125 f.selector().criteria()));
126 tracePrint.append("\n");
127 }
128 });
129 return tracePrint;
130 }
131
132 //Prints the groups for a given trace and a specified level of verbosity
133 private static StringBuilder printGroups(StaticPacketTrace trace, boolean verbose, ConnectPoint connectPoint,
134 StringBuilder tracePrint) {
135 List<GroupsInDevice> groupsInDevice = trace.getGroupOuputs(connectPoint.deviceId());
136 if (groupsInDevice != null) {
137 tracePrint.append("Groups");
138 tracePrint.append("\n");
139 groupsInDevice.forEach(output -> {
140 if (output.getOutput().equals(connectPoint)) {
141 output.getGroups().forEach(group -> {
142 if (verbose) {
143 tracePrint.append(String.format(GROUP_FORMAT, Integer.toHexString(group.id().id()),
144 group.state(), group.type(), group.bytes(), group.packets(),
145 group.appId().name(), group.referenceCount()));
146 tracePrint.append("\n");
147 int i = 0;
148 for (GroupBucket bucket : group.buckets().buckets()) {
149 tracePrint.append(String.format(GROUP_BUCKET_FORMAT,
150 Integer.toHexString(group.id().id()),
151 ++i, bucket.bytes(), bucket.packets(),
152 bucket.treatment().allInstructions()));
153 tracePrint.append("\n");
154 }
155 } else {
156 tracePrint.append(" groupId=" + group.id());
157 tracePrint.append("\n");
158 }
159 });
160 tracePrint.append("Outgoing Packet " + output.getFinalPacket());
161 tracePrint.append("\n");
162 }
163 });
164 }
165 return tracePrint;
166 }
167
168 private static String printTreatment(TrafficTreatment treatment) {
169 final String delimiter = ", ";
170 StringBuilder builder = new StringBuilder("[");
171 if (!treatment.immediate().isEmpty()) {
172 builder.append("immediate=" + treatment.immediate() + delimiter);
173 }
174 if (!treatment.deferred().isEmpty()) {
175 builder.append("deferred=" + treatment.deferred() + delimiter);
176 }
177 if (treatment.clearedDeferred()) {
178 builder.append("clearDeferred" + delimiter);
179 }
180 if (treatment.tableTransition() != null) {
181 builder.append("transition=" + treatment.tableTransition() + delimiter);
182 }
183 if (treatment.metered() != null) {
184 builder.append("meter=" + treatment.metered() + delimiter);
185 }
186 if (treatment.writeMetadata() != null) {
187 builder.append("metadata=" + treatment.writeMetadata() + delimiter);
188 }
189 // Chop off last delimiter
190 builder.replace(builder.length() - delimiter.length(), builder.length(), "");
191 builder.append("]");
192 return builder.toString();
193 }
194}