*/
package org.opendaylight.openflowplugin.learningswitch;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareConsumer;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
import org.opendaylight.controller.sal.binding.api.NotificationService;
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
import org.opendaylight.openflowplugin.learningswitch.multi.LearningSwitchManagerMultiImpl;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
import org.osgi.framework.BundleContext;
/**
* learning switch activator
- *
+ * <p/>
* Activator is derived from AbstractBindingAwareConsumer, which takes care
* of looking up MD-SAL in Service Registry and registering consumer
* when MD-SAL is present.
*/
public class Activator extends AbstractBindingAwareConsumer implements AutoCloseable {
-
+
private static final Logger LOG = LoggerFactory.getLogger(Activator.class);
private LearningSwitchManager learningSwitch;
-
+
@Override
protected void startImpl(BundleContext context) {
LOG.info("startImpl() passing");
}
-
+
/**
* Invoked when consumer is registered to the MD-SAL.
- *
*/
@Override
public void onSessionInitialized(ConsumerContext session) {
/**
* We create instance of our LearningSwitchManager
* and set all required dependencies,
- *
+ *
* which are
* Data Broker (data storage service) - for configuring flows and reading stored switch state
* PacketProcessingService - for sending out packets
* NotificationService - for receiving notifications such as packet in.
- *
+ *
*/
learningSwitch = new LearningSwitchManagerMultiImpl();
- learningSwitch.setDataBroker(session.getSALService(DataBrokerService.class));
+ learningSwitch.setDataBroker(session.getSALService(DataBroker.class));
learningSwitch.setPacketProcessingService(session.getRpcService(PacketProcessingService.class));
learningSwitch.setNotificationService(session.getSALService(NotificationService.class));
learningSwitch.start();
learningSwitch.stop();
}
}
-
+
@Override
protected void stopImpl(BundleContext context) {
close();
package org.opendaylight.openflowplugin.learningswitch;
-import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
/**
package org.opendaylight.openflowplugin.learningswitch;
+import com.google.common.util.concurrent.CheckedFuture;
import java.util.concurrent.Future;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
* @return transaction commit
*
*/
- Future<RpcResult<TransactionStatus>> writeFlowToConfig(InstanceIdentifier<Flow> flowPath, Flow flowBody);
+ CheckedFuture<Void, TransactionCommitFailedException> writeFlowToConfig(InstanceIdentifier<Flow> flowPath, Flow flowBody);
}
package org.opendaylight.openflowplugin.learningswitch;
+import com.google.common.util.concurrent.CheckedFuture;
import java.util.concurrent.Future;
-
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
/**
- *
+ *
*/
public class FlowCommitWrapperImpl implements FlowCommitWrapper {
-
- private DataBrokerService dataBrokerService;
+
+ private DataBroker dataBrokerService;
/**
* @param dataBrokerService
*/
- public FlowCommitWrapperImpl(DataBrokerService dataBrokerService) {
+ public FlowCommitWrapperImpl(DataBroker dataBrokerService) {
this.dataBrokerService = dataBrokerService;
}
@Override
- public Future<RpcResult<TransactionStatus>> writeFlowToConfig(InstanceIdentifier<Flow> flowPath,
- Flow flowBody) {
- DataModificationTransaction addFlowTransaction = dataBrokerService.beginTransaction();
- addFlowTransaction.putConfigurationData(flowPath, flowBody);
- return addFlowTransaction.commit();
+ public CheckedFuture<Void, TransactionCommitFailedException> writeFlowToConfig(InstanceIdentifier<Flow> flowPath,
+ Flow flowBody) {
+ ReadWriteTransaction addFlowTransaction = dataBrokerService.newReadWriteTransaction();
+ addFlowTransaction.put(LogicalDatastoreType.CONFIGURATION, flowPath, flowBody);
+ return addFlowTransaction.submit();
}
}
package org.opendaylight.openflowplugin.learningswitch;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.sal.binding.api.NotificationService;
import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
/**
- *
+ *
*/
public interface LearningSwitchManager {
/**
* Set's Data Broker dependency.
- *
+ * <p/>
* Data Broker is used to access overal operational and configuration
* tree.
- *
- * In simple Learning Switch handler, data broker is used to listen
- * for changes in Openflow tables and to configure flows which will
- * be provisioned down to the Openflow switch.
- *
- * inject {@link DataBrokerService}
+ * <p/>
+ * In simple Learning Switch handler, data broker is used to listen
+ * for changes in Openflow tables and to configure flows which will
+ * be provisioned down to the Openflow switch.
+ * <p/>
+ * inject {@link DataBroker}
+ *
* @param data
*/
- void setDataBroker(DataBrokerService data);
+ void setDataBroker(DataBroker data);
/**
* Set's Packet Processing dependency.
- *
+ * <p/>
* Packet Processing service is used to send packet Out on Openflow
* switch.
- *
+ * <p/>
* inject {@link PacketProcessingService}
- *
+ *
* @param packetProcessingService
*/
void setPacketProcessingService(
/**
* Set's Notification service dependency.
- *
- * Notification service is used to register for listening
+ * <p/>
+ * Notification service is used to register for listening
* packet-in notifications.
- *
+ * <p/>
* inject {@link NotificationService}
+ *
* @param notificationService
*/
void setNotificationService(NotificationService notificationService);
*/
package org.opendaylight.openflowplugin.learningswitch;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.sal.binding.api.NotificationService;
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
private NotificationService notificationService;
private PacketProcessingService packetProcessingService;
- private DataBrokerService data;
+ private DataBroker data;
private Registration packetInRegistration;
- private ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
+ private ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
/**
* @param notificationService the notificationService to set
* @param data the data to set
*/
@Override
- public void setDataBroker(DataBrokerService data) {
+ public void setDataBroker(DataBroker data) {
this.data = data;
}
WakeupOnNode wakeupListener = new WakeupOnNode();
wakeupListener.setLearningSwitchHandler(learningSwitchHandler);
- dataChangeListenerRegistration = data.registerDataChangeListener(
+ dataChangeListenerRegistration = data.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
InstanceIdentifier.builder(Nodes.class)
.child(Node.class)
.augmentation(FlowCapableNode.class)
.child(Table.class).toInstance(),
- wakeupListener);
+ wakeupListener,
+ DataBroker.DataChangeScope.SUBTREE);
LOG.debug("start() <--");
}
import java.util.Map;
import java.util.Map.Entry;
-
-import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
-import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.LoggerFactory;
/**
- *
+ *
*/
public class WakeupOnNode implements DataChangeListener {
-
+
private static final Logger LOG = LoggerFactory
.getLogger(WakeupOnNode.class);
-
+
private LearningSwitchHandler learningSwitchHandler;
@Override
- public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+ public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
Short requiredTableId = 0;
-
+
// TODO add flow
- Map<InstanceIdentifier<?>, DataObject> updated = change.getUpdatedOperationalData();
+
+ Map<InstanceIdentifier<?>, DataObject> updated = change.getUpdatedData();
for (Entry<InstanceIdentifier<?>, DataObject> updateItem : updated.entrySet()) {
DataObject table = updateItem.getValue();
if (table instanceof Table) {
Table tableSure = (Table) table;
LOG.trace("table: {}", table);
-
+
if (requiredTableId.equals(tableSure.getId())) {
@SuppressWarnings("unchecked")
InstanceIdentifier<Table> tablePath = (InstanceIdentifier<Table>) updateItem.getKey();
}
}
}
-
+
/**
* @param learningSwitchHandler the learningSwitchHandler to set
*/
LearningSwitchHandler learningSwitchHandler) {
this.learningSwitchHandler = learningSwitchHandler;
}
+
}
*/
package org.opendaylight.openflowplugin.learningswitch.multi;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.sal.binding.api.NotificationService;
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
import org.opendaylight.openflowplugin.learningswitch.DataChangeListenerRegistrationHolder;
-import org.opendaylight.openflowplugin.learningswitch.LearningSwitchManager;
import org.opendaylight.openflowplugin.learningswitch.FlowCommitWrapper;
import org.opendaylight.openflowplugin.learningswitch.FlowCommitWrapperImpl;
+import org.opendaylight.openflowplugin.learningswitch.LearningSwitchManager;
import org.opendaylight.openflowplugin.learningswitch.WakeupOnNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.concepts.Registration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * Listens to packetIn notification and
+ * Listens to packetIn notification and
* <ul>
* <li>in HUB mode simply floods all switch ports (except ingress port)</li>
- * <li>in LSWITCH mode collects source MAC address of packetIn and bind it with ingress port.
- * If target MAC address is already bound then a flow is created (for direct communication between
+ * <li>in LSWITCH mode collects source MAC address of packetIn and bind it with ingress port.
+ * If target MAC address is already bound then a flow is created (for direct communication between
* corresponding MACs)</li>
* </ul>
*/
public class LearningSwitchManagerMultiImpl implements DataChangeListenerRegistrationHolder,
LearningSwitchManager {
-
+
protected static final Logger LOG = LoggerFactory
.getLogger(LearningSwitchManagerMultiImpl.class);
private NotificationService notificationService;
private PacketProcessingService packetProcessingService;
- private DataBrokerService data;
+ private DataBroker data;
private Registration packetInRegistration;
- private ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
-
+ private ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
+
/**
* @param notificationService the notificationService to set
*/
PacketProcessingService packetProcessingService) {
this.packetProcessingService = packetProcessingService;
}
-
+
/**
* @param data the data to set
*/
@Override
- public void setDataBroker(DataBrokerService data) {
+ public void setDataBroker(DataBroker data) {
this.data = data;
}
learningSwitchHandler.setPacketProcessingService(packetProcessingService);
learningSwitchHandler.setPacketInDispatcher(packetInDispatcher);
packetInRegistration = notificationService.registerNotificationListener(packetInDispatcher);
-
+
WakeupOnNode wakeupListener = new WakeupOnNode();
wakeupListener.setLearningSwitchHandler(learningSwitchHandler);
- dataChangeListenerRegistration = data.registerDataChangeListener(
+ dataChangeListenerRegistration = data.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
InstanceIdentifier.builder(Nodes.class)
- .child(Node.class)
- .augmentation(FlowCapableNode.class)
- .child(Table.class).toInstance(),
- wakeupListener);
+ .child(Node.class)
+ .augmentation(FlowCapableNode.class)
+ .child(Table.class).toInstance(),
+ wakeupListener,
+ DataBroker.DataChangeScope.SUBTREE);
LOG.debug("start() <--");
}
-
+
/**
- * stopping learning switch
+ * stopping learning switch
*/
@Override
public void stop() {
}
LOG.debug("stop() <--");
}
-
-
+
+
@Override
public ListenerRegistration<DataChangeListener> getDataChangeListenerRegistration() {
return dataChangeListenerRegistration;