blob: e2375a787eb834f303b7a21477600adf4ef3d392 [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) {
114 tracePrint.append("Flows");
115 tracePrint.append("\n");
116 trace.getFlowsForDevice(connectPoint.deviceId()).forEach(f -> {
117 if (verbose) {
118 tracePrint.append(String.format(FLOW_SHORT_FORMAT, f.state(), f.bytes(), f.packets(),
119 f.table(), f.priority(), f.selector().criteria(),
120 printTreatment(f.treatment())));
121 tracePrint.append("\n");
122 } else {
123 tracePrint.append(String.format(" flowId=%s, table=%s, selector=%s", f.id(), f.table(),
124 f.selector().criteria()));
125 tracePrint.append("\n");
126 }
127 });
128 return tracePrint;
129 }
130
131 //Prints the groups for a given trace and a specified level of verbosity
132 private static StringBuilder printGroups(StaticPacketTrace trace, boolean verbose, ConnectPoint connectPoint,
133 StringBuilder tracePrint) {
134 List<GroupsInDevice> groupsInDevice = trace.getGroupOuputs(connectPoint.deviceId());
135 if (groupsInDevice != null) {
136 tracePrint.append("Groups");
137 tracePrint.append("\n");
138 groupsInDevice.forEach(output -> {
139 if (output.getOutput().equals(connectPoint)) {
140 output.getGroups().forEach(group -> {
141 if (verbose) {
142 tracePrint.append(String.format(GROUP_FORMAT, Integer.toHexString(group.id().id()),
143 group.state(), group.type(), group.bytes(), group.packets(),
144 group.appId().name(), group.referenceCount()));
145 tracePrint.append("\n");
146 int i = 0;
147 for (GroupBucket bucket : group.buckets().buckets()) {
148 tracePrint.append(String.format(GROUP_BUCKET_FORMAT,
149 Integer.toHexString(group.id().id()),
150 ++i, bucket.bytes(), bucket.packets(),
151 bucket.treatment().allInstructions()));
152 tracePrint.append("\n");
153 }
154 } else {
155 tracePrint.append(" groupId=" + group.id());
156 tracePrint.append("\n");
157 }
158 });
159 tracePrint.append("Outgoing Packet " + output.getFinalPacket());
160 tracePrint.append("\n");
161 }
162 });
163 }
164 return tracePrint;
165 }
166
167 private static String printTreatment(TrafficTreatment treatment) {
168 final String delimiter = ", ";
169 StringBuilder builder = new StringBuilder("[");
170 if (!treatment.immediate().isEmpty()) {
171 builder.append("immediate=" + treatment.immediate() + delimiter);
172 }
173 if (!treatment.deferred().isEmpty()) {
174 builder.append("deferred=" + treatment.deferred() + delimiter);
175 }
176 if (treatment.clearedDeferred()) {
177 builder.append("clearDeferred" + delimiter);
178 }
179 if (treatment.tableTransition() != null) {
180 builder.append("transition=" + treatment.tableTransition() + delimiter);
181 }
182 if (treatment.metered() != null) {
183 builder.append("meter=" + treatment.metered() + delimiter);
184 }
185 if (treatment.writeMetadata() != null) {
186 builder.append("metadata=" + treatment.writeMetadata() + delimiter);
187 }
188 // Chop off last delimiter
189 builder.replace(builder.length() - delimiter.length(), builder.length(), "");
190 builder.append("]");
191 return builder.toString();
192 }
193}