<build>
<plugins>
+ <plugin>
+ <groupId>org.apache.aries.blueprint</groupId>
+ <artifactId>blueprint-maven-plugin</artifactId>
+ <configuration>
+ <scanPaths>
+ <scanPath>org.opendaylight.sfc.ovs</scanPath>
+ </scanPaths>
+ </configuration>
+ </plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
package org.opendaylight.sfc.ovs.listener;
import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
+import javax.annotation.Nonnull;
+import javax.inject.Inject;
+import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.datastoreutils.listeners.AbstractSyncDataTreeChangeListener;
import org.opendaylight.ovsdb.southbound.SouthboundConstants;
import org.opendaylight.sfc.ovs.provider.SfcOvsUtil;
-import org.opendaylight.sfc.provider.listeners.AbstractDataTreeChangeListener;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.ServiceFunctionForwarders;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class SfcOvsNodeDataListener extends AbstractDataTreeChangeListener<Node> {
+@Singleton
+public class SfcOvsNodeDataListener extends AbstractSyncDataTreeChangeListener<Node> {
+
private static final Logger LOG = LoggerFactory.getLogger(SfcOvsNodeDataListener.class);
+
private final DataBroker dataBroker;
- private ListenerRegistration<SfcOvsNodeDataListener> listenerRegistration;
+ @Inject
public SfcOvsNodeDataListener(final DataBroker dataBroker) {
+ super(dataBroker, LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
+ .child(Node.class));
this.dataBroker = dataBroker;
}
- public void init() {
- LOG.debug("Initializing...");
- registerListeners();
- }
-
- private void registerListeners() {
- final DataTreeIdentifier<Node> treeId = new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
- InstanceIdentifier.create(NetworkTopology.class)
- .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
- .child(Node.class));
- listenerRegistration = dataBroker.registerDataTreeChangeListener(treeId, this);
- }
-
- @Override
- public void close() throws Exception {
- LOG.debug("Closing listener...");
- if (listenerRegistration != null) {
- listenerRegistration.close();
- }
- }
-
@Override
- protected void add(Node createdNode) {
+ public void add(@Nonnull Node node) {
/*
* NODE CREATION When user puts SFF into config DS, reading from
* topology is involved to write OVSDB bridge and termination point
* might put SFF into config DS before topology in operational DS gets
* populated.
*/
+ LOG.debug("Created OVS Node: {}", node.toString());
- LOG.debug("\nCreated OVS Node: {}", createdNode.toString());
-
- OvsdbNodeAugmentation ovsdbNodeAugmentation = createdNode.getAugmentation(OvsdbNodeAugmentation.class);
+ OvsdbNodeAugmentation ovsdbNodeAugmentation = node.getAugmentation(OvsdbNodeAugmentation.class);
if (ovsdbNodeAugmentation != null) {
final ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
if (connectionInfo != null) {
- CheckedFuture<Optional<ServiceFunctionForwarders>, ReadFailedException>
- exitsingSffs = readServiceFunctionForwarders();
- Futures.addCallback(exitsingSffs, new FutureCallback<Optional<ServiceFunctionForwarders>>() {
+ ListenableFuture<Optional<ServiceFunctionForwarders>> exitsingSffs = readServiceFunctionForwarders();
+ Futures.addCallback(exitsingSffs, new FutureCallback<Optional<ServiceFunctionForwarders>>() {
@Override
public void onSuccess(Optional<ServiceFunctionForwarders> optionalSffs) {
if (optionalSffs != null && optionalSffs.isPresent()) {
}
@Override
- protected void remove(Node deletedNode) {
+ public void remove(@Nonnull Node node) {
/*
* NODE UPDATE and NODE DELETE This case would mean, that user has
* modified vSwitch state directly by ovs command, which is not handled
}
@Override
- protected void update(Node originalNode, Node updatedNode) {
+ public void update(@Nonnull Node originalNode, @Nonnull Node updatedNode) {
/*
* NODE UPDATE and NODE DELETE This case would mean, that user has
* modified vSwitch state directly by ovs command, which is not handled
*/
}
- private CheckedFuture<Optional<ServiceFunctionForwarders>, ReadFailedException> readServiceFunctionForwarders() {
+ private ListenableFuture<Optional<ServiceFunctionForwarders>> readServiceFunctionForwarders() {
ReadTransaction transaction = dataBroker.newReadOnlyTransaction();
InstanceIdentifier<ServiceFunctionForwarders> sffIid = InstanceIdentifier
.builder(ServiceFunctionForwarders.class).build();
return transaction.read(LogicalDatastoreType.CONFIGURATION, sffIid);
}
-
}
package org.opendaylight.sfc.ovs.listener;
import java.util.List;
+import javax.annotation.Nonnull;
+import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.datastoreutils.listeners.AbstractSyncDataTreeChangeListener;
import org.opendaylight.sfc.ovs.api.SfcSffToOvsMappingAPI;
import org.opendaylight.sfc.ovs.provider.SfcOvsUtil;
-import org.opendaylight.sfc.provider.listeners.AbstractDataTreeChangeListener;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.SffOvsLocatorOptionsAugmentation;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.ServiceFunctionForwarders;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarder.base.SffDataPlaneLocator;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.VxlanGpe;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class SfcOvsSffEntryDataListener extends AbstractDataTreeChangeListener<ServiceFunctionForwarder> {
+@Singleton
+public class SfcOvsSffEntryDataListener extends AbstractSyncDataTreeChangeListener<ServiceFunctionForwarder> {
private static final Logger LOG = LoggerFactory.getLogger(SfcOvsSffEntryDataListener.class);
- private final DataBroker dataBroker;
- private ListenerRegistration<SfcOvsSffEntryDataListener> listenerRegistration;
public SfcOvsSffEntryDataListener(final DataBroker dataBroker) {
- this.dataBroker = dataBroker;
- }
-
- public void init() {
- LOG.debug("Initializing...");
- registerListeners();
- }
-
- private void registerListeners() {
- final DataTreeIdentifier<ServiceFunctionForwarder> treeId = new DataTreeIdentifier<>(
- LogicalDatastoreType.CONFIGURATION,
- InstanceIdentifier.create(ServiceFunctionForwarders.class).child(ServiceFunctionForwarder.class));
- listenerRegistration = dataBroker.registerDataTreeChangeListener(treeId, this);
+ super(dataBroker, LogicalDatastoreType.CONFIGURATION,
+ InstanceIdentifier.create(ServiceFunctionForwarders.class).child(ServiceFunctionForwarder.class));
}
@Override
- public void close() throws Exception {
- LOG.debug("Closing listener...");
- if (listenerRegistration != null) {
- listenerRegistration.close();
- }
- }
-
- @Override
- protected void add(ServiceFunctionForwarder serviceFunctionForwarder) {
- LOG.info("\nCreated Service Function Forwarder: {}", serviceFunctionForwarder.toString());
+ public void add(@Nonnull ServiceFunctionForwarder serviceFunctionForwarder) {
+ LOG.info("Created Service Function Forwarder: {}", serviceFunctionForwarder.toString());
// add augmentations for serviceFunctionForwarder
addOvsdbAugmentations(serviceFunctionForwarder);
}
@Override
- protected void remove(ServiceFunctionForwarder deletedServiceFunctionForwarder) {
- LOG.info("\nDeleted Service Function Forwarder: {}", deletedServiceFunctionForwarder.toString());
+ public void remove(@Nonnull ServiceFunctionForwarder deletedServiceFunctionForwarder) {
+ LOG.info("Deleted Service Function Forwarder: {}", deletedServiceFunctionForwarder.toString());
deleteOvsdbAugmentations(deletedServiceFunctionForwarder);
}
@Override
- protected void update(ServiceFunctionForwarder originalServiceFunctionForwarder,
- ServiceFunctionForwarder updatedServiceFunctionForwarder) {
+ public void update(@Nonnull ServiceFunctionForwarder originalServiceFunctionForwarder,
+ @Nonnull ServiceFunctionForwarder updatedServiceFunctionForwarder) {
// Notice: Adding an SffDpl to an existing SFF will trigger this
// listener, not a separate SffDplListener
// which means 2 different listeners are not needed. This was tested
// -X PUT --user admin:admin
// http://localhost:${PORT}/restconf/config/service-function-forwarder:service-function-forwarders/service-function-forwarder/sff1/sff-data-plane-locator/vxgpe1
- LOG.info("\nModified Service Function Forwarder : {}", updatedServiceFunctionForwarder.toString());
+ LOG.info("Modified Service Function Forwarder : {}", updatedServiceFunctionForwarder.toString());
// rewrite augmentations for serviceFunctionForwarder
addOvsdbAugmentations(updatedServiceFunctionForwarder);
}
* @param sff
* ServiceFunctionForwarder Object.
*/
- static void addOvsdbAugmentations(ServiceFunctionForwarder sff) {
-
+ public static void addOvsdbAugmentations(ServiceFunctionForwarder sff) {
OvsdbBridgeAugmentation ovsdbBridge = SfcSffToOvsMappingAPI.buildOvsdbBridgeAugmentation(sff);
if (ovsdbBridge != null) {
* @param sff
* ServiceFunctionForwarder Object.
*/
- private static void deleteOvsdbAugmentations(ServiceFunctionForwarder sff) {
-
+ private void deleteOvsdbAugmentations(ServiceFunctionForwarder sff) {
// Since in most cases, the OvsdbNode was not created by SFC, lets not
// delete it
-
// Iterate the SFF DPLs and delete the VXGPE port
final List<SffDataPlaneLocator> sffDataPlaneLocatorList = sff.getSffDataPlaneLocator();
if (sffDataPlaneLocatorList == null || sffDataPlaneLocatorList.isEmpty()) {
return;
}
-
NodeId ovsdbBridgeNodeId = SfcOvsUtil.getOvsdbAugmentationNodeIdBySff(sff);
for (SffDataPlaneLocator sffDpl : sffDataPlaneLocatorList) {
// Only delete the port if this SFF is OVS augmented and the
SfcOvsUtil.buildOvsdbTerminationPointIID(ovsdbBridgeNodeId, sffDpl.getName().getValue()));
}
}
-
}
}
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
- xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
- odl:use-default-for-reference-types="true">
+ xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+ odl:use-default-for-reference-types="true">
- <reference id="dataBroker"
- interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"
- odl:type="default" />
+ <reference id="dataBroker"
+ interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"
+ odl:type="default"/>
- <bean id="sfcOvsRpc" class="org.opendaylight.sfc.ovs.provider.SfcOvsRpc" destroy-method="close"/>
+ <bean id="sfcOvsRpc" class="org.opendaylight.sfc.ovs.provider.SfcOvsRpc" destroy-method="close"/>
- <odl:rpc-implementation ref="sfcOvsRpc"/>
-
- <bean id="sfcOvsNodeDataListener"
- class="org.opendaylight.sfc.ovs.listener.SfcOvsNodeDataListener"
- init-method="init" destroy-method="close">
- <argument ref="dataBroker"/>
- </bean>
-
- <bean id="sfcOvsSffEntryDataListener"
- class="org.opendaylight.sfc.ovs.listener.SfcOvsSffEntryDataListener"
- init-method="init" destroy-method="close">
- <argument ref="dataBroker"/>
- </bean>
+ <odl:rpc-implementation ref="sfcOvsRpc"/>
</blueprint>
dataTreeModification = mock(DataTreeModification.class);
dataObjectModification = mock(DataObjectModification.class);
sfcOvsNodeDataListener = new SfcOvsNodeDataListener(getDataBroker());
- // Dont initialize it since the listener may launch when we're not ready
- // yet
- // sfcOvsNodeDataListener.init();
}
@After
dataTreeModification = mock(DataTreeModification.class);
dataObjectModification = mock(DataObjectModification.class);
sfcOvsSffEntryDataListener = new SfcOvsSffEntryDataListener(getDataBroker());
- sfcOvsSffEntryDataListener.init();
}
@After
dataTreeModification = mock(DataTreeModification.class);
dataObjectModification = mock(DataObjectModification.class);
sfcOvsSffEntryDataListener = new SfcOvsSffEntryDataListener(getDataBroker());
- sfcOvsSffEntryDataListener.init();
}
@After