2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.l2switch.packethandler.decoders;
10 import java.util.concurrent.ExecutorService;
11 import java.util.concurrent.Executors;
12 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
13 import org.opendaylight.yangtools.concepts.Registration;
14 import org.opendaylight.yangtools.yang.binding.Notification;
15 import org.opendaylight.yangtools.yang.binding.NotificationListener;
18 * A base class for all decoders. Each extended decoder should also implement a
19 * notification listener that it can consume.
21 public abstract class AbstractPacketDecoder<C, P extends Notification>
22 implements NotificationProviderService.NotificationInterestListener, AutoCloseable {
24 private final Class<P> producedPacketNotificationType;
25 private final NotificationProviderService notificationProviderService;
27 private static final int CPUS = Runtime.getRuntime().availableProcessors();
28 private final ExecutorService decodeAndPublishExecutor = Executors.newFixedThreadPool(CPUS);
30 protected Registration listenerRegistration;
35 public AbstractPacketDecoder(Class<P> producedPacketNotificationType,
36 NotificationProviderService notificationProviderService) {
37 this.producedPacketNotificationType = producedPacketNotificationType;
38 this.notificationProviderService = notificationProviderService;
39 notificationProviderService.registerInterestListener(this);
43 * Keeps track of listeners registered for the notification that a decoder
47 public synchronized void onNotificationSubscribtion(Class<? extends Notification> clazz) {
48 if (clazz != null && clazz.equals(producedPacketNotificationType)) {
49 if (listenerRegistration == null) {
50 NotificationListener notificationListener = getConsumedNotificationListener();
51 listenerRegistration = notificationProviderService.registerNotificationListener(notificationListener);
57 * Every extended decoder should call this method on a receipt of a input
58 * packet notification. This method would make sure it decodes only when
59 * necessary and publishes corresponding event on successful decoding.
61 public void decodeAndPublish(final C consumedPacketNotification) {
62 decodeAndPublishExecutor.submit(() -> {
63 P packetNotification = null;
64 if (consumedPacketNotification != null && canDecode(consumedPacketNotification)) {
65 packetNotification = decode(consumedPacketNotification);
67 if (packetNotification != null) {
68 notificationProviderService.publish(packetNotification);
74 * Decodes the payload in given Packet further and returns a extension of
75 * Packet. e.g. ARP, IPV4, LLDP etc.
79 public abstract P decode(C consumedPacketNotification);
81 public abstract NotificationListener getConsumedNotificationListener();
83 public abstract boolean canDecode(C consumedPacketNotification);
86 public void close() throws Exception {
87 if (listenerRegistration != null) {
88 listenerRegistration.close();
90 decodeAndPublishExecutor.shutdown();