Ray Milkey
Committed by Gerrit Code Review

Add bulk delete for flows

Change-Id: I77f266c75d0f9d1e99155eb48c216bff3fab2f40
...@@ -18,6 +18,8 @@ package org.onosproject.rest.resources; ...@@ -18,6 +18,8 @@ package org.onosproject.rest.resources;
18 import com.fasterxml.jackson.databind.JsonNode; 18 import com.fasterxml.jackson.databind.JsonNode;
19 import com.fasterxml.jackson.databind.node.ArrayNode; 19 import com.fasterxml.jackson.databind.node.ArrayNode;
20 import com.fasterxml.jackson.databind.node.ObjectNode; 20 import com.fasterxml.jackson.databind.node.ObjectNode;
21 +import com.google.common.collect.ArrayListMultimap;
22 +import com.google.common.collect.ListMultimap;
21 import org.onlab.util.ItemNotFoundException; 23 import org.onlab.util.ItemNotFoundException;
22 import org.onosproject.net.Device; 24 import org.onosproject.net.Device;
23 import org.onosproject.net.DeviceId; 25 import org.onosproject.net.DeviceId;
...@@ -41,9 +43,12 @@ import javax.ws.rs.core.UriBuilder; ...@@ -41,9 +43,12 @@ import javax.ws.rs.core.UriBuilder;
41 import javax.ws.rs.core.UriInfo; 43 import javax.ws.rs.core.UriInfo;
42 import java.io.IOException; 44 import java.io.IOException;
43 import java.io.InputStream; 45 import java.io.InputStream;
46 +import java.util.ArrayList;
44 import java.util.List; 47 import java.util.List;
45 import java.util.stream.StreamSupport; 48 import java.util.stream.StreamSupport;
46 49
50 +import static org.onlab.util.Tools.nullIsNotFound;
51 +
47 /** 52 /**
48 * Query and program flow rules. 53 * Query and program flow rules.
49 */ 54 */
...@@ -55,7 +60,10 @@ public class FlowsWebResource extends AbstractWebResource { ...@@ -55,7 +60,10 @@ public class FlowsWebResource extends AbstractWebResource {
55 UriInfo uriInfo; 60 UriInfo uriInfo;
56 61
57 public static final String DEVICE_NOT_FOUND = "Device is not found"; 62 public static final String DEVICE_NOT_FOUND = "Device is not found";
63 + public static final String FLOW_NOT_FOUND = "Flow is not found";
58 public static final String FLOWS = "flows"; 64 public static final String FLOWS = "flows";
65 + public static final String DEVICE_ID = "deviceId";
66 + public static final String FLOW_ID = "flowId";
59 67
60 final FlowRuleService service = get(FlowRuleService.class); 68 final FlowRuleService service = get(FlowRuleService.class);
61 final ObjectNode root = mapper().createObjectNode(); 69 final ObjectNode root = mapper().createObjectNode();
...@@ -104,10 +112,16 @@ public class FlowsWebResource extends AbstractWebResource { ...@@ -104,10 +112,16 @@ public class FlowsWebResource extends AbstractWebResource {
104 ArrayNode flowsArray = (ArrayNode) jsonTree.get(FLOWS); 112 ArrayNode flowsArray = (ArrayNode) jsonTree.get(FLOWS);
105 List<FlowRule> rules = codec(FlowRule.class).decode(flowsArray, this); 113 List<FlowRule> rules = codec(FlowRule.class).decode(flowsArray, this);
106 service.applyFlowRules(rules.toArray(new FlowRule[rules.size()])); 114 service.applyFlowRules(rules.toArray(new FlowRule[rules.size()]));
115 + rules.forEach(flowRule -> {
116 + ObjectNode flowNode = mapper().createObjectNode();
117 + flowNode.put(DEVICE_ID, flowRule.deviceId().toString())
118 + .put(FLOW_ID, flowRule.id().value());
119 + flowsNode.add(flowNode);
120 + });
107 } catch (IOException ex) { 121 } catch (IOException ex) {
108 throw new IllegalArgumentException(ex); 122 throw new IllegalArgumentException(ex);
109 } 123 }
110 - return Response.ok().build(); 124 + return Response.ok(root).build();
111 } 125 }
112 126
113 /** 127 /**
...@@ -228,4 +242,45 @@ public class FlowsWebResource extends AbstractWebResource { ...@@ -228,4 +242,45 @@ public class FlowsWebResource extends AbstractWebResource {
228 .forEach(service::removeFlowRules); 242 .forEach(service::removeFlowRules);
229 } 243 }
230 244
245 + /**
246 + * Removes a batch of flow rules.
247 + */
248 + @DELETE
249 + @Produces(MediaType.APPLICATION_JSON)
250 + public void deleteFlows(InputStream stream) {
251 + ListMultimap<DeviceId, Long> deviceMap = ArrayListMultimap.create();
252 + List<FlowEntry> rulesToRemove = new ArrayList<>();
253 +
254 + try {
255 + ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
256 +
257 + JsonNode jsonFlows = jsonTree.get("flows");
258 +
259 + jsonFlows.forEach(node -> {
260 + DeviceId deviceId =
261 + DeviceId.deviceId(
262 + nullIsNotFound(node.get(DEVICE_ID),
263 + DEVICE_NOT_FOUND).asText());
264 + long flowId = nullIsNotFound(node.get(FLOW_ID),
265 + FLOW_NOT_FOUND).asLong();
266 + deviceMap.put(deviceId, flowId);
267 +
268 + });
269 + } catch (IOException ex) {
270 + throw new IllegalArgumentException(ex);
271 + }
272 +
273 + deviceMap.keySet().forEach(deviceId -> {
274 + List<Long> flowIds = deviceMap.get(deviceId);
275 + Iterable<FlowEntry> entries = service.getFlowEntries(deviceId);
276 + flowIds.forEach(flowId -> {
277 + StreamSupport.stream(entries.spliterator(), false)
278 + .filter(entry -> flowId == entry.id().value())
279 + .forEach(rulesToRemove::add);
280 + });
281 + });
282 +
283 + service.removeFlowRules(rulesToRemove.toArray(new FlowEntry[0]));
284 + }
285 +
231 } 286 }
......