Committed by
Gerrit Code Review
Implementation of new Flow Subsystem:
The subsystem no longer returns futures for tracking completion of work. Notifications are explicitely returned via a call back mechanism. Also, the subsystem is now asynchronous. Change-Id: I1a4cef931c24820f9ae9ed9a5398f163f05dfbc9 more flowservice improvements Change-Id: I5c9c1b6be4b2ebfa523b64f6f52e7634b7d3e05f more flowservice impl Change-Id: I05f6774460effb53ced8c36844bcda2f8f6c096f Manager to store functional (at least i believe it) Change-Id: I09b04989bd1004c98fe0bafed4c76714b9155d53 flow subsystem functional: need to fix unit tests Change-Id: I1667f25b91320f625a03e5e1d5e92823184d9de0 flow subsystem functional Change-Id: I429b3335c16d4fc16f5d55f233dd37c4d1d6111d finished refactor of flow subsystem Change-Id: I1899abc6ff6a974a2018d936cc555049c70a6804 fix for null flow provider to use new api Change-Id: If2fd9bd5baf74d9c61c5c8085cef8bc2d204cbdc
Showing
34 changed files
with
648 additions
and
228 deletions
... | @@ -19,29 +19,30 @@ package org.onosproject.cli.net; | ... | @@ -19,29 +19,30 @@ package org.onosproject.cli.net; |
19 | import com.fasterxml.jackson.databind.ObjectMapper; | 19 | import com.fasterxml.jackson.databind.ObjectMapper; |
20 | import com.fasterxml.jackson.databind.node.ArrayNode; | 20 | import com.fasterxml.jackson.databind.node.ArrayNode; |
21 | import com.fasterxml.jackson.databind.node.ObjectNode; | 21 | import com.fasterxml.jackson.databind.node.ObjectNode; |
22 | +import com.google.common.base.Stopwatch; | ||
22 | import com.google.common.collect.Lists; | 23 | import com.google.common.collect.Lists; |
23 | -import com.google.common.collect.Sets; | 24 | +import org.apache.commons.lang.math.RandomUtils; |
24 | import org.apache.karaf.shell.commands.Argument; | 25 | import org.apache.karaf.shell.commands.Argument; |
25 | import org.apache.karaf.shell.commands.Command; | 26 | import org.apache.karaf.shell.commands.Command; |
27 | +import org.onlab.packet.MacAddress; | ||
26 | import org.onosproject.cli.AbstractShellCommand; | 28 | import org.onosproject.cli.AbstractShellCommand; |
29 | +import org.onosproject.core.ApplicationId; | ||
30 | +import org.onosproject.core.CoreService; | ||
27 | import org.onosproject.net.Device; | 31 | import org.onosproject.net.Device; |
28 | import org.onosproject.net.PortNumber; | 32 | import org.onosproject.net.PortNumber; |
29 | import org.onosproject.net.device.DeviceService; | 33 | import org.onosproject.net.device.DeviceService; |
30 | -import org.onosproject.net.flow.CompletedBatchOperation; | ||
31 | import org.onosproject.net.flow.DefaultFlowRule; | 34 | import org.onosproject.net.flow.DefaultFlowRule; |
32 | import org.onosproject.net.flow.DefaultTrafficSelector; | 35 | import org.onosproject.net.flow.DefaultTrafficSelector; |
33 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 36 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
34 | -import org.onosproject.net.flow.FlowRuleBatchEntry; | 37 | +import org.onosproject.net.flow.FlowRuleOperations; |
35 | -import org.onosproject.net.flow.FlowRuleBatchOperation; | 38 | +import org.onosproject.net.flow.FlowRuleOperationsContext; |
36 | import org.onosproject.net.flow.FlowRuleService; | 39 | import org.onosproject.net.flow.FlowRuleService; |
37 | import org.onosproject.net.flow.TrafficSelector; | 40 | import org.onosproject.net.flow.TrafficSelector; |
38 | import org.onosproject.net.flow.TrafficTreatment; | 41 | import org.onosproject.net.flow.TrafficTreatment; |
39 | -import org.onlab.packet.MacAddress; | ||
40 | 42 | ||
41 | import java.util.ArrayList; | 43 | import java.util.ArrayList; |
42 | -import java.util.Set; | 44 | +import java.util.concurrent.CountDownLatch; |
43 | -import java.util.concurrent.ExecutionException; | 45 | +import java.util.concurrent.TimeUnit; |
44 | -import java.util.concurrent.Future; | ||
45 | 46 | ||
46 | /** | 47 | /** |
47 | * Installs many many flows. | 48 | * Installs many many flows. |
... | @@ -50,6 +51,8 @@ import java.util.concurrent.Future; | ... | @@ -50,6 +51,8 @@ import java.util.concurrent.Future; |
50 | description = "Installs a number of test flow rules - for testing only") | 51 | description = "Installs a number of test flow rules - for testing only") |
51 | public class AddFlowsCommand extends AbstractShellCommand { | 52 | public class AddFlowsCommand extends AbstractShellCommand { |
52 | 53 | ||
54 | + private CountDownLatch latch; | ||
55 | + | ||
53 | @Argument(index = 0, name = "flowPerDevice", description = "Number of flows to add per device", | 56 | @Argument(index = 0, name = "flowPerDevice", description = "Number of flows to add per device", |
54 | required = true, multiValued = false) | 57 | required = true, multiValued = false) |
55 | String flows = null; | 58 | String flows = null; |
... | @@ -63,6 +66,9 @@ public class AddFlowsCommand extends AbstractShellCommand { | ... | @@ -63,6 +66,9 @@ public class AddFlowsCommand extends AbstractShellCommand { |
63 | 66 | ||
64 | FlowRuleService flowService = get(FlowRuleService.class); | 67 | FlowRuleService flowService = get(FlowRuleService.class); |
65 | DeviceService deviceService = get(DeviceService.class); | 68 | DeviceService deviceService = get(DeviceService.class); |
69 | + CoreService coreService = get(CoreService.class); | ||
70 | + | ||
71 | + ApplicationId appId = coreService.registerApplication("onos.test.flow.installer"); | ||
66 | 72 | ||
67 | int flowsPerDevice = Integer.parseInt(flows); | 73 | int flowsPerDevice = Integer.parseInt(flows); |
68 | int num = Integer.parseInt(numOfRuns); | 74 | int num = Integer.parseInt(numOfRuns); |
... | @@ -70,49 +76,73 @@ public class AddFlowsCommand extends AbstractShellCommand { | ... | @@ -70,49 +76,73 @@ public class AddFlowsCommand extends AbstractShellCommand { |
70 | ArrayList<Long> results = Lists.newArrayList(); | 76 | ArrayList<Long> results = Lists.newArrayList(); |
71 | Iterable<Device> devices = deviceService.getDevices(); | 77 | Iterable<Device> devices = deviceService.getDevices(); |
72 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() | 78 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
73 | - .setOutput(PortNumber.portNumber(1)).build(); | 79 | + .setOutput(PortNumber.portNumber(RandomUtils.nextInt())).build(); |
74 | TrafficSelector.Builder sbuilder; | 80 | TrafficSelector.Builder sbuilder; |
75 | - Set<FlowRuleBatchEntry> rules = Sets.newHashSet(); | 81 | + FlowRuleOperations.Builder rules = FlowRuleOperations.builder(); |
76 | - Set<FlowRuleBatchEntry> remove = Sets.newHashSet(); | 82 | + FlowRuleOperations.Builder remove = FlowRuleOperations.builder(); |
83 | + | ||
77 | for (Device d : devices) { | 84 | for (Device d : devices) { |
78 | for (int i = 0; i < flowsPerDevice; i++) { | 85 | for (int i = 0; i < flowsPerDevice; i++) { |
79 | sbuilder = DefaultTrafficSelector.builder(); | 86 | sbuilder = DefaultTrafficSelector.builder(); |
80 | - sbuilder.matchEthSrc(MacAddress.valueOf(i)) | 87 | + |
81 | - .matchEthDst(MacAddress.valueOf(Integer.MAX_VALUE - i)); | 88 | + sbuilder.matchEthSrc(MacAddress.valueOf(RandomUtils.nextInt() * i)) |
82 | - rules.add(new FlowRuleBatchEntry(FlowRuleBatchEntry.FlowRuleOperation.ADD, | 89 | + .matchEthDst(MacAddress.valueOf((Integer.MAX_VALUE - i) * RandomUtils.nextInt())); |
83 | - new DefaultFlowRule(d.id(), sbuilder.build(), treatment, | 90 | + |
84 | - 100, (long) 0, 10, false))); | 91 | + |
85 | - remove.add(new FlowRuleBatchEntry(FlowRuleBatchEntry.FlowRuleOperation.REMOVE, | 92 | + int randomPriority = RandomUtils.nextInt(); |
86 | - new DefaultFlowRule(d.id(), sbuilder.build(), treatment, | 93 | + rules.add(new DefaultFlowRule(d.id(), sbuilder.build(), treatment, |
87 | - 100, (long) 0, 10, false))); | 94 | + randomPriority, appId, 10, false)); |
95 | + remove.remove(new DefaultFlowRule(d.id(), sbuilder.build(), treatment, | ||
96 | + randomPriority, appId, 10, false)); | ||
88 | 97 | ||
89 | } | 98 | } |
90 | } | 99 | } |
91 | - boolean isSuccess = true; | 100 | + |
92 | for (int i = 0; i < num; i++) { | 101 | for (int i = 0; i < num; i++) { |
93 | - long startTime = System.currentTimeMillis(); | 102 | + |
94 | - Future<CompletedBatchOperation> op = flowService.applyBatch( | 103 | + latch = new CountDownLatch(2); |
95 | - new FlowRuleBatchOperation(rules)); | 104 | + flowService.apply(rules.build(new FlowRuleOperationsContext() { |
105 | + | ||
106 | + private final Stopwatch timer = Stopwatch.createStarted(); | ||
107 | + | ||
108 | + @Override | ||
109 | + public void onSuccess(FlowRuleOperations ops) { | ||
110 | + | ||
111 | + timer.stop(); | ||
112 | + results.add(timer.elapsed(TimeUnit.MILLISECONDS)); | ||
113 | + if (results.size() == num) { | ||
114 | + if (outputJson()) { | ||
115 | + print("%s", json(new ObjectMapper(), true, results)); | ||
116 | + } else { | ||
117 | + printTime(true, results); | ||
118 | + } | ||
119 | + } | ||
120 | + latch.countDown(); | ||
121 | + } | ||
122 | + })); | ||
123 | + | ||
124 | + | ||
125 | + flowService.apply(remove.build(new FlowRuleOperationsContext() { | ||
126 | + @Override | ||
127 | + public void onSuccess(FlowRuleOperations ops) { | ||
128 | + latch.countDown(); | ||
129 | + } | ||
130 | + })); | ||
96 | try { | 131 | try { |
97 | - isSuccess &= op.get().isSuccess(); | 132 | + latch.await(); |
98 | - } catch (InterruptedException | ExecutionException e) { | 133 | + } catch (InterruptedException e) { |
99 | e.printStackTrace(); | 134 | e.printStackTrace(); |
100 | } | 135 | } |
101 | - long endTime = System.currentTimeMillis(); | 136 | + |
102 | - results.add(endTime - startTime); | ||
103 | - flowService.applyBatch( | ||
104 | - new FlowRuleBatchOperation(remove)); | ||
105 | - } | ||
106 | - if (outputJson()) { | ||
107 | - print("%s", json(new ObjectMapper(), isSuccess, results)); | ||
108 | - } else { | ||
109 | - printTime(isSuccess, results); | ||
110 | } | 137 | } |
111 | 138 | ||
112 | 139 | ||
113 | 140 | ||
141 | + | ||
114 | } | 142 | } |
115 | 143 | ||
144 | + | ||
145 | + | ||
116 | private Object json(ObjectMapper mapper, boolean isSuccess, ArrayList<Long> elapsed) { | 146 | private Object json(ObjectMapper mapper, boolean isSuccess, ArrayList<Long> elapsed) { |
117 | ObjectNode result = mapper.createObjectNode(); | 147 | ObjectNode result = mapper.createObjectNode(); |
118 | result.put("Success", isSuccess); | 148 | result.put("Success", isSuccess); | ... | ... |
... | @@ -21,6 +21,7 @@ import java.util.Set; | ... | @@ -21,6 +21,7 @@ import java.util.Set; |
21 | 21 | ||
22 | import com.google.common.base.MoreObjects; | 22 | import com.google.common.base.MoreObjects; |
23 | import com.google.common.collect.ImmutableSet; | 23 | import com.google.common.collect.ImmutableSet; |
24 | +import org.onosproject.net.DeviceId; | ||
24 | 25 | ||
25 | /** | 26 | /** |
26 | * Representation of a completed flow rule batch operation. | 27 | * Representation of a completed flow rule batch operation. |
... | @@ -30,19 +31,22 @@ public class CompletedBatchOperation implements BatchOperationResult<FlowRule> { | ... | @@ -30,19 +31,22 @@ public class CompletedBatchOperation implements BatchOperationResult<FlowRule> { |
30 | private final boolean success; | 31 | private final boolean success; |
31 | private final Set<FlowRule> failures; | 32 | private final Set<FlowRule> failures; |
32 | private final Set<Long> failedIds; | 33 | private final Set<Long> failedIds; |
34 | + private final DeviceId deviceId; | ||
33 | 35 | ||
34 | /** | 36 | /** |
35 | * Creates a new batch completion result. | 37 | * Creates a new batch completion result. |
36 | * | 38 | * |
37 | - * @param success indicates whether the completion is successful. | 39 | + * @param success indicates whether the completion is successful |
38 | * @param failures set of any failures encountered | 40 | * @param failures set of any failures encountered |
39 | * @param failedIds (optional) set of failed operation ids | 41 | * @param failedIds (optional) set of failed operation ids |
42 | + * @param deviceId the device this operation completed for | ||
40 | */ | 43 | */ |
41 | public CompletedBatchOperation(boolean success, Set<? extends FlowRule> failures, | 44 | public CompletedBatchOperation(boolean success, Set<? extends FlowRule> failures, |
42 | - Set<Long> failedIds) { | 45 | + Set<Long> failedIds, DeviceId deviceId) { |
43 | this.success = success; | 46 | this.success = success; |
44 | this.failures = ImmutableSet.copyOf(failures); | 47 | this.failures = ImmutableSet.copyOf(failures); |
45 | this.failedIds = ImmutableSet.copyOf(failedIds); | 48 | this.failedIds = ImmutableSet.copyOf(failedIds); |
49 | + this.deviceId = deviceId; | ||
46 | } | 50 | } |
47 | 51 | ||
48 | /** | 52 | /** |
... | @@ -51,10 +55,12 @@ public class CompletedBatchOperation implements BatchOperationResult<FlowRule> { | ... | @@ -51,10 +55,12 @@ public class CompletedBatchOperation implements BatchOperationResult<FlowRule> { |
51 | * @param success indicates whether the completion is successful. | 55 | * @param success indicates whether the completion is successful. |
52 | * @param failures set of any failures encountered | 56 | * @param failures set of any failures encountered |
53 | */ | 57 | */ |
54 | - public CompletedBatchOperation(boolean success, Set<? extends FlowRule> failures) { | 58 | + public CompletedBatchOperation(boolean success, Set<? extends FlowRule> failures, |
59 | + DeviceId deviceId) { | ||
55 | this.success = success; | 60 | this.success = success; |
56 | this.failures = ImmutableSet.copyOf(failures); | 61 | this.failures = ImmutableSet.copyOf(failures); |
57 | this.failedIds = Collections.emptySet(); | 62 | this.failedIds = Collections.emptySet(); |
63 | + this.deviceId = deviceId; | ||
58 | } | 64 | } |
59 | 65 | ||
60 | 66 | ||
... | @@ -73,12 +79,17 @@ public class CompletedBatchOperation implements BatchOperationResult<FlowRule> { | ... | @@ -73,12 +79,17 @@ public class CompletedBatchOperation implements BatchOperationResult<FlowRule> { |
73 | return failedIds; | 79 | return failedIds; |
74 | } | 80 | } |
75 | 81 | ||
82 | + public DeviceId deviceId() { | ||
83 | + return this.deviceId; | ||
84 | + } | ||
85 | + | ||
76 | @Override | 86 | @Override |
77 | public String toString() { | 87 | public String toString() { |
78 | return MoreObjects.toStringHelper(getClass()) | 88 | return MoreObjects.toStringHelper(getClass()) |
79 | .add("success?", success) | 89 | .add("success?", success) |
80 | .add("failedItems", failures) | 90 | .add("failedItems", failures) |
81 | .add("failedIds", failedIds) | 91 | .add("failedIds", failedIds) |
92 | + .add("deviceId", deviceId) | ||
82 | .toString(); | 93 | .toString(); |
83 | } | 94 | } |
84 | } | 95 | } | ... | ... |
... | @@ -16,12 +16,14 @@ | ... | @@ -16,12 +16,14 @@ |
16 | package org.onosproject.net.flow; | 16 | package org.onosproject.net.flow; |
17 | 17 | ||
18 | import org.onosproject.event.AbstractEvent; | 18 | import org.onosproject.event.AbstractEvent; |
19 | +import org.onosproject.net.DeviceId; | ||
19 | 20 | ||
20 | /** | 21 | /** |
21 | * Describes flow rule batch event. | 22 | * Describes flow rule batch event. |
22 | */ | 23 | */ |
23 | public final class FlowRuleBatchEvent extends AbstractEvent<FlowRuleBatchEvent.Type, FlowRuleBatchRequest> { | 24 | public final class FlowRuleBatchEvent extends AbstractEvent<FlowRuleBatchEvent.Type, FlowRuleBatchRequest> { |
24 | 25 | ||
26 | + | ||
25 | /** | 27 | /** |
26 | * Type of flow rule events. | 28 | * Type of flow rule events. |
27 | */ | 29 | */ |
... | @@ -42,14 +44,17 @@ public final class FlowRuleBatchEvent extends AbstractEvent<FlowRuleBatchEvent.T | ... | @@ -42,14 +44,17 @@ public final class FlowRuleBatchEvent extends AbstractEvent<FlowRuleBatchEvent.T |
42 | } | 44 | } |
43 | 45 | ||
44 | private final CompletedBatchOperation result; | 46 | private final CompletedBatchOperation result; |
47 | + private final DeviceId deviceId; | ||
45 | 48 | ||
46 | /** | 49 | /** |
47 | * Constructs a new FlowRuleBatchEvent. | 50 | * Constructs a new FlowRuleBatchEvent. |
48 | - * @param request batch operation request. | 51 | + * |
52 | + * @param request batch operation request | ||
53 | + * @param deviceId the device this batch will be processed on | ||
49 | * @return event. | 54 | * @return event. |
50 | */ | 55 | */ |
51 | - public static FlowRuleBatchEvent requested(FlowRuleBatchRequest request) { | 56 | + public static FlowRuleBatchEvent requested(FlowRuleBatchRequest request, DeviceId deviceId) { |
52 | - FlowRuleBatchEvent event = new FlowRuleBatchEvent(Type.BATCH_OPERATION_REQUESTED, request, null); | 57 | + FlowRuleBatchEvent event = new FlowRuleBatchEvent(Type.BATCH_OPERATION_REQUESTED, request, deviceId); |
53 | return event; | 58 | return event; |
54 | } | 59 | } |
55 | 60 | ||
... | @@ -73,13 +78,36 @@ public final class FlowRuleBatchEvent extends AbstractEvent<FlowRuleBatchEvent.T | ... | @@ -73,13 +78,36 @@ public final class FlowRuleBatchEvent extends AbstractEvent<FlowRuleBatchEvent.T |
73 | } | 78 | } |
74 | 79 | ||
75 | /** | 80 | /** |
81 | + * Returns the deviceId for this batch. | ||
82 | + * @return device id | ||
83 | + */ | ||
84 | + public DeviceId deviceId() { | ||
85 | + return deviceId; | ||
86 | + } | ||
87 | + | ||
88 | + /** | ||
76 | * Creates an event of a given type and for the specified flow rule batch. | 89 | * Creates an event of a given type and for the specified flow rule batch. |
77 | * | 90 | * |
78 | * @param type flow rule batch event type | 91 | * @param type flow rule batch event type |
79 | - * @param batch event flow rule batch subject | 92 | + * @param request event flow rule batch subject |
93 | + * @param result the result of the batch operation | ||
80 | */ | 94 | */ |
81 | private FlowRuleBatchEvent(Type type, FlowRuleBatchRequest request, CompletedBatchOperation result) { | 95 | private FlowRuleBatchEvent(Type type, FlowRuleBatchRequest request, CompletedBatchOperation result) { |
82 | super(type, request); | 96 | super(type, request); |
83 | this.result = result; | 97 | this.result = result; |
98 | + this.deviceId = result.deviceId(); | ||
99 | + } | ||
100 | + | ||
101 | + /** | ||
102 | + * Creates an event of a given type and for the specified flow rule batch. | ||
103 | + * | ||
104 | + * @param type flow rule batch event type | ||
105 | + * @param request event flow rule batch subject | ||
106 | + * @param deviceId the device id for this batch | ||
107 | + */ | ||
108 | + private FlowRuleBatchEvent(Type type, FlowRuleBatchRequest request, DeviceId deviceId) { | ||
109 | + super(type, request); | ||
110 | + this.result = null; | ||
111 | + this.deviceId = deviceId; | ||
84 | } | 112 | } |
85 | } | 113 | } | ... | ... |
... | @@ -15,12 +15,37 @@ | ... | @@ -15,12 +15,37 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.flow; | 16 | package org.onosproject.net.flow; |
17 | 17 | ||
18 | +import org.onosproject.net.DeviceId; | ||
19 | + | ||
18 | import java.util.Collection; | 20 | import java.util.Collection; |
19 | 21 | ||
22 | +/** | ||
23 | + * Class used with the flow subsystem to process per device | ||
24 | + * batches. | ||
25 | + */ | ||
20 | public class FlowRuleBatchOperation | 26 | public class FlowRuleBatchOperation |
21 | extends BatchOperation<FlowRuleBatchEntry> { | 27 | extends BatchOperation<FlowRuleBatchEntry> { |
22 | 28 | ||
23 | - public FlowRuleBatchOperation(Collection<FlowRuleBatchEntry> operations) { | 29 | + /** |
30 | + * This id is used to cary to id of the original | ||
31 | + * FlowOperations and track where this batch operation | ||
32 | + * came from. The id is unique cluster wide. | ||
33 | + */ | ||
34 | + private final long id; | ||
35 | + private final DeviceId deviceId; | ||
36 | + | ||
37 | + public FlowRuleBatchOperation(Collection<FlowRuleBatchEntry> operations, | ||
38 | + DeviceId deviceId, long flowOperationId) { | ||
24 | super(operations); | 39 | super(operations); |
40 | + this.id = flowOperationId; | ||
41 | + this.deviceId = deviceId; | ||
42 | + } | ||
43 | + | ||
44 | + public DeviceId deviceId() { | ||
45 | + return this.deviceId; | ||
46 | + } | ||
47 | + | ||
48 | + public long id() { | ||
49 | + return id; | ||
25 | } | 50 | } |
26 | } | 51 | } | ... | ... |
... | @@ -15,59 +15,43 @@ | ... | @@ -15,59 +15,43 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.flow; | 16 | package org.onosproject.net.flow; |
17 | 17 | ||
18 | +import com.google.common.collect.Lists; | ||
19 | +import org.onosproject.net.DeviceId; | ||
20 | + | ||
18 | import java.util.Collections; | 21 | import java.util.Collections; |
19 | import java.util.List; | 22 | import java.util.List; |
23 | +import java.util.Set; | ||
20 | 24 | ||
21 | -import com.google.common.base.Function; | 25 | +public class FlowRuleBatchRequest { |
22 | -import com.google.common.collect.FluentIterable; | ||
23 | - | ||
24 | - | ||
25 | 26 | ||
26 | -import com.google.common.collect.Lists; | 27 | + /** |
28 | + * This id is used to cary to id of the original | ||
29 | + * FlowOperations and track where this batch operation | ||
30 | + * came from. The id is unique cluster wide. | ||
31 | + */ | ||
32 | + private final long batchId; | ||
27 | 33 | ||
28 | -public class FlowRuleBatchRequest { | 34 | + private final Set<FlowRuleBatchEntry> ops; |
29 | 35 | ||
30 | - private final int batchId; | ||
31 | - private final List<FlowRuleBatchEntry> toAdd; | ||
32 | - private final List<FlowRuleBatchEntry> toRemove; | ||
33 | 36 | ||
34 | - public FlowRuleBatchRequest(int batchId, List<FlowRuleBatchEntry> toAdd, | 37 | + public FlowRuleBatchRequest(long batchId, Set<FlowRuleBatchEntry> ops) { |
35 | - List<FlowRuleBatchEntry> toRemove) { | ||
36 | this.batchId = batchId; | 38 | this.batchId = batchId; |
37 | - this.toAdd = Collections.unmodifiableList(toAdd); | 39 | + this.ops = Collections.unmodifiableSet(ops); |
38 | - this.toRemove = Collections.unmodifiableList(toRemove); | ||
39 | - } | ||
40 | 40 | ||
41 | - public List<FlowRule> toAdd() { | ||
42 | - return FluentIterable.from(toAdd).transform( | ||
43 | - new Function<FlowRuleBatchEntry, FlowRule>() { | ||
44 | 41 | ||
45 | - @Override | ||
46 | - public FlowRule apply(FlowRuleBatchEntry input) { | ||
47 | - return input.target(); | ||
48 | } | 42 | } |
49 | - }).toList(); | ||
50 | - } | ||
51 | - | ||
52 | - public List<FlowRule> toRemove() { | ||
53 | - return FluentIterable.from(toRemove).transform( | ||
54 | - new Function<FlowRuleBatchEntry, FlowRule>() { | ||
55 | 43 | ||
56 | - @Override | 44 | + public Set<FlowRuleBatchEntry> ops() { |
57 | - public FlowRule apply(FlowRuleBatchEntry input) { | 45 | + return ops; |
58 | - return input.target(); | ||
59 | - } | ||
60 | - }).toList(); | ||
61 | } | 46 | } |
62 | 47 | ||
63 | - public FlowRuleBatchOperation asBatchOperation() { | 48 | + public FlowRuleBatchOperation asBatchOperation(DeviceId deviceId) { |
64 | List<FlowRuleBatchEntry> entries = Lists.newArrayList(); | 49 | List<FlowRuleBatchEntry> entries = Lists.newArrayList(); |
65 | - entries.addAll(toAdd); | 50 | + entries.addAll(ops); |
66 | - entries.addAll(toRemove); | 51 | + return new FlowRuleBatchOperation(entries, deviceId, batchId); |
67 | - return new FlowRuleBatchOperation(entries); | ||
68 | } | 52 | } |
69 | 53 | ||
70 | - public int batchId() { | 54 | + public long batchId() { |
71 | return batchId; | 55 | return batchId; |
72 | } | 56 | } |
73 | } | 57 | } | ... | ... |
1 | +/* | ||
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 | + */ | ||
16 | +package org.onosproject.net.flow; | ||
17 | + | ||
18 | +import com.google.common.base.MoreObjects; | ||
19 | + | ||
20 | +/** | ||
21 | + * Representation of an operation on a flow rule table. | ||
22 | + */ | ||
23 | +public class FlowRuleOperation { | ||
24 | + | ||
25 | + /** | ||
26 | + * Type of flow table operations. | ||
27 | + */ | ||
28 | + public enum Type { | ||
29 | + ADD, | ||
30 | + MODIFY, | ||
31 | + REMOVE | ||
32 | + } | ||
33 | + | ||
34 | + private final FlowRule rule; | ||
35 | + private final Type type; | ||
36 | + | ||
37 | + public FlowRuleOperation(FlowRule rule, Type type) { | ||
38 | + this.rule = rule; | ||
39 | + this.type = type; | ||
40 | + } | ||
41 | + | ||
42 | + /** | ||
43 | + * Returns the type of operation. | ||
44 | + * | ||
45 | + * @return type | ||
46 | + */ | ||
47 | + public Type type() { | ||
48 | + return type; | ||
49 | + } | ||
50 | + | ||
51 | + /** | ||
52 | + * Returns the flow rule. | ||
53 | + * | ||
54 | + * @return flow rule | ||
55 | + */ | ||
56 | + public FlowRule rule() { | ||
57 | + return rule; | ||
58 | + } | ||
59 | + | ||
60 | + @Override | ||
61 | + public String toString() { | ||
62 | + return MoreObjects.toStringHelper(this) | ||
63 | + .add("rule", rule) | ||
64 | + .add("type", type) | ||
65 | + .toString(); | ||
66 | + } | ||
67 | +} |
1 | +/* | ||
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 | + */ | ||
16 | +package org.onosproject.net.flow; | ||
17 | + | ||
18 | +import com.google.common.base.MoreObjects; | ||
19 | +import com.google.common.collect.ImmutableList; | ||
20 | +import com.google.common.collect.ImmutableSet; | ||
21 | +import com.google.common.collect.Lists; | ||
22 | + | ||
23 | +import java.util.List; | ||
24 | +import java.util.Set; | ||
25 | + | ||
26 | +import static org.onosproject.net.flow.FlowRuleOperation.Type.*; | ||
27 | + | ||
28 | +/** | ||
29 | + * A batch of flow rule operations that are broken into stages. | ||
30 | + * TODO move this up to parent's package | ||
31 | + */ | ||
32 | +public class FlowRuleOperations { | ||
33 | + | ||
34 | + private final List<Set<FlowRuleOperation>> stages; | ||
35 | + private final FlowRuleOperationsContext callback; // TODO consider Optional | ||
36 | + | ||
37 | + private FlowRuleOperations(List<Set<FlowRuleOperation>> stages, | ||
38 | + FlowRuleOperationsContext cb) { | ||
39 | + this.stages = stages; | ||
40 | + this.callback = cb; | ||
41 | + } | ||
42 | + | ||
43 | + // kryo-constructor | ||
44 | + protected FlowRuleOperations() { | ||
45 | + this.stages = Lists.newArrayList(); | ||
46 | + this.callback = null; | ||
47 | + } | ||
48 | + | ||
49 | + /** | ||
50 | + * Returns the flow rule operations as sets of stages that should be | ||
51 | + * executed sequentially. | ||
52 | + * | ||
53 | + * @return flow rule stages | ||
54 | + */ | ||
55 | + public List<Set<FlowRuleOperation>> stages() { | ||
56 | + return stages; | ||
57 | + } | ||
58 | + | ||
59 | + /** | ||
60 | + * Returns the callback for this batch of operations. | ||
61 | + * | ||
62 | + * @return callback | ||
63 | + */ | ||
64 | + public FlowRuleOperationsContext callback() { | ||
65 | + return callback; | ||
66 | + } | ||
67 | + | ||
68 | + /** | ||
69 | + * Returns a new builder. | ||
70 | + * | ||
71 | + * @return new builder | ||
72 | + */ | ||
73 | + public static Builder builder() { | ||
74 | + return new Builder(); | ||
75 | + } | ||
76 | + | ||
77 | + @Override | ||
78 | + public String toString() { | ||
79 | + return MoreObjects.toStringHelper(this) | ||
80 | + .add("stages", stages) | ||
81 | + .toString(); | ||
82 | + } | ||
83 | + | ||
84 | + /** | ||
85 | + * A builder for constructing flow rule operations. | ||
86 | + */ | ||
87 | + public static final class Builder { | ||
88 | + | ||
89 | + private final ImmutableList.Builder<Set<FlowRuleOperation>> listBuilder = ImmutableList.builder(); | ||
90 | + private ImmutableSet.Builder<FlowRuleOperation> currentStage = ImmutableSet.builder(); | ||
91 | + | ||
92 | + // prevent use of the default constructor outside of this file; use the above method | ||
93 | + private Builder() {} | ||
94 | + | ||
95 | + /** | ||
96 | + * Appends a flow rule add to the current stage. | ||
97 | + * | ||
98 | + * @param flowRule flow rule | ||
99 | + * @return this | ||
100 | + */ | ||
101 | + public Builder add(FlowRule flowRule) { | ||
102 | + currentStage.add(new FlowRuleOperation(flowRule, ADD)); | ||
103 | + return this; | ||
104 | + } | ||
105 | + | ||
106 | + /** | ||
107 | + * Appends a flow rule modify to the current stage. | ||
108 | + * | ||
109 | + * @param flowRule flow rule | ||
110 | + * @return this | ||
111 | + */ | ||
112 | + public Builder modify(FlowRule flowRule) { | ||
113 | + currentStage.add(new FlowRuleOperation(flowRule, MODIFY)); | ||
114 | + return this; | ||
115 | + } | ||
116 | + | ||
117 | + /** | ||
118 | + * Appends a flow rule remove to the current stage. | ||
119 | + * | ||
120 | + * @param flowRule flow rule | ||
121 | + * @return this | ||
122 | + */ | ||
123 | + // FIXME this is confusing, consider renaming | ||
124 | + public Builder remove(FlowRule flowRule) { | ||
125 | + currentStage.add(new FlowRuleOperation(flowRule, REMOVE)); | ||
126 | + return this; | ||
127 | + } | ||
128 | + | ||
129 | + /** | ||
130 | + * Closes the current stage. | ||
131 | + */ | ||
132 | + private void closeStage() { | ||
133 | + ImmutableSet<FlowRuleOperation> stage = currentStage.build(); | ||
134 | + if (!stage.isEmpty()) { | ||
135 | + listBuilder.add(stage); | ||
136 | + } | ||
137 | + } | ||
138 | + | ||
139 | + /** | ||
140 | + * Closes the current stage and starts a new one. | ||
141 | + * | ||
142 | + * @return this | ||
143 | + */ | ||
144 | + public Builder newStage() { | ||
145 | + closeStage(); | ||
146 | + currentStage = ImmutableSet.builder(); | ||
147 | + return this; | ||
148 | + } | ||
149 | + | ||
150 | + /** | ||
151 | + * Builds the immutable flow rule operations. | ||
152 | + * | ||
153 | + * @return flow rule operations | ||
154 | + */ | ||
155 | + public FlowRuleOperations build() { | ||
156 | + return build(null); | ||
157 | + } | ||
158 | + | ||
159 | + /** | ||
160 | + * Builds the immutable flow rule operations. | ||
161 | + * | ||
162 | + * @param cb the callback to call when this operation completes | ||
163 | + * @return flow rule operations | ||
164 | + */ | ||
165 | + public FlowRuleOperations build(FlowRuleOperationsContext cb) { | ||
166 | + closeStage(); | ||
167 | + return new FlowRuleOperations(listBuilder.build(), cb); | ||
168 | + } | ||
169 | + } | ||
170 | +} |
1 | +/* | ||
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 | + */ | ||
16 | +package org.onosproject.net.flow; | ||
17 | + | ||
18 | +/** | ||
19 | + * The context of a flow rule operations that will become the subject of | ||
20 | + * the notification. | ||
21 | + * | ||
22 | + * Implementations of this class must be serializable. | ||
23 | + */ | ||
24 | +public interface FlowRuleOperationsContext { | ||
25 | + // TODO we might also want to execute a method on behalf of the app | ||
26 | + default void onSuccess(FlowRuleOperations ops){} | ||
27 | + default void onError(FlowRuleOperations ops){} | ||
28 | +} |
... | @@ -18,8 +18,6 @@ package org.onosproject.net.flow; | ... | @@ -18,8 +18,6 @@ package org.onosproject.net.flow; |
18 | import org.onosproject.core.ApplicationId; | 18 | import org.onosproject.core.ApplicationId; |
19 | import org.onosproject.net.provider.Provider; | 19 | import org.onosproject.net.provider.Provider; |
20 | 20 | ||
21 | -import java.util.concurrent.Future; | ||
22 | - | ||
23 | /** | 21 | /** |
24 | * Abstraction of a flow rule provider. | 22 | * Abstraction of a flow rule provider. |
25 | */ | 23 | */ |
... | @@ -56,8 +54,7 @@ public interface FlowRuleProvider extends Provider { | ... | @@ -56,8 +54,7 @@ public interface FlowRuleProvider extends Provider { |
56 | * Installs a batch of flow rules. Each flowrule is associated to an | 54 | * Installs a batch of flow rules. Each flowrule is associated to an |
57 | * operation which results in either addition, removal or modification. | 55 | * operation which results in either addition, removal or modification. |
58 | * @param batch a batch of flow rules | 56 | * @param batch a batch of flow rules |
59 | - * @return a future indicating the status of this execution | ||
60 | */ | 57 | */ |
61 | - Future<CompletedBatchOperation> executeBatch(BatchOperation<FlowRuleBatchEntry> batch); | 58 | + void executeBatch(FlowRuleBatchOperation batch); |
62 | 59 | ||
63 | } | 60 | } | ... | ... |
... | @@ -40,4 +40,13 @@ public interface FlowRuleProviderService extends ProviderService<FlowRuleProvide | ... | @@ -40,4 +40,13 @@ public interface FlowRuleProviderService extends ProviderService<FlowRuleProvide |
40 | */ | 40 | */ |
41 | void pushFlowMetrics(DeviceId deviceId, Iterable<FlowEntry> flowEntries); | 41 | void pushFlowMetrics(DeviceId deviceId, Iterable<FlowEntry> flowEntries); |
42 | 42 | ||
43 | + /** | ||
44 | + * Indicates to the core that the requested batch operation has | ||
45 | + * been completed. | ||
46 | + * | ||
47 | + * @param batchId the batch which was processed | ||
48 | + * @param operation the resulting outcome of the operation | ||
49 | + */ | ||
50 | + void batchOperationCompleted(long batchId, CompletedBatchOperation operation); | ||
51 | + | ||
43 | } | 52 | } | ... | ... |
... | @@ -15,11 +15,11 @@ | ... | @@ -15,11 +15,11 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.flow; | 16 | package org.onosproject.net.flow; |
17 | 17 | ||
18 | -import java.util.concurrent.Future; | ||
19 | - | ||
20 | import org.onosproject.core.ApplicationId; | 18 | import org.onosproject.core.ApplicationId; |
21 | import org.onosproject.net.DeviceId; | 19 | import org.onosproject.net.DeviceId; |
22 | 20 | ||
21 | +import java.util.concurrent.Future; | ||
22 | + | ||
23 | /** | 23 | /** |
24 | * Service for injecting flow rules into the environment and for obtaining | 24 | * Service for injecting flow rules into the environment and for obtaining |
25 | * information about flow rules already in the environment. This implements | 25 | * information about flow rules already in the environment. This implements |
... | @@ -30,6 +30,11 @@ import org.onosproject.net.DeviceId; | ... | @@ -30,6 +30,11 @@ import org.onosproject.net.DeviceId; |
30 | public interface FlowRuleService { | 30 | public interface FlowRuleService { |
31 | 31 | ||
32 | /** | 32 | /** |
33 | + * The topic used for obtaining globally unique ids. | ||
34 | + */ | ||
35 | + static String FLOW_OP_TOPIC = "flow-ops-ids"; | ||
36 | + | ||
37 | + /** | ||
33 | * Returns the number of flow rules in the system. | 38 | * Returns the number of flow rules in the system. |
34 | * | 39 | * |
35 | * @return flow rule count | 40 | * @return flow rule count |
... | @@ -96,11 +101,20 @@ public interface FlowRuleService { | ... | @@ -96,11 +101,20 @@ public interface FlowRuleService { |
96 | * Applies a batch operation of FlowRules. | 101 | * Applies a batch operation of FlowRules. |
97 | * | 102 | * |
98 | * @param batch batch operation to apply | 103 | * @param batch batch operation to apply |
99 | - * @return future indicating the state of the batch operation | 104 | + * @return future indicating the state of the batch operation, due to the |
105 | + * deprecation of this api the future will immediately return | ||
100 | */ | 106 | */ |
107 | + @Deprecated | ||
101 | Future<CompletedBatchOperation> applyBatch(FlowRuleBatchOperation batch); | 108 | Future<CompletedBatchOperation> applyBatch(FlowRuleBatchOperation batch); |
102 | 109 | ||
103 | /** | 110 | /** |
111 | + * Applies a batch operation of FlowRules. | ||
112 | + * | ||
113 | + * @param ops batch operation to apply | ||
114 | + */ | ||
115 | + void apply(FlowRuleOperations ops); | ||
116 | + | ||
117 | + /** | ||
104 | * Adds the specified flow rule listener. | 118 | * Adds the specified flow rule listener. |
105 | * | 119 | * |
106 | * @param listener flow rule listener | 120 | * @param listener flow rule listener | ... | ... |
... | @@ -15,8 +15,6 @@ | ... | @@ -15,8 +15,6 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.flow; | 16 | package org.onosproject.net.flow; |
17 | 17 | ||
18 | -import java.util.concurrent.Future; | ||
19 | - | ||
20 | import org.onosproject.net.DeviceId; | 18 | import org.onosproject.net.DeviceId; |
21 | import org.onosproject.store.Store; | 19 | import org.onosproject.store.Store; |
22 | 20 | ||
... | @@ -54,6 +52,7 @@ public interface FlowRuleStore extends Store<FlowRuleBatchEvent, FlowRuleStoreDe | ... | @@ -54,6 +52,7 @@ public interface FlowRuleStore extends Store<FlowRuleBatchEvent, FlowRuleStoreDe |
54 | * | 52 | * |
55 | * @param rule the flow rule to add | 53 | * @param rule the flow rule to add |
56 | */ | 54 | */ |
55 | + @Deprecated | ||
57 | void storeFlowRule(FlowRule rule); | 56 | void storeFlowRule(FlowRule rule); |
58 | 57 | ||
59 | /** | 58 | /** |
... | @@ -61,10 +60,9 @@ public interface FlowRuleStore extends Store<FlowRuleBatchEvent, FlowRuleStoreDe | ... | @@ -61,10 +60,9 @@ public interface FlowRuleStore extends Store<FlowRuleBatchEvent, FlowRuleStoreDe |
61 | * | 60 | * |
62 | * @param batchOperation batch of flow rules. | 61 | * @param batchOperation batch of flow rules. |
63 | * A batch can contain flow rules for a single device only. | 62 | * A batch can contain flow rules for a single device only. |
64 | - * @return Future response indicating success/failure of the batch operation | 63 | + * |
65 | - * all the way down to the device. | ||
66 | */ | 64 | */ |
67 | - Future<CompletedBatchOperation> storeBatch(FlowRuleBatchOperation batchOperation); | 65 | + void storeBatch(FlowRuleBatchOperation batchOperation); |
68 | 66 | ||
69 | /** | 67 | /** |
70 | * Invoked on the completion of a storeBatch operation. | 68 | * Invoked on the completion of a storeBatch operation. | ... | ... |
... | @@ -46,10 +46,10 @@ public class FlowRuleBatchOperationTest { | ... | @@ -46,10 +46,10 @@ public class FlowRuleBatchOperationTest { |
46 | final LinkedList<FlowRuleBatchEntry> ops3 = new LinkedList<>(); | 46 | final LinkedList<FlowRuleBatchEntry> ops3 = new LinkedList<>(); |
47 | ops3.add(entry3); | 47 | ops3.add(entry3); |
48 | 48 | ||
49 | - final FlowRuleBatchOperation operation1 = new FlowRuleBatchOperation(ops1); | 49 | + final FlowRuleBatchOperation operation1 = new FlowRuleBatchOperation(ops1, null, 0); |
50 | - final FlowRuleBatchOperation sameAsOperation1 = new FlowRuleBatchOperation(ops1); | 50 | + final FlowRuleBatchOperation sameAsOperation1 = new FlowRuleBatchOperation(ops1, null, 0); |
51 | - final FlowRuleBatchOperation operation2 = new FlowRuleBatchOperation(ops2); | 51 | + final FlowRuleBatchOperation operation2 = new FlowRuleBatchOperation(ops2, null, 0); |
52 | - final FlowRuleBatchOperation operation3 = new FlowRuleBatchOperation(ops3); | 52 | + final FlowRuleBatchOperation operation3 = new FlowRuleBatchOperation(ops3, null, 0); |
53 | 53 | ||
54 | new EqualsTester() | 54 | new EqualsTester() |
55 | .addEqualityGroup(operation1, sameAsOperation1) | 55 | .addEqualityGroup(operation1, sameAsOperation1) | ... | ... |
... | @@ -15,17 +15,18 @@ | ... | @@ -15,17 +15,18 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.flow; | 16 | package org.onosproject.net.flow; |
17 | 17 | ||
18 | -import java.util.LinkedList; | ||
19 | -import java.util.List; | ||
20 | - | ||
21 | import org.junit.Test; | 18 | import org.junit.Test; |
22 | import org.onosproject.net.intent.IntentTestsMocks; | 19 | import org.onosproject.net.intent.IntentTestsMocks; |
23 | 20 | ||
24 | -import static org.onosproject.net.flow.FlowRuleBatchEntry.FlowRuleOperation.*; | 21 | +import java.util.HashSet; |
22 | +import java.util.List; | ||
23 | +import java.util.Set; | ||
25 | 24 | ||
26 | import static org.hamcrest.MatcherAssert.assertThat; | 25 | import static org.hamcrest.MatcherAssert.assertThat; |
27 | import static org.hamcrest.Matchers.hasSize; | 26 | import static org.hamcrest.Matchers.hasSize; |
28 | import static org.hamcrest.Matchers.is; | 27 | import static org.hamcrest.Matchers.is; |
28 | +import static org.onosproject.net.flow.FlowRuleBatchEntry.FlowRuleOperation.ADD; | ||
29 | +import static org.onosproject.net.flow.FlowRuleBatchEntry.FlowRuleOperation.REMOVE; | ||
29 | 30 | ||
30 | /** | 31 | /** |
31 | * Unit tests for the FlowRuleBatchRequest class. | 32 | * Unit tests for the FlowRuleBatchRequest class. |
... | @@ -40,22 +41,19 @@ public class FlowRuleBatchRequestTest { | ... | @@ -40,22 +41,19 @@ public class FlowRuleBatchRequestTest { |
40 | public void testConstruction() { | 41 | public void testConstruction() { |
41 | final FlowRule rule1 = new IntentTestsMocks.MockFlowRule(1); | 42 | final FlowRule rule1 = new IntentTestsMocks.MockFlowRule(1); |
42 | final FlowRule rule2 = new IntentTestsMocks.MockFlowRule(2); | 43 | final FlowRule rule2 = new IntentTestsMocks.MockFlowRule(2); |
43 | - final List<FlowRuleBatchEntry> toAdd = new LinkedList<>(); | 44 | + final Set<FlowRuleBatchEntry> batch = new HashSet<>(); |
44 | - toAdd.add(new FlowRuleBatchEntry(ADD, rule1)); | 45 | + batch.add(new FlowRuleBatchEntry(ADD, rule1)); |
45 | - final List<FlowRuleBatchEntry> toRemove = new LinkedList<>(); | 46 | + |
46 | - toRemove.add(new FlowRuleBatchEntry(REMOVE, rule2)); | 47 | + batch.add(new FlowRuleBatchEntry(REMOVE, rule2)); |
47 | 48 | ||
48 | 49 | ||
49 | final FlowRuleBatchRequest request = | 50 | final FlowRuleBatchRequest request = |
50 | - new FlowRuleBatchRequest(1, toAdd, toRemove); | 51 | + new FlowRuleBatchRequest(1, batch); |
51 | 52 | ||
52 | - assertThat(request.toAdd(), hasSize(1)); | 53 | + assertThat(request.ops(), hasSize(2)); |
53 | - assertThat(request.toAdd().get(0), is(rule1)); | 54 | + assertThat(request.batchId(), is(1L)); |
54 | - assertThat(request.toRemove(), hasSize(1)); | ||
55 | - assertThat(request.toRemove().get(0), is(rule2)); | ||
56 | - assertThat(request.batchId(), is(1)); | ||
57 | 55 | ||
58 | - final FlowRuleBatchOperation op = request.asBatchOperation(); | 56 | + final FlowRuleBatchOperation op = request.asBatchOperation(rule1.deviceId()); |
59 | assertThat(op.size(), is(2)); | 57 | assertThat(op.size(), is(2)); |
60 | 58 | ||
61 | final List<FlowRuleBatchEntry> ops = op.getOperations(); | 59 | final List<FlowRuleBatchEntry> ops = op.getOperations(); | ... | ... |
... | @@ -66,6 +66,11 @@ public class FlowRuleServiceAdapter implements FlowRuleService { | ... | @@ -66,6 +66,11 @@ public class FlowRuleServiceAdapter implements FlowRuleService { |
66 | } | 66 | } |
67 | 67 | ||
68 | @Override | 68 | @Override |
69 | + public void apply(FlowRuleOperations ops) { | ||
70 | + | ||
71 | + } | ||
72 | + | ||
73 | + @Override | ||
69 | public void addListener(FlowRuleListener listener) { | 74 | public void addListener(FlowRuleListener listener) { |
70 | 75 | ||
71 | } | 76 | } | ... | ... |
This diff is collapsed. Click to expand it.
... | @@ -1151,6 +1151,7 @@ public class IntentManager | ... | @@ -1151,6 +1151,7 @@ public class IntentManager |
1151 | */ | 1151 | */ |
1152 | protected Future<CompletedBatchOperation> applyNextBatch(List<CompletedIntentUpdate> updates) { | 1152 | protected Future<CompletedBatchOperation> applyNextBatch(List<CompletedIntentUpdate> updates) { |
1153 | //TODO test this. (also, maybe save this batch) | 1153 | //TODO test this. (also, maybe save this batch) |
1154 | + | ||
1154 | FlowRuleBatchOperation batch = createFlowRuleBatchOperation(updates); | 1155 | FlowRuleBatchOperation batch = createFlowRuleBatchOperation(updates); |
1155 | if (batch.size() > 0) { | 1156 | if (batch.size() > 0) { |
1156 | //FIXME apply batch might throw an exception | 1157 | //FIXME apply batch might throw an exception |
... | @@ -1165,7 +1166,7 @@ public class IntentManager | ... | @@ -1165,7 +1166,7 @@ public class IntentManager |
1165 | } | 1166 | } |
1166 | 1167 | ||
1167 | private FlowRuleBatchOperation createFlowRuleBatchOperation(List<CompletedIntentUpdate> intentUpdates) { | 1168 | private FlowRuleBatchOperation createFlowRuleBatchOperation(List<CompletedIntentUpdate> intentUpdates) { |
1168 | - FlowRuleBatchOperation batch = new FlowRuleBatchOperation(Collections.emptyList()); | 1169 | + FlowRuleBatchOperation batch = new FlowRuleBatchOperation(Collections.emptyList(), null, 0); |
1169 | for (CompletedIntentUpdate update : intentUpdates) { | 1170 | for (CompletedIntentUpdate update : intentUpdates) { |
1170 | FlowRuleBatchOperation currentBatch = update.currentBatch(); | 1171 | FlowRuleBatchOperation currentBatch = update.currentBatch(); |
1171 | if (currentBatch != null) { | 1172 | if (currentBatch != null) { | ... | ... |
... | @@ -98,6 +98,7 @@ public class LinkCollectionIntentInstaller | ... | @@ -98,6 +98,7 @@ public class LinkCollectionIntentInstaller |
98 | outputPorts.put(egressPoint.deviceId(), egressPoint.port()); | 98 | outputPorts.put(egressPoint.deviceId(), egressPoint.port()); |
99 | } | 99 | } |
100 | 100 | ||
101 | + //FIXME change to new api | ||
101 | FlowRuleBatchOperation batchOperation = | 102 | FlowRuleBatchOperation batchOperation = |
102 | new FlowRuleBatchOperation(outputPorts | 103 | new FlowRuleBatchOperation(outputPorts |
103 | .keys() | 104 | .keys() |
... | @@ -105,7 +106,7 @@ public class LinkCollectionIntentInstaller | ... | @@ -105,7 +106,7 @@ public class LinkCollectionIntentInstaller |
105 | .map(deviceId -> createBatchEntry(operation, | 106 | .map(deviceId -> createBatchEntry(operation, |
106 | intent, deviceId, | 107 | intent, deviceId, |
107 | outputPorts.get(deviceId))) | 108 | outputPorts.get(deviceId))) |
108 | - .collect(Collectors.toList())); | 109 | + .collect(Collectors.toList()), null, 0); |
109 | 110 | ||
110 | return Collections.singletonList(batchOperation); | 111 | return Collections.singletonList(batchOperation); |
111 | } | 112 | } | ... | ... |
... | @@ -181,6 +181,7 @@ public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIn | ... | @@ -181,6 +181,7 @@ public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIn |
181 | true); | 181 | true); |
182 | rules.add(new FlowRuleBatchEntry(operation, rule)); | 182 | rules.add(new FlowRuleBatchEntry(operation, rule)); |
183 | 183 | ||
184 | - return Lists.newArrayList(new FlowRuleBatchOperation(rules)); | 184 | + //FIXME change to new api |
185 | + return Lists.newArrayList(new FlowRuleBatchOperation(rules, null, 0)); | ||
185 | } | 186 | } |
186 | } | 187 | } | ... | ... |
... | @@ -108,7 +108,8 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { | ... | @@ -108,7 +108,8 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { |
108 | intent.id().fingerprint())); | 108 | intent.id().fingerprint())); |
109 | prev = link.dst(); | 109 | prev = link.dst(); |
110 | } | 110 | } |
111 | - return Lists.newArrayList(new FlowRuleBatchOperation(rules)); | 111 | + //FIXME this should change to new api. |
112 | + return Lists.newArrayList(new FlowRuleBatchOperation(rules, null, 0)); | ||
112 | } | 113 | } |
113 | 114 | ||
114 | @Override | 115 | @Override |
... | @@ -138,7 +139,8 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { | ... | @@ -138,7 +139,8 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { |
138 | intent.id().fingerprint())); | 139 | intent.id().fingerprint())); |
139 | prev = link.dst(); | 140 | prev = link.dst(); |
140 | } | 141 | } |
141 | - return Lists.newArrayList(new FlowRuleBatchOperation(rules)); | 142 | + // FIXME this should change to new api |
143 | + return Lists.newArrayList(new FlowRuleBatchOperation(rules, null, 0)); | ||
142 | } | 144 | } |
143 | 145 | ||
144 | @Override | 146 | @Override | ... | ... |
... | @@ -31,7 +31,7 @@ public class TestEventDispatcher extends DefaultEventSinkRegistry | ... | @@ -31,7 +31,7 @@ public class TestEventDispatcher extends DefaultEventSinkRegistry |
31 | 31 | ||
32 | @Override | 32 | @Override |
33 | @SuppressWarnings("unchecked") | 33 | @SuppressWarnings("unchecked") |
34 | - public void post(Event event) { | 34 | + public synchronized void post(Event event) { |
35 | EventSink sink = getSink(event.getClass()); | 35 | EventSink sink = getSink(event.getClass()); |
36 | checkState(sink != null, "No sink for event %s", event); | 36 | checkState(sink != null, "No sink for event %s", event); |
37 | sink.process(event); | 37 | sink.process(event); | ... | ... |
... | @@ -20,12 +20,15 @@ import com.google.common.collect.ImmutableMap; | ... | @@ -20,12 +20,15 @@ import com.google.common.collect.ImmutableMap; |
20 | import com.google.common.collect.Lists; | 20 | import com.google.common.collect.Lists; |
21 | import com.google.common.collect.Sets; | 21 | import com.google.common.collect.Sets; |
22 | import com.google.common.util.concurrent.ListenableFuture; | 22 | import com.google.common.util.concurrent.ListenableFuture; |
23 | - | 23 | +import com.google.common.util.concurrent.MoreExecutors; |
24 | import org.junit.After; | 24 | import org.junit.After; |
25 | import org.junit.Before; | 25 | import org.junit.Before; |
26 | import org.junit.Test; | 26 | import org.junit.Test; |
27 | import org.onosproject.core.ApplicationId; | 27 | import org.onosproject.core.ApplicationId; |
28 | +import org.onosproject.core.CoreService; | ||
28 | import org.onosproject.core.DefaultApplicationId; | 29 | import org.onosproject.core.DefaultApplicationId; |
30 | +import org.onosproject.core.IdGenerator; | ||
31 | +import org.onosproject.core.Version; | ||
29 | import org.onosproject.event.impl.TestEventDispatcher; | 32 | import org.onosproject.event.impl.TestEventDispatcher; |
30 | import org.onosproject.net.DefaultDevice; | 33 | import org.onosproject.net.DefaultDevice; |
31 | import org.onosproject.net.Device; | 34 | import org.onosproject.net.Device; |
... | @@ -36,7 +39,6 @@ import org.onosproject.net.Port; | ... | @@ -36,7 +39,6 @@ import org.onosproject.net.Port; |
36 | import org.onosproject.net.PortNumber; | 39 | import org.onosproject.net.PortNumber; |
37 | import org.onosproject.net.device.DeviceListener; | 40 | import org.onosproject.net.device.DeviceListener; |
38 | import org.onosproject.net.device.DeviceServiceAdapter; | 41 | import org.onosproject.net.device.DeviceServiceAdapter; |
39 | -import org.onosproject.net.flow.BatchOperation; | ||
40 | import org.onosproject.net.flow.CompletedBatchOperation; | 42 | import org.onosproject.net.flow.CompletedBatchOperation; |
41 | import org.onosproject.net.flow.DefaultFlowEntry; | 43 | import org.onosproject.net.flow.DefaultFlowEntry; |
42 | import org.onosproject.net.flow.DefaultFlowRule; | 44 | import org.onosproject.net.flow.DefaultFlowRule; |
... | @@ -72,6 +74,7 @@ import java.util.concurrent.Executor; | ... | @@ -72,6 +74,7 @@ import java.util.concurrent.Executor; |
72 | import java.util.concurrent.Future; | 74 | import java.util.concurrent.Future; |
73 | import java.util.concurrent.TimeUnit; | 75 | import java.util.concurrent.TimeUnit; |
74 | import java.util.concurrent.TimeoutException; | 76 | import java.util.concurrent.TimeoutException; |
77 | +import java.util.concurrent.atomic.AtomicLong; | ||
75 | 78 | ||
76 | import static org.junit.Assert.*; | 79 | import static org.junit.Assert.*; |
77 | import static org.onosproject.net.flow.FlowRuleEvent.Type.*; | 80 | import static org.onosproject.net.flow.FlowRuleEvent.Type.*; |
... | @@ -97,12 +100,16 @@ public class FlowRuleManagerTest { | ... | @@ -97,12 +100,16 @@ public class FlowRuleManagerTest { |
97 | protected TestListener listener = new TestListener(); | 100 | protected TestListener listener = new TestListener(); |
98 | private ApplicationId appId; | 101 | private ApplicationId appId; |
99 | 102 | ||
103 | + | ||
100 | @Before | 104 | @Before |
101 | public void setUp() { | 105 | public void setUp() { |
102 | mgr = new FlowRuleManager(); | 106 | mgr = new FlowRuleManager(); |
103 | mgr.store = new SimpleFlowRuleStore(); | 107 | mgr.store = new SimpleFlowRuleStore(); |
104 | mgr.eventDispatcher = new TestEventDispatcher(); | 108 | mgr.eventDispatcher = new TestEventDispatcher(); |
105 | mgr.deviceService = new TestDeviceService(); | 109 | mgr.deviceService = new TestDeviceService(); |
110 | + mgr.coreService = new TestCoreService(); | ||
111 | + mgr.operationsService = MoreExecutors.newDirectExecutorService(); | ||
112 | + mgr.deviceInstallers = MoreExecutors.newDirectExecutorService(); | ||
106 | service = mgr; | 113 | service = mgr; |
107 | registry = mgr; | 114 | registry = mgr; |
108 | 115 | ||
... | @@ -246,14 +253,23 @@ public class FlowRuleManagerTest { | ... | @@ -246,14 +253,23 @@ public class FlowRuleManagerTest { |
246 | 253 | ||
247 | @Test | 254 | @Test |
248 | public void flowRemoved() { | 255 | public void flowRemoved() { |
256 | + | ||
249 | FlowRule f1 = addFlowRule(1); | 257 | FlowRule f1 = addFlowRule(1); |
250 | FlowRule f2 = addFlowRule(2); | 258 | FlowRule f2 = addFlowRule(2); |
251 | StoredFlowEntry fe1 = new DefaultFlowEntry(f1); | 259 | StoredFlowEntry fe1 = new DefaultFlowEntry(f1); |
252 | FlowEntry fe2 = new DefaultFlowEntry(f2); | 260 | FlowEntry fe2 = new DefaultFlowEntry(f2); |
261 | + | ||
262 | + | ||
253 | providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2)); | 263 | providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2)); |
254 | service.removeFlowRules(f1); | 264 | service.removeFlowRules(f1); |
265 | + | ||
255 | fe1.setState(FlowEntryState.REMOVED); | 266 | fe1.setState(FlowEntryState.REMOVED); |
267 | + | ||
268 | + | ||
269 | + | ||
256 | providerService.flowRemoved(fe1); | 270 | providerService.flowRemoved(fe1); |
271 | + | ||
272 | + | ||
257 | validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADDED, | 273 | validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADDED, |
258 | RULE_ADDED, RULE_REMOVE_REQUESTED, RULE_REMOVED); | 274 | RULE_ADDED, RULE_REMOVE_REQUESTED, RULE_REMOVED); |
259 | 275 | ||
... | @@ -263,11 +279,13 @@ public class FlowRuleManagerTest { | ... | @@ -263,11 +279,13 @@ public class FlowRuleManagerTest { |
263 | FlowRule f3 = flowRule(3, 3); | 279 | FlowRule f3 = flowRule(3, 3); |
264 | FlowEntry fe3 = new DefaultFlowEntry(f3); | 280 | FlowEntry fe3 = new DefaultFlowEntry(f3); |
265 | service.applyFlowRules(f3); | 281 | service.applyFlowRules(f3); |
282 | + | ||
266 | providerService.pushFlowMetrics(DID, Collections.singletonList(fe3)); | 283 | providerService.pushFlowMetrics(DID, Collections.singletonList(fe3)); |
267 | validateEvents(RULE_ADD_REQUESTED, RULE_ADDED); | 284 | validateEvents(RULE_ADD_REQUESTED, RULE_ADDED); |
268 | 285 | ||
269 | providerService.flowRemoved(fe3); | 286 | providerService.flowRemoved(fe3); |
270 | validateEvents(); | 287 | validateEvents(); |
288 | + | ||
271 | } | 289 | } |
272 | 290 | ||
273 | @Test | 291 | @Test |
... | @@ -281,7 +299,6 @@ public class FlowRuleManagerTest { | ... | @@ -281,7 +299,6 @@ public class FlowRuleManagerTest { |
281 | FlowEntry fe1 = new DefaultFlowEntry(f1); | 299 | FlowEntry fe1 = new DefaultFlowEntry(f1); |
282 | FlowEntry fe2 = new DefaultFlowEntry(f2); | 300 | FlowEntry fe2 = new DefaultFlowEntry(f2); |
283 | 301 | ||
284 | - | ||
285 | //FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED); | 302 | //FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED); |
286 | //FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED); | 303 | //FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED); |
287 | 304 | ||
... | @@ -388,7 +405,7 @@ public class FlowRuleManagerTest { | ... | @@ -388,7 +405,7 @@ public class FlowRuleManagerTest { |
388 | FlowRuleBatchEntry.FlowRuleOperation.ADD, f2); | 405 | FlowRuleBatchEntry.FlowRuleOperation.ADD, f2); |
389 | 406 | ||
390 | FlowRuleBatchOperation fbo = new FlowRuleBatchOperation( | 407 | FlowRuleBatchOperation fbo = new FlowRuleBatchOperation( |
391 | - Lists.newArrayList(fbe1, fbe2)); | 408 | + Lists.newArrayList(fbe1, fbe2), null, 0); |
392 | Future<CompletedBatchOperation> future = mgr.applyBatch(fbo); | 409 | Future<CompletedBatchOperation> future = mgr.applyBatch(fbo); |
393 | assertTrue("Entries in wrong state", | 410 | assertTrue("Entries in wrong state", |
394 | validateState(ImmutableMap.of( | 411 | validateState(ImmutableMap.of( |
... | @@ -406,53 +423,6 @@ public class FlowRuleManagerTest { | ... | @@ -406,53 +423,6 @@ public class FlowRuleManagerTest { |
406 | 423 | ||
407 | } | 424 | } |
408 | 425 | ||
409 | - @Test | ||
410 | - public void cancelBatch() { | ||
411 | - FlowRule f1 = flowRule(1, 1); | ||
412 | - FlowRule f2 = flowRule(2, 2); | ||
413 | - | ||
414 | - | ||
415 | - mgr.applyFlowRules(f1); | ||
416 | - | ||
417 | - assertTrue("Entries in wrong state", | ||
418 | - validateState(ImmutableMap.of( | ||
419 | - f1, FlowEntryState.PENDING_ADD))); | ||
420 | - | ||
421 | - FlowEntry fe1 = new DefaultFlowEntry(f1); | ||
422 | - providerService.pushFlowMetrics(DID, Collections.<FlowEntry>singletonList(fe1)); | ||
423 | - | ||
424 | - assertTrue("Entries in wrong state", | ||
425 | - validateState(ImmutableMap.of( | ||
426 | - f1, FlowEntryState.ADDED))); | ||
427 | - | ||
428 | - | ||
429 | - FlowRuleBatchEntry fbe1 = new FlowRuleBatchEntry( | ||
430 | - FlowRuleBatchEntry.FlowRuleOperation.REMOVE, f1); | ||
431 | - | ||
432 | - FlowRuleBatchEntry fbe2 = new FlowRuleBatchEntry( | ||
433 | - FlowRuleBatchEntry.FlowRuleOperation.ADD, f2); | ||
434 | - | ||
435 | - FlowRuleBatchOperation fbo = new FlowRuleBatchOperation( | ||
436 | - Lists.newArrayList(fbe1, fbe2)); | ||
437 | - Future<CompletedBatchOperation> future = mgr.applyBatch(fbo); | ||
438 | - | ||
439 | - future.cancel(true); | ||
440 | - | ||
441 | - assertTrue(flowCount() == 2); | ||
442 | - | ||
443 | - /* | ||
444 | - * Rule f1 should be re-added to the list and therefore be in a pending add | ||
445 | - * state. | ||
446 | - */ | ||
447 | - assertTrue("Entries in wrong state", | ||
448 | - validateState(ImmutableMap.of( | ||
449 | - f2, FlowEntryState.PENDING_REMOVE, | ||
450 | - f1, FlowEntryState.PENDING_ADD))); | ||
451 | - | ||
452 | - | ||
453 | - } | ||
454 | - | ||
455 | - | ||
456 | private static class TestListener implements FlowRuleListener { | 426 | private static class TestListener implements FlowRuleListener { |
457 | final List<FlowRuleEvent> events = new ArrayList<>(); | 427 | final List<FlowRuleEvent> events = new ArrayList<>(); |
458 | 428 | ||
... | @@ -528,9 +498,8 @@ public class FlowRuleManagerTest { | ... | @@ -528,9 +498,8 @@ public class FlowRuleManagerTest { |
528 | } | 498 | } |
529 | 499 | ||
530 | @Override | 500 | @Override |
531 | - public ListenableFuture<CompletedBatchOperation> executeBatch( | 501 | + public void executeBatch(FlowRuleBatchOperation batch) { |
532 | - BatchOperation<FlowRuleBatchEntry> batch) { | 502 | + // TODO: need to call batchOperationComplete |
533 | - return new TestInstallationFuture(); | ||
534 | } | 503 | } |
535 | 504 | ||
536 | private class TestInstallationFuture | 505 | private class TestInstallationFuture |
... | @@ -554,14 +523,14 @@ public class FlowRuleManagerTest { | ... | @@ -554,14 +523,14 @@ public class FlowRuleManagerTest { |
554 | @Override | 523 | @Override |
555 | public CompletedBatchOperation get() | 524 | public CompletedBatchOperation get() |
556 | throws InterruptedException, ExecutionException { | 525 | throws InterruptedException, ExecutionException { |
557 | - return new CompletedBatchOperation(true, Collections.<FlowRule>emptySet()); | 526 | + return new CompletedBatchOperation(true, Collections.<FlowRule>emptySet(), null); |
558 | } | 527 | } |
559 | 528 | ||
560 | @Override | 529 | @Override |
561 | public CompletedBatchOperation get(long timeout, TimeUnit unit) | 530 | public CompletedBatchOperation get(long timeout, TimeUnit unit) |
562 | throws InterruptedException, | 531 | throws InterruptedException, |
563 | ExecutionException, TimeoutException { | 532 | ExecutionException, TimeoutException { |
564 | - return new CompletedBatchOperation(true, Collections.<FlowRule>emptySet()); | 533 | + return new CompletedBatchOperation(true, Collections.<FlowRule>emptySet(), null); |
565 | } | 534 | } |
566 | 535 | ||
567 | @Override | 536 | @Override |
... | @@ -644,4 +613,37 @@ public class FlowRuleManagerTest { | ... | @@ -644,4 +613,37 @@ public class FlowRuleManagerTest { |
644 | } | 613 | } |
645 | } | 614 | } |
646 | 615 | ||
616 | + private class TestCoreService implements CoreService { | ||
617 | + @Override | ||
618 | + public Version version() { | ||
619 | + return null; | ||
620 | + } | ||
621 | + | ||
622 | + @Override | ||
623 | + public Set<ApplicationId> getAppIds() { | ||
624 | + return null; | ||
625 | + } | ||
626 | + | ||
627 | + @Override | ||
628 | + public ApplicationId getAppId(Short id) { | ||
629 | + return null; | ||
630 | + } | ||
631 | + | ||
632 | + @Override | ||
633 | + public ApplicationId registerApplication(String identifier) { | ||
634 | + return null; | ||
635 | + } | ||
636 | + | ||
637 | + @Override | ||
638 | + public IdGenerator getIdGenerator(String topic) { | ||
639 | + return new IdGenerator() { | ||
640 | + private AtomicLong counter = new AtomicLong(0); | ||
641 | + @Override | ||
642 | + public long getNewId() { | ||
643 | + return counter.getAndIncrement(); | ||
644 | + } | ||
645 | + }; | ||
646 | + } | ||
647 | + } | ||
648 | + | ||
647 | } | 649 | } | ... | ... |
... | @@ -201,7 +201,7 @@ public class IntentManagerTest { | ... | @@ -201,7 +201,7 @@ public class IntentManagerTest { |
201 | FlowRule fr = new IntentTestsMocks.MockFlowRule(intent.number().intValue()); | 201 | FlowRule fr = new IntentTestsMocks.MockFlowRule(intent.number().intValue()); |
202 | List<FlowRuleBatchEntry> rules = Lists.newLinkedList(); | 202 | List<FlowRuleBatchEntry> rules = Lists.newLinkedList(); |
203 | rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, fr)); | 203 | rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, fr)); |
204 | - return Lists.newArrayList(new FlowRuleBatchOperation(rules)); | 204 | + return Lists.newArrayList(new FlowRuleBatchOperation(rules, fr.deviceId(), 0)); |
205 | } | 205 | } |
206 | 206 | ||
207 | @Override | 207 | @Override |
... | @@ -209,7 +209,7 @@ public class IntentManagerTest { | ... | @@ -209,7 +209,7 @@ public class IntentManagerTest { |
209 | FlowRule fr = new IntentTestsMocks.MockFlowRule(intent.number().intValue()); | 209 | FlowRule fr = new IntentTestsMocks.MockFlowRule(intent.number().intValue()); |
210 | List<FlowRuleBatchEntry> rules = Lists.newLinkedList(); | 210 | List<FlowRuleBatchEntry> rules = Lists.newLinkedList(); |
211 | rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, fr)); | 211 | rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, fr)); |
212 | - return Lists.newArrayList(new FlowRuleBatchOperation(rules)); | 212 | + return Lists.newArrayList(new FlowRuleBatchOperation(rules, fr.deviceId(), 0)); |
213 | } | 213 | } |
214 | 214 | ||
215 | @Override | 215 | @Override |
... | @@ -219,7 +219,7 @@ public class IntentManagerTest { | ... | @@ -219,7 +219,7 @@ public class IntentManagerTest { |
219 | List<FlowRuleBatchEntry> rules = Lists.newLinkedList(); | 219 | List<FlowRuleBatchEntry> rules = Lists.newLinkedList(); |
220 | rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, fr)); | 220 | rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, fr)); |
221 | rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, fr2)); | 221 | rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, fr2)); |
222 | - return Lists.newArrayList(new FlowRuleBatchOperation(rules)); | 222 | + return Lists.newArrayList(new FlowRuleBatchOperation(rules, fr.deviceId(), 0)); |
223 | } | 223 | } |
224 | } | 224 | } |
225 | 225 | ... | ... |
... | @@ -27,6 +27,7 @@ import org.onosproject.net.flow.FlowRule; | ... | @@ -27,6 +27,7 @@ import org.onosproject.net.flow.FlowRule; |
27 | import org.onosproject.net.flow.FlowRuleBatchEntry; | 27 | import org.onosproject.net.flow.FlowRuleBatchEntry; |
28 | import org.onosproject.net.flow.FlowRuleBatchOperation; | 28 | import org.onosproject.net.flow.FlowRuleBatchOperation; |
29 | import org.onosproject.net.flow.FlowRuleListener; | 29 | import org.onosproject.net.flow.FlowRuleListener; |
30 | +import org.onosproject.net.flow.FlowRuleOperations; | ||
30 | import org.onosproject.net.flow.FlowRuleService; | 31 | import org.onosproject.net.flow.FlowRuleService; |
31 | 32 | ||
32 | import com.google.common.collect.ImmutableSet; | 33 | import com.google.common.collect.ImmutableSet; |
... | @@ -45,11 +46,11 @@ public class MockFlowRuleService implements FlowRuleService { | ... | @@ -45,11 +46,11 @@ public class MockFlowRuleService implements FlowRuleService { |
45 | 46 | ||
46 | public void setFuture(boolean success, long intentId) { | 47 | public void setFuture(boolean success, long intentId) { |
47 | if (success) { | 48 | if (success) { |
48 | - future = Futures.immediateFuture(new CompletedBatchOperation(true, Collections.emptySet())); | 49 | + future = Futures.immediateFuture(new CompletedBatchOperation(true, Collections.emptySet(), null)); |
49 | } else { | 50 | } else { |
50 | final Set<Long> failedIds = ImmutableSet.of(intentId); | 51 | final Set<Long> failedIds = ImmutableSet.of(intentId); |
51 | future = Futures.immediateFuture( | 52 | future = Futures.immediateFuture( |
52 | - new CompletedBatchOperation(false, flows, failedIds)); | 53 | + new CompletedBatchOperation(false, flows, failedIds, null)); |
53 | } | 54 | } |
54 | } | 55 | } |
55 | 56 | ||
... | @@ -74,6 +75,11 @@ public class MockFlowRuleService implements FlowRuleService { | ... | @@ -74,6 +75,11 @@ public class MockFlowRuleService implements FlowRuleService { |
74 | } | 75 | } |
75 | 76 | ||
76 | @Override | 77 | @Override |
78 | + public void apply(FlowRuleOperations ops) { | ||
79 | + | ||
80 | + } | ||
81 | + | ||
82 | + @Override | ||
77 | public int getFlowRuleCount() { | 83 | public int getFlowRuleCount() { |
78 | return flows.size(); | 84 | return flows.size(); |
79 | } | 85 | } | ... | ... |
This diff is collapsed. Click to expand it.
... | @@ -34,4 +34,7 @@ public final class FlowStoreMessageSubjects { | ... | @@ -34,4 +34,7 @@ public final class FlowStoreMessageSubjects { |
34 | 34 | ||
35 | public static final MessageSubject REMOVE_FLOW_ENTRY | 35 | public static final MessageSubject REMOVE_FLOW_ENTRY |
36 | = new MessageSubject("peer-forward-remove-flow-entry"); | 36 | = new MessageSubject("peer-forward-remove-flow-entry"); |
37 | + | ||
38 | + public static final MessageSubject REMOTE_APPLY_COMPLETED | ||
39 | + = new MessageSubject("peer-apply-completed"); | ||
37 | } | 40 | } | ... | ... |
... | @@ -59,15 +59,17 @@ import org.onosproject.net.PortNumber; | ... | @@ -59,15 +59,17 @@ import org.onosproject.net.PortNumber; |
59 | import org.onosproject.net.device.DefaultDeviceDescription; | 59 | import org.onosproject.net.device.DefaultDeviceDescription; |
60 | import org.onosproject.net.device.DefaultPortDescription; | 60 | import org.onosproject.net.device.DefaultPortDescription; |
61 | import org.onosproject.net.flow.CompletedBatchOperation; | 61 | import org.onosproject.net.flow.CompletedBatchOperation; |
62 | -import org.onosproject.net.flow.FlowRule; | ||
63 | import org.onosproject.net.flow.DefaultFlowEntry; | 62 | import org.onosproject.net.flow.DefaultFlowEntry; |
64 | import org.onosproject.net.flow.DefaultFlowRule; | 63 | import org.onosproject.net.flow.DefaultFlowRule; |
65 | import org.onosproject.net.flow.DefaultTrafficSelector; | 64 | import org.onosproject.net.flow.DefaultTrafficSelector; |
66 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 65 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
67 | import org.onosproject.net.flow.FlowEntry; | 66 | import org.onosproject.net.flow.FlowEntry; |
68 | import org.onosproject.net.flow.FlowId; | 67 | import org.onosproject.net.flow.FlowId; |
68 | +import org.onosproject.net.flow.FlowRule; | ||
69 | import org.onosproject.net.flow.FlowRuleBatchEntry; | 69 | import org.onosproject.net.flow.FlowRuleBatchEntry; |
70 | +import org.onosproject.net.flow.FlowRuleBatchEvent; | ||
70 | import org.onosproject.net.flow.FlowRuleBatchOperation; | 71 | import org.onosproject.net.flow.FlowRuleBatchOperation; |
72 | +import org.onosproject.net.flow.FlowRuleBatchRequest; | ||
71 | import org.onosproject.net.flow.StoredFlowEntry; | 73 | import org.onosproject.net.flow.StoredFlowEntry; |
72 | import org.onosproject.net.flow.criteria.Criteria; | 74 | import org.onosproject.net.flow.criteria.Criteria; |
73 | import org.onosproject.net.flow.criteria.Criterion; | 75 | import org.onosproject.net.flow.criteria.Criterion; |
... | @@ -162,6 +164,7 @@ public final class KryoNamespaces { | ... | @@ -162,6 +164,7 @@ public final class KryoNamespaces { |
162 | .register(Collections.emptySet().getClass()) | 164 | .register(Collections.emptySet().getClass()) |
163 | .register(Optional.class) | 165 | .register(Optional.class) |
164 | .register(Collections.emptyList().getClass()) | 166 | .register(Collections.emptyList().getClass()) |
167 | + .register(Collections.unmodifiableSet(Collections.emptySet()).getClass()) | ||
165 | .build(); | 168 | .build(); |
166 | 169 | ||
167 | /** | 170 | /** |
... | @@ -255,6 +258,9 @@ public final class KryoNamespaces { | ... | @@ -255,6 +258,9 @@ public final class KryoNamespaces { |
255 | L3ModificationInstruction.L3SubType.class, | 258 | L3ModificationInstruction.L3SubType.class, |
256 | L3ModificationInstruction.ModIPInstruction.class, | 259 | L3ModificationInstruction.ModIPInstruction.class, |
257 | RoleInfo.class, | 260 | RoleInfo.class, |
261 | + FlowRuleBatchEvent.class, | ||
262 | + FlowRuleBatchEvent.Type.class, | ||
263 | + FlowRuleBatchRequest.class, | ||
258 | FlowRuleBatchOperation.class, | 264 | FlowRuleBatchOperation.class, |
259 | CompletedBatchOperation.class, | 265 | CompletedBatchOperation.class, |
260 | FlowRuleBatchEntry.class, | 266 | FlowRuleBatchEntry.class, | ... | ... |
... | @@ -21,13 +21,13 @@ import com.google.common.cache.CacheBuilder; | ... | @@ -21,13 +21,13 @@ import com.google.common.cache.CacheBuilder; |
21 | import com.google.common.cache.RemovalListener; | 21 | import com.google.common.cache.RemovalListener; |
22 | import com.google.common.cache.RemovalNotification; | 22 | import com.google.common.cache.RemovalNotification; |
23 | import com.google.common.collect.FluentIterable; | 23 | import com.google.common.collect.FluentIterable; |
24 | -import com.google.common.util.concurrent.Futures; | 24 | +import com.google.common.collect.Sets; |
25 | import com.google.common.util.concurrent.SettableFuture; | 25 | import com.google.common.util.concurrent.SettableFuture; |
26 | - | ||
27 | import org.apache.felix.scr.annotations.Activate; | 26 | import org.apache.felix.scr.annotations.Activate; |
28 | import org.apache.felix.scr.annotations.Component; | 27 | import org.apache.felix.scr.annotations.Component; |
29 | import org.apache.felix.scr.annotations.Deactivate; | 28 | import org.apache.felix.scr.annotations.Deactivate; |
30 | import org.apache.felix.scr.annotations.Service; | 29 | import org.apache.felix.scr.annotations.Service; |
30 | +import org.onlab.util.NewConcurrentHashMap; | ||
31 | import org.onosproject.net.DeviceId; | 31 | import org.onosproject.net.DeviceId; |
32 | import org.onosproject.net.flow.CompletedBatchOperation; | 32 | import org.onosproject.net.flow.CompletedBatchOperation; |
33 | import org.onosproject.net.flow.DefaultFlowEntry; | 33 | import org.onosproject.net.flow.DefaultFlowEntry; |
... | @@ -46,7 +46,6 @@ import org.onosproject.net.flow.FlowRuleStore; | ... | @@ -46,7 +46,6 @@ import org.onosproject.net.flow.FlowRuleStore; |
46 | import org.onosproject.net.flow.FlowRuleStoreDelegate; | 46 | import org.onosproject.net.flow.FlowRuleStoreDelegate; |
47 | import org.onosproject.net.flow.StoredFlowEntry; | 47 | import org.onosproject.net.flow.StoredFlowEntry; |
48 | import org.onosproject.store.AbstractStore; | 48 | import org.onosproject.store.AbstractStore; |
49 | -import org.onlab.util.NewConcurrentHashMap; | ||
50 | import org.slf4j.Logger; | 49 | import org.slf4j.Logger; |
51 | 50 | ||
52 | import java.util.ArrayList; | 51 | import java.util.ArrayList; |
... | @@ -56,7 +55,6 @@ import java.util.concurrent.ConcurrentHashMap; | ... | @@ -56,7 +55,6 @@ import java.util.concurrent.ConcurrentHashMap; |
56 | import java.util.concurrent.ConcurrentMap; | 55 | import java.util.concurrent.ConcurrentMap; |
57 | import java.util.concurrent.CopyOnWriteArrayList; | 56 | import java.util.concurrent.CopyOnWriteArrayList; |
58 | import java.util.concurrent.ExecutionException; | 57 | import java.util.concurrent.ExecutionException; |
59 | -import java.util.concurrent.Future; | ||
60 | import java.util.concurrent.TimeUnit; | 58 | import java.util.concurrent.TimeUnit; |
61 | import java.util.concurrent.TimeoutException; | 59 | import java.util.concurrent.TimeoutException; |
62 | import java.util.concurrent.atomic.AtomicInteger; | 60 | import java.util.concurrent.atomic.AtomicInteger; |
... | @@ -261,13 +259,14 @@ public class SimpleFlowRuleStore | ... | @@ -261,13 +259,14 @@ public class SimpleFlowRuleStore |
261 | } | 259 | } |
262 | 260 | ||
263 | @Override | 261 | @Override |
264 | - public Future<CompletedBatchOperation> storeBatch( | 262 | + public void storeBatch( |
265 | - FlowRuleBatchOperation batchOperation) { | 263 | + FlowRuleBatchOperation operation) { |
266 | List<FlowRuleBatchEntry> toAdd = new ArrayList<>(); | 264 | List<FlowRuleBatchEntry> toAdd = new ArrayList<>(); |
267 | List<FlowRuleBatchEntry> toRemove = new ArrayList<>(); | 265 | List<FlowRuleBatchEntry> toRemove = new ArrayList<>(); |
268 | - for (FlowRuleBatchEntry entry : batchOperation.getOperations()) { | 266 | + |
269 | - final FlowRule flowRule = entry.target(); | 267 | + for (FlowRuleBatchEntry entry : operation.getOperations()) { |
270 | - if (entry.operator().equals(FlowRuleOperation.ADD)) { | 268 | + final FlowRule flowRule = entry.getTarget(); |
269 | + if (entry.getOperator().equals(FlowRuleOperation.ADD)) { | ||
271 | if (!getFlowEntries(flowRule.deviceId(), flowRule.id()).contains(flowRule)) { | 270 | if (!getFlowEntries(flowRule.deviceId(), flowRule.id()).contains(flowRule)) { |
272 | storeFlowRule(flowRule); | 271 | storeFlowRule(flowRule); |
273 | toAdd.add(entry); | 272 | toAdd.add(entry); |
... | @@ -283,21 +282,27 @@ public class SimpleFlowRuleStore | ... | @@ -283,21 +282,27 @@ public class SimpleFlowRuleStore |
283 | } | 282 | } |
284 | 283 | ||
285 | if (toAdd.isEmpty() && toRemove.isEmpty()) { | 284 | if (toAdd.isEmpty() && toRemove.isEmpty()) { |
286 | - return Futures.immediateFuture(new CompletedBatchOperation(true, Collections.<FlowRule>emptySet())); | 285 | + notifyDelegate(FlowRuleBatchEvent.completed( |
286 | + new FlowRuleBatchRequest(operation.id(), Collections.emptySet()), | ||
287 | + new CompletedBatchOperation(true, Collections.emptySet(), | ||
288 | + operation.deviceId()))); | ||
289 | + return; | ||
287 | } | 290 | } |
288 | 291 | ||
289 | SettableFuture<CompletedBatchOperation> r = SettableFuture.create(); | 292 | SettableFuture<CompletedBatchOperation> r = SettableFuture.create(); |
290 | final int batchId = localBatchIdGen.incrementAndGet(); | 293 | final int batchId = localBatchIdGen.incrementAndGet(); |
291 | 294 | ||
292 | pendingFutures.put(batchId, r); | 295 | pendingFutures.put(batchId, r); |
293 | - notifyDelegate(FlowRuleBatchEvent.requested(new FlowRuleBatchRequest(batchId, toAdd, toRemove))); | ||
294 | 296 | ||
295 | - return r; | 297 | + toAdd.addAll(toRemove); |
298 | + notifyDelegate(FlowRuleBatchEvent.requested( | ||
299 | + new FlowRuleBatchRequest(batchId, Sets.newHashSet(toAdd)), operation.deviceId())); | ||
300 | + | ||
296 | } | 301 | } |
297 | 302 | ||
298 | @Override | 303 | @Override |
299 | public void batchOperationComplete(FlowRuleBatchEvent event) { | 304 | public void batchOperationComplete(FlowRuleBatchEvent event) { |
300 | - final Integer batchId = event.subject().batchId(); | 305 | + final Long batchId = event.subject().batchId(); |
301 | SettableFuture<CompletedBatchOperation> future | 306 | SettableFuture<CompletedBatchOperation> future |
302 | = pendingFutures.getIfPresent(batchId); | 307 | = pendingFutures.getIfPresent(batchId); |
303 | if (future != null) { | 308 | if (future != null) { | ... | ... |
providers/null/device/src/main/java/org/onosproject/provider/nil/device/impl/NullDeviceProvider.java
... | @@ -116,7 +116,7 @@ public class NullDeviceProvider extends AbstractProvider implements DeviceProvid | ... | @@ -116,7 +116,7 @@ public class NullDeviceProvider extends AbstractProvider implements DeviceProvid |
116 | @Activate | 116 | @Activate |
117 | public void activate(ComponentContext context) { | 117 | public void activate(ComponentContext context) { |
118 | providerService = providerRegistry.register(this); | 118 | providerService = providerRegistry.register(this); |
119 | - if (modified(context)) { | 119 | + if (!modified(context)) { |
120 | deviceBuilder.submit(new DeviceCreator(true)); | 120 | deviceBuilder.submit(new DeviceCreator(true)); |
121 | } | 121 | } |
122 | log.info("Started"); | 122 | log.info("Started"); |
... | @@ -173,6 +173,9 @@ public class NullDeviceProvider extends AbstractProvider implements DeviceProvid | ... | @@ -173,6 +173,9 @@ public class NullDeviceProvider extends AbstractProvider implements DeviceProvid |
173 | chgd |= true; | 173 | chgd |= true; |
174 | } | 174 | } |
175 | log.info("Using settings numDevices={}, numPorts={}", numDevices, numPorts); | 175 | log.info("Using settings numDevices={}, numPorts={}", numDevices, numPorts); |
176 | + if (chgd) { | ||
177 | + deviceBuilder.submit(new DeviceCreator(true)); | ||
178 | + } | ||
176 | return chgd; | 179 | return chgd; |
177 | } | 180 | } |
178 | 181 | ... | ... |
... | @@ -15,9 +15,7 @@ | ... | @@ -15,9 +15,7 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.provider.nil.flow.impl; | 16 | package org.onosproject.provider.nil.flow.impl; |
17 | 17 | ||
18 | -import com.google.common.collect.HashMultimap; | 18 | +import com.google.common.collect.Sets; |
19 | -import com.google.common.collect.Multimap; | ||
20 | -import com.google.common.util.concurrent.Futures; | ||
21 | import org.apache.felix.scr.annotations.Activate; | 19 | import org.apache.felix.scr.annotations.Activate; |
22 | import org.apache.felix.scr.annotations.Component; | 20 | import org.apache.felix.scr.annotations.Component; |
23 | import org.apache.felix.scr.annotations.Deactivate; | 21 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -29,12 +27,12 @@ import org.jboss.netty.util.TimerTask; | ... | @@ -29,12 +27,12 @@ import org.jboss.netty.util.TimerTask; |
29 | import org.onlab.util.Timer; | 27 | import org.onlab.util.Timer; |
30 | import org.onosproject.core.ApplicationId; | 28 | import org.onosproject.core.ApplicationId; |
31 | import org.onosproject.net.DeviceId; | 29 | import org.onosproject.net.DeviceId; |
32 | -import org.onosproject.net.flow.BatchOperation; | ||
33 | import org.onosproject.net.flow.CompletedBatchOperation; | 30 | import org.onosproject.net.flow.CompletedBatchOperation; |
34 | import org.onosproject.net.flow.DefaultFlowEntry; | 31 | import org.onosproject.net.flow.DefaultFlowEntry; |
35 | import org.onosproject.net.flow.FlowEntry; | 32 | import org.onosproject.net.flow.FlowEntry; |
36 | import org.onosproject.net.flow.FlowRule; | 33 | import org.onosproject.net.flow.FlowRule; |
37 | import org.onosproject.net.flow.FlowRuleBatchEntry; | 34 | import org.onosproject.net.flow.FlowRuleBatchEntry; |
35 | +import org.onosproject.net.flow.FlowRuleBatchOperation; | ||
38 | import org.onosproject.net.flow.FlowRuleProvider; | 36 | import org.onosproject.net.flow.FlowRuleProvider; |
39 | import org.onosproject.net.flow.FlowRuleProviderRegistry; | 37 | import org.onosproject.net.flow.FlowRuleProviderRegistry; |
40 | import org.onosproject.net.flow.FlowRuleProviderService; | 38 | import org.onosproject.net.flow.FlowRuleProviderService; |
... | @@ -43,7 +41,9 @@ import org.onosproject.net.provider.ProviderId; | ... | @@ -43,7 +41,9 @@ import org.onosproject.net.provider.ProviderId; |
43 | import org.slf4j.Logger; | 41 | import org.slf4j.Logger; |
44 | 42 | ||
45 | import java.util.Collections; | 43 | import java.util.Collections; |
46 | -import java.util.concurrent.Future; | 44 | +import java.util.Set; |
45 | +import java.util.concurrent.ConcurrentHashMap; | ||
46 | +import java.util.concurrent.ConcurrentMap; | ||
47 | import java.util.concurrent.TimeUnit; | 47 | import java.util.concurrent.TimeUnit; |
48 | 48 | ||
49 | import static org.slf4j.LoggerFactory.getLogger; | 49 | import static org.slf4j.LoggerFactory.getLogger; |
... | @@ -59,7 +59,7 @@ public class NullFlowRuleProvider extends AbstractProvider implements FlowRulePr | ... | @@ -59,7 +59,7 @@ public class NullFlowRuleProvider extends AbstractProvider implements FlowRulePr |
59 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 59 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
60 | protected FlowRuleProviderRegistry providerRegistry; | 60 | protected FlowRuleProviderRegistry providerRegistry; |
61 | 61 | ||
62 | - private Multimap<DeviceId, FlowEntry> flowTable = HashMultimap.create(); | 62 | + private ConcurrentMap<DeviceId, Set<FlowEntry>> flowTable = new ConcurrentHashMap<>(); |
63 | 63 | ||
64 | private FlowRuleProviderService providerService; | 64 | private FlowRuleProviderService providerService; |
65 | 65 | ||
... | @@ -88,18 +88,10 @@ public class NullFlowRuleProvider extends AbstractProvider implements FlowRulePr | ... | @@ -88,18 +88,10 @@ public class NullFlowRuleProvider extends AbstractProvider implements FlowRulePr |
88 | } | 88 | } |
89 | 89 | ||
90 | @Override | 90 | @Override |
91 | - public void applyFlowRule(FlowRule... flowRules) { | 91 | + public void applyFlowRule(FlowRule... flowRules) {} |
92 | - for (int i = 0; i < flowRules.length; i++) { | ||
93 | - flowTable.put(flowRules[i].deviceId(), new DefaultFlowEntry(flowRules[i])); | ||
94 | - } | ||
95 | - } | ||
96 | 92 | ||
97 | @Override | 93 | @Override |
98 | - public void removeFlowRule(FlowRule... flowRules) { | 94 | + public void removeFlowRule(FlowRule... flowRules) {} |
99 | - for (int i = 0; i < flowRules.length; i++) { | ||
100 | - flowTable.remove(flowRules[i].deviceId(), flowRules[i]); | ||
101 | - } | ||
102 | - } | ||
103 | 95 | ||
104 | @Override | 96 | @Override |
105 | public void removeRulesById(ApplicationId id, FlowRule... flowRules) { | 97 | public void removeRulesById(ApplicationId id, FlowRule... flowRules) { |
... | @@ -107,26 +99,32 @@ public class NullFlowRuleProvider extends AbstractProvider implements FlowRulePr | ... | @@ -107,26 +99,32 @@ public class NullFlowRuleProvider extends AbstractProvider implements FlowRulePr |
107 | } | 99 | } |
108 | 100 | ||
109 | @Override | 101 | @Override |
110 | - public Future<CompletedBatchOperation> executeBatch( | 102 | + public void executeBatch( |
111 | - BatchOperation<FlowRuleBatchEntry> batch) { | 103 | + FlowRuleBatchOperation batch) { |
104 | + Set<FlowEntry> flowRules = flowTable.getOrDefault(batch.deviceId(), Sets.newConcurrentHashSet()); | ||
112 | for (FlowRuleBatchEntry fbe : batch.getOperations()) { | 105 | for (FlowRuleBatchEntry fbe : batch.getOperations()) { |
113 | switch (fbe.operator()) { | 106 | switch (fbe.operator()) { |
114 | case ADD: | 107 | case ADD: |
115 | - applyFlowRule(fbe.target()); | 108 | + flowRules.add(new DefaultFlowEntry(fbe.target())); |
116 | break; | 109 | break; |
117 | case REMOVE: | 110 | case REMOVE: |
118 | - removeFlowRule(fbe.target()); | 111 | + flowRules.remove(new DefaultFlowEntry(fbe.target())); |
119 | break; | 112 | break; |
120 | case MODIFY: | 113 | case MODIFY: |
121 | - removeFlowRule(fbe.target()); | 114 | + FlowEntry entry = new DefaultFlowEntry(fbe.target()); |
122 | - applyFlowRule(fbe.target()); | 115 | + flowRules.remove(entry); |
116 | + flowRules.add(entry); | ||
123 | break; | 117 | break; |
124 | default: | 118 | default: |
125 | log.error("Unknown flow operation: {}", fbe); | 119 | log.error("Unknown flow operation: {}", fbe); |
126 | } | 120 | } |
127 | } | 121 | } |
128 | - return Futures.immediateFuture( | 122 | + flowTable.put(batch.deviceId(), flowRules); |
129 | - new CompletedBatchOperation(true, Collections.emptySet())); | 123 | + providerService.batchOperationCompleted(batch.id(), |
124 | + new CompletedBatchOperation( | ||
125 | + true, | ||
126 | + Collections.emptySet(), | ||
127 | + batch.deviceId())); | ||
130 | } | 128 | } |
131 | 129 | ||
132 | private class StatisticTask implements TimerTask { | 130 | private class StatisticTask implements TimerTask { |
... | @@ -134,10 +132,11 @@ public class NullFlowRuleProvider extends AbstractProvider implements FlowRulePr | ... | @@ -134,10 +132,11 @@ public class NullFlowRuleProvider extends AbstractProvider implements FlowRulePr |
134 | @Override | 132 | @Override |
135 | public void run(Timeout to) throws Exception { | 133 | public void run(Timeout to) throws Exception { |
136 | for (DeviceId devId : flowTable.keySet()) { | 134 | for (DeviceId devId : flowTable.keySet()) { |
137 | - providerService.pushFlowMetrics(devId, flowTable.get(devId)); | 135 | + providerService.pushFlowMetrics(devId, |
136 | + flowTable.getOrDefault(devId, Collections.emptySet())); | ||
138 | } | 137 | } |
139 | - | ||
140 | timeout = timer.newTimeout(to.getTask(), 5, TimeUnit.SECONDS); | 138 | timeout = timer.newTimeout(to.getTask(), 5, TimeUnit.SECONDS); |
139 | + | ||
141 | } | 140 | } |
142 | } | 141 | } |
143 | } | 142 | } | ... | ... |
... | @@ -35,6 +35,7 @@ import org.onosproject.net.flow.FlowRule; | ... | @@ -35,6 +35,7 @@ import org.onosproject.net.flow.FlowRule; |
35 | import org.onosproject.net.flow.TrafficSelector; | 35 | import org.onosproject.net.flow.TrafficSelector; |
36 | import org.onosproject.net.flow.TrafficTreatment; | 36 | import org.onosproject.net.flow.TrafficTreatment; |
37 | import org.onosproject.openflow.controller.Dpid; | 37 | import org.onosproject.openflow.controller.Dpid; |
38 | +import org.projectfloodlight.openflow.protocol.OFFlowMod; | ||
38 | import org.projectfloodlight.openflow.protocol.OFFlowRemoved; | 39 | import org.projectfloodlight.openflow.protocol.OFFlowRemoved; |
39 | import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry; | 40 | import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry; |
40 | import org.projectfloodlight.openflow.protocol.OFInstructionType; | 41 | import org.projectfloodlight.openflow.protocol.OFInstructionType; |
... | @@ -74,13 +75,16 @@ public class FlowEntryBuilder { | ... | @@ -74,13 +75,16 @@ public class FlowEntryBuilder { |
74 | 75 | ||
75 | private final OFFlowStatsEntry stat; | 76 | private final OFFlowStatsEntry stat; |
76 | private final OFFlowRemoved removed; | 77 | private final OFFlowRemoved removed; |
78 | + private final OFFlowMod flowMod; | ||
77 | 79 | ||
78 | private final Match match; | 80 | private final Match match; |
79 | private final List<OFAction> actions; | 81 | private final List<OFAction> actions; |
80 | 82 | ||
81 | private final Dpid dpid; | 83 | private final Dpid dpid; |
82 | 84 | ||
83 | - private final boolean addedRule; | 85 | + public enum FlowType { STAT, REMOVED, MOD } |
86 | + | ||
87 | + private final FlowType type; | ||
84 | 88 | ||
85 | 89 | ||
86 | public FlowEntryBuilder(Dpid dpid, OFFlowStatsEntry entry) { | 90 | public FlowEntryBuilder(Dpid dpid, OFFlowStatsEntry entry) { |
... | @@ -89,7 +93,8 @@ public class FlowEntryBuilder { | ... | @@ -89,7 +93,8 @@ public class FlowEntryBuilder { |
89 | this.actions = getActions(entry); | 93 | this.actions = getActions(entry); |
90 | this.dpid = dpid; | 94 | this.dpid = dpid; |
91 | this.removed = null; | 95 | this.removed = null; |
92 | - this.addedRule = true; | 96 | + this.flowMod = null; |
97 | + this.type = FlowType.STAT; | ||
93 | } | 98 | } |
94 | 99 | ||
95 | public FlowEntryBuilder(Dpid dpid, OFFlowRemoved removed) { | 100 | public FlowEntryBuilder(Dpid dpid, OFFlowRemoved removed) { |
... | @@ -99,26 +104,48 @@ public class FlowEntryBuilder { | ... | @@ -99,26 +104,48 @@ public class FlowEntryBuilder { |
99 | this.dpid = dpid; | 104 | this.dpid = dpid; |
100 | this.actions = null; | 105 | this.actions = null; |
101 | this.stat = null; | 106 | this.stat = null; |
102 | - this.addedRule = false; | 107 | + this.flowMod = null; |
108 | + this.type = FlowType.REMOVED; | ||
109 | + | ||
110 | + } | ||
103 | 111 | ||
112 | + public FlowEntryBuilder(Dpid dpid, OFFlowMod fm) { | ||
113 | + this.match = fm.getMatch(); | ||
114 | + this.dpid = dpid; | ||
115 | + this.actions = fm.getActions(); | ||
116 | + this.type = FlowType.MOD; | ||
117 | + this.flowMod = fm; | ||
118 | + this.stat = null; | ||
119 | + this.removed = null; | ||
104 | } | 120 | } |
105 | 121 | ||
106 | - public FlowEntry build() { | 122 | + public FlowEntry build(FlowEntryState... state) { |
107 | - if (addedRule) { | 123 | + FlowRule rule; |
108 | - FlowRule rule = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)), | 124 | + switch (this.type) { |
125 | + case STAT: | ||
126 | + rule = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)), | ||
109 | buildSelector(), buildTreatment(), stat.getPriority(), | 127 | buildSelector(), buildTreatment(), stat.getPriority(), |
110 | stat.getCookie().getValue(), stat.getIdleTimeout(), false); | 128 | stat.getCookie().getValue(), stat.getIdleTimeout(), false); |
111 | return new DefaultFlowEntry(rule, FlowEntryState.ADDED, | 129 | return new DefaultFlowEntry(rule, FlowEntryState.ADDED, |
112 | stat.getDurationSec(), stat.getPacketCount().getValue(), | 130 | stat.getDurationSec(), stat.getPacketCount().getValue(), |
113 | stat.getByteCount().getValue()); | 131 | stat.getByteCount().getValue()); |
114 | - | 132 | + case REMOVED: |
115 | - } else { | 133 | + rule = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)), |
116 | - FlowRule rule = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)), | ||
117 | buildSelector(), null, removed.getPriority(), | 134 | buildSelector(), null, removed.getPriority(), |
118 | removed.getCookie().getValue(), removed.getIdleTimeout(), false); | 135 | removed.getCookie().getValue(), removed.getIdleTimeout(), false); |
119 | return new DefaultFlowEntry(rule, FlowEntryState.REMOVED, removed.getDurationSec(), | 136 | return new DefaultFlowEntry(rule, FlowEntryState.REMOVED, removed.getDurationSec(), |
120 | removed.getPacketCount().getValue(), removed.getByteCount().getValue()); | 137 | removed.getPacketCount().getValue(), removed.getByteCount().getValue()); |
138 | + case MOD: | ||
139 | + FlowEntryState flowState = state.length > 0 ? state[0] : FlowEntryState.FAILED; | ||
140 | + rule = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)), | ||
141 | + buildSelector(), buildTreatment(), flowMod.getPriority(), | ||
142 | + flowMod.getCookie().getValue(), flowMod.getIdleTimeout(), false); | ||
143 | + return new DefaultFlowEntry(rule, flowState, 0, 0, 0); | ||
144 | + default: | ||
145 | + log.error("Unknown flow type : {}", this.type); | ||
146 | + return null; | ||
121 | } | 147 | } |
148 | + | ||
122 | } | 149 | } |
123 | 150 | ||
124 | private List<OFAction> getActions(OFFlowStatsEntry entry) { | 151 | private List<OFAction> getActions(OFFlowStatsEntry entry) { | ... | ... |
This diff is collapsed. Click to expand it.
... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
2 | # Instance-specific configurations, in this case, the number of | 2 | # Instance-specific configurations, in this case, the number of |
3 | # devices per node. | 3 | # devices per node. |
4 | # | 4 | # |
5 | -devConfigs = 192.168.56.30:5,192.168.56.40:7 | 5 | +devConfigs = 192.168.97.132:5,192.168.97.131:5 |
6 | 6 | ||
7 | # | 7 | # |
8 | # Number of ports per device. This is global to all devices | 8 | # Number of ports per device. This is global to all devices | ... | ... |
-
Please register or login to post a comment