alshabib
Committed by Gerrit Code Review

implemented a distributed default flow registration mechanism to avoid duplicate…

… requests from other onos instances

Change-Id: Ib2abb483456538e3e08e9790c4b4b0d50db8b384

implemented a distributed default flow registration mechanism to avoid
duplicate requests from other onos instances

Change-Id: I620cc51ac29cddaffa73cdbb20e9a9acbdd9ea69
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.packet;
17 +
18 +import com.google.common.base.MoreObjects;
19 +import org.onosproject.core.ApplicationId;
20 +import org.onosproject.net.flow.FlowRule;
21 +import org.onosproject.net.flow.TrafficSelector;
22 +
23 +/**
24 + * Default implementation of a packet request.
25 + */
26 +public final class DefaultPacketRequest implements PacketRequest {
27 + private final TrafficSelector selector;
28 + private final PacketPriority priority;
29 + private final ApplicationId appId;
30 + private final FlowRule.Type tableType;
31 +
32 + public DefaultPacketRequest(TrafficSelector selector, PacketPriority priority,
33 + ApplicationId appId, FlowRule.Type tableType) {
34 + this.selector = selector;
35 + this.priority = priority;
36 + this.appId = appId;
37 + this.tableType = tableType;
38 + }
39 +
40 + public TrafficSelector selector() {
41 + return selector;
42 + }
43 +
44 + public PacketPriority priority() {
45 + return priority;
46 + }
47 +
48 + public ApplicationId appId() {
49 + return appId;
50 + }
51 +
52 + public FlowRule.Type tableType() {
53 + return tableType;
54 + }
55 +
56 + @Override
57 + public boolean equals(Object o) {
58 + if (this == o) {
59 + return true;
60 + }
61 + if (o == null || getClass() != o.getClass()) {
62 + return false;
63 + }
64 +
65 + DefaultPacketRequest that = (DefaultPacketRequest) o;
66 +
67 + if (priority != that.priority) {
68 + return false;
69 + }
70 + if (!selector.equals(that.selector)) {
71 + return false;
72 + }
73 + if (!tableType.equals(that.tableType)) {
74 + return false;
75 + }
76 +
77 + return true;
78 + }
79 +
80 + @Override
81 + public int hashCode() {
82 + int result = selector.hashCode();
83 + result = 31 * result + priority.hashCode();
84 + return result;
85 + }
86 +
87 + @Override
88 + public String toString() {
89 + return MoreObjects.toStringHelper(this.getClass())
90 + .add("selector", selector)
91 + .add("priority", priority)
92 + .add("appId", appId)
93 + .add("table-type", tableType).toString();
94 + }
95 +}
...\ No newline at end of file ...\ No newline at end of file
...@@ -46,4 +46,8 @@ public enum PacketPriority { ...@@ -46,4 +46,8 @@ public enum PacketPriority {
46 public int priorityValue() { 46 public int priorityValue() {
47 return priorityValue; 47 return priorityValue;
48 } 48 }
49 +
50 + public String toString() {
51 + return String.valueOf(priorityValue);
52 + }
49 } 53 }
...\ No newline at end of file ...\ No newline at end of file
......
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.packet;
17 +
18 +import org.onosproject.core.ApplicationId;
19 +import org.onosproject.net.flow.FlowRule;
20 +import org.onosproject.net.flow.TrafficSelector;
21 +
22 +/**
23 + * Represents a packet request made to devices.
24 + */
25 +public interface PacketRequest {
26 +
27 + /**
28 + * Obtain the traffic selector.
29 + * @return a traffic selector
30 + */
31 + public TrafficSelector selector();
32 +
33 + /**
34 + * Obtain the priority.
35 + * @return a PacketPriority
36 + */
37 + public PacketPriority priority();
38 +
39 + /**
40 + * Obtain the application id.
41 + * @return an application id
42 + */
43 + public ApplicationId appId();
44 +
45 + /**
46 + * Obtain the table type.
47 + * @return a table type
48 + */
49 + public FlowRule.Type tableType();
50 +
51 +}
...@@ -17,6 +17,8 @@ package org.onosproject.net.packet; ...@@ -17,6 +17,8 @@ package org.onosproject.net.packet;
17 17
18 import org.onosproject.store.Store; 18 import org.onosproject.store.Store;
19 19
20 +import java.util.Set;
21 +
20 /** 22 /**
21 * Manages routing of outbound packets. 23 * Manages routing of outbound packets.
22 */ 24 */
...@@ -31,4 +33,21 @@ public interface PacketStore extends Store<PacketEvent, PacketStoreDelegate> { ...@@ -31,4 +33,21 @@ public interface PacketStore extends Store<PacketEvent, PacketStoreDelegate> {
31 */ 33 */
32 void emit(OutboundPacket packet); 34 void emit(OutboundPacket packet);
33 35
36 + /**
37 + * Register a request for packets. If the registration
38 + * is successful the manager can proceed, otherwise it should
39 + * consider these packet already available in the system.
40 + *
41 + * @param request a packet request
42 + * @return a boolean indicating registration state.
43 + */
44 + boolean requestPackets(PacketRequest request);
45 +
46 + /**
47 + * Obtains all existing requests in the system.
48 + *
49 + * @return a set of packet requests
50 + */
51 + Set<PacketRequest> existingRequests();
52 +
34 } 53 }
......
...@@ -23,7 +23,6 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; ...@@ -23,7 +23,6 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
23 import org.apache.felix.scr.annotations.Service; 23 import org.apache.felix.scr.annotations.Service;
24 import org.onosproject.core.ApplicationId; 24 import org.onosproject.core.ApplicationId;
25 import org.onosproject.net.Device; 25 import org.onosproject.net.Device;
26 -import org.onosproject.net.MastershipRole;
27 import org.onosproject.net.device.DeviceEvent; 26 import org.onosproject.net.device.DeviceEvent;
28 import org.onosproject.net.device.DeviceListener; 27 import org.onosproject.net.device.DeviceListener;
29 import org.onosproject.net.device.DeviceService; 28 import org.onosproject.net.device.DeviceService;
...@@ -33,6 +32,7 @@ import org.onosproject.net.flow.FlowRule; ...@@ -33,6 +32,7 @@ import org.onosproject.net.flow.FlowRule;
33 import org.onosproject.net.flow.FlowRuleService; 32 import org.onosproject.net.flow.FlowRuleService;
34 import org.onosproject.net.flow.TrafficSelector; 33 import org.onosproject.net.flow.TrafficSelector;
35 import org.onosproject.net.flow.TrafficTreatment; 34 import org.onosproject.net.flow.TrafficTreatment;
35 +import org.onosproject.net.packet.DefaultPacketRequest;
36 import org.onosproject.net.packet.OutboundPacket; 36 import org.onosproject.net.packet.OutboundPacket;
37 import org.onosproject.net.packet.PacketContext; 37 import org.onosproject.net.packet.PacketContext;
38 import org.onosproject.net.packet.PacketEvent; 38 import org.onosproject.net.packet.PacketEvent;
...@@ -41,6 +41,7 @@ import org.onosproject.net.packet.PacketProcessor; ...@@ -41,6 +41,7 @@ import org.onosproject.net.packet.PacketProcessor;
41 import org.onosproject.net.packet.PacketProvider; 41 import org.onosproject.net.packet.PacketProvider;
42 import org.onosproject.net.packet.PacketProviderRegistry; 42 import org.onosproject.net.packet.PacketProviderRegistry;
43 import org.onosproject.net.packet.PacketProviderService; 43 import org.onosproject.net.packet.PacketProviderService;
44 +import org.onosproject.net.packet.PacketRequest;
44 import org.onosproject.net.packet.PacketService; 45 import org.onosproject.net.packet.PacketService;
45 import org.onosproject.net.packet.PacketStore; 46 import org.onosproject.net.packet.PacketStore;
46 import org.onosproject.net.packet.PacketStoreDelegate; 47 import org.onosproject.net.packet.PacketStoreDelegate;
...@@ -48,9 +49,7 @@ import org.onosproject.net.provider.AbstractProviderRegistry; ...@@ -48,9 +49,7 @@ import org.onosproject.net.provider.AbstractProviderRegistry;
48 import org.onosproject.net.provider.AbstractProviderService; 49 import org.onosproject.net.provider.AbstractProviderService;
49 import org.slf4j.Logger; 50 import org.slf4j.Logger;
50 51
51 -import java.util.Collections;
52 import java.util.Map; 52 import java.util.Map;
53 -import java.util.Set;
54 import java.util.concurrent.ConcurrentHashMap; 53 import java.util.concurrent.ConcurrentHashMap;
55 54
56 import static com.google.common.base.Preconditions.checkNotNull; 55 import static com.google.common.base.Preconditions.checkNotNull;
...@@ -82,68 +81,6 @@ implements PacketService, PacketProviderRegistry { ...@@ -82,68 +81,6 @@ implements PacketService, PacketProviderRegistry {
82 81
83 private final Map<Integer, PacketProcessor> processors = new ConcurrentHashMap<>(); 82 private final Map<Integer, PacketProcessor> processors = new ConcurrentHashMap<>();
84 83
85 - private Set<PacketRequest> packetRequests =
86 - Collections.newSetFromMap(new ConcurrentHashMap<>());
87 -
88 - private final class PacketRequest {
89 - private final TrafficSelector selector;
90 - private final PacketPriority priority;
91 - private final ApplicationId appId;
92 - private final FlowRule.Type tableType;
93 -
94 - public PacketRequest(TrafficSelector selector, PacketPriority priority,
95 - ApplicationId appId, FlowRule.Type tableType) {
96 - this.selector = selector;
97 - this.priority = priority;
98 - this.appId = appId;
99 - this.tableType = tableType;
100 - }
101 -
102 - public TrafficSelector selector() {
103 - return selector;
104 - }
105 -
106 - public PacketPriority priority() {
107 - return priority;
108 - }
109 -
110 - public ApplicationId appId() {
111 - return appId;
112 - }
113 -
114 - public FlowRule.Type tableType() {
115 - return tableType;
116 - }
117 -
118 - @Override
119 - public boolean equals(Object o) {
120 - if (this == o) {
121 - return true;
122 - }
123 - if (o == null || getClass() != o.getClass()) {
124 - return false;
125 - }
126 -
127 - PacketRequest that = (PacketRequest) o;
128 -
129 - if (priority != that.priority) {
130 - return false;
131 - }
132 - if (!selector.equals(that.selector)) {
133 - return false;
134 - }
135 -
136 - return true;
137 - }
138 -
139 - @Override
140 - public int hashCode() {
141 - int result = selector.hashCode();
142 - result = 31 * result + priority.hashCode();
143 - return result;
144 - }
145 - }
146 -
147 @Activate 84 @Activate
148 public void activate() { 85 public void activate() {
149 store.setDelegate(delegate); 86 store.setDelegate(delegate);
...@@ -177,10 +114,11 @@ implements PacketService, PacketProviderRegistry { ...@@ -177,10 +114,11 @@ implements PacketService, PacketProviderRegistry {
177 checkNotNull(appId, "Application ID cannot be null"); 114 checkNotNull(appId, "Application ID cannot be null");
178 115
179 PacketRequest request = 116 PacketRequest request =
180 - new PacketRequest(selector, priority, appId, FlowRule.Type.DEFAULT); 117 + new DefaultPacketRequest(selector, priority, appId, FlowRule.Type.DEFAULT);
181 118
182 - packetRequests.add(request); 119 + if (store.requestPackets(request)) {
183 - pushToAllDevices(request); 120 + pushToAllDevices(request);
121 + }
184 } 122 }
185 123
186 @Override 124 @Override
...@@ -192,11 +130,12 @@ implements PacketService, PacketProviderRegistry { ...@@ -192,11 +130,12 @@ implements PacketService, PacketProviderRegistry {
192 + "without table hints, use other methods in the packetService API"); 130 + "without table hints, use other methods in the packetService API");
193 131
194 PacketRequest request = 132 PacketRequest request =
195 - new PacketRequest(selector, priority, appId, tableType); 133 + new DefaultPacketRequest(selector, priority, appId, tableType);
196 134
197 - if (packetRequests.add(request)) { 135 + if (store.requestPackets(request)) {
198 pushToAllDevices(request); 136 pushToAllDevices(request);
199 } 137 }
138 +
200 } 139 }
201 140
202 /** 141 /**
...@@ -206,9 +145,7 @@ implements PacketService, PacketProviderRegistry { ...@@ -206,9 +145,7 @@ implements PacketService, PacketProviderRegistry {
206 */ 145 */
207 private void pushToAllDevices(PacketRequest request) { 146 private void pushToAllDevices(PacketRequest request) {
208 for (Device device : deviceService.getDevices()) { 147 for (Device device : deviceService.getDevices()) {
209 - if (deviceService.getRole(device.id()) == MastershipRole.MASTER) { 148 + pushRule(device, request);
210 - pushRule(device, request);
211 - }
212 } 149 }
213 } 150 }
214 151
...@@ -303,7 +240,7 @@ implements PacketService, PacketProviderRegistry { ...@@ -303,7 +240,7 @@ implements PacketService, PacketProviderRegistry {
303 public void event(DeviceEvent event) { 240 public void event(DeviceEvent event) {
304 Device device = event.subject(); 241 Device device = event.subject();
305 if (event.type() == DeviceEvent.Type.DEVICE_ADDED) { 242 if (event.type() == DeviceEvent.Type.DEVICE_ADDED) {
306 - for (PacketRequest request : packetRequests) { 243 + for (PacketRequest request : store.existingRequests()) {
307 pushRule(device, request); 244 pushRule(device, request);
308 } 245 }
309 } 246 }
......
...@@ -28,6 +28,7 @@ import org.onosproject.mastership.MastershipService; ...@@ -28,6 +28,7 @@ import org.onosproject.mastership.MastershipService;
28 import org.onosproject.net.packet.OutboundPacket; 28 import org.onosproject.net.packet.OutboundPacket;
29 import org.onosproject.net.packet.PacketEvent; 29 import org.onosproject.net.packet.PacketEvent;
30 import org.onosproject.net.packet.PacketEvent.Type; 30 import org.onosproject.net.packet.PacketEvent.Type;
31 +import org.onosproject.net.packet.PacketRequest;
31 import org.onosproject.net.packet.PacketStore; 32 import org.onosproject.net.packet.PacketStore;
32 import org.onosproject.net.packet.PacketStoreDelegate; 33 import org.onosproject.net.packet.PacketStoreDelegate;
33 import org.onosproject.store.AbstractStore; 34 import org.onosproject.store.AbstractStore;
...@@ -37,8 +38,12 @@ import org.onosproject.store.cluster.messaging.ClusterMessageHandler; ...@@ -37,8 +38,12 @@ import org.onosproject.store.cluster.messaging.ClusterMessageHandler;
37 import org.onosproject.store.cluster.messaging.MessageSubject; 38 import org.onosproject.store.cluster.messaging.MessageSubject;
38 import org.onosproject.store.serializers.KryoNamespaces; 39 import org.onosproject.store.serializers.KryoNamespaces;
39 import org.onosproject.store.serializers.KryoSerializer; 40 import org.onosproject.store.serializers.KryoSerializer;
41 +import org.onosproject.store.service.ConsistentMap;
42 +import org.onosproject.store.service.Serializer;
43 +import org.onosproject.store.service.StorageService;
40 import org.slf4j.Logger; 44 import org.slf4j.Logger;
41 45
46 +import java.util.Set;
42 import java.util.concurrent.ExecutorService; 47 import java.util.concurrent.ExecutorService;
43 import java.util.concurrent.Executors; 48 import java.util.concurrent.Executors;
44 49
...@@ -69,6 +74,11 @@ public class DistributedPacketStore ...@@ -69,6 +74,11 @@ public class DistributedPacketStore
69 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 74 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
70 protected ClusterCommunicationService communicationService; 75 protected ClusterCommunicationService communicationService;
71 76
77 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
78 + protected StorageService storageService;
79 +
80 + private PacketRequestTracker tracker;
81 +
72 private static final MessageSubject PACKET_OUT_SUBJECT = 82 private static final MessageSubject PACKET_OUT_SUBJECT =
73 new MessageSubject("packet-out"); 83 new MessageSubject("packet-out");
74 84
...@@ -94,6 +104,8 @@ public class DistributedPacketStore ...@@ -94,6 +104,8 @@ public class DistributedPacketStore
94 new InternalClusterMessageHandler(), 104 new InternalClusterMessageHandler(),
95 messageHandlingExecutor); 105 messageHandlingExecutor);
96 106
107 + tracker = new PacketRequestTracker();
108 +
97 log.info("Started"); 109 log.info("Started");
98 } 110 }
99 111
...@@ -125,6 +137,16 @@ public class DistributedPacketStore ...@@ -125,6 +137,16 @@ public class DistributedPacketStore
125 // error log: log.warn("Failed to send packet-out to {}", master); 137 // error log: log.warn("Failed to send packet-out to {}", master);
126 } 138 }
127 139
140 + @Override
141 + public boolean requestPackets(PacketRequest request) {
142 + return tracker.add(request);
143 + }
144 +
145 + @Override
146 + public Set<PacketRequest> existingRequests() {
147 + return tracker.requests();
148 + }
149 +
128 /** 150 /**
129 * Handles incoming cluster messages. 151 * Handles incoming cluster messages.
130 */ 152 */
...@@ -140,4 +162,46 @@ public class DistributedPacketStore ...@@ -140,4 +162,46 @@ public class DistributedPacketStore
140 } 162 }
141 } 163 }
142 164
165 + private class PacketRequestTracker {
166 +
167 + private ConsistentMap<PacketRequest, Boolean> requests;
168 +
169 + public PacketRequestTracker() {
170 + requests = storageService.<PacketRequest, Boolean>consistentMapBuilder()
171 + .withName("packet-requests")
172 + .withSerializer(new Serializer() {
173 + KryoNamespace kryo = new KryoNamespace.Builder()
174 + .register(KryoNamespaces.API)
175 + .build();
176 + @Override
177 + public <T> byte[] encode(T object) {
178 + return kryo.serialize(object);
179 + }
180 +
181 + @Override
182 + public <T> T decode(byte[] bytes) {
183 + return kryo.deserialize(bytes);
184 + }
185 + }).build();
186 + }
187 +
188 + public boolean add(PacketRequest request) {
189 + if (requests.putIfAbsent(request, true) == null) {
190 + return true;
191 + }
192 + return false;
193 + }
194 +
195 + public boolean remove(PacketRequest request) {
196 + if (requests.remove(request) == null) {
197 + return false;
198 + }
199 + return true;
200 + }
201 +
202 + public Set<PacketRequest> requests() {
203 + return requests.keySet();
204 + }
205 +
206 + }
143 } 207 }
......
...@@ -106,6 +106,8 @@ import org.onosproject.net.intent.constraint.ObstacleConstraint; ...@@ -106,6 +106,8 @@ import org.onosproject.net.intent.constraint.ObstacleConstraint;
106 import org.onosproject.net.intent.constraint.WaypointConstraint; 106 import org.onosproject.net.intent.constraint.WaypointConstraint;
107 import org.onosproject.net.link.DefaultLinkDescription; 107 import org.onosproject.net.link.DefaultLinkDescription;
108 import org.onosproject.net.packet.DefaultOutboundPacket; 108 import org.onosproject.net.packet.DefaultOutboundPacket;
109 +import org.onosproject.net.packet.DefaultPacketRequest;
110 +import org.onosproject.net.packet.PacketPriority;
109 import org.onosproject.net.provider.ProviderId; 111 import org.onosproject.net.provider.ProviderId;
110 import org.onosproject.net.resource.Bandwidth; 112 import org.onosproject.net.resource.Bandwidth;
111 import org.onosproject.net.resource.BandwidthResourceAllocation; 113 import org.onosproject.net.resource.BandwidthResourceAllocation;
...@@ -225,6 +227,8 @@ public final class KryoNamespaces { ...@@ -225,6 +227,8 @@ public final class KryoNamespaces {
225 FlowRule.Type.class, 227 FlowRule.Type.class,
226 DefaultFlowRule.class, 228 DefaultFlowRule.class,
227 DefaultFlowEntry.class, 229 DefaultFlowEntry.class,
230 + DefaultPacketRequest.class,
231 + PacketPriority.class,
228 FlowEntry.FlowEntryState.class, 232 FlowEntry.FlowEntryState.class,
229 FlowId.class, 233 FlowId.class,
230 DefaultTrafficSelector.class, 234 DefaultTrafficSelector.class,
......
...@@ -15,15 +15,21 @@ ...@@ -15,15 +15,21 @@
15 */ 15 */
16 package org.onosproject.store.trivial.impl; 16 package org.onosproject.store.trivial.impl;
17 17
18 +import com.google.common.collect.Sets;
18 import org.apache.felix.scr.annotations.Component; 19 import org.apache.felix.scr.annotations.Component;
19 import org.apache.felix.scr.annotations.Service; 20 import org.apache.felix.scr.annotations.Service;
20 import org.onosproject.net.packet.OutboundPacket; 21 import org.onosproject.net.packet.OutboundPacket;
21 import org.onosproject.net.packet.PacketEvent; 22 import org.onosproject.net.packet.PacketEvent;
22 import org.onosproject.net.packet.PacketEvent.Type; 23 import org.onosproject.net.packet.PacketEvent.Type;
24 +import org.onosproject.net.packet.PacketRequest;
23 import org.onosproject.net.packet.PacketStore; 25 import org.onosproject.net.packet.PacketStore;
24 import org.onosproject.net.packet.PacketStoreDelegate; 26 import org.onosproject.net.packet.PacketStoreDelegate;
25 import org.onosproject.store.AbstractStore; 27 import org.onosproject.store.AbstractStore;
26 28
29 +
30 +import java.util.Collections;
31 +import java.util.Set;
32 +
27 /** 33 /**
28 * Simple single instance implementation of the packet store. 34 * Simple single instance implementation of the packet store.
29 */ 35 */
...@@ -33,9 +39,21 @@ public class SimplePacketStore ...@@ -33,9 +39,21 @@ public class SimplePacketStore
33 extends AbstractStore<PacketEvent, PacketStoreDelegate> 39 extends AbstractStore<PacketEvent, PacketStoreDelegate>
34 implements PacketStore { 40 implements PacketStore {
35 41
42 + private Set<PacketRequest> requests = Sets.newConcurrentHashSet();
43 +
36 @Override 44 @Override
37 public void emit(OutboundPacket packet) { 45 public void emit(OutboundPacket packet) {
38 notifyDelegate(new PacketEvent(Type.EMIT, packet)); 46 notifyDelegate(new PacketEvent(Type.EMIT, packet));
39 } 47 }
40 48
49 + @Override
50 + public boolean requestPackets(PacketRequest request) {
51 + return requests.add(request);
52 + }
53 +
54 + @Override
55 + public Set<PacketRequest> existingRequests() {
56 + return Collections.unmodifiableSet(requests);
57 + }
58 +
41 } 59 }
......