package org.opendaylight.genius.interfacemanager.listeners;
import com.google.common.util.concurrent.ListenableFuture;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
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.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.datastoreutils.AsyncClusteredDataTreeChangeListenerBase;
-import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
import org.opendaylight.genius.interfacemanager.IfmConstants;
+import org.opendaylight.genius.interfacemanager.IfmUtil;
import org.opendaylight.genius.interfacemanager.InterfacemgrProvider;
-import org.opendaylight.genius.interfacemanager.renderer.ovs.statehelpers.OvsInterfaceTopologyStateAddHelper;
-import org.opendaylight.genius.interfacemanager.renderer.ovs.statehelpers.OvsInterfaceTopologyStateRemoveHelper;
+import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.genius.interfacemanager.commons.InterfaceMetaUtils;
import org.opendaylight.genius.interfacemanager.renderer.ovs.statehelpers.OvsInterfaceTopologyStateUpdateHelper;
-import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.IfmClusterUtils;
+import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils;
+import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
+import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.BridgeEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeRef;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
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.topology.Node;
import org.slf4j.LoggerFactory;
@Singleton
-public class InterfaceTopologyStateListener extends AsyncClusteredDataTreeChangeListenerBase<OvsdbBridgeAugmentation, InterfaceTopologyStateListener> {
+public class InterfaceTopologyStateListener
+ extends AsyncClusteredDataTreeChangeListenerBase<OvsdbBridgeAugmentation, InterfaceTopologyStateListener> {
private static final Logger LOG = LoggerFactory.getLogger(InterfaceTopologyStateListener.class);
private final DataBroker dataBroker;
private final InterfacemgrProvider interfaceMgrProvider;
+ private final EntityOwnershipUtils entityOwnershipUtils;
+ private final JobCoordinator coordinator;
+ private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
+ private final OvsInterfaceTopologyStateUpdateHelper ovsInterfaceTopologyStateUpdateHelper;
@Inject
- public InterfaceTopologyStateListener(final DataBroker dataBroker,
- final InterfacemgrProvider interfaceMgrProvider) {
+ public InterfaceTopologyStateListener(final DataBroker dataBroker, final InterfacemgrProvider interfaceMgrProvider,
+ final EntityOwnershipUtils entityOwnershipUtils, final JobCoordinator coordinator,
+ final InterfaceManagerCommonUtils interfaceManagerCommonUtils,
+ final OvsInterfaceTopologyStateUpdateHelper ovsInterfaceTopologyStateUpdateHelper) {
super(OvsdbBridgeAugmentation.class, InterfaceTopologyStateListener.class);
this.dataBroker = dataBroker;
this.interfaceMgrProvider = interfaceMgrProvider;
+ this.entityOwnershipUtils = entityOwnershipUtils;
+ this.coordinator = coordinator;
+ this.interfaceManagerCommonUtils = interfaceManagerCommonUtils;
+ this.ovsInterfaceTopologyStateUpdateHelper = ovsInterfaceTopologyStateUpdateHelper;
this.registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
}
return InterfaceTopologyStateListener.this;
}
+ private void runOnlyInOwnerNode(String jobDesc, Runnable job) {
+ entityOwnershipUtils.runOnlyInOwnerNode(IfmConstants.INTERFACE_CONFIG_ENTITY,
+ IfmConstants.INTERFACE_CONFIG_ENTITY, coordinator, jobDesc, job);
+ }
+
@Override
protected void remove(InstanceIdentifier<OvsdbBridgeAugmentation> identifier, OvsdbBridgeAugmentation bridgeOld) {
LOG.debug("Received Remove DataChange Notification for identifier: {}, ovsdbBridgeAugmentation: {}",
InstanceIdentifier<Node> nodeIid = identifier.firstIdentifierOf(Node.class);
interfaceMgrProvider.removeBridgeForNodeIid(nodeIid);
- IfmClusterUtils.runOnlyInLeaderNode(() -> {
- DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance();
+ runOnlyInOwnerNode("OVSDB bridge removed", () -> {
RendererStateRemoveWorker rendererStateRemoveWorker = new RendererStateRemoveWorker(identifier, bridgeOld);
- jobCoordinator.enqueueJob(bridgeOld.getBridgeName().getValue(), rendererStateRemoveWorker,
+ coordinator.enqueueJob(bridgeOld.getBridgeName().getValue(), rendererStateRemoveWorker,
IfmConstants.JOB_MAX_RETRIES);
- }, IfmClusterUtils.INTERFACE_CONFIG_ENTITY);
+ });
}
@Override
InstanceIdentifier<Node> nodeIid = identifier.firstIdentifierOf(Node.class);
interfaceMgrProvider.addBridgeForNodeIid(nodeIid, bridgeNew);
- IfmClusterUtils.runOnlyInLeaderNode(() -> {
+ runOnlyInOwnerNode("OVSDB bridge updated", () -> {
DatapathId oldDpid = bridgeOld.getDatapathId();
DatapathId newDpid = bridgeNew.getDatapathId();
- if(oldDpid == null && newDpid != null){
- DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance();
+ if (oldDpid == null && newDpid != null) {
RendererStateAddWorker rendererStateAddWorker = new RendererStateAddWorker(identifier, bridgeNew);
- jobCoordinator.enqueueJob(bridgeNew.getBridgeName().getValue(), rendererStateAddWorker,
- IfmConstants.JOB_MAX_RETRIES);
- } else if(oldDpid != null && !oldDpid.equals(newDpid)){
- DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance();
- RendererStateUpdateWorker rendererStateAddWorker = new RendererStateUpdateWorker(identifier, bridgeNew, bridgeOld);
- jobCoordinator.enqueueJob(bridgeNew.getBridgeName().getValue(), rendererStateAddWorker,
- IfmConstants.JOB_MAX_RETRIES);
+ coordinator.enqueueJob(bridgeNew.getBridgeName().getValue(), rendererStateAddWorker,
+ IfmConstants.JOB_MAX_RETRIES);
+ } else if (oldDpid != null && !oldDpid.equals(newDpid)) {
+ RendererStateUpdateWorker rendererStateAddWorker = new RendererStateUpdateWorker(identifier, bridgeNew,
+ bridgeOld);
+ coordinator.enqueueJob(bridgeNew.getBridgeName().getValue(), rendererStateAddWorker,
+ IfmConstants.JOB_MAX_RETRIES);
}
- }, IfmClusterUtils.INTERFACE_CONFIG_ENTITY);
+ });
}
@Override
InstanceIdentifier<Node> nodeIid = identifier.firstIdentifierOf(Node.class);
interfaceMgrProvider.addBridgeForNodeIid(nodeIid, bridgeNew);
- IfmClusterUtils.runOnlyInLeaderNode(() -> {
- DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance();
+ runOnlyInOwnerNode("OVSDB bridge added", () -> {
RendererStateAddWorker rendererStateAddWorker = new RendererStateAddWorker(identifier, bridgeNew);
- jobCoordinator.enqueueJob(bridgeNew.getBridgeName().getValue(), rendererStateAddWorker,
+ coordinator.enqueueJob(bridgeNew.getBridgeName().getValue(), rendererStateAddWorker,
IfmConstants.JOB_MAX_RETRIES);
- }, IfmClusterUtils.INTERFACE_CONFIG_ENTITY);
+ });
}
private class RendererStateAddWorker implements Callable<List<ListenableFuture<Void>>> {
@Override
public List<ListenableFuture<Void>> call() {
- // If another renderer(for eg : CSS) needs to be supported, check
- // can be performed here
- // to call the respective helpers.
- return OvsInterfaceTopologyStateAddHelper.addPortToBridge(instanceIdentifier, bridgeNew, dataBroker);
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+
+ if (bridgeNew.getDatapathId() == null) {
+ LOG.info("DataPathId found as null for Bridge Augmentation: {}... returning...", bridgeNew);
+ return futures;
+ }
+ BigInteger dpnId = IfmUtil.getDpnId(bridgeNew.getDatapathId());
+ LOG.debug("adding bridge references for bridge: {}, dpn: {}", bridgeNew, dpnId);
+ // create bridge reference entry in interface meta operational DS
+ WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
+ InterfaceMetaUtils.createBridgeRefEntry(dpnId, instanceIdentifier, writeTransaction);
+
+ // handle pre-provisioning of tunnels for the newly connected dpn
+ BridgeEntry bridgeEntry = InterfaceMetaUtils.getBridgeEntryFromConfigDS(dpnId, dataBroker);
+ if (bridgeEntry == null) {
+ LOG.debug("Bridge entry not found in config DS for dpn: {}", dpnId);
+ futures.add(writeTransaction.submit());
+ return futures;
+ }
+ futures.add(writeTransaction.submit());
+ SouthboundUtils.addAllPortsToBridge(bridgeEntry, dataBroker, interfaceManagerCommonUtils,
+ instanceIdentifier, bridgeNew);
+ return futures;
}
}
@Override
public List<ListenableFuture<Void>> call() {
- // If another renderer(for eg : CSS) needs to be supported, check
- // can be performed here
- // to call the respective helpers.
- return OvsInterfaceTopologyStateRemoveHelper.removePortFromBridge(instanceIdentifier, bridgeNew,
- dataBroker);
+ BigInteger dpnId = IfmUtil.getDpnId(bridgeNew.getDatapathId());
+
+ if (dpnId == null) {
+ LOG.warn("Got Null DPID for Bridge: {}", bridgeNew);
+ return Collections.emptyList();
+ }
+
+ WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
+ LOG.debug("removing bridge references for bridge: {}, dpn: {}", bridgeNew, dpnId);
+ // delete bridge reference entry in interface meta operational DS
+ InterfaceMetaUtils.deleteBridgeRefEntry(dpnId, transaction);
+
+ // the bridge reference is copied to dpn-tunnel interfaces map, so that
+ // whenever a northbound delete
+ // happens when bridge is not connected, we need the bridge reference to
+ // clean up the topology config DS
+ InterfaceMetaUtils.addBridgeRefToBridgeInterfaceEntry(dpnId, new OvsdbBridgeRef(instanceIdentifier),
+ transaction);
+
+ return Collections.singletonList(transaction.submit());
}
}
@Override
public List<ListenableFuture<Void>> call() {
- // If another renderer(for eg : CSS) needs to be supported, check
- // can be performed here
- // to call the respective helpers.
- return OvsInterfaceTopologyStateUpdateHelper.updateBridgeRefEntry(instanceIdentifier, bridgeNew, bridgeOld,
- dataBroker);
+ return ovsInterfaceTopologyStateUpdateHelper.updateBridgeRefEntry(instanceIdentifier, bridgeNew, bridgeOld);
}
}
}