X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=vpnmanager%2Fvpnmanager-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fvpnservice%2FVpnManager.java;fp=vpnmanager%2Fvpnmanager-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fvpnservice%2FVpnManager.java;h=1a454018d0a3f912570d99da250693f6f9a03c19;hb=ab27b7d22b7b23d63391621aad715d803ffdbf8c;hp=5567d3e6206a47e3c47d2a65f283ff2ddc62ed3d;hpb=c103ce9e5b1e4acfb3320f245503e46332593e43;p=vpnservice.git diff --git a/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnManager.java b/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnManager.java index 5567d3e6..1a454018 100644 --- a/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnManager.java +++ b/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnManager.java @@ -10,12 +10,15 @@ package org.opendaylight.vpnservice; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.concurrent.*; +import com.google.common.util.concurrent.CheckedFuture; import org.opendaylight.bgpmanager.api.IBgpManager; 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.md.sal.common.api.data.AsyncDataBroker.DataChangeScope; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; 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.opendaylight.l3vpn.rev130911.VpnInstanceToVpnId; import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstanceToVpnIdBuilder; @@ -51,12 +54,15 @@ import com.google.common.util.concurrent.Futures; public class VpnManager extends AbstractDataChangeListener implements AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(VpnManager.class); - private ListenerRegistration listenerRegistration, fibListenerRegistration; + private ListenerRegistration listenerRegistration, fibListenerRegistration, opListenerRegistration; + private ConcurrentMap vpnOpMap = new ConcurrentHashMap(); + private ExecutorService executorService = Executors.newSingleThreadExecutor(); private final DataBroker broker; private final IBgpManager bgpManager; private IdManagerService idManager; private VpnInterfaceManager vpnInterfaceManager; private final FibEntriesListener fibListener; + private final VpnInstanceOpListener vpnInstOpListener; private static final FutureCallback DEFAULT_CALLBACK = new FutureCallback() { @@ -80,6 +86,7 @@ public class VpnManager extends AbstractDataChangeListener implemen broker = db; this.bgpManager = bgpManager; this.fibListener = new FibEntriesListener(); + this.vpnInstOpListener = new VpnInstanceOpListener(); registerListener(db); } @@ -89,6 +96,9 @@ public class VpnManager extends AbstractDataChangeListener implemen getWildCardPath(), VpnManager.this, DataChangeScope.SUBTREE); fibListenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, getFibEntryListenerPath(), fibListener, DataChangeScope.BASE); + opListenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, + getVpnInstanceOpListenerPath(), vpnInstOpListener, DataChangeScope.SUBTREE); + } catch (final Exception e) { LOG.error("VPN Service DataChange listener registration fail !", e); throw new IllegalStateException("VPN Service registration Listener failed.", e); @@ -103,6 +113,21 @@ public class VpnManager extends AbstractDataChangeListener implemen this.vpnInterfaceManager = vpnInterfaceManager; } + private void waitForOpDataRemoval(String id) { + //wait till DCN for removal of all DPNs in VPN arrivaes + Runnable notifyTask = new VpnNotifyTask(); + synchronized (id.intern()) { + vpnOpMap.put(id, notifyTask); + synchronized (notifyTask) { + try { + notifyTask.wait(VpnConstants.WAIT_TIME_IN_MILLISECONDS); + } catch (InterruptedException e) { + } + } + } + + } + @Override protected void remove(InstanceIdentifier identifier, VpnInstance del) { LOG.trace("Remove VPN event - Key: {}, value: {}", identifier, del); @@ -131,13 +156,15 @@ public class VpnManager extends AbstractDataChangeListener implemen if (rd !=null) { - delete(LogicalDatastoreType.OPERATIONAL, VpnUtil.getVpnInstanceOpDataIdentifier(rd)); try { bgpManager.deleteVrf(rd); - } catch(Exception e) { + } catch (Exception e) { LOG.error("Exception when removing VRF from BGP", e); } + waitForOpDataRemoval(rd); + delete(LogicalDatastoreType.OPERATIONAL, VpnUtil.getVpnInstanceOpDataIdentifier(rd)); } else { + waitForOpDataRemoval(vpnName); delete(LogicalDatastoreType.OPERATIONAL, VpnUtil.getVpnInstanceOpDataIdentifier(vpnName)); } } @@ -151,30 +178,30 @@ public class VpnManager extends AbstractDataChangeListener implemen @Override protected void add(InstanceIdentifier identifier, VpnInstance value) { - LOG.trace("key: {}, value: {}", identifier, value); + LOG.trace("VPN Instance key: {}, value: {}", identifier, value); VpnAfConfig config = value.getIpv4Family(); String rd = config.getRouteDistinguisher(); long vpnId = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME, value.getVpnInstanceName()); - + LOG.trace("VPN instance to ID generated."); org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance vpnInstanceToVpnId = VpnUtil.getVpnInstanceToVpnId(value.getVpnInstanceName(), vpnId, (rd != null) ? rd : value.getVpnInstanceName()); - asyncWrite(LogicalDatastoreType.CONFIGURATION, + syncWrite(LogicalDatastoreType.CONFIGURATION, VpnUtil.getVpnInstanceToVpnIdIdentifier(value.getVpnInstanceName()), vpnInstanceToVpnId, DEFAULT_CALLBACK); if(rd == null) { - asyncWrite(LogicalDatastoreType.OPERATIONAL, + syncWrite(LogicalDatastoreType.OPERATIONAL, VpnUtil.getVpnInstanceOpDataIdentifier(value.getVpnInstanceName()), - VpnUtil.getVpnInstanceOpData(value.getVpnInstanceName(), vpnId), DEFAULT_CALLBACK); + VpnUtil.getVpnInstanceOpDataBuilder(value.getVpnInstanceName(), vpnId), DEFAULT_CALLBACK); } else { - asyncWrite(LogicalDatastoreType.OPERATIONAL, + syncWrite(LogicalDatastoreType.OPERATIONAL, VpnUtil.getVpnInstanceOpDataIdentifier(rd), - VpnUtil.getVpnInstanceOpData(rd, vpnId), DEFAULT_CALLBACK); + VpnUtil.getVpnInstanceOpDataBuilder(rd, vpnId), DEFAULT_CALLBACK); List vpnTargetList = config.getVpnTargets().getVpnTarget(); @@ -200,6 +227,22 @@ public class VpnManager extends AbstractDataChangeListener implemen LOG.error("Exception when adding VRF to BGP", e); } } + //Try to add up vpn Interfaces if already in Operational Datastore + LOG.trace("Trying to add the vpn interfaces -1."); + InstanceIdentifier vpnInterfacesId = InstanceIdentifier.builder(VpnInterfaces.class).build(); + Optional optionalVpnInterfaces = read(LogicalDatastoreType.CONFIGURATION, vpnInterfacesId); + + if(optionalVpnInterfaces.isPresent()) { + List vpnInterfaces = optionalVpnInterfaces.get().getVpnInterface(); + for(VpnInterface vpnInterface : vpnInterfaces) { + if(vpnInterface.getVpnInstanceName().equals(value.getVpnInstanceName())) { + LOG.debug("VpnInterface {} will be added from VPN {}", vpnInterface.getName(), value.getVpnInstanceName()); + vpnInterfaceManager.add( + VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getName()), vpnInterface); + + } + } + } } private InstanceIdentifier getWildCardPath() { @@ -211,6 +254,11 @@ public class VpnManager extends AbstractDataChangeListener implemen .child(VrfEntry.class); } + private InstanceIdentifier getVpnInstanceOpListenerPath() { + return InstanceIdentifier.create(VpnInstanceOpData.class).child(VpnInstanceOpDataEntry.class); + + } + @Override public void close() throws Exception { if (listenerRegistration != null) { @@ -229,6 +277,15 @@ public class VpnManager extends AbstractDataChangeListener implemen } fibListenerRegistration = null; } + if (opListenerRegistration != null) { + try { + opListenerRegistration.close(); + } catch (final Exception e) { + LOG.error("Error when cleaning up VPN Instance Operational entries DataChangeListener.", e); + } + opListenerRegistration = null; + } + LOG.trace("VPN Manager Closed"); } @@ -254,6 +311,19 @@ public class VpnManager extends AbstractDataChangeListener implemen Futures.addCallback(tx.submit(), callback); } + private void syncWrite(LogicalDatastoreType datastoreType, + InstanceIdentifier path, T data, FutureCallback callback) { + WriteTransaction tx = broker.newWriteOnlyTransaction(); + tx.put(datastoreType, path, data, true); + CheckedFuture futures = tx.submit(); + try { + futures.get(); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Error writing VPN instance to ID info to datastore (path, data) : ({}, {})", path, data); + throw new RuntimeException(e.getMessage()); + } + } + protected VpnInstanceOpDataEntry getVpnInstanceOpData(String rd) { InstanceIdentifier id = VpnUtil.getVpnInstanceOpDataIdentifier(rd); Optional vpnInstanceOpData = read(LogicalDatastoreType.OPERATIONAL, id); @@ -327,4 +397,42 @@ public class VpnManager extends AbstractDataChangeListener implemen } } } + + class VpnInstanceOpListener extends org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener { + + public VpnInstanceOpListener() { + super(VpnInstanceOpDataEntry.class); + } + + @Override + protected void remove(InstanceIdentifier identifier, VpnInstanceOpDataEntry del) { + + } + + @Override + protected void update(InstanceIdentifier identifier, VpnInstanceOpDataEntry original, VpnInstanceOpDataEntry update) { + final VpnInstanceOpDataEntryKey key = identifier.firstKeyOf(VpnInstanceOpDataEntry.class, VpnInstanceOpDataEntryKey.class); + String vpnName = key.getVrfId(); + + LOG.trace("VpnInstanceOpListener update: vpn name {} interface count in Old VpnOp Instance {} in New VpnOp Instance {}" , + vpnName, original.getVpnInterfaceCount(), update.getVpnInterfaceCount() ); + + //if((original.getVpnToDpnList().size() != update.getVpnToDpnList().size()) && (update.getVpnToDpnList().size() == 0)) { + if((original.getVpnInterfaceCount() != update.getVpnInterfaceCount()) && (update.getVpnInterfaceCount() == 0)) { + notifyTaskIfRequired(vpnName); + } + } + + private void notifyTaskIfRequired(String vpnName) { + Runnable notifyTask = vpnOpMap.remove(vpnName); + if (notifyTask == null) { + return; + } + executorService.execute(notifyTask); + } + + @Override + protected void add(InstanceIdentifier identifier, VpnInstanceOpDataEntry add) { + } + } }