blob: 0086255ba83586d4eb3e37d7c804a1deaa1c5ae3 [file] [log] [blame]
Ray Milkeyd03eda02015-01-09 14:58:48 -08001/*
2 * Copyright 2015 Open Networking Laboratory
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 */
16package org.onosproject.codec.impl;
17
18import org.hamcrest.Description;
Ray Milkeyd03eda02015-01-09 14:58:48 -080019import org.hamcrest.TypeSafeDiagnosingMatcher;
20import org.onosproject.net.flow.instructions.Instruction;
21
22import com.fasterxml.jackson.databind.JsonNode;
23
Ray Milkeyd03eda02015-01-09 14:58:48 -080024import static org.onosproject.net.flow.instructions.Instructions.*;
25import static org.onosproject.net.flow.instructions.L0ModificationInstruction.*;
26import static org.onosproject.net.flow.instructions.L2ModificationInstruction.*;
27import static org.onosproject.net.flow.instructions.L3ModificationInstruction.*;
28
29/**
30 * Hamcrest matcher for instructions.
31 */
Ray Milkeydb358082015-01-13 16:34:38 -080032public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {
Ray Milkeyd03eda02015-01-09 14:58:48 -080033
34 private final Instruction instruction;
35
Ray Milkeydb358082015-01-13 16:34:38 -080036 private InstructionJsonMatcher(Instruction instructionValue) {
Ray Milkeyd03eda02015-01-09 14:58:48 -080037 instruction = instructionValue;
38 }
39
40 /**
41 * Matches the contents of a push header instruction.
42 *
43 * @param instructionJson JSON instruction to match
44 * @return true if contents match, false otherwise
45 */
46 private boolean matchPushHeaderInstruction(JsonNode instructionJson,
47 Description description) {
48 PushHeaderInstructions instructionToMatch =
49 (PushHeaderInstructions) instruction;
50 final String jsonSubtype = instructionJson.get("subtype").textValue();
51 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
52 description.appendText("subtype was " + jsonSubtype);
53 return false;
54 }
55
56 final String jsonType = instructionJson.get("type").textValue();
57 if (!instructionToMatch.type().name().equals(jsonType)) {
58 description.appendText("type was " + jsonType);
59 return false;
60 }
61
62 final JsonNode ethJson = instructionJson.get("ethernetType");
63 if (ethJson == null) {
64 description.appendText("ethernetType was not null");
65 return false;
66 }
67
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -080068 if (instructionToMatch.ethernetType() != ethJson.asInt()) {
69 description.appendText("ethernetType was " + ethJson);
Ray Milkeyd03eda02015-01-09 14:58:48 -080070 return false;
71 }
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -080072
Ray Milkeyd03eda02015-01-09 14:58:48 -080073 return true;
74 }
75
76 /**
77 * Matches the contents of an output instruction.
78 *
79 * @param instructionJson JSON instruction to match
80 * @return true if contents match, false otherwise
81 */
82 private boolean matchOutputInstruction(JsonNode instructionJson,
83 Description description) {
84 OutputInstruction instructionToMatch = (OutputInstruction) instruction;
85
86 final String jsonType = instructionJson.get("type").textValue();
87 if (!instructionToMatch.type().name().equals(jsonType)) {
88 description.appendText("type was " + jsonType);
89 return false;
90 }
91
92 final long jsonPort = instructionJson.get("port").asLong();
93 if (instructionToMatch.port().toLong() != jsonPort) {
94 description.appendText("port was " + jsonPort);
95 return false;
96 }
97
98 return true;
99 }
100
101 /**
102 * Matches the contents of a mod lambda instruction.
103 *
104 * @param instructionJson JSON instruction to match
105 * @return true if contents match, false otherwise
106 */
107 private boolean matchModLambdaInstruction(JsonNode instructionJson,
108 Description description) {
109 ModLambdaInstruction instructionToMatch =
110 (ModLambdaInstruction) instruction;
111 final String jsonSubtype = instructionJson.get("subtype").textValue();
112 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
113 description.appendText("subtype was " + jsonSubtype);
114 return false;
115 }
116
117 final String jsonType = instructionJson.get("type").textValue();
118 if (!instructionToMatch.type().name().equals(jsonType)) {
119 description.appendText("type was " + jsonType);
120 return false;
121 }
122
123 final long jsonLambda = instructionJson.get("lambda").shortValue();
124 if (instructionToMatch.lambda() != jsonLambda) {
125 description.appendText("lambda was " + jsonLambda);
126 return false;
127 }
128
129 return true;
130 }
131
132 /**
Ray Milkeydb358082015-01-13 16:34:38 -0800133 * Matches the contents of a mod Ethernet instruction.
Ray Milkeyd03eda02015-01-09 14:58:48 -0800134 *
135 * @param instructionJson JSON instruction to match
136 * @return true if contents match, false otherwise
137 */
138 private boolean matchModEtherInstruction(JsonNode instructionJson,
139 Description description) {
140 ModEtherInstruction instructionToMatch =
141 (ModEtherInstruction) instruction;
142 final String jsonSubtype = instructionJson.get("subtype").textValue();
143 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
144 description.appendText("subtype was " + jsonSubtype);
145 return false;
146 }
147
148 final String jsonType = instructionJson.get("type").textValue();
149 if (!instructionToMatch.type().name().equals(jsonType)) {
150 description.appendText("type was " + jsonType);
151 return false;
152 }
153
154 final String jsonMac = instructionJson.get("mac").textValue();
155 final String mac = instructionToMatch.mac().toString();
156 if (!mac.equals(jsonMac)) {
157 description.appendText("mac was " + jsonMac);
158 return false;
159 }
160
161 return true;
162 }
163
164 /**
165 * Matches the contents of a mod vlan id instruction.
166 *
167 * @param instructionJson JSON instruction to match
168 * @return true if contents match, false otherwise
169 */
170 private boolean matchModVlanIdInstruction(JsonNode instructionJson,
171 Description description) {
172 ModVlanIdInstruction instructionToMatch =
173 (ModVlanIdInstruction) instruction;
174 final String jsonSubtype = instructionJson.get("subtype").textValue();
175 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
176 description.appendText("subtype was " + jsonSubtype);
177 return false;
178 }
179
180 final String jsonType = instructionJson.get("type").textValue();
181 if (!instructionToMatch.type().name().equals(jsonType)) {
182 description.appendText("type was " + jsonType);
183 return false;
184 }
185
186 final short jsonVlanId = instructionJson.get("vlanId").shortValue();
187 final short vlanId = instructionToMatch.vlanId().toShort();
188 if (jsonVlanId != vlanId) {
189 description.appendText("vlan id was " + jsonVlanId);
190 return false;
191 }
192
193 return true;
194 }
195
196 /**
197 * Matches the contents of a mod vlan pcp instruction.
198 *
199 * @param instructionJson JSON instruction to match
200 * @return true if contents match, false otherwise
201 */
202 private boolean matchModVlanPcpInstruction(JsonNode instructionJson,
203 Description description) {
204 ModVlanPcpInstruction instructionToMatch =
205 (ModVlanPcpInstruction) instruction;
206 final String jsonSubtype = instructionJson.get("subtype").textValue();
207 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
208 description.appendText("subtype was " + jsonSubtype);
209 return false;
210 }
211
212 final String jsonType = instructionJson.get("type").textValue();
213 if (!instructionToMatch.type().name().equals(jsonType)) {
214 description.appendText("type was " + jsonType);
215 return false;
216 }
217
218 final short jsonVlanPcp = instructionJson.get("vlanPcp").shortValue();
219 final short vlanId = instructionToMatch.vlanPcp();
220 if (jsonVlanPcp != vlanId) {
221 description.appendText("vlan pcp was " + jsonVlanPcp);
222 return false;
223 }
224
225 return true;
226 }
227
228 /**
229 * Matches the contents of a mod ip instruction.
230 *
231 * @param instructionJson JSON instruction to match
232 * @return true if contents match, false otherwise
233 */
234 private boolean matchModIpInstruction(JsonNode instructionJson,
235 Description description) {
236 ModIPInstruction instructionToMatch =
237 (ModIPInstruction) instruction;
238 final String jsonSubtype = instructionJson.get("subtype").textValue();
239 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
240 description.appendText("subtype was " + jsonSubtype);
241 return false;
242 }
243
244 final String jsonType = instructionJson.get("type").textValue();
245 if (!instructionToMatch.type().name().equals(jsonType)) {
246 description.appendText("type was " + jsonType);
247 return false;
248 }
249
250 final String jsonIp = instructionJson.get("ip").textValue();
251 final String ip = instructionToMatch.ip().toString();
252 if (!ip.equals(jsonIp)) {
253 description.appendText("ip was " + jsonIp);
254 return false;
255 }
256
257 return true;
258 }
259
260 /**
Ray Milkeydb358082015-01-13 16:34:38 -0800261 * Matches the contents of a mod MPLS label instruction.
Ray Milkeyd03eda02015-01-09 14:58:48 -0800262 *
263 * @param instructionJson JSON instruction to match
264 * @return true if contents match, false otherwise
265 */
266 private boolean matchModMplsLabelInstruction(JsonNode instructionJson,
267 Description description) {
268 ModMplsLabelInstruction instructionToMatch =
269 (ModMplsLabelInstruction) instruction;
270 final String jsonSubtype = instructionJson.get("subtype").textValue();
271 if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
272 description.appendText("subtype was " + jsonSubtype);
273 return false;
274 }
275
276 final String jsonType = instructionJson.get("type").textValue();
277 if (!instructionToMatch.type().name().equals(jsonType)) {
278 description.appendText("type was " + jsonType);
279 return false;
280 }
281
282 final int jsonLabel = instructionJson.get("label").intValue();
283 final int label = instructionToMatch.label();
284 if (label != jsonLabel) {
285 description.appendText("ip was " + jsonLabel);
286 return false;
287 }
288
289 return true;
290 }
291
292 @Override
293 public boolean matchesSafely(JsonNode jsonInstruction, Description description) {
294
295 // check type
296 final JsonNode jsonTypeNode = jsonInstruction.get("type");
297 final String jsonType = jsonTypeNode.textValue();
298 final String type = instruction.type().name();
299 if (!jsonType.equals(type)) {
300 description.appendText("type was " + type);
301 return false;
302 }
303
304 if (instruction instanceof PushHeaderInstructions) {
305 return matchPushHeaderInstruction(jsonInstruction, description);
306 } else if (instruction instanceof DropInstruction) {
307 return true;
308 } else if (instruction instanceof OutputInstruction) {
309 return matchOutputInstruction(jsonInstruction, description);
310 } else if (instruction instanceof ModLambdaInstruction) {
311 return matchModLambdaInstruction(jsonInstruction, description);
312 } else if (instruction instanceof ModEtherInstruction) {
313 return matchModEtherInstruction(jsonInstruction, description);
314 } else if (instruction instanceof ModVlanIdInstruction) {
315 return matchModVlanIdInstruction(jsonInstruction, description);
316 } else if (instruction instanceof ModVlanPcpInstruction) {
317 return matchModVlanPcpInstruction(jsonInstruction, description);
318 } else if (instruction instanceof ModIPInstruction) {
319 return matchModIpInstruction(jsonInstruction, description);
320 } else if (instruction instanceof ModMplsLabelInstruction) {
321 return matchModMplsLabelInstruction(jsonInstruction, description);
322 }
323
324 return false;
325 }
326
327 @Override
328 public void describeTo(Description description) {
329 description.appendText(instruction.toString());
330 }
331
332 /**
333 * Factory to allocate an instruction matcher.
334 *
335 * @param instruction instruction object we are looking for
336 * @return matcher
337 */
338 public static InstructionJsonMatcher matchesInstruction(Instruction instruction) {
339 return new InstructionJsonMatcher(instruction);
340 }
341}