<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-binding-api</artifactId>
*/
package org.opendaylight.l2switch.packethandler;
-import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareConsumer;
+import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.controller.sal.binding.api.NotificationService;
import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
import org.opendaylight.l2switch.packethandler.decoders.DecoderRegistry;
import org.opendaylight.l2switch.packethandler.decoders.PacketDecoderService;
import org.opendaylight.l2switch.packethandler.decoders.PacketDecoderServiceImpl;
import org.opendaylight.l2switch.packethandler.decoders.PacketNotificationRegistry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
import org.opendaylight.yangtools.concepts.Registration;
import org.opendaylight.yangtools.yang.binding.NotificationListener;
import org.slf4j.Logger;
/**
* PacketHandlerProvider serves as the Activator for our L2Switch OSGI bundle.
*/
-public class PacketHandlerProvider extends AbstractBindingAwareConsumer
+public class PacketHandlerProvider extends AbstractBindingAwareProvider
implements AutoCloseable {
private final static Logger _logger = LoggerFactory.getLogger(PacketHandlerProvider.class);
/**
* Setup the packet handler.
*
- * @param consumerContext The context of the L2Switch.
+ * @param providerContext The context of the L2Switch.
*/
@Override
- public void onSessionInitialized(BindingAwareBroker.ConsumerContext consumerContext) {
- DataBrokerService dataService = consumerContext.<DataBrokerService>getSALService(DataBrokerService.class);
+ public void onSessionInitiated(BindingAwareBroker.ProviderContext providerContext) {
+ DataBrokerService dataService = providerContext.<DataBrokerService>getSALService(DataBrokerService.class);
NotificationProviderService notificationProviderService =
- consumerContext.<NotificationProviderService>getSALService(NotificationProviderService.class);
+ providerContext.<NotificationProviderService>getSALService(NotificationProviderService.class);
DecoderRegistry decoderRegistry = new DecoderRegistry();
import org.opendaylight.l2switch.packethandler.decoders.PacketNotificationRegistry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.EthernetPacket;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.EthernetPacketGrp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.EthernetPacketReceived;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.EthernetPacketReceivedBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
import org.opendaylight.yangtools.yang.binding.Notification;
import org.slf4j.LoggerFactory;
/**
- * Created by amitmandke on 6/4/14.
+ * RawPacketHandler subscribes to RawPacket in event. Calls the Ethernet decoder to
*/
public class RawPacketHandler implements PacketProcessingListener {
private final static Logger _logger = LoggerFactory.getLogger(RawPacketHandler.class);
return;
}
+ // publish ethernet notification if listener is subscribed
+ if(packetNotificationRegistry.isListenerSubscribed(EthernetPacketReceived.class)) {
+ EthernetPacketReceivedBuilder ethernetPacketReceivedBuilder = new EthernetPacketReceivedBuilder(ethernetPacket);
+ EthernetPacketReceived ethernetNotification = ethernetPacketReceivedBuilder.build();
+ notificationProviderService.publish(ethernetNotification);
+ }
+
if(!packetNotificationRegistry.isListenerSubscribed(ethernetPacket.getEthertype())) {
_logger.info("No Listener is subscribed for {} notification.",ethernetPacket.getEthertype());
return;
package org.opendaylight.l2switch.packethandler.decoders;
+import org.opendaylight.controller.sal.binding.api.BindingAwareService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.KnownEtherType;
import org.opendaylight.yangtools.yang.binding.Notification;
/**
* Created by amitmandke on 6/4/14.
*/
-public interface PacketDecoderService {
+public interface PacketDecoderService extends BindingAwareService {
public <C extends Notification> void registerDecoder(KnownEtherType etherType, PacketDecoder packetDecoder, Class<C> packetReceivedNotificationType);
}
private Map<KnownEtherType, Class<? extends Notification>> etherTypeToPacketNotificationTypeMap = new EnumMap<KnownEtherType, Class<? extends Notification>>(KnownEtherType.class);
private Map<Class<? extends Notification>, Integer> packetNotificationTypeToListenerCountMap = new HashMap<Class<? extends Notification>, Integer>();
+
/**
* Increments the listener count for given notification type.
*
public void onNotificationSubscribtion(Class<? extends Notification> aClass) {
if(aClass == null) return;
- int listenerCount = packetNotificationTypeToListenerCountMap.get(aClass);
- packetNotificationTypeToListenerCountMap.put(aClass,listenerCount++);
-
+ synchronized(this) {
+ Integer listenerCount = packetNotificationTypeToListenerCountMap.get(aClass);
+ if(listenerCount == null)
+ listenerCount =0;
+ packetNotificationTypeToListenerCountMap.put(aClass, ++listenerCount);
+ }
}
/**
* Maintains map of EtherType to notificationType
*
* @param notificationType
- * @param <C>
+ * @param <N>
*/
- public <C extends Notification> void trackPacketNotificationListener(KnownEtherType etherType, Class<C> notificationType) {
+ public <N extends Notification> void trackPacketNotificationListener(KnownEtherType etherType, Class<N> notificationType) {
if(etherType == null || notificationType == null) return;
- synchronized(this){
- etherTypeToPacketNotificationTypeMap.put(etherType,notificationType);
+ synchronized(this) {
+ etherTypeToPacketNotificationTypeMap.put(etherType, notificationType);
}
}
public boolean isListenerSubscribed(KnownEtherType etherType) {
if(etherType == null) return false;
- int listenerCount = packetNotificationTypeToListenerCountMap.get(etherTypeToPacketNotificationTypeMap.get(etherType));
+ Class<?> packetNotification = etherTypeToPacketNotificationTypeMap.get(etherType);
+ if(packetNotification == null) return false;
+
+ return isListenerSubscribed((Class<? extends Notification>) packetNotification);
+ }
+
+ /**
+ * Checks if a listener is subscribed to give the notification type .
+ *
+ * @param packetNotificationType
+ * @return
+ */
+ public boolean isListenerSubscribed(Class<? extends Notification> packetNotificationType) {
+ if(packetNotificationType == null) return false;
+
+ Integer listenerCount = packetNotificationTypeToListenerCountMap.get(packetNotificationType);
+
+ if(listenerCount == null) return false;
- return listenerCount>0;
+ return listenerCount > 0;
}
}
--- /dev/null
+package org.opendaylight.l2switch.packethandler.decoders;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.KnownEtherType;
+
+import static junit.framework.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+
+/**
+ * Created by amitmandke on 6/5/14.
+ */
+public class DecoderRegistryTest {
+ private DecoderRegistry decoderRegistry = null;
+ private PacketDecoder packetDecoder;
+
+ @Before
+ public void init() {
+ decoderRegistry = new DecoderRegistry();
+ packetDecoder = mock(PacketDecoder.class);
+ }
+
+ @Test
+ public void testAddDecoderSunnyDay() {
+ decoderRegistry.addDecoder(KnownEtherType.Arp, packetDecoder);
+ assertEquals(packetDecoder, decoderRegistry.getDecoder(KnownEtherType.Arp));
+ }
+
+ public void testGetDecoderWithoutAdding() {
+ PacketDecoder decoder = decoderRegistry.getDecoder(KnownEtherType.Arp);
+ assertEquals(null, decoder);
+ }
+}
--- /dev/null
+package org.opendaylight.l2switch.packethandler.decoders;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.KnownEtherType;
+import org.opendaylight.yangtools.yang.binding.Notification;
+
+import static junit.framework.Assert.assertEquals;
+
+
+/**
+ * Created by amitmandke on 6/5/14.
+ */
+public class PacketNotificationRegistryTest {
+ PacketNotificationRegistry packetNotificationRegistry = null;
+
+ @Before
+ public void init() {
+ packetNotificationRegistry = new PacketNotificationRegistry();
+ }
+
+ @Test
+ public void testIsListenerSubscribedByNotificationTypeWithoutAddingAnyListener() {
+ assertEquals(false, packetNotificationRegistry.isListenerSubscribed(Notification.class));
+ }
+
+ @Test
+ public void testIsListenerSubscribedByEtherTypeWithoutAddingAnyListener() {
+ assertEquals(false, packetNotificationRegistry.isListenerSubscribed(KnownEtherType.Arp));
+ }
+
+ @Test
+ public void testIsListenerSubscribedByNotificationTypeSunnyDay() {
+ addNotification();
+ assertEquals(true, packetNotificationRegistry.isListenerSubscribed(Notification.class));
+ }
+
+ @Test
+ public void testIsListenerSubscribedByEtherTypeWithoutAddingEtherType() {
+ addNotification();
+ assertEquals(false, packetNotificationRegistry.isListenerSubscribed(KnownEtherType.Arp));
+ }
+
+ @Test
+ public void testIsListenerSubscribedByEtherTypeSunnyDay() {
+ addNotification();
+ addEtherTypeNotification();
+ assertEquals(true, packetNotificationRegistry.isListenerSubscribed(KnownEtherType.Arp));
+ }
+
+ private void addNotification() {
+ packetNotificationRegistry.onNotificationSubscribtion(Notification.class);
+
+ }
+
+ private void addEtherTypeNotification() {
+ packetNotificationRegistry.trackPacketNotificationListener(KnownEtherType.Arp, Notification.class);
+ }
+}