Ray Milkey

Add bulk delete for flows

Change-Id: I77f266c75d0f9d1e99155eb48c216bff3fab2f40
......@@ -19,6 +19,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.StreamSupport;
......@@ -44,6 +45,10 @@ import org.onosproject.rest.AbstractWebResource;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import static org.onlab.util.Tools.nullIsNotFound;
/**
* Query and program flow rules.
......@@ -53,7 +58,10 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
public class FlowsWebResource extends AbstractWebResource {
public static final String DEVICE_NOT_FOUND = "Device is not found";
public static final String FLOW_NOT_FOUND = "Flow is not found";
public static final String FLOWS = "flows";
public static final String DEVICE_ID = "deviceId";
public static final String FLOW_ID = "flowId";
final FlowRuleService service = get(FlowRuleService.class);
final ObjectNode root = mapper().createObjectNode();
......@@ -102,10 +110,16 @@ public class FlowsWebResource extends AbstractWebResource {
ArrayNode flowsArray = (ArrayNode) jsonTree.get(FLOWS);
List<FlowRule> rules = codec(FlowRule.class).decode(flowsArray, this);
service.applyFlowRules(rules.toArray(new FlowRule[rules.size()]));
rules.forEach(flowRule -> {
ObjectNode flowNode = mapper().createObjectNode();
flowNode.put(DEVICE_ID, flowRule.deviceId().toString())
.put(FLOW_ID, flowRule.id().value());
flowsNode.add(flowNode);
});
} catch (IOException ex) {
throw new IllegalArgumentException(ex);
}
return Response.ok().build();
return Response.ok(root).build();
}
/**
......@@ -224,4 +238,45 @@ public class FlowsWebResource extends AbstractWebResource {
.forEach(service::removeFlowRules);
}
/**
* Removes a batch of flow rules.
*/
@DELETE
@Produces(MediaType.APPLICATION_JSON)
public void deleteFlows(InputStream stream) {
ListMultimap<DeviceId, Long> deviceMap = ArrayListMultimap.create();
List<FlowEntry> rulesToRemove = new ArrayList<>();
try {
ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
JsonNode jsonFlows = jsonTree.get("flows");
jsonFlows.forEach(node -> {
DeviceId deviceId =
DeviceId.deviceId(
nullIsNotFound(node.get(DEVICE_ID),
DEVICE_NOT_FOUND).asText());
long flowId = nullIsNotFound(node.get(FLOW_ID),
FLOW_NOT_FOUND).asLong();
deviceMap.put(deviceId, flowId);
});
} catch (IOException ex) {
throw new IllegalArgumentException(ex);
}
deviceMap.keySet().forEach(deviceId -> {
List<Long> flowIds = deviceMap.get(deviceId);
Iterable<FlowEntry> entries = service.getFlowEntries(deviceId);
flowIds.forEach(flowId -> {
StreamSupport.stream(entries.spliterator(), false)
.filter(entry -> flowId == entry.id().value())
.forEach(rulesToRemove::add);
});
});
service.removeFlowRules(rulesToRemove.toArray(new FlowEntry[0]));
}
}
......