blob: b0682701245a0b2fdec4d707737780e25cda7a65 [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2014-present Open Networking Laboratory
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07003 *
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 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.net.packet.impl;
alshabib7674db42014-09-12 23:40:46 -070017
Thomas Vachuska924cda42015-09-22 12:11:27 -070018import com.google.common.collect.ImmutableList;
19import com.google.common.collect.Lists;
Madan Jampani6f8b7022015-12-07 16:59:59 -080020
alshabib7674db42014-09-12 23:40:46 -070021import org.apache.felix.scr.annotations.Activate;
22import org.apache.felix.scr.annotations.Component;
23import org.apache.felix.scr.annotations.Deactivate;
24import org.apache.felix.scr.annotations.Reference;
25import org.apache.felix.scr.annotations.ReferenceCardinality;
26import org.apache.felix.scr.annotations.Service;
Madan Jampani6f8b7022015-12-07 16:59:59 -080027import org.onosproject.cluster.ClusterService;
28import org.onosproject.cluster.NodeId;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080029import org.onosproject.core.ApplicationId;
Thomas Vachuska6cba4952015-04-22 12:38:22 -070030import org.onosproject.core.CoreService;
Brian O'Connorabafb502014-12-02 22:26:20 -080031import org.onosproject.net.Device;
alshabib19e2cea2015-12-07 11:31:49 -080032import org.onosproject.net.DeviceId;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080033import org.onosproject.net.device.DeviceEvent;
34import org.onosproject.net.device.DeviceListener;
Brian O'Connorabafb502014-12-02 22:26:20 -080035import org.onosproject.net.device.DeviceService;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080036import org.onosproject.net.flow.DefaultTrafficTreatment;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080037import org.onosproject.net.flow.FlowRuleService;
38import org.onosproject.net.flow.TrafficSelector;
Jonathan Hart17d00452015-04-21 17:10:00 -070039import org.onosproject.net.flowobjective.DefaultForwardingObjective;
40import org.onosproject.net.flowobjective.FlowObjectiveService;
41import org.onosproject.net.flowobjective.ForwardingObjective;
42import org.onosproject.net.flowobjective.Objective;
43import org.onosproject.net.flowobjective.ObjectiveContext;
44import org.onosproject.net.flowobjective.ObjectiveError;
alshabib42947782015-03-31 14:59:06 -070045import org.onosproject.net.packet.DefaultPacketRequest;
Brian O'Connorabafb502014-12-02 22:26:20 -080046import org.onosproject.net.packet.OutboundPacket;
47import org.onosproject.net.packet.PacketContext;
48import org.onosproject.net.packet.PacketEvent;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080049import org.onosproject.net.packet.PacketPriority;
Brian O'Connorabafb502014-12-02 22:26:20 -080050import org.onosproject.net.packet.PacketProcessor;
Thomas Vachuska924cda42015-09-22 12:11:27 -070051import org.onosproject.net.packet.PacketProcessorEntry;
Brian O'Connorabafb502014-12-02 22:26:20 -080052import org.onosproject.net.packet.PacketProvider;
53import org.onosproject.net.packet.PacketProviderRegistry;
54import org.onosproject.net.packet.PacketProviderService;
alshabib42947782015-03-31 14:59:06 -070055import org.onosproject.net.packet.PacketRequest;
Brian O'Connorabafb502014-12-02 22:26:20 -080056import org.onosproject.net.packet.PacketService;
57import org.onosproject.net.packet.PacketStore;
58import org.onosproject.net.packet.PacketStoreDelegate;
59import org.onosproject.net.provider.AbstractProviderRegistry;
60import org.onosproject.net.provider.AbstractProviderService;
alshabib7674db42014-09-12 23:40:46 -070061import org.slf4j.Logger;
62
Thomas Vachuska7f171b22015-08-21 12:49:08 -070063import java.util.List;
alshabib19e2cea2015-12-07 11:31:49 -080064import java.util.Optional;
Madan Jampanic626f1e2015-05-29 13:53:38 -070065import java.util.concurrent.ExecutorService;
66import java.util.concurrent.Executors;
alshabib089bb772015-03-03 18:26:26 -080067
68import static com.google.common.base.Preconditions.checkNotNull;
Madan Jampanic626f1e2015-05-29 13:53:38 -070069import static org.onlab.util.Tools.groupedThreads;
Changhoon Yoon541ef712015-05-23 17:18:34 +090070import static org.onosproject.security.AppGuard.checkPermission;
Changhoon Yoonb856b812015-08-10 03:47:19 +090071import static org.onosproject.security.AppPermission.Type.*;
Thomas Vachuska7f171b22015-08-21 12:49:08 -070072import static org.slf4j.LoggerFactory.getLogger;
alshabib089bb772015-03-03 18:26:26 -080073
alshabib7674db42014-09-12 23:40:46 -070074/**
75 * Provides a basic implementation of the packet SB & NB APIs.
alshabib7674db42014-09-12 23:40:46 -070076 */
77@Component(immediate = true)
78@Service
tom202175a2014-09-19 19:00:11 -070079public class PacketManager
Thomas Vachuska6cba4952015-04-22 12:38:22 -070080 extends AbstractProviderRegistry<PacketProvider, PacketProviderService>
81 implements PacketService, PacketProviderRegistry {
alshabib7674db42014-09-12 23:40:46 -070082
83 private final Logger log = getLogger(getClass());
84
Thomas Vachuska27bee092015-06-23 19:03:10 -070085 private static final String TABLE_TYPE_MSG =
86 "Table Type cannot be null. For requesting packets without " +
87 "table hints, use other methods in the packetService API";
88
Jonathan Hart4f60f982014-10-27 08:11:17 -070089 private final PacketStoreDelegate delegate = new InternalStoreDelegate();
90
alshabib7674db42014-09-12 23:40:46 -070091 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Andrea Campanella5b240532016-02-05 09:44:41 -080092 protected CoreService coreService;
Thomas Vachuska6cba4952015-04-22 12:38:22 -070093
94 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Andrea Campanella5b240532016-02-05 09:44:41 -080095 protected ClusterService clusterService;
Madan Jampani6f8b7022015-12-07 16:59:59 -080096
97 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Andrea Campanella5b240532016-02-05 09:44:41 -080098 protected DeviceService deviceService;
alshabib7674db42014-09-12 23:40:46 -070099
Jonathan Hart4f60f982014-10-27 08:11:17 -0700100 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Andrea Campanella5b240532016-02-05 09:44:41 -0800101 protected FlowRuleService flowService;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800102
103 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Andrea Campanella5b240532016-02-05 09:44:41 -0800104 protected PacketStore store;
Jonathan Hart4f60f982014-10-27 08:11:17 -0700105
Thomas Vachuska866b46a2015-04-30 00:26:55 -0700106 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
107 private FlowObjectiveService objectiveService;
108
Madan Jampanic626f1e2015-05-29 13:53:38 -0700109 private ExecutorService eventHandlingExecutor;
110
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800111 private final DeviceListener deviceListener = new InternalDeviceListener();
112
Thomas Vachuska924cda42015-09-22 12:11:27 -0700113 private final List<ProcessorEntry> processors = Lists.newCopyOnWriteArrayList();
alshabib7674db42014-09-12 23:40:46 -0700114
Andrea Campanella5b240532016-02-05 09:44:41 -0800115 private final PacketDriverProvider defaultProvider = new PacketDriverProvider();
116
Thomas Vachuska6cba4952015-04-22 12:38:22 -0700117 private ApplicationId appId;
Madan Jampani6f8b7022015-12-07 16:59:59 -0800118 private NodeId localNodeId;
Thomas Vachuska6cba4952015-04-22 12:38:22 -0700119
alshabib7674db42014-09-12 23:40:46 -0700120 @Activate
121 public void activate() {
Madan Jampanic626f1e2015-05-29 13:53:38 -0700122 eventHandlingExecutor = Executors.newSingleThreadExecutor(
Thomas Vachuska924cda42015-09-22 12:11:27 -0700123 groupedThreads("onos/net/packet", "event-handler"));
Madan Jampani6f8b7022015-12-07 16:59:59 -0800124 localNodeId = clusterService.getLocalNode().id();
Thomas Vachuska6cba4952015-04-22 12:38:22 -0700125 appId = coreService.getAppId(CoreService.CORE_APP_NAME);
Jonathan Hart4f60f982014-10-27 08:11:17 -0700126 store.setDelegate(delegate);
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800127 deviceService.addListener(deviceListener);
Thomas Vachuska924cda42015-09-22 12:11:27 -0700128 store.existingRequests().forEach(this::pushToAllDevices);
Andrea Campanella5b240532016-02-05 09:44:41 -0800129 defaultProvider.init(deviceService);
alshabib7674db42014-09-12 23:40:46 -0700130 log.info("Started");
131 }
132
133 @Deactivate
134 public void deactivate() {
Jonathan Hart4f60f982014-10-27 08:11:17 -0700135 store.unsetDelegate(delegate);
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800136 deviceService.removeListener(deviceListener);
Madan Jampanic626f1e2015-05-29 13:53:38 -0700137 eventHandlingExecutor.shutdown();
alshabib7674db42014-09-12 23:40:46 -0700138 log.info("Stopped");
139 }
140
141 @Override
Andrea Campanella5b240532016-02-05 09:44:41 -0800142 protected PacketProvider defaultProvider() {
143 return defaultProvider;
144 }
145
146 @Override
alshabib7674db42014-09-12 23:40:46 -0700147 public void addProcessor(PacketProcessor processor, int priority) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900148 checkPermission(PACKET_EVENT);
alshabib030111e2014-09-15 15:56:42 -0700149 checkNotNull(processor, "Processor cannot be null");
Thomas Vachuska924cda42015-09-22 12:11:27 -0700150 ProcessorEntry entry = new ProcessorEntry(processor, priority);
151
152 // Insert the new processor according to its priority.
153 int i = 0;
154 for (; i < processors.size(); i++) {
155 if (priority < processors.get(i).priority()) {
156 break;
157 }
158 }
159 processors.add(i, entry);
alshabib7674db42014-09-12 23:40:46 -0700160 }
161
162 @Override
163 public void removeProcessor(PacketProcessor processor) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900164 checkPermission(PACKET_EVENT);
tomc370ebd2014-09-16 01:25:21 -0700165 checkNotNull(processor, "Processor cannot be null");
Thomas Vachuska924cda42015-09-22 12:11:27 -0700166
167 // Remove the processor entry.
168 for (int i = 0; i < processors.size(); i++) {
169 if (processors.get(i).processor() == processor) {
170 processors.remove(i);
171 break;
172 }
173 }
alshabib7674db42014-09-12 23:40:46 -0700174 }
175
176 @Override
Thomas Vachuska924cda42015-09-22 12:11:27 -0700177 public List<PacketProcessorEntry> getProcessors() {
Heedo Kang4a47a302016-02-29 17:40:23 +0900178 checkPermission(PACKET_READ);
Thomas Vachuska924cda42015-09-22 12:11:27 -0700179 return ImmutableList.copyOf(processors);
Thomas Vachuska7f171b22015-08-21 12:49:08 -0700180 }
181
182 @Override
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800183 public void requestPackets(TrafficSelector selector, PacketPriority priority,
184 ApplicationId appId) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900185 checkPermission(PACKET_READ);
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800186 checkNotNull(selector, "Selector cannot be null");
187 checkNotNull(appId, "Application ID cannot be null");
188
alshabib19e2cea2015-12-07 11:31:49 -0800189 PacketRequest request = new DefaultPacketRequest(selector, priority, appId,
190 localNodeId, Optional.empty());
Brian O'Connor21b028e2015-10-08 22:50:02 -0700191 store.requestPackets(request);
Saurav Dasc313c402015-02-27 10:09:47 -0800192 }
193
194 @Override
alshabib19e2cea2015-12-07 11:31:49 -0800195 public void requestPackets(TrafficSelector selector, PacketPriority priority,
196 ApplicationId appId, Optional<DeviceId> deviceId) {
197 checkPermission(PACKET_READ);
198 checkNotNull(selector, "Selector cannot be null");
199 checkNotNull(appId, "Application ID cannot be null");
200
201 PacketRequest request =
202 new DefaultPacketRequest(selector, priority, appId,
203 localNodeId, deviceId);
204
205 store.requestPackets(request);
206
207 }
208
209 @Override
Thomas Vachuska27bee092015-06-23 19:03:10 -0700210 public void cancelPackets(TrafficSelector selector, PacketPriority priority,
211 ApplicationId appId) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900212 checkPermission(PACKET_READ);
Saurav Dasc313c402015-02-27 10:09:47 -0800213 checkNotNull(selector, "Selector cannot be null");
214 checkNotNull(appId, "Application ID cannot be null");
Saurav Dasc313c402015-02-27 10:09:47 -0800215
alshabib19e2cea2015-12-07 11:31:49 -0800216
217 PacketRequest request = new DefaultPacketRequest(selector, priority, appId,
218 localNodeId, Optional.empty());
219 store.cancelPackets(request);
220 }
221
222 @Override
223 public void cancelPackets(TrafficSelector selector, PacketPriority priority,
224 ApplicationId appId, Optional<DeviceId> deviceId) {
225 checkPermission(PACKET_READ);
226 checkNotNull(selector, "Selector cannot be null");
227 checkNotNull(appId, "Application ID cannot be null");
228
229 PacketRequest request = new DefaultPacketRequest(selector, priority,
230 appId, localNodeId,
231 deviceId);
Brian O'Connor21b028e2015-10-08 22:50:02 -0700232 store.cancelPackets(request);
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800233 }
234
Thomas Vachuska7f171b22015-08-21 12:49:08 -0700235 @Override
236 public List<PacketRequest> getRequests() {
Heedo Kang4a47a302016-02-29 17:40:23 +0900237 checkPermission(PACKET_READ);
Thomas Vachuska7f171b22015-08-21 12:49:08 -0700238 return store.existingRequests();
239 }
240
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800241 /**
Thomas Vachuska924cda42015-09-22 12:11:27 -0700242 * Pushes all rules to the specified device.
243 *
244 * @param device device on which to install packet request flows
245 */
246 private void pushRulesToDevice(Device device) {
247 log.debug("Pushing packet requests to device {}", device.id());
248 for (PacketRequest request : store.existingRequests()) {
alshabib19e2cea2015-12-07 11:31:49 -0800249 if (!request.deviceId().isPresent()) {
250 pushRule(device, request);
251 } else if (request.deviceId().get().equals(device.id())) {
252 pushRule(device, request);
253 }
254
Thomas Vachuska924cda42015-09-22 12:11:27 -0700255 }
256 }
257
258 /**
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800259 * Pushes a packet request flow rule to all devices.
260 *
261 * @param request the packet request
262 */
263 private void pushToAllDevices(PacketRequest request) {
Thomas Vachuska88fd6902015-08-04 10:08:34 -0700264 log.debug("Pushing packet request {} to all devices", request);
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800265 for (Device device : deviceService.getDevices()) {
alshabib42947782015-03-31 14:59:06 -0700266 pushRule(device, request);
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800267 }
268 }
269
270 /**
Thomas Vachuska27bee092015-06-23 19:03:10 -0700271 * Removes packet request flow rule from all devices.
272 *
273 * @param request the packet request
274 */
275 private void removeFromAllDevices(PacketRequest request) {
Thomas Vachuska924cda42015-09-22 12:11:27 -0700276 deviceService.getAvailableDevices().forEach(d -> removeRule(d, request));
Thomas Vachuska27bee092015-06-23 19:03:10 -0700277 }
278
279 /**
280 * Pushes packet intercept flow rules to the device.
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800281 *
Thomas Vachuska6cba4952015-04-22 12:38:22 -0700282 * @param device the device to push the rules to
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800283 * @param request the packet request
284 */
285 private void pushRule(Device device, PacketRequest request) {
Marc De Leenheerb9311372015-07-09 11:36:49 -0700286 if (!device.type().equals(Device.Type.SWITCH)) {
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800287 return;
288 }
289
Thomas Vachuska27bee092015-06-23 19:03:10 -0700290 ForwardingObjective forwarding = createBuilder(request)
Jonathan Hart17d00452015-04-21 17:10:00 -0700291 .add(new ObjectiveContext() {
292 @Override
Jonathan Hart17d00452015-04-21 17:10:00 -0700293 public void onError(Objective objective, ObjectiveError error) {
Thomas Vachuska88fd6902015-08-04 10:08:34 -0700294 log.warn("Failed to install packet request {} to {}: {}",
295 request, device.id(), error);
Jonathan Hart17d00452015-04-21 17:10:00 -0700296 }
297 });
298
299 objectiveService.forward(device.id(), forwarding);
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800300 }
301
Thomas Vachuska27bee092015-06-23 19:03:10 -0700302 /**
303 * Removes packet intercept flow rules from the device.
304 *
305 * @param device the device to remove the rules deom
306 * @param request the packet request
307 */
308 private void removeRule(Device device, PacketRequest request) {
Marc De Leenheerb9311372015-07-09 11:36:49 -0700309 if (!device.type().equals(Device.Type.SWITCH)) {
Thomas Vachuska27bee092015-06-23 19:03:10 -0700310 return;
311 }
Thomas Vachuska27bee092015-06-23 19:03:10 -0700312 ForwardingObjective forwarding = createBuilder(request)
313 .remove(new ObjectiveContext() {
314 @Override
315 public void onError(Objective objective, ObjectiveError error) {
Thomas Vachuska88fd6902015-08-04 10:08:34 -0700316 log.warn("Failed to withdraw packet request {} from {}: {}",
317 request, device.id(), error);
Thomas Vachuska27bee092015-06-23 19:03:10 -0700318 }
319 });
Thomas Vachuska27bee092015-06-23 19:03:10 -0700320 objectiveService.forward(device.id(), forwarding);
321 }
322
323 private DefaultForwardingObjective.Builder createBuilder(PacketRequest request) {
324 return DefaultForwardingObjective.builder()
325 .withPriority(request.priority().priorityValue())
326 .withSelector(request.selector())
327 .fromApp(appId)
328 .withFlag(ForwardingObjective.Flag.VERSATILE)
329 .withTreatment(DefaultTrafficTreatment.builder().punt().build())
330 .makePermanent();
331 }
332
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800333 @Override
alshabib7674db42014-09-12 23:40:46 -0700334 public void emit(OutboundPacket packet) {
Changhoon Yoonb856b812015-08-10 03:47:19 +0900335 checkPermission(PACKET_WRITE);
tomc370ebd2014-09-16 01:25:21 -0700336 checkNotNull(packet, "Packet cannot be null");
Jonathan Hart4f60f982014-10-27 08:11:17 -0700337 store.emit(packet);
338 }
339
340 private void localEmit(OutboundPacket packet) {
Thomas Vachuska924cda42015-09-22 12:11:27 -0700341 Device device = deviceService.getDevice(packet.sendThrough());
Jonathan Hart7466d612014-11-24 17:09:53 -0800342 if (device == null) {
343 return;
344 }
Thomas Vachuska27bee092015-06-23 19:03:10 -0700345 PacketProvider packetProvider = getProvider(device.providerId());
alshabib3d643ec2014-10-22 18:33:00 -0700346 if (packetProvider != null) {
347 packetProvider.emit(packet);
348 }
alshabib7674db42014-09-12 23:40:46 -0700349 }
350
351 @Override
tomc370ebd2014-09-16 01:25:21 -0700352 protected PacketProviderService createProviderService(PacketProvider provider) {
alshabib7674db42014-09-12 23:40:46 -0700353 return new InternalPacketProviderService(provider);
354 }
355
Thomas Vachuska924cda42015-09-22 12:11:27 -0700356 /**
357 * Personalized packet provider service issued to the supplied provider.
358 */
alshabib7674db42014-09-12 23:40:46 -0700359 private class InternalPacketProviderService
Thomas Vachuska6cba4952015-04-22 12:38:22 -0700360 extends AbstractProviderService<PacketProvider>
361 implements PacketProviderService {
alshabib7674db42014-09-12 23:40:46 -0700362
363 protected InternalPacketProviderService(PacketProvider provider) {
364 super(provider);
365 }
366
367 @Override
368 public void processPacket(PacketContext context) {
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800369 // TODO filter packets sent to processors based on registrations
Thomas Vachuska924cda42015-09-22 12:11:27 -0700370 for (ProcessorEntry entry : processors) {
Jonathan Hartf5638302015-11-16 10:56:20 -0800371 try {
372 long start = System.nanoTime();
373 entry.processor().process(context);
374 entry.addNanos(System.nanoTime() - start);
375 } catch (Exception e) {
376 log.warn("Packet processor {} threw an exception", entry.processor(), e);
377 }
alshabib7674db42014-09-12 23:40:46 -0700378 }
379 }
380
381 }
Jonathan Hart4f60f982014-10-27 08:11:17 -0700382
alshabib19e2cea2015-12-07 11:31:49 -0800383
Jonathan Hart4f60f982014-10-27 08:11:17 -0700384 /**
385 * Internal callback from the packet store.
386 */
Andrea Campanella5b240532016-02-05 09:44:41 -0800387 protected class InternalStoreDelegate implements PacketStoreDelegate {
Jonathan Hart4f60f982014-10-27 08:11:17 -0700388 @Override
389 public void notify(PacketEvent event) {
390 localEmit(event.subject());
391 }
Brian O'Connor21b028e2015-10-08 22:50:02 -0700392
393 @Override
394 public void requestPackets(PacketRequest request) {
alshabib19e2cea2015-12-07 11:31:49 -0800395 DeviceId deviceid = request.deviceId().orElse(null);
396
397 if (deviceid != null) {
398 pushRule(deviceService.getDevice(deviceid), request);
399 } else {
400 pushToAllDevices(request);
401 }
Brian O'Connor21b028e2015-10-08 22:50:02 -0700402 }
403
404 @Override
405 public void cancelPackets(PacketRequest request) {
alshabib19e2cea2015-12-07 11:31:49 -0800406 DeviceId deviceid = request.deviceId().orElse(null);
407
408 if (deviceid != null) {
409 removeRule(deviceService.getDevice(deviceid), request);
410 } else {
411 removeFromAllDevices(request);
412 }
Brian O'Connor21b028e2015-10-08 22:50:02 -0700413 }
Jonathan Hart4f60f982014-10-27 08:11:17 -0700414 }
415
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800416 /**
417 * Internal listener for device service events.
418 */
419 private class InternalDeviceListener implements DeviceListener {
420 @Override
421 public void event(DeviceEvent event) {
Madan Jampanic626f1e2015-05-29 13:53:38 -0700422 eventHandlingExecutor.execute(() -> {
423 try {
424 Device device = event.subject();
425 switch (event.type()) {
Thomas Vachuska924cda42015-09-22 12:11:27 -0700426 case DEVICE_ADDED:
427 case DEVICE_AVAILABILITY_CHANGED:
428 if (deviceService.isAvailable(event.subject().id())) {
429 pushRulesToDevice(device);
Madan Jampanic626f1e2015-05-29 13:53:38 -0700430 }
Thomas Vachuska924cda42015-09-22 12:11:27 -0700431 break;
432 default:
433 break;
sangho864a9db22015-04-28 12:06:31 -0700434 }
Madan Jampanic626f1e2015-05-29 13:53:38 -0700435 } catch (Exception e) {
436 log.warn("Failed to process {}", event, e);
437 }
438 });
Jonathan Hart3cfce8e2015-01-14 16:43:27 -0800439 }
440 }
441
Thomas Vachuska924cda42015-09-22 12:11:27 -0700442 /**
443 * Entity for tracking stats for a packet processor.
444 */
445 private class ProcessorEntry implements PacketProcessorEntry {
446 private final PacketProcessor processor;
447 private final int priority;
448 private long invocations = 0;
449 private long nanos = 0;
450
451 public ProcessorEntry(PacketProcessor processor, int priority) {
452 this.processor = processor;
453 this.priority = priority;
454 }
455
456 @Override
457 public PacketProcessor processor() {
458 return processor;
459 }
460
461 @Override
462 public int priority() {
463 return priority;
464 }
465
466 @Override
467 public long invocations() {
468 return invocations;
469 }
470
471 @Override
472 public long totalNanos() {
473 return nanos;
474 }
475
476 @Override
477 public long averageNanos() {
478 return invocations > 0 ? nanos / invocations : 0;
479 }
480
481 void addNanos(long nanos) {
482 this.nanos += nanos;
483 this.invocations++;
484 }
485 }
alshabibae857582014-09-12 23:53:10 -0700486}