Unblock the Netvirt CSIT Issue from VPNManager 44/91344/2
authorKarthikeyan Krishnan <karthikeyangceb007@gmail.com>
Thu, 16 Jul 2020 08:46:25 +0000 (14:16 +0530)
committerKarthikeyan Krishnan <karthikeyangceb007@gmail.com>
Thu, 16 Jul 2020 09:30:01 +0000 (15:00 +0530)
Issue:
=====

(1)
org.opendaylight.netvirt.vpnmanager-impl - 0.11.0.SNAPSHOT | SUBNETROUTE:
onInterfaceUp: Unable to handle interface up event for port
d92aa7f0-2b83-4bd0-860c-026e672a955c in subnet
5b33e49f-129b-4c53-9859-56304676bca7
java.lang.IllegalArgumentException: Multiple entries with same key:
SubnetToDpnKey{_dpnId=105707792905079}=SubnetToDpn{_dpnId=105707792905079,
_vpnInterfaces={VpnInterfacesKey{_interfaceName=d92aa7f0-2b83-4bd0-860c-026e672a955c}
=VpnInterfaces{_interfaceName=d92aa7f0-2b83-4bd0-860c-026e672a955c,
augmentation=[]}}, augmentation=[]} and
SubnetToDpnKey{_dpnId=105707792905079}=SubnetToDpn{getDpnId=105707792905079,
getVpnInterfaces={VpnInterfacesKey{_interfaceName=d92aa7f0-2b83-4bd0-860c-026e672a955c}
=VpnInterfaces{getInterfaceName=d92aa7f0-2b83-4bd0-860c-026e672a955c,
augmentation=[]}},
augmentation=[]}. To index multiple values under a key, use
Multimaps.index.at com.google.common.collect.Maps.uniqueIndex(Maps.java:1338) ~[bundleFile:?]
at com.google.common.collect.Maps.uniqueIndex(Maps.java:1293)~[bundleFile:?]
at org.opendaylight.yangtools.yang.binding.CodeHelpers.compatMap(CodeHelpers.java:296)
[bundleFile:?]at org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data
.SubnetOpDataEntryBuilder.setSubnetToDpn(SubnetOpDataEntryBuilder.java:356)
~[bundleFile:?]
at org.opendaylight.netvirt.vpnmanager.VpnSubnetRouteHandler .onInterfaceUp(VpnSubnetRouteHandler.java:625)
[bundleFile:?]

(2)
mainWorker=org.opendaylight.netvirt.vpnmanager.VpnInterfaceManager$$Lambda$2571/0x0000000101e1ec40@9e41c5d,
rollbackWorker=null, retryCount=3/3,
futures=[com.google.common.util.concurrent.ImmediateFuture$ImmediateFailedFuture@2c561c96[status=FAILURE,
cause=[java.lang.NullPointerException]],
com.google.common.util.concurrent.AbstractTransformFuture$TransformFuture@32bf6f0b[status=SUCCESS,
result=[null]],
com.google.common.util.concurrent.AbstractTransformFuture$TransformFuture@74a13a04[status=SUCCESS,
result=[null]]]}
java.lang.NullPointerException: null

Solution:
=========
(1)
Introduced new method to convert the List to Map before
building the subnetToDpn Map builder

(2) Changed proper adjacency check in vpninterfacemanager

Signed-off-by: Karthikeyan Krishnan <karthikeyangceb007@gmail.com>
Change-Id: Iec6ffb5e036c38cca83e1c78e85c21785e901730

vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInterfaceManager.java
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnSubnetRouteHandler.java

index 4212b5fd643632cce66d0cf24a664736ad9672fe..0cd01626f5ee6fde10804373a9ae7a6addfc7590 100755 (executable)
@@ -1405,7 +1405,7 @@ public class VpnInterfaceManager extends AbstractAsyncDataTreeChangeListener<Vpn
             }
             AdjacenciesOp adjacencies = vpnInterfaceOpDataEnteryOptional.get().augmentation(AdjacenciesOp.class);
 
-            if (adjacencies != null && !adjacencies.getAdjacency().isEmpty()) {
+            if (adjacencies != null && adjacencies.getAdjacency() != null) {
                 Map<AdjacencyKey, Adjacency> nextHopsMap = adjacencies.nonnullAdjacency();
                 LOG.info("removeAdjacenciesFromVpn: NextHops for interface {} on dpn {} for vpn {} are {}",
                         interfaceName, dpnId, vpnName, nextHopsMap);
index 6f7fe053eacf9e5ebc43f5a8406dee798d4cb0e2..4ce6f2243d79122407aff9eab5519c3377d09077 100644 (file)
@@ -16,7 +16,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.Set;
 import java.util.concurrent.ExecutionException;
+import java.util.stream.Collectors;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.eclipse.jdt.annotation.NonNull;
@@ -485,8 +487,9 @@ public class VpnSubnetRouteHandler {
             }
             SubnetOpDataEntry subnetOpDataEntry = optionalSubs.get();
             SubnetOpDataEntryBuilder subOpBuilder = new SubnetOpDataEntryBuilder(subnetOpDataEntry);
-            subOpBuilder.setSubnetToDpn(concat(new ArrayList<SubnetToDpn>(subnetOpDataEntry
-                            .nonnullSubnetToDpn().values()), subDpn));
+            List<SubnetToDpn> subnetToDpnList = concat(new ArrayList<SubnetToDpn>(subnetOpDataEntry
+                    .nonnullSubnetToDpn().values()), subDpn);
+            subOpBuilder.setSubnetToDpn(getSubnetToDpnMap(subnetToDpnList));
             if (subOpBuilder.getRouteAdvState() != TaskState.Advertised) {
                 if (subOpBuilder.getNhDpnId() == null) {
                     // No nexthop selected yet, elect one now
@@ -622,8 +625,9 @@ public class VpnSubnetRouteHandler {
                     subOpBuilder.getRouteAdvState(), subOpBuilder.getLastAdvState());
             boolean isExternalSubnetVpn = VpnUtil.isExternalSubnetVpn(subnetOpDataEntry.getVpnName(),
                     subnetId.getValue());
-            subOpBuilder.setSubnetToDpn(concat(new ArrayList<SubnetToDpn>(subnetOpDataEntry
-                            .nonnullSubnetToDpn().values()), subDpn));
+            List<SubnetToDpn> subnetToDpnList = concat(new ArrayList<SubnetToDpn>(subnetOpDataEntry
+                    .nonnullSubnetToDpn().values()), subDpn);
+            subOpBuilder.setSubnetToDpn(getSubnetToDpnMap(subnetToDpnList));
             if (subOpBuilder.getRouteAdvState() != TaskState.Advertised) {
                 if (subOpBuilder.getNhDpnId() == null) {
                     // No nexthop selected yet, elect one now
@@ -655,6 +659,16 @@ public class VpnSubnetRouteHandler {
         }
     }
 
+    private Map<SubnetToDpnKey, SubnetToDpn> getSubnetToDpnMap(List<SubnetToDpn> subnetToDpnList) {
+        //convert to set to remove duplicates.
+        Set<SubnetToDpn> subnetToDpnSet = subnetToDpnList.stream().collect(Collectors.toSet());
+        Map<SubnetToDpnKey, SubnetToDpn> subnetToDpnMap = new HashMap<>();
+        for (SubnetToDpn subnetToDpn : subnetToDpnSet) {
+            subnetToDpnMap.put(new SubnetToDpnKey(subnetToDpn.key()), subnetToDpn);
+        }
+        return subnetToDpnMap;
+    }
+
     // TODO Clean up the exception handling
     @SuppressWarnings("checkstyle:IllegalCatch")
     public void onInterfaceDown(final Uint64 dpnId, final String interfaceName, Uuid subnetId) {