Andrea Campanella
Committed by Gerrit Code Review

ONOS-3562 Changing the flow instructions port to human readable format

Change-Id: Ia6b1a755bc400295600f4112cb3ebe676e533eb2
...@@ -15,18 +15,19 @@ ...@@ -15,18 +15,19 @@
15 */ 15 */
16 package org.onosproject.net; 16 package org.onosproject.net;
17 17
18 -import static com.google.common.base.Preconditions.checkArgument;
19 -import static com.google.common.base.Preconditions.checkNotNull;
20 -
21 -import java.util.Map;
22 -import java.util.regex.Matcher;
23 -import java.util.regex.Pattern;
24 import com.google.common.base.Supplier; 18 import com.google.common.base.Supplier;
25 import com.google.common.base.Suppliers; 19 import com.google.common.base.Suppliers;
26 import com.google.common.collect.ImmutableMap; 20 import com.google.common.collect.ImmutableMap;
27 import com.google.common.collect.ImmutableMap.Builder; 21 import com.google.common.collect.ImmutableMap.Builder;
28 import com.google.common.primitives.UnsignedLongs; 22 import com.google.common.primitives.UnsignedLongs;
29 23
24 +import java.util.Map;
25 +import java.util.regex.Matcher;
26 +import java.util.regex.Pattern;
27 +
28 +import static com.google.common.base.Preconditions.checkArgument;
29 +import static com.google.common.base.Preconditions.checkNotNull;
30 +
30 /** 31 /**
31 * Representation of a port number. 32 * Representation of a port number.
32 */ 33 */
...@@ -67,6 +68,7 @@ public final class PortNumber { ...@@ -67,6 +68,7 @@ public final class PortNumber {
67 68
68 /** 69 /**
69 * PortNumber instance for the logical port. 70 * PortNumber instance for the logical port.
71 + *
70 * @return {@link PortNumber} 72 * @return {@link PortNumber}
71 */ 73 */
72 public PortNumber instance() { 74 public PortNumber instance() {
...@@ -145,6 +147,38 @@ public final class PortNumber { ...@@ -145,6 +147,38 @@ public final class PortNumber {
145 } 147 }
146 148
147 /** 149 /**
150 + * Returns PortNumber instance from String representation.
151 + *
152 + * @param s String representation equivalent to {@link PortNumber#toString()}
153 + * @return {@link PortNumber} instance
154 + * @throws IllegalArgumentException if given String was malformed
155 + */
156 + public static PortNumber fromString(String s) {
157 + checkNotNull(s);
158 + checkArgument(!s.isEmpty(), "cannot be empty");
159 +
160 + if (isAsciiDecimal(s.charAt(0))) {
161 + // unsigned decimal string
162 + return portNumber(s);
163 + } else if (s.startsWith("[")) {
164 + // named PortNumber
165 + Matcher matcher = NAMED.matcher(s);
166 + checkArgument(matcher.matches(), "Invalid named PortNumber %s", s);
167 +
168 + String name = matcher.group("name");
169 + String num = matcher.group("num");
170 + return portNumber(UnsignedLongs.parseUnsignedLong(num), name);
171 + }
172 +
173 + // Logical
174 + if (s.startsWith("UNKNOWN(") && s.endsWith(")")) {
175 + return portNumber(s.substring("UNKNOWN(".length(), s.length() - 1));
176 + } else {
177 + return Logical.valueOf(s).instance;
178 + }
179 + }
180 +
181 + /**
148 * Indicates whether or not this port number is a reserved logical one or 182 * Indicates whether or not this port number is a reserved logical one or
149 * whether it corresponds to a normal physical port of a device or NIC. 183 * whether it corresponds to a normal physical port of a device or NIC.
150 * 184 *
...@@ -207,38 +241,6 @@ public final class PortNumber { ...@@ -207,38 +241,6 @@ public final class PortNumber {
207 return '0' <= c && c <= '9'; 241 return '0' <= c && c <= '9';
208 } 242 }
209 243
210 - /**
211 - * Returns PortNumber instance from String representation.
212 - *
213 - * @param s String representation equivalent to {@link PortNumber#toString()}
214 - * @return {@link PortNumber} instance
215 - * @throws IllegalArgumentException if given String was malformed
216 - */
217 - public static PortNumber fromString(String s) {
218 - checkNotNull(s);
219 - checkArgument(!s.isEmpty(), "cannot be empty");
220 -
221 - if (isAsciiDecimal(s.charAt(0))) {
222 - // unsigned decimal string
223 - return portNumber(s);
224 - } else if (s.startsWith("[")) {
225 - // named PortNumber
226 - Matcher matcher = NAMED.matcher(s);
227 - checkArgument(matcher.matches(), "Invalid named PortNumber %s", s);
228 -
229 - String name = matcher.group("name");
230 - String num = matcher.group("num");
231 - return portNumber(UnsignedLongs.parseUnsignedLong(num), name);
232 - }
233 -
234 - // Logical
235 - if (s.startsWith("UNKNOWN(") && s.endsWith(")")) {
236 - return portNumber(s.substring("UNKNOWN(".length(), s.length() - 1));
237 - } else {
238 - return Logical.valueOf(s).instance;
239 - }
240 - }
241 -
242 @Override 244 @Override
243 public String toString() { 245 public String toString() {
244 if (isLogical()) { 246 if (isLogical()) {
......
...@@ -240,9 +240,22 @@ public final class DecodeInstructionCodecHelper { ...@@ -240,9 +240,22 @@ public final class DecodeInstructionCodecHelper {
240 String type = json.get(InstructionCodec.TYPE).asText(); 240 String type = json.get(InstructionCodec.TYPE).asText();
241 241
242 if (type.equals(Instruction.Type.OUTPUT.name())) { 242 if (type.equals(Instruction.Type.OUTPUT.name())) {
243 - PortNumber portNumber = 243 + PortNumber portNumber;
244 - PortNumber.portNumber(nullIsIllegal(json.get(InstructionCodec.PORT), 244 + if (json.get(InstructionCodec.PORT).isLong() || json.get(InstructionCodec.PORT).isInt()) {
245 - InstructionCodec.PORT + InstructionCodec.MISSING_MEMBER_MESSAGE).asLong()); 245 + portNumber = PortNumber
246 + .portNumber(nullIsIllegal(json.get(InstructionCodec.PORT)
247 + .asLong(), InstructionCodec.PORT
248 + + InstructionCodec.MISSING_MEMBER_MESSAGE));
249 + } else if (json.get(InstructionCodec.PORT).isTextual()) {
250 + portNumber = PortNumber
251 + .fromString(nullIsIllegal(json.get(InstructionCodec.PORT)
252 + .textValue(), InstructionCodec.PORT
253 + + InstructionCodec.MISSING_MEMBER_MESSAGE));
254 + } else {
255 + throw new IllegalArgumentException("Port value "
256 + + json.get(InstructionCodec.PORT).toString()
257 + + " is not supported");
258 + }
246 return Instructions.createOutput(portNumber); 259 return Instructions.createOutput(portNumber);
247 } else if (type.equals(Instruction.Type.DROP.name())) { 260 } else if (type.equals(Instruction.Type.DROP.name())) {
248 return Instructions.createDrop(); 261 return Instructions.createDrop();
......
...@@ -87,8 +87,6 @@ public final class EncodeInstructionCodecHelper { ...@@ -87,8 +87,6 @@ public final class EncodeInstructionCodecHelper {
87 * Encode an L1 modification instruction. 87 * Encode an L1 modification instruction.
88 * 88 *
89 * @param result json node that the instruction attributes are added to 89 * @param result json node that the instruction attributes are added to
90 - * @param instruction The L1 instruction
91 - * @param context context of the request
92 */ 90 */
93 private void encodeL1(ObjectNode result) { 91 private void encodeL1(ObjectNode result) {
94 L1ModificationInstruction instruction = 92 L1ModificationInstruction instruction =
...@@ -244,7 +242,7 @@ public final class EncodeInstructionCodecHelper { ...@@ -244,7 +242,7 @@ public final class EncodeInstructionCodecHelper {
244 case OUTPUT: 242 case OUTPUT:
245 final Instructions.OutputInstruction outputInstruction = 243 final Instructions.OutputInstruction outputInstruction =
246 (Instructions.OutputInstruction) instruction; 244 (Instructions.OutputInstruction) instruction;
247 - result.put(InstructionCodec.PORT, outputInstruction.port().toLong()); 245 + result.put(InstructionCodec.PORT, outputInstruction.port().toString());
248 break; 246 break;
249 247
250 case DROP: 248 case DROP:
......
...@@ -93,19 +93,32 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json ...@@ -93,19 +93,32 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json
93 */ 93 */
94 private boolean matchOutputInstruction(JsonNode instructionJson, 94 private boolean matchOutputInstruction(JsonNode instructionJson,
95 Description description) { 95 Description description) {
96 - OutputInstruction instructionToMatch = (OutputInstruction) instruction;
97 -
98 final String jsonType = instructionJson.get("type").textValue(); 96 final String jsonType = instructionJson.get("type").textValue();
97 + OutputInstruction instructionToMatch = (OutputInstruction) instruction;
99 if (!instructionToMatch.type().name().equals(jsonType)) { 98 if (!instructionToMatch.type().name().equals(jsonType)) {
100 description.appendText("type was " + jsonType); 99 description.appendText("type was " + jsonType);
101 return false; 100 return false;
102 } 101 }
103 102
103 + if (instructionJson.get("port").isLong() ||
104 + instructionJson.get("port").isInt()) {
104 final long jsonPort = instructionJson.get("port").asLong(); 105 final long jsonPort = instructionJson.get("port").asLong();
105 - if (instructionToMatch.port().toLong() != jsonPort) { 106 + if (instructionToMatch.port().toLong() != (jsonPort)) {
106 description.appendText("port was " + jsonPort); 107 description.appendText("port was " + jsonPort);
107 return false; 108 return false;
108 } 109 }
110 + } else if (instructionJson.get("port").isTextual()) {
111 + final String jsonPort = instructionJson.get("port").textValue();
112 + if (!instructionToMatch.port().toString().equals(jsonPort)) {
113 + description.appendText("port was " + jsonPort);
114 + return false;
115 + }
116 + } else {
117 + final String jsonPort = instructionJson.get("port").toString();
118 + description.appendText("Unmathcing types ");
119 + description.appendText("instructionToMatch " + instructionToMatch.port().toString());
120 + description.appendText("jsonPort " + jsonPort);
121 + }
109 122
110 return true; 123 return true;
111 } 124 }
......
...@@ -118,9 +118,8 @@ ...@@ -118,9 +118,8 @@
118 "example": "OUTPUT" 118 "example": "OUTPUT"
119 }, 119 },
120 "port": { 120 "port": {
121 - "type": "integer", 121 + "type": "string",
122 - "format": "int64", 122 + "example": "CONTROLLER"
123 - "example": -3
124 } 123 }
125 } 124 }
126 } 125 }
......
...@@ -54,9 +54,8 @@ ...@@ -54,9 +54,8 @@
54 "example": "OUTPUT" 54 "example": "OUTPUT"
55 }, 55 },
56 "port": { 56 "port": {
57 - "type": "integer", 57 + "type": "string",
58 - "format": "int64", 58 + "example": "CONTROLLER"
59 - "example": -3
60 } 59 }
61 } 60 }
62 } 61 }
......
...@@ -55,6 +55,7 @@ import org.onosproject.net.flow.TrafficTreatment; ...@@ -55,6 +55,7 @@ import org.onosproject.net.flow.TrafficTreatment;
55 import org.onosproject.net.flow.criteria.Criterion; 55 import org.onosproject.net.flow.criteria.Criterion;
56 import org.onosproject.net.flow.instructions.Instruction; 56 import org.onosproject.net.flow.instructions.Instruction;
57 import org.onosproject.net.flow.instructions.Instructions; 57 import org.onosproject.net.flow.instructions.Instructions;
58 +import org.onosproject.rest.resources.CoreWebApplication;
58 59
59 import javax.ws.rs.core.MediaType; 60 import javax.ws.rs.core.MediaType;
60 import java.io.InputStream; 61 import java.io.InputStream;
...@@ -251,6 +252,10 @@ public class FlowsResourceTest extends ResourceTest { ...@@ -251,6 +252,10 @@ public class FlowsResourceTest extends ResourceTest {
251 .andReturn(rules.get(deviceId2)).anyTimes(); 252 .andReturn(rules.get(deviceId2)).anyTimes();
252 } 253 }
253 254
255 + public FlowsResourceTest() {
256 + super(CoreWebApplication.class);
257 + }
258 +
254 /** 259 /**
255 * Sets up the global values for all the tests. 260 * Sets up the global values for all the tests.
256 */ 261 */
......