X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=vpnmanager%2Fimpl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetvirt%2Fvpnmanager%2FVpnInstanceListener.java;h=a77c0c9a8647464e4a14e9759c9babac36150fd3;hb=97c8a6961453727e929878b58399626485382a1f;hp=969dc2e171c91e14532cbe05a305df81cc2428d9;hpb=82fc8f6178fa492fc7aa52219a56f85f78316492;p=netvirt.git diff --git a/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInstanceListener.java b/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInstanceListener.java index 969dc2e171..a77c0c9a86 100644 --- a/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInstanceListener.java +++ b/vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInstanceListener.java @@ -7,28 +7,33 @@ */ package org.opendaylight.netvirt.vpnmanager; -import com.google.common.base.Optional; +import static org.opendaylight.genius.infra.Datastore.CONFIGURATION; +import static org.opendaylight.genius.infra.Datastore.OPERATIONAL; + 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 java.math.BigInteger; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.concurrent.Callable; -import javax.annotation.PostConstruct; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.locks.ReentrantLock; +import javax.annotation.PreDestroy; 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.controller.md.sal.common.api.data.ReadFailedException; -import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase; +import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker; +import org.opendaylight.genius.infra.Datastore.Configuration; +import org.opendaylight.genius.infra.Datastore.Operational; import org.opendaylight.genius.infra.ManagedNewTransactionRunner; import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl; +import org.opendaylight.genius.infra.TypedWriteTransaction; import org.opendaylight.genius.mdsalutil.FlowEntity; import org.opendaylight.genius.mdsalutil.InstructionInfo; import org.opendaylight.genius.mdsalutil.MDSALUtil; @@ -40,34 +45,43 @@ import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable; import org.opendaylight.genius.mdsalutil.instructions.InstructionWriteMetadata; import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager; import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId; +import org.opendaylight.genius.utils.JvmGlobalLocks; import org.opendaylight.genius.utils.SystemPropertyReader; import org.opendaylight.infrautils.jobcoordinator.JobCoordinator; -import org.opendaylight.infrautils.utils.concurrent.ListenableFutures; +import org.opendaylight.infrautils.utils.concurrent.Executors; +import org.opendaylight.infrautils.utils.concurrent.LoggingFutures; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.netvirt.fibmanager.api.IFibManager; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargets; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTarget; -import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance; +import org.opendaylight.serviceutils.tools.listener.AbstractAsyncDataTreeChangeListener; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.DcGatewayIpList; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIpKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnTargetsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpntargets.VpnTargetBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpntargets.VpnTargetKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInstances; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.VpnTargets; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.vpntargets.VpnTarget; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.Uint32; +import org.opendaylight.yangtools.yang.common.Uint64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Singleton -public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase { +public class VpnInstanceListener extends AbstractAsyncDataTreeChangeListener { private static final Logger LOG = LoggerFactory.getLogger(VpnInstanceListener.class); private static final String LOGGING_PREFIX_ADD = "VPN-ADD:"; + private static final String LOGGING_PREFIX_UPDATE = "VPN-UPDATE:"; private static final String LOGGING_PREFIX_DELETE = "VPN-REMOVE:"; private final DataBroker dataBroker; private final ManagedNewTransactionRunner txRunner; @@ -77,13 +91,16 @@ public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase getWildCardPath() { - return InstanceIdentifier.create(VpnInstances.class).child(VpnInstance.class); + @PreDestroy + public void close() { + super.close(); + Executors.shutdownAndAwaitTermination(getExecutorService()); } - @Override - protected VpnInstanceListener getDataTreeChangeListener() { - return VpnInstanceListener.this; - } @Override - protected void remove(InstanceIdentifier identifier, VpnInstance del) { - LOG.trace("{} remove: VPN event key: {}, value: {}", LOGGING_PREFIX_DELETE, identifier, del); + public void remove(InstanceIdentifier identifier, VpnInstance del) { + LOG.trace("{} : VPN event key: {}, value: {}", LOGGING_PREFIX_DELETE, identifier, del); final String vpnName = del.getVpnInstanceName(); Optional vpnOpValue; - String primaryRd = VpnUtil.getPrimaryRd(del); + String primaryRd = vpnUtil.getVpnRd(vpnName); + if (primaryRd == null) { + LOG.error("{}, failed to remove VPN: primaryRd is null for vpn {}", LOGGING_PREFIX_DELETE, vpnName); + return; + } //TODO(vpnteam): Entire code would need refactoring to listen only on the parent object - VPNInstance try { vpnOpValue = SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL, VpnUtil.getVpnInstanceOpDataIdentifier(primaryRd)); - } catch (ReadFailedException e) { - LOG.error("{} remove: Exception when attempting to retrieve VpnInstanceOpDataEntry for VPN {}. ", + } catch (InterruptedException | ExecutionException e) { + LOG.error("{}, failed to remove VPN: Exception while retrieving VpnInstanceOpDataEntry for VPN {}. ", LOGGING_PREFIX_DELETE, vpnName, e); return; } if (!vpnOpValue.isPresent()) { - LOG.error("{} remove: Unable to retrieve VpnInstanceOpDataEntry for VPN {}. ", LOGGING_PREFIX_DELETE, - vpnName); + LOG.error("{}, failed to remove VPN: Unable to retrieve VpnInstanceOpDataEntry for VPN {}. ", + LOGGING_PREFIX_DELETE, vpnName); return; } else { jobCoordinator.enqueueJob("VPN-" + vpnName, () -> - Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> { - VpnInstanceOpDataEntryBuilder builder = new VpnInstanceOpDataEntryBuilder().setVrfId(primaryRd) - .setVpnState(VpnInstanceOpDataEntry.VpnState.PendingDelete); - InstanceIdentifier id = - VpnUtil.getVpnInstanceOpDataIdentifier(primaryRd); - tx.merge(LogicalDatastoreType.OPERATIONAL, id, builder.build()); + Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> { + VpnInstanceOpDataEntryBuilder builder = null; + InstanceIdentifier id = null; + if (primaryRd != null) { + builder = new VpnInstanceOpDataEntryBuilder().setVrfId(primaryRd) + .setVpnState(VpnInstanceOpDataEntry.VpnState.PendingDelete); + id = VpnUtil.getVpnInstanceOpDataIdentifier(primaryRd); + } else { + builder = new VpnInstanceOpDataEntryBuilder().setVrfId(vpnName) + .setVpnState(VpnInstanceOpDataEntry.VpnState.PendingDelete); + id = VpnUtil.getVpnInstanceOpDataIdentifier(vpnName); + } + tx.merge(id, builder.build()); LOG.info("{} call: Operational status set to PENDING_DELETE for vpn {} with rd {}", LOGGING_PREFIX_DELETE, vpnName, primaryRd); @@ -147,22 +173,31 @@ public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase identifier, + public void update(InstanceIdentifier identifier, VpnInstance original, VpnInstance update) { - LOG.trace("VPN-UPDATE: update: VPN event key: {}, value: {}. Ignoring", identifier, update); + LOG.trace("VPN-UPDATE: update: VPN event key: {}, value: {}.", identifier, update); String vpnName = update.getVpnInstanceName(); + if (original != null && update != null + && original.getRouteDistinguisher() != null + && update.getRouteDistinguisher() != null + && original.getRouteDistinguisher().size() + != update.getRouteDistinguisher().size()) { + LOG.debug("VPN-UPDATE: VpnInstance:{} updated with new RDs: {} from old RDs: {}", vpnName, + update.getRouteDistinguisher(), original.getRouteDistinguisher()); + vpnUtil.updateVpnInstanceWithRdList(vpnName, update.getRouteDistinguisher()); + } vpnInterfaceManager.updateVpnInterfacesForUnProcessAdjancencies(vpnName); } @Override - protected void add(final InstanceIdentifier identifier, final VpnInstance value) { + public void add(final InstanceIdentifier identifier, final VpnInstance value) { LOG.trace("{} add: Add VPN event key: {}, value: {}", LOGGING_PREFIX_ADD, identifier, value); final String vpnName = value.getVpnInstanceName(); jobCoordinator.enqueueJob("VPN-" + vpnName, new AddVpnInstanceWorker(dataBroker, value), SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries()); } - private class AddVpnInstanceWorker implements Callable>> { + private class AddVpnInstanceWorker implements Callable>> { private final Logger log = LoggerFactory.getLogger(AddVpnInstanceWorker.class); VpnInstance vpnInstance; DataBroker broker; @@ -178,11 +213,12 @@ public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase> futures = new ArrayList<>(2); - futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(confTx -> { - ListenableFuture future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(operTx -> + futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, confTx -> { + ListenableFuture future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, operTx -> addVpnInstance(vpnInstance, confTx, operTx)); - ListenableFutures.addErrorLogging(future, LOG, "{} call: error creating VPN {}", LOGGING_PREFIX_ADD, - vpnInstance.getVpnInstanceName()); + LoggingFutures.addErrorLogging(future, LOG, "{} call: error creating VPN {} rd {}", + LOGGING_PREFIX_ADD, vpnInstance.getVpnInstanceName(), + vpnInstance.getRouteDistinguisher()); futures.add(future); })); Futures.addCallback(Futures.allAsList(futures), @@ -194,23 +230,22 @@ public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase writeConfigTxn, + TypedWriteTransaction writeOperTxn) { if (writeConfigTxn == null) { - ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> + LoggingFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> addVpnInstance(value, tx, writeOperTxn)), LOG, "Error adding VPN instance {}", value); return; } if (writeOperTxn == null) { - ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> + LoggingFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> addVpnInstance(value, writeConfigTxn, tx)), LOG, "Error adding VPN instance {}", value); return; } - VpnAfConfig config = value.getIpv4Family(); String vpnInstanceName = value.getVpnInstanceName(); - long vpnId = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME, vpnInstanceName); - if (vpnId == 0) { + Uint32 vpnId = vpnUtil.getUniqueId(VpnConstants.VPN_IDPOOL_NAME, vpnInstanceName); + if (vpnId.longValue() == 0) { LOG.error("{} addVpnInstance: Unable to fetch label from Id Manager. Bailing out of adding operational" + " data for Vpn Instance {}", LOGGING_PREFIX_ADD, value.getVpnInstanceName()); return; @@ -221,16 +256,13 @@ public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase opVpnTargetList = new ArrayList<>(); @@ -262,14 +293,16 @@ public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase vpnTargetList = vpnTargets.getVpnTarget(); - if (vpnTargetList != null) { - for (VpnTarget vpnTarget : vpnTargetList) { + @Nullable Map vpnTargetListMap + = vpnTargets.nonnullVpnTarget(); + if (vpnTargetListMap != null) { + for (VpnTarget vpnTarget : vpnTargetListMap.values()) { VpnTargetBuilder vpnTargetBuilder = new VpnTargetBuilder().withKey(new VpnTargetKey(vpnTarget.key().getVrfRTValue())) .setVrfRTType(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn @@ -283,14 +316,12 @@ public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase rds = config.getRouteDistinguisher(); + List rds = value.getRouteDistinguisher(); builder.setRd(rds); } else { builder.setBgpvpnType(VpnInstanceOpDataEntry.BgpvpnType.VPN); } - writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, - VpnUtil.getVpnInstanceOpDataIdentifier(primaryRd), - builder.build(), true); + writeOperTxn.mergeParentStructureMerge(VpnUtil.getVpnInstanceOpDataIdentifier(primaryRd), builder.build()); LOG.info("{} addVpnInstance: VpnInstanceOpData populated successfully for vpn {} rd {}", LOGGING_PREFIX_ADD, vpnInstanceName, primaryRd); } @@ -314,41 +345,44 @@ public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase rd = config.getRouteDistinguisher(); + List rd = vpnInstance.getRouteDistinguisher(); if (rd == null || addBgpVrf()) { notifyTask(); vpnInterfaceManager.vpnInstanceIsReady(vpnName); } log.info("{} onSuccess: Vpn Instance Op Data addition for {} successful.", LOGGING_PREFIX_ADD, vpnName); - VpnInstanceOpDataEntry vpnInstanceOpDataEntry = VpnUtil.getVpnInstanceOpData(dataBroker, + VpnInstanceOpDataEntry vpnInstanceOpDataEntry = vpnUtil.getVpnInstanceOpData( VpnUtil.getPrimaryRd(vpnInstance)); // bind service on each tunnel interface //TODO (KIRAN): Add a new listener to handle creation of new DC-GW binding and deletion of existing DC-GW. if (VpnUtil.isL3VpnOverVxLan(vpnInstance.getL3vni())) { //Handled for L3VPN Over VxLAN for (String tunnelInterfaceName: getDcGatewayTunnelInterfaceNameList()) { - VpnUtil.bindService(vpnInstance.getVpnInstanceName(), tunnelInterfaceName, dataBroker, - true/*isTunnelInterface*/, jobCoordinator); + vpnUtil.bindService(vpnInstance.getVpnInstanceName(), tunnelInterfaceName, + true/*isTunnelInterface*/); } // install flow List mkMatches = new ArrayList<>(); - mkMatches.add(new MatchTunnelId(BigInteger.valueOf(vpnInstance.getL3vni()))); + mkMatches.add(new MatchTunnelId(Uint64.valueOf(vpnInstance.getL3vni()))); List instructions = Arrays.asList(new InstructionWriteMetadata(MetaDataUtil.getVpnIdMetadata(vpnInstanceOpDataEntry - .getVpnId()), MetaDataUtil.METADATA_MASK_VRFID), + .getVpnId().toJava()), MetaDataUtil.METADATA_MASK_VRFID), new InstructionGotoTable(NwConstants.L3_GW_MAC_TABLE)); - - for (BigInteger dpnId: NWUtil.getOperativeDPNs(dataBroker)) { - String flowRef = getFibFlowRef(dpnId, NwConstants.L3VNI_EXTERNAL_TUNNEL_DEMUX_TABLE, - vpnName, VpnConstants.DEFAULT_FLOW_PRIORITY); - FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId, - NwConstants.L3VNI_EXTERNAL_TUNNEL_DEMUX_TABLE, flowRef, VpnConstants.DEFAULT_FLOW_PRIORITY, - "VxLAN VPN Tunnel Bind Service", 0, 0, NwConstants.COOKIE_VM_FIB_TABLE, - mkMatches, instructions); - mdsalManager.installFlow(dpnId, flowEntity); + try { + for (Uint64 dpnId: NWUtil.getOperativeDPNs(dataBroker)) { + String flowRef = getFibFlowRef(dpnId, NwConstants.L3VNI_EXTERNAL_TUNNEL_DEMUX_TABLE, + vpnName, VpnConstants.DEFAULT_FLOW_PRIORITY); + FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId, + NwConstants.L3VNI_EXTERNAL_TUNNEL_DEMUX_TABLE, flowRef, + VpnConstants.DEFAULT_FLOW_PRIORITY, "VxLAN VPN Tunnel Bind Service", + 0, 0, NwConstants.COOKIE_VM_FIB_TABLE, mkMatches, instructions); + mdsalManager.installFlow(dpnId, flowEntity); + } + } catch (ExecutionException | InterruptedException e) { + LOG.error("PostAddVpnInstanceWorker: Exception while getting the list of Operative DPNs for Vpn {}", + vpnName, e); } /////////////////////// @@ -358,17 +392,23 @@ public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase vpnTargetList = config.getVpnTargets().getVpnTarget(); + String primaryRd = vpnUtil.getPrimaryRd(vpnName); + @Nullable Map vpnTargetList + = vpnInstance.getVpnTargets().getVpnTarget(); if (vpnTargetList == null) { log.error("{} addBgpVrf: vpn target list is empty for vpn {} RD {}", LOGGING_PREFIX_ADD, this.vpnName, primaryRd); return false; } - synchronized (vpnName.intern()) { + // FIXME: separate out to somehow? + final ReentrantLock lock = JvmGlobalLocks.getLockForString(vpnName); + lock.lock(); + try { fibManager.addVrfTable(primaryRd, null); + } finally { + lock.unlock(); } vpnInterfaceManager.handleVpnsExportingRoutes(this.vpnName, primaryRd); return true; @@ -394,71 +434,73 @@ public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase id = VpnUtil.getVpnInstanceOpDataIdentifier(rd); try { return SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL, - id).orNull(); - } catch (ReadFailedException e) { + id).orElse(null); + } catch (InterruptedException | ExecutionException e) { throw new RuntimeException("Error reading VPN instance data for " + rd, e); } } + @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", + justification = "https://github.com/spotbugs/spotbugs/issues/811") private List getDcGatewayTunnelInterfaceNameList() { List tunnelInterfaceNameList = new ArrayList<>(); - - InstanceIdentifier dcGatewayIpListInstanceIdentifier = InstanceIdentifier - .create(DcGatewayIpList.class); - Optional dcGatewayIpListOptional = VpnUtil.read(dataBroker, - LogicalDatastoreType.CONFIGURATION, dcGatewayIpListInstanceIdentifier); - if (!dcGatewayIpListOptional.isPresent()) { - LOG.info("No DC gateways configured."); - return tunnelInterfaceNameList; - } - List dcGatewayIps = dcGatewayIpListOptional.get().getDcGatewayIp(); - - InstanceIdentifier externalTunnelListId = InstanceIdentifier - .create(ExternalTunnelList.class); - - Optional externalTunnelListOptional = VpnUtil.read(dataBroker, - LogicalDatastoreType.OPERATIONAL, externalTunnelListId); - if (externalTunnelListOptional.isPresent()) { - List externalTunnels = externalTunnelListOptional.get().getExternalTunnel(); - - List externalTunnelIpList = new ArrayList<>(); - for (ExternalTunnel externalTunnel: externalTunnels) { - externalTunnelIpList.add(externalTunnel.getDestinationDevice()); - } - - List dcGatewayIpList = new ArrayList<>(); - for (DcGatewayIp dcGatewayIp: dcGatewayIps) { - dcGatewayIpList.add(dcGatewayIp.getIpAddress().getIpv4Address().toString()); + try { + InstanceIdentifier dcGatewayIpListInstanceIdentifier = InstanceIdentifier + .create(DcGatewayIpList.class); + Optional dcGatewayIpListOptional = SingleTransactionDataBroker.syncReadOptional( + dataBroker, LogicalDatastoreType.CONFIGURATION, dcGatewayIpListInstanceIdentifier); + if (!dcGatewayIpListOptional.isPresent()) { + LOG.info("No DC gateways configured."); + return tunnelInterfaceNameList; } - - // Find all externalTunnelIps present in dcGateWayIpList - List externalTunnelIpsInDcGatewayIpList = new ArrayList<>(); - for (String externalTunnelIp: externalTunnelIpList) { - for (String dcGateWayIp: dcGatewayIpList) { - if (externalTunnelIp.contentEquals(dcGateWayIp)) { - externalTunnelIpsInDcGatewayIpList.add(externalTunnelIp); + Map keyDcGatewayIpMap = dcGatewayIpListOptional.get().nonnullDcGatewayIp(); + InstanceIdentifier externalTunnelListId = InstanceIdentifier + .create(ExternalTunnelList.class); + Optional externalTunnelListOptional = SingleTransactionDataBroker.syncReadOptional( + dataBroker, LogicalDatastoreType.OPERATIONAL, externalTunnelListId); + if (externalTunnelListOptional.isPresent()) { + Map keyExternalTunnelMap + = externalTunnelListOptional.get().nonnullExternalTunnel(); + List externalTunnelIpList = new ArrayList<>(); + for (ExternalTunnel externalTunnel: keyExternalTunnelMap.values()) { + externalTunnelIpList.add(externalTunnel.getDestinationDevice()); + } + List dcGatewayIpList = new ArrayList<>(); + for (DcGatewayIp dcGatewayIp: keyDcGatewayIpMap.values()) { + dcGatewayIpList.add(dcGatewayIp.getIpAddress().getIpv4Address().toString()); + } + // Find all externalTunnelIps present in dcGateWayIpList + List externalTunnelIpsInDcGatewayIpList = new ArrayList<>(); + for (String externalTunnelIp: externalTunnelIpList) { + for (String dcGateWayIp: dcGatewayIpList) { + if (externalTunnelIp.contentEquals(dcGateWayIp)) { + externalTunnelIpsInDcGatewayIpList.add(externalTunnelIp); + } } } - } - - - for (String externalTunnelIpsInDcGatewayIp: externalTunnelIpsInDcGatewayIpList) { - for (ExternalTunnel externalTunnel: externalTunnels) { - if (externalTunnel.getDestinationDevice().contentEquals(externalTunnelIpsInDcGatewayIp)) { - tunnelInterfaceNameList.add(externalTunnel.getTunnelInterfaceName()); + for (String externalTunnelIpsInDcGatewayIp: externalTunnelIpsInDcGatewayIpList) { + for (ExternalTunnel externalTunnel: keyExternalTunnelMap.values()) { + if (externalTunnel.getDestinationDevice().contentEquals(externalTunnelIpsInDcGatewayIp)) { + tunnelInterfaceNameList.add(externalTunnel.getTunnelInterfaceName()); + } } } - } + } + } catch (InterruptedException | ExecutionException e) { + LOG.error("getDcGatewayTunnelInterfaceNameList: Failed to read data store"); } return tunnelInterfaceNameList; } - private String getFibFlowRef(BigInteger dpnId, short tableId, String vpnName, int priority) { + @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", + justification = "https://github.com/spotbugs/spotbugs/issues/811") + private String getFibFlowRef(Uint64 dpnId, short tableId, String vpnName, int priority) { return VpnConstants.FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId + NwConstants.FLOWID_SEPARATOR + vpnName + NwConstants.FLOWID_SEPARATOR + priority; }