Unsupported operation exception handling
[netvirt.git] / vpnmanager / impl / src / main / java / org / opendaylight / netvirt / vpnmanager / intervpnlink / InterVpnLinkListener.java
index 0034b61564a00ed4336750bc2e69ab8f2e0b28ba..114cff1ca30159ae2bdca27738f55bbde40d2bce 100755 (executable)
@@ -7,13 +7,15 @@
  */
 package org.opendaylight.netvirt.vpnmanager.intervpnlink;
 
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 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 java.util.Collections;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
@@ -23,7 +25,6 @@ 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.NotificationPublishService;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
@@ -74,6 +75,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLinkKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.Uint32;
+import org.opendaylight.yangtools.yang.common.Uint64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -97,6 +100,8 @@ public class InterVpnLinkListener extends AsyncDataTreeChangeListenerBase<InterV
     private final VpnOpDataSyncer vpnOpDataSyncer;
     private final JobCoordinator jobCoordinator;
     private final InterVpnLinkCache interVpnLinkCache;
+    private final VpnUtil vpnUtil;
+    private final InterVpnLinkUtil interVpnLinkUtil;
 
     @Inject
     public InterVpnLinkListener(final DataBroker dataBroker, final IdManagerService idManager,
@@ -107,7 +112,8 @@ public class InterVpnLinkListener extends AsyncDataTreeChangeListenerBase<InterV
                                 final VpnFootprintService vpnFootprintService,
                                 final VpnOpDataSyncer vpnOpDataSyncer,
                                 final JobCoordinator jobCoordinator,
-                                final InterVpnLinkCache interVpnLinkCache) {
+                                final InterVpnLinkCache interVpnLinkCache, final VpnUtil vpnUtil,
+                                final InterVpnLinkUtil interVpnLinkUtil) {
         this.dataBroker = dataBroker;
         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
         this.idManager = idManager;
@@ -121,6 +127,8 @@ public class InterVpnLinkListener extends AsyncDataTreeChangeListenerBase<InterV
         this.vpnOpDataSyncer = vpnOpDataSyncer;
         this.jobCoordinator = jobCoordinator;
         this.interVpnLinkCache = interVpnLinkCache;
+        this.vpnUtil = vpnUtil;
+        this.interVpnLinkUtil = interVpnLinkUtil;
     }
 
     @PostConstruct
@@ -152,16 +160,16 @@ public class InterVpnLinkListener extends AsyncDataTreeChangeListenerBase<InterV
         InterVpnLinkState vpnLinkState = new InterVpnLinkStateBuilder().setInterVpnLinkName(ivpnLinkName).build();
         MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnLinkStateIid, vpnLinkState);
 
-        InterVpnLinkKey key = add.getKey();
+        InterVpnLinkKey key = add.key();
         Uuid vpn1Uuid = add.getFirstEndpoint().getVpnUuid();
         String vpn1Name = vpn1Uuid.getValue();
         Uuid vpn2Uuid = add.getSecondEndpoint().getVpnUuid();
         String vpn2Name = vpn2Uuid.getValue();
-        String vpn1PrimaryRd = VpnUtil.getPrimaryRd(dataBroker, vpn1Name);
-        String vpn2PrimaryRd = VpnUtil.getPrimaryRd(dataBroker, vpn1Name);
-        if (!VpnUtil.isVpnPendingDelete(dataBroker, vpn1PrimaryRd)
-                && !VpnUtil.isVpnPendingDelete(dataBroker, vpn2PrimaryRd)) {
-            if (VpnUtil.getVpnInstance(this.dataBroker, vpn1Name) == null) {
+        String vpn1PrimaryRd = vpnUtil.getPrimaryRd(vpn1Name);
+        String vpn2PrimaryRd = vpnUtil.getPrimaryRd(vpn1Name);
+        if (!vpnUtil.isVpnPendingDelete(vpn1PrimaryRd)
+                && !vpnUtil.isVpnPendingDelete(vpn2PrimaryRd)) {
+            if (vpnUtil.getVpnInstance(vpn1Name) == null) {
                 String errMsg = "InterVpnLink " + ivpnLinkName + " creation error: could not find 1st endpoint Vpn "
                         + vpn1Name;
                 setInError(vpnLinkStateIid, vpnLinkState, errMsg);
@@ -175,7 +183,7 @@ public class InterVpnLinkListener extends AsyncDataTreeChangeListenerBase<InterV
             }
 
             // Second VPN
-            if (VpnUtil.getVpnInstance(this.dataBroker, vpn2Name) == null) {
+            if (vpnUtil.getVpnInstance(vpn2Name) == null) {
                 String errMsg = "InterVpnLink " + ivpnLinkName + " creation error: could not find 2nd endpoint Vpn "
                         + vpn2Name;
                 setInError(vpnLinkStateIid, vpnLinkState, errMsg);
@@ -191,8 +199,8 @@ public class InterVpnLinkListener extends AsyncDataTreeChangeListenerBase<InterV
             interVpnLinkCache.addInterVpnLinkToCaches(add);
 
             // Wait for VPN Operational data ready
-            long vpn1Id = VpnUtil.getVpnId(dataBroker, vpn1Name);
-            if (vpn1Id == VpnConstants.INVALID_ID) {
+            Uint32 vpn1Id = vpnUtil.getVpnId(vpn1Name);
+            if (VpnConstants.INVALID_ID.equals(vpn1Id)) {
                 boolean vpn1Ready =
                         vpnOpDataSyncer.waitForVpnDataReady(VpnOpDataSyncer.VpnOpDataType.vpnInstanceToId, vpn1Name,
                                 VpnConstants.PER_VPN_INSTANCE_MAX_WAIT_TIME_IN_MILLISECONDS);
@@ -205,8 +213,8 @@ public class InterVpnLinkListener extends AsyncDataTreeChangeListenerBase<InterV
                     return;
                 }
             }
-            long vpn2Id = VpnUtil.getVpnId(dataBroker, vpn2Name);
-            if (vpn2Id == VpnConstants.INVALID_ID) {
+            Uint32 vpn2Id = vpnUtil.getVpnId(vpn2Name);
+            if (VpnConstants.INVALID_ID.equals(vpn2Id)) {
                 boolean vpn1Ready =
                         vpnOpDataSyncer.waitForVpnDataReady(VpnOpDataSyncer.VpnOpDataType.vpnInstanceToId,vpn2Name,
                                 VpnConstants.PER_VPN_INSTANCE_MAX_WAIT_TIME_IN_MILLISECONDS);
@@ -220,9 +228,9 @@ public class InterVpnLinkListener extends AsyncDataTreeChangeListenerBase<InterV
                 }
             }
 
-            List<BigInteger> firstDpnList = ivpnLinkLocator.selectSuitableDpns(add);
+            List<Uint64> firstDpnList = ivpnLinkLocator.selectSuitableDpns(add);
             if (firstDpnList != null && !firstDpnList.isEmpty()) {
-                List<BigInteger> secondDpnList = firstDpnList;
+                List<Uint64> secondDpnList = firstDpnList;
 
                 Long firstVpnLportTag = allocateVpnLinkLportTag(key.getName() + vpn1Name);
                 Long secondVpnLportTag = allocateVpnLinkLportTag(key.getName() + vpn2Name);
@@ -233,21 +241,21 @@ public class InterVpnLinkListener extends AsyncDataTreeChangeListenerBase<InterV
                         new SecondEndpointStateBuilder().setVpnUuid(vpn2Uuid).setDpId(secondDpnList)
                                 .setLportTag(secondVpnLportTag).build();
 
-                InterVpnLinkUtil.updateInterVpnLinkState(dataBroker, ivpnLinkName, InterVpnLinkState.State.Active,
+                interVpnLinkUtil.updateInterVpnLinkState(ivpnLinkName, InterVpnLinkState.State.Active,
                         firstEndPointState, secondEndPointState, interVpnLinkCache);
 
                 // Note that in the DPN of the firstEndpoint we install the lportTag of the secondEndpoint and viceversa
-                InterVpnLinkUtil.installLPortDispatcherTableFlow(dataBroker, mdsalManager, ivpnLinkName, firstDpnList,
-                        vpn2Name, secondVpnLportTag);
-                InterVpnLinkUtil.installLPortDispatcherTableFlow(dataBroker, mdsalManager, ivpnLinkName, secondDpnList,
-                        vpn1Name, firstVpnLportTag);
+                interVpnLinkUtil.installLPortDispatcherTableFlow(ivpnLinkName, firstDpnList, vpn2Name,
+                        secondVpnLportTag);
+                interVpnLinkUtil.installLPortDispatcherTableFlow(ivpnLinkName, secondDpnList, vpn1Name,
+                        firstVpnLportTag);
                 // Update the VPN -> DPNs Map.
                 // Note: when a set of DPNs is calculated for Vpn1, these DPNs are added to the VpnToDpn map of Vpn2.
                 // Why? because we do the handover from Vpn1 to Vpn2 in those DPNs, so in those DPNs we must know how
                 // to reach to Vpn2 targets. If new Vpn2 targets are added later, the Fib will be maintained in these
                 // DPNs even if Vpn2 is not physically present there.
-                InterVpnLinkUtil.updateVpnFootprint(vpnFootprintService, vpn2Name, vpn2PrimaryRd, firstDpnList);
-                InterVpnLinkUtil.updateVpnFootprint(vpnFootprintService, vpn1Name, vpn1PrimaryRd, secondDpnList);
+                interVpnLinkUtil.updateVpnFootprint(vpn2Name, vpn2PrimaryRd, firstDpnList);
+                interVpnLinkUtil.updateVpnFootprint(vpn1Name, vpn1PrimaryRd, secondDpnList);
 
                 // Program static routes if needed
                 Optional<InterVpnLinkDataComposite> interVpnLink =
@@ -267,7 +275,7 @@ public class InterVpnLinkListener extends AsyncDataTreeChangeListenerBase<InterV
                 SecondEndpointState secondEndPointState =
                         new SecondEndpointStateBuilder().setVpnUuid(vpn2Uuid).setLportTag(secondVpnLportTag)
                                 .setDpId(Collections.emptyList()).build();
-                InterVpnLinkUtil.updateInterVpnLinkState(dataBroker, ivpnLinkName, InterVpnLinkState.State.Error,
+                interVpnLinkUtil.updateInterVpnLinkState(ivpnLinkName, InterVpnLinkState.State.Error,
                         firstEndPointState, secondEndPointState, interVpnLinkCache);
             }
         }
@@ -296,25 +304,25 @@ public class InterVpnLinkListener extends AsyncDataTreeChangeListenerBase<InterV
 
         // For each endpoint, remove all routes that have been learnt by intervpnLink
         String vpn1Uuid = del.getFirstEndpoint().getVpnUuid().getValue();
-        String rd1 = VpnUtil.getVpnRd(dataBroker, vpn1Uuid);
+        String rd1 = vpnUtil.getVpnRd(vpn1Uuid);
         LOG.debug("Removing leaked routes in VPN {}  rd={}", vpn1Uuid, rd1);
-        VpnUtil.removeVrfEntriesByOrigin(dataBroker, rd1, RouteOrigin.INTERVPN);
+        vpnUtil.removeVrfEntriesByOrigin(rd1, RouteOrigin.INTERVPN);
         List<VrfEntry> vrfEntriesSecondEndpoint =
-            VpnUtil.findVrfEntriesByNexthop(dataBroker, rd1, del.getSecondEndpoint().getIpAddress().getValue());
+            vpnUtil.findVrfEntriesByNexthop(rd1, del.getSecondEndpoint().getIpAddress().getValue());
 
         String vpn2Uuid = del.getSecondEndpoint().getVpnUuid().getValue();
-        String rd2 = VpnUtil.getVpnRd(dataBroker, vpn2Uuid);
+        String rd2 = vpnUtil.getVpnRd(vpn2Uuid);
         LOG.debug("Removing leaked routes in VPN {}  rd={}", vpn2Uuid, rd2);
-        VpnUtil.removeVrfEntriesByOrigin(dataBroker, rd2, RouteOrigin.INTERVPN);
+        vpnUtil.removeVrfEntriesByOrigin(rd2, RouteOrigin.INTERVPN);
         List<VrfEntry> vrfEntriesFirstEndpoint =
-            VpnUtil.findVrfEntriesByNexthop(dataBroker, rd2, del.getFirstEndpoint().getIpAddress().getValue());
+            vpnUtil.findVrfEntriesByNexthop(rd2, del.getFirstEndpoint().getIpAddress().getValue());
 
-        Optional<InterVpnLinkState> optIVpnLinkState = InterVpnLinkUtil.getInterVpnLinkState(dataBroker, del.getName());
+        Optional<InterVpnLinkState> optIVpnLinkState = interVpnLinkUtil.getInterVpnLinkState(del.getName());
         if (optIVpnLinkState.isPresent()) {
             InterVpnLinkState interVpnLinkState = optIVpnLinkState.get();
             boolean isVpnFirstEndPoint = true;
             if (interVpnLinkState.getFirstEndpointState() != null) {
-                Long firstEndpointLportTag = interVpnLinkState.getFirstEndpointState().getLportTag();
+                Long firstEndpointLportTag = interVpnLinkState.getFirstEndpointState().getLportTag().toJava();
                 removeVpnLinkEndpointFlows(del, vpn2Uuid, rd1,
                     interVpnLinkState.getSecondEndpointState().getDpId(),
                     firstEndpointLportTag.intValue(),
@@ -325,7 +333,7 @@ public class InterVpnLinkListener extends AsyncDataTreeChangeListenerBase<InterV
             }
             isVpnFirstEndPoint = false;
             if (interVpnLinkState.getSecondEndpointState() != null) {
-                Long secondEndpointLportTag = interVpnLinkState.getSecondEndpointState().getLportTag();
+                Long secondEndpointLportTag = interVpnLinkState.getSecondEndpointState().getLportTag().toJava();
                 removeVpnLinkEndpointFlows(del, vpn1Uuid, rd2,
                                            interVpnLinkState.getFirstEndpointState().getDpId(),
                                            secondEndpointLportTag.intValue(),
@@ -336,14 +344,14 @@ public class InterVpnLinkListener extends AsyncDataTreeChangeListenerBase<InterV
             }
         }
 
-        VpnUtil.removeVrfEntries(dataBroker, rd1, vrfEntriesSecondEndpoint);
-        VpnUtil.removeVrfEntries(dataBroker, rd2, vrfEntriesFirstEndpoint);
-        VpnUtil.withdrawRoutes(bgpManager, rd1, vrfEntriesSecondEndpoint);
-        VpnUtil.withdrawRoutes(bgpManager, rd2, vrfEntriesFirstEndpoint);
+        vpnUtil.removeVrfEntries(rd1, vrfEntriesSecondEndpoint);
+        vpnUtil.removeVrfEntries(rd2, vrfEntriesFirstEndpoint);
+        vpnUtil.withdrawRoutes(rd1, vrfEntriesSecondEndpoint);
+        vpnUtil.withdrawRoutes(rd2, vrfEntriesFirstEndpoint);
 
         // Release idManager with LPortTag associated to endpoints
         LOG.debug("Releasing InterVpnLink {} endpoints LportTags", del.getName());
-        InterVpnLinkKey key = del.getKey();
+        InterVpnLinkKey key = del.key();
         Uuid firstEndpointVpnUuid = del.getFirstEndpoint().getVpnUuid();
         Uuid secondEndpointVpnUuid = del.getSecondEndpoint().getVpnUuid();
         releaseVpnLinkLPortTag(key.getName() + firstEndpointVpnUuid.getValue());
@@ -357,15 +365,14 @@ public class InterVpnLinkListener extends AsyncDataTreeChangeListenerBase<InterV
         // Removing the InterVpnLinkState
         InstanceIdentifier<InterVpnLinkState> interVpnLinkStateIid =
             InterVpnLinkUtil.getInterVpnLinkStateIid(del.getName());
-        ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
-            tx.delete(LogicalDatastoreType.CONFIGURATION, interVpnLinkStateIid)), LOG,
-                "Error deleting inter-VPN link state {}", interVpnLinkStateIid);
+        ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx ->
+            tx.delete(interVpnLinkStateIid)), LOG, "Error deleting inter-VPN link state {}", interVpnLinkStateIid);
     }
 
     // We're catching Exception here to continue deleting as much as possible
     // TODO Rework this so it's done in one transaction
     @SuppressWarnings("checkstyle:IllegalCatch")
-    private void removeVpnLinkEndpointFlows(InterVpnLink del, String vpnUuid, String rd, List<BigInteger> dpns,
+    private void removeVpnLinkEndpointFlows(InterVpnLink del, String vpnUuid, String rd, List<Uint64> dpns,
                                             int otherEndpointLportTag, String otherEndpointIpAddr,
                                             List<VrfEntry> vrfEntries, final boolean isVpnFirstEndPoint) {
 
@@ -378,18 +385,18 @@ public class InterVpnLinkListener extends AsyncDataTreeChangeListenerBase<InterV
             return;
         }
 
-        for (BigInteger dpnId : dpns) {
+        for (Uint64 dpnId : dpns) {
             try {
                 // Removing flow from LportDispatcher table
                 String flowRef = InterVpnLinkUtil.getLportDispatcherFlowRef(interVpnLinkName, otherEndpointLportTag);
                 FlowKey flowKey = new FlowKey(new FlowId(flowRef));
-                Flow flow = new FlowBuilder().setKey(flowKey).setId(new FlowId(flowRef))
+                Flow flow = new FlowBuilder().withKey(flowKey).setId(new FlowId(flowRef))
                     .setTableId(NwConstants.LPORT_DISPATCHER_TABLE).setFlowName(flowRef)
                     .build();
                 mdsalManager.removeFlow(dpnId, flow);
 
                 // Also remove the 'fake' iface from the VpnToDpn map
-                InterVpnLinkUtil.removeIVpnLinkIfaceFromVpnFootprint(vpnFootprintService, vpnUuid, rd, dpnId);
+                interVpnLinkUtil.removeIVpnLinkIfaceFromVpnFootprint(vpnUuid, rd, dpnId);
 
             } catch (Exception e) {
                 // Whatever happens it should not stop it from trying to remove as much as possible
@@ -425,7 +432,8 @@ public class InterVpnLinkListener extends AsyncDataTreeChangeListenerBase<InterV
 
         String specificJobKey = "InterVpnLink.update." + original.getName();
         jobCoordinator.enqueueJob(specificJobKey, new InterVpnLinkRemoverTask(dataBroker, identifier));
-        jobCoordinator.enqueueJob(specificJobKey, new InterVpnLinkCleanedCheckerTask(dataBroker, original));
+        jobCoordinator.enqueueJob(specificJobKey, new InterVpnLinkCleanedCheckerTask(dataBroker, original,
+                interVpnLinkUtil, vpnUtil));
         jobCoordinator.enqueueJob(specificJobKey, new InterVpnLinkCreatorTask(dataBroker, update));
     }
 
@@ -438,7 +446,7 @@ public class InterVpnLinkListener extends AsyncDataTreeChangeListenerBase<InterV
             Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
             RpcResult<AllocateIdOutput> rpcResult = result.get();
             if (rpcResult.isSuccessful()) {
-                return rpcResult.getResult().getIdValue();
+                return rpcResult.getResult().getIdValue().toJava();
             } else {
                 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
             }
@@ -458,9 +466,8 @@ public class InterVpnLinkListener extends AsyncDataTreeChangeListenerBase<InterV
             new InterVpnLinkStateBuilder(vpnLinkState).setState(InterVpnLinkState.State.Error)
                 .setErrorDescription(errorMsg)
                 .build();
-        ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
-            tx.put(LogicalDatastoreType.CONFIGURATION, vpnLinkStateIid, vpnLinkErrorState,
-                    WriteTransaction.CREATE_MISSING_PARENTS)),
+        ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx ->
+            tx.put(vpnLinkStateIid, vpnLinkErrorState, CREATE_MISSING_PARENTS)),
                 LOG, "Error storing the VPN link error state for {}, {}", vpnLinkStateIid, vpnLinkErrorState);
 
         // Sending out an error Notification