b7e5f57ca9f50281f53024adbc7d353d11d919f0
[l2switch.git] / packethandler / implementation / src / main / java / org / opendaylight / l2switch / packethandler / decoders / AbstractPacketDecoder.java
1 package org.opendaylight.l2switch.packethandler.decoders;
2
3 import com.google.common.collect.ImmutableMap;
4 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
5 import org.opendaylight.yangtools.concepts.Registration;
6 import org.opendaylight.yangtools.yang.binding.Notification;
7 import org.opendaylight.yangtools.yang.binding.NotificationListener;
8
9 /**
10  * A base class for all decoders. Each extended decoder should also implement a notification listener
11  * that it can consume. And make use of
12  */
13 public abstract class AbstractPacketDecoder<ConsumedPacketNotification, ProducedPacketNotification extends Notification>
14     implements  NotificationProviderService.NotificationInterestListener , AutoCloseable {
15
16
17   private Class<ProducedPacketNotification> producedPacketNotificationType;
18   private NotificationProviderService notificationProviderService;
19
20
21   protected Registration<NotificationListener> listenerRegistration;
22
23   /**
24    * Constructor to
25    * @param producedPacketNotificationType
26    * @param notificationProviderService
27    */
28   public  AbstractPacketDecoder(Class<ProducedPacketNotification> producedPacketNotificationType, NotificationProviderService notificationProviderService) {
29     this.producedPacketNotificationType = producedPacketNotificationType;
30     this.notificationProviderService = notificationProviderService;
31     notificationProviderService.registerInterestListener(this);
32   }
33
34
35   /**
36    * Keeps track of listeners registered for the notification that a decoder produces.
37    * @param aClass
38    */
39   @Override
40   public void onNotificationSubscribtion(Class<? extends Notification> aClass) {
41     if (aClass !=null && aClass.equals(producedPacketNotificationType)) {
42       if(listenerRegistration == null) {
43         NotificationListener notificationListener = getConsumedNotificationListener();
44         listenerRegistration = notificationProviderService.registerNotificationListener(notificationListener);
45       }
46     }
47   }
48
49
50   /**
51    * Every extended decoder should call this method on a receipt of a input packet notification.
52    * This method would make sure it decodes only when necessary and publishes corresponding event
53    * on successful decoding.
54    */
55   public void decodeAndPublish(ConsumedPacketNotification consumedPacketNotification) {
56     ProducedPacketNotification packetNotification=null;
57     if(consumedPacketNotification!= null && canDecode(consumedPacketNotification)) {
58       packetNotification = decode(consumedPacketNotification);
59     }
60     if(packetNotification != null) {
61       notificationProviderService.publish(packetNotification);
62     }
63   }
64   /**
65    * Decodes the payload in given Packet further and returns a extension of Packet.
66    * e.g. ARP, IPV4, LLDP etc.
67    *
68    * @return
69    */
70   public abstract ProducedPacketNotification decode(ConsumedPacketNotification consumedPacketNotification);
71
72
73   public abstract NotificationListener getConsumedNotificationListener();
74
75   public abstract boolean canDecode(ConsumedPacketNotification consumedPacketNotification);
76
77
78   @Override
79   public void close() throws Exception {
80     if(listenerRegistration != null) {
81       listenerRegistration.close();
82     }
83   }
84 }