blob: 26c814e87215f7cba375c7461d15b07e85d4ad57 [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
Andrea Campanella94dfb9e2018-02-27 12:36:00 +010019import org.apache.commons.lang.StringUtils;
Andrea Campanella55c3f422018-02-08 17:10:11 +010020import org.onosproject.net.ConnectPoint;
21import org.onosproject.net.flow.TrafficTreatment;
22import org.onosproject.net.group.GroupBucket;
23import org.onosproject.t3.api.GroupsInDevice;
24import org.onosproject.t3.api.StaticPacketTrace;
25
26import java.util.List;
27
28/**
29 * Class containing utility methods for T3 cli.
30 */
31final class T3CliUtils {
32
33 private T3CliUtils() {
34 //banning construction
35 }
36
37 private static final String FLOW_SHORT_FORMAT = " %s, bytes=%s, packets=%s, "
38 + "table=%s, priority=%s, selector=%s, treatment=%s";
39
40 private static final String GROUP_FORMAT =
41 " id=0x%s, state=%s, type=%s, bytes=%s, packets=%s, appId=%s, referenceCount=%s";
42 private static final String GROUP_BUCKET_FORMAT =
43 " id=0x%s, bucket=%s, bytes=%s, packets=%s, actions=%s";
44
45 /**
46 * Builds a string output for the given trace for a specific level of verbosity.
47 *
48 * @param trace the trace
49 * @param verbosity1 middle verbosity level
50 * @param verbosity2 high verbosity level
51 * @return a string representing the trace.
52 */
53 static String printTrace(StaticPacketTrace trace, boolean verbosity1, boolean verbosity2) {
54 StringBuilder tracePrint = new StringBuilder();
55 //Print based on verbosity
56 if (verbosity1) {
57 tracePrint = printTrace(trace, false, tracePrint);
58 } else if (verbosity2) {
59 tracePrint = printTrace(trace, true, tracePrint);
60 } else {
61 tracePrint.append("Paths");
62 tracePrint.append("\n");
63 List<List<ConnectPoint>> paths = trace.getCompletePaths();
64 for (List<ConnectPoint> path : paths) {
65 tracePrint.append(path);
66 tracePrint.append("\n");
67 }
68 }
69 tracePrint.append("Result: \n" + trace.resultMessage());
70 return tracePrint.toString();
71 }
72
73 //prints the trace
74 private static StringBuilder printTrace(StaticPacketTrace trace, boolean verbose, StringBuilder tracePrint) {
75 List<List<ConnectPoint>> paths = trace.getCompletePaths();
76 for (List<ConnectPoint> path : paths) {
77 tracePrint.append("Path " + path);
78 tracePrint.append("\n");
79 ConnectPoint previous = null;
80 if (path.size() == 1) {
81 ConnectPoint connectPoint = path.get(0);
82 tracePrint.append("Device " + connectPoint.deviceId());
83 tracePrint.append("\n");
84 tracePrint.append("Input from " + connectPoint);
85 tracePrint.append("\n");
86 tracePrint = printFlows(trace, verbose, connectPoint, tracePrint);
87 tracePrint = printGroups(trace, verbose, connectPoint, tracePrint);
Andrea Campanella55c3f422018-02-08 17:10:11 +010088 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");
Andrea Campanellaf8b53192018-03-08 11:12:05 -080094 tracePrint.append(" Input from " + connectPoint);
Andrea Campanella55c3f422018-02-08 17:10:11 +010095 tracePrint.append("\n");
96 tracePrint = printFlows(trace, verbose, connectPoint, tracePrint);
97 } else {
98 tracePrint = printGroups(trace, verbose, connectPoint, tracePrint);
Andrea Campanellaf8b53192018-03-08 11:12:05 -080099 tracePrint.append(" Output through " + connectPoint);
Andrea Campanella55c3f422018-02-08 17:10:11 +0100100 tracePrint.append("\n");
101 }
102 previous = connectPoint;
103 }
104 }
Andrea Campanella94dfb9e2018-02-27 12:36:00 +0100105 tracePrint.append(StringUtils.leftPad("\n", 100, '-'));
Andrea Campanella55c3f422018-02-08 17:10:11 +0100106 }
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 Campanellaf8b53192018-03-08 11:12:05 -0800114 tracePrint.append(" Flows ");
Andrea Campanella4c6170a2018-01-17 16:34:51 +0100115 tracePrint.append(trace.getFlowsForDevice(connectPoint.deviceId()).size());
Andrea Campanellaf8b53192018-03-08 11:12:05 -0800116 tracePrint.append(" \n");
Andrea Campanella55c3f422018-02-08 17:10:11 +0100117 trace.getFlowsForDevice(connectPoint.deviceId()).forEach(f -> {
118 if (verbose) {
Andrea Campanellaf8b53192018-03-08 11:12:05 -0800119 tracePrint.append(" " + String.format(FLOW_SHORT_FORMAT, f.state(), f.bytes(), f.packets(),
Andrea Campanella55c3f422018-02-08 17:10:11 +0100120 f.table(), f.priority(), f.selector().criteria(),
121 printTreatment(f.treatment())));
122 tracePrint.append("\n");
123 } else {
Andrea Campanellaf8b53192018-03-08 11:12:05 -0800124 tracePrint.append(String.format(" flowId=%s, table=%s, selector=%s", f.id(), f.table(),
Andrea Campanella55c3f422018-02-08 17:10:11 +0100125 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) {
Andrea Campanellaf8b53192018-03-08 11:12:05 -0800137 tracePrint.append(" Groups");
Andrea Campanella55c3f422018-02-08 17:10:11 +0100138 tracePrint.append("\n");
139 groupsInDevice.forEach(output -> {
140 if (output.getOutput().equals(connectPoint)) {
141 output.getGroups().forEach(group -> {
142 if (verbose) {
Andrea Campanellaf8b53192018-03-08 11:12:05 -0800143 tracePrint.append(" " + String.format(GROUP_FORMAT, Integer.toHexString(group.id().id()),
Andrea Campanella55c3f422018-02-08 17:10:11 +0100144 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()) {
Andrea Campanellaf8b53192018-03-08 11:12:05 -0800149 tracePrint.append(" " + String.format(GROUP_BUCKET_FORMAT,
Andrea Campanella55c3f422018-02-08 17:10:11 +0100150 Integer.toHexString(group.id().id()),
151 ++i, bucket.bytes(), bucket.packets(),
152 bucket.treatment().allInstructions()));
153 tracePrint.append("\n");
154 }
155 } else {
Andrea Campanellaf8b53192018-03-08 11:12:05 -0800156 tracePrint.append(" groupId=" + group.id());
Andrea Campanella55c3f422018-02-08 17:10:11 +0100157 tracePrint.append("\n");
158 }
159 });
Andrea Campanellaf8b53192018-03-08 11:12:05 -0800160 tracePrint.append(" Outgoing Packet " + output.getFinalPacket());
Andrea Campanella55c3f422018-02-08 17:10:11 +0100161 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}