Convert to JobCoordinator in policyservice-impl
[netvirt.git] / vpnservice / policyservice / impl / src / main / java / org / opendaylight / netvirt / policyservice / util / PolicyServiceUtil.java
index c8177d7745eaec773808da1e167a6f4d39c83f27..5554bfc0f4f526cec02161ddb853184491fcb03f 100644 (file)
@@ -9,26 +9,26 @@
 package org.opendaylight.netvirt.policyservice.util;
 
 import com.google.common.base.Optional;
-
 import java.math.BigInteger;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.stream.Collectors;
-
+import javax.annotation.Nonnull;
 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.DataStoreJobCoordinator;
 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
+import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
 import org.opendaylight.netvirt.elanmanager.api.IElanBridgeManager;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.AccessLists;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.AclBase;
@@ -39,10 +39,14 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.cont
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.AceKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.Actions;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan.L2vlanMode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeLogicalGroup;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionBase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionEgress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.PolicyAcl;
@@ -61,6 +65,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.po
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.UnderlayNetwork;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.UnderlayNetworkKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.DpnToInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.DpnToInterfaceBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.DpnToInterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.PolicyProfileBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.dpn.to._interface.TunnelInterface;
@@ -73,26 +78,28 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+@SuppressWarnings("deprecation")
 @Singleton
 public class PolicyServiceUtil {
     private static final Logger LOG = LoggerFactory.getLogger(PolicyServiceUtil.class);
 
-    private static final String LOCAL_IPS = "local_ips";
+    public static final String LOCAL_IPS = "local_ips";
 
     private final DataBroker dataBroker;
     private final IElanBridgeManager bridgeManager;
     private final ItmRpcService itmRpcService;
     private final IInterfaceManager interfaceManager;
-    private final DataStoreJobCoordinator coordinator;
+    private final JobCoordinator coordinator;
 
     @Inject
     public PolicyServiceUtil(final DataBroker dataBroker, final IElanBridgeManager bridgeManager,
-            final ItmRpcService itmRpcService, final IInterfaceManager interfaceManager) {
+            final ItmRpcService itmRpcService, final IInterfaceManager interfaceManager,
+            final JobCoordinator coordinator) {
         this.dataBroker = dataBroker;
         this.bridgeManager = bridgeManager;
         this.itmRpcService = itmRpcService;
         this.interfaceManager = interfaceManager;
-        this.coordinator = DataStoreJobCoordinator.getInstance();
+        this.coordinator = coordinator;
     }
 
     public Optional<String> getAcePolicyClassifier(Ace ace) {
@@ -108,7 +115,7 @@ public class PolicyServiceUtil {
             direction = setPolicyClassifier.getDirection();
         } catch (IllegalArgumentException e) {
             LOG.warn("Failed to parse policy classifier direction");
-            return null;
+            return Optional.absent();
         }
 
         if (direction == null || !direction.isAssignableFrom(DirectionEgress.class)) {
@@ -157,7 +164,7 @@ public class PolicyServiceUtil {
 
     public List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay
         .network.PolicyProfile> getUnderlayNetworkPolicyProfiles(String underlayNetwork) {
-        InstanceIdentifier<UnderlayNetwork> identifier = getUnderlyNetworkIdentifier(underlayNetwork);
+        InstanceIdentifier<UnderlayNetwork> identifier = getUnderlayNetworkIdentifier(underlayNetwork);
         try {
             Optional<UnderlayNetwork> optUnderlayNet = SingleTransactionDataBroker.syncReadOptional(dataBroker,
                     LogicalDatastoreType.OPERATIONAL, identifier);
@@ -184,8 +191,8 @@ public class PolicyServiceUtil {
     public void updateTunnelInterfaceForUnderlayNetwork(String underlayNetwork, BigInteger srcDpId, BigInteger dstDpId,
             String tunnelInterfaceName, boolean isAdded) {
         coordinator.enqueueJob(underlayNetwork, () -> {
-            InstanceIdentifier<TunnelInterface> identifier = getUnderlyNetworkTunnelIdentifier(underlayNetwork, srcDpId,
-                    tunnelInterfaceName);
+            InstanceIdentifier<TunnelInterface> identifier = getUnderlayNetworkTunnelIdentifier(underlayNetwork,
+                    srcDpId, tunnelInterfaceName);
             WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
             if (isAdded) {
                 TunnelInterface tunnelInterface = new TunnelInterfaceBuilder().setInterfaceName(tunnelInterfaceName)
@@ -202,31 +209,49 @@ public class PolicyServiceUtil {
         });
     }
 
+    public void updateTunnelInterfacesForUnderlayNetwork(String underlayNetwork, BigInteger srcDpId,
+            List<TunnelInterface> tunnelInterfaces, boolean isAdded) {
+        coordinator.enqueueJob(underlayNetwork, () -> {
+            InstanceIdentifier<DpnToInterface> identifier = getUnderlayNetworkDpnIdentifier(underlayNetwork, srcDpId);
+            WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
+            if (isAdded) {
+                DpnToInterface dpnToInterface = new DpnToInterfaceBuilder().setDpId(srcDpId)
+                        .setTunnelInterface(tunnelInterfaces).build();
+                tx.merge(LogicalDatastoreType.OPERATIONAL, identifier, dpnToInterface, true);
+                LOG.info("Add tunnel interfaces {} on DPN {} to underlay network {}", tunnelInterfaces, srcDpId,
+                        underlayNetwork);
+            } else {
+                tx.delete(LogicalDatastoreType.OPERATIONAL, identifier);
+                LOG.info("Remove tunnel interfaces {} from DPN {} on underlay network {}", tunnelInterfaces, srcDpId,
+                        underlayNetwork);
+            }
+            return Collections.singletonList(tx.submit());
+        });
+    }
+
     public void updatePolicyClassifierForUnderlayNetworks(List<String> underlayNetworks, String policyClassifier,
             boolean isAdded) {
         if (underlayNetworks == null || underlayNetworks.isEmpty()) {
             LOG.debug("No underlay networks found for policy classifier {}", policyClassifier);
         }
 
-        underlayNetworks.forEach(underlayNetwork -> {
-            coordinator.enqueueJob(underlayNetwork, () -> {
-                WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
-                InstanceIdentifier<
-                        org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks
-                        .underlay.network.PolicyProfile> identifier = getUnderlayNetworkPolicyClassifierIdentifier(
-                                policyClassifier, underlayNetwork);
-
-                if (isAdded) {
-                    tx.merge(LogicalDatastoreType.OPERATIONAL, identifier,
-                            new PolicyProfileBuilder().setPolicyClassifier(policyClassifier).build(), true);
-                    LOG.info("Add policy classifier {} to underlay network {}", policyClassifier, underlayNetwork);
-                } else {
-                    tx.delete(LogicalDatastoreType.OPERATIONAL, identifier);
-                    LOG.info("Remove policy classifier {} from underlay network {}", policyClassifier, underlayNetwork);
-                }
-                return Collections.singletonList(tx.submit());
-            });
-        });
+        underlayNetworks.forEach(underlayNetwork -> coordinator.enqueueJob(underlayNetwork, () -> {
+            WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
+            InstanceIdentifier<
+                    org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks
+                    .underlay.network.PolicyProfile> identifier = getUnderlayNetworkPolicyClassifierIdentifier(
+                            policyClassifier, underlayNetwork);
+
+            if (isAdded) {
+                tx.merge(LogicalDatastoreType.OPERATIONAL, identifier,
+                        new PolicyProfileBuilder().setPolicyClassifier(policyClassifier).build(), true);
+                LOG.info("Add policy classifier {} to underlay network {}", policyClassifier, underlayNetwork);
+            } else {
+                tx.delete(LogicalDatastoreType.OPERATIONAL, identifier);
+                LOG.info("Remove policy classifier {} from underlay network {}", policyClassifier, underlayNetwork);
+            }
+            return Collections.singletonList(tx.submit());
+        }));
     }
 
     public void updateAclRuleForPolicyClassifier(String policyClassifier, String aclName, String ruleName,
@@ -261,7 +286,7 @@ public class PolicyServiceUtil {
             return Collections.emptyList();
         }
 
-        return underlayNetworks.stream().map(t -> getUnderlayNetworkRemoteDpns(t)).flatMap(t -> t.stream()).distinct()
+        return underlayNetworks.stream().map(this::getUnderlayNetworkRemoteDpns).flatMap(Collection::stream).distinct()
                 .collect(Collectors.toList());
     }
 
@@ -274,31 +299,19 @@ public class PolicyServiceUtil {
     }
 
     public static boolean dpnToInterfacesContainsDpn(List<DpnToInterface> dpnToInterfaces, BigInteger dpId) {
-        if (dpnToInterfaces == null) {
-            return false;
-        }
-
-        return dpnToInterfaces.stream().filter(dpnToInterface -> dpnToInterface.getDpId().equals(dpId)).findFirst()
-                .isPresent();
+        return dpnToInterfaces != null && dpnToInterfaces.stream().anyMatch(
+            dpnToInterface -> dpnToInterface.getDpId().equals(dpId));
     }
 
     public static boolean dpnToInterfacesContainsRemoteDpn(List<DpnToInterface> dpnToInterfaces, BigInteger dpId) {
-        if (dpnToInterfaces == null) {
-            return false;
-        }
-
-        return dpnToInterfaces.stream().filter(dpnToInterface -> dpnToInterfaceContainsRemoteDpn(dpnToInterface, dpId))
-                .findFirst().isPresent();
+        return dpnToInterfaces != null && dpnToInterfaces.stream().anyMatch(
+            dpnToInterface -> dpnToInterfaceContainsRemoteDpn(dpnToInterface, dpId));
     }
 
     public static boolean dpnToInterfaceContainsRemoteDpn(DpnToInterface dpnToInterface, BigInteger dpId) {
         List<TunnelInterface> tunnelInterfaces = dpnToInterface.getTunnelInterface();
-        if (tunnelInterfaces == null) {
-            return false;
-        }
-
-        return tunnelInterfaces.stream().filter(tunnelInterface -> tunnelInterface.getRemoteDpId().equals(dpId))
-                .findFirst().isPresent();
+        return tunnelInterfaces != null && tunnelInterfaces.stream().anyMatch(
+            tunnelInterface -> tunnelInterface.getRemoteDpId().equals(dpId));
     }
 
     public String getTunnelUnderlayNetwork(BigInteger dpId, IpAddress tunnelIp) {
@@ -317,7 +330,7 @@ public class PolicyServiceUtil {
             return Collections.emptyList();
         }
 
-        return dpnToInterfaces.stream().map(t -> t.getDpId()).collect(Collectors.toList());
+        return dpnToInterfaces.stream().map(DpnToInterface::getDpId).collect(Collectors.toList());
     }
 
     public static List<BigInteger> getRemoteDpnsFromDpnToInterfaces(List<DpnToInterface> dpnToInterfaces) {
@@ -325,8 +338,8 @@ public class PolicyServiceUtil {
             return Collections.emptyList();
         }
 
-        return dpnToInterfaces.stream().map(dpnToInterface -> getRemoteDpnsFromDpnToInterface(dpnToInterface))
-                .flatMap(t -> t.stream()).distinct().collect(Collectors.toList());
+        return dpnToInterfaces.stream().map(PolicyServiceUtil::getRemoteDpnsFromDpnToInterface)
+                .flatMap(Collection::stream).distinct().collect(Collectors.toList());
     }
 
     public static List<BigInteger> getRemoteDpnsFromDpnToInterface(DpnToInterface dpnToInterface) {
@@ -335,7 +348,7 @@ public class PolicyServiceUtil {
             return Collections.emptyList();
         }
 
-        return tunnelInterfaces.stream().map(tunnelInterface -> tunnelInterface.getRemoteDpId())
+        return tunnelInterfaces.stream().map(TunnelInterface::getRemoteDpId)
                 .collect(Collectors.toList());
     }
 
@@ -344,7 +357,7 @@ public class PolicyServiceUtil {
             return Collections.emptyList();
         }
 
-        return policyRoutes.stream().map(policyRoute -> policyRoute.getRoute())
+        return policyRoutes.stream().map(PolicyRoute::getRoute)
                 .filter(route -> route instanceof BasicRoute).map(route -> ((BasicRoute) route).getNetworkName())
                 .collect(Collectors.toList());
     }
@@ -353,26 +366,46 @@ public class PolicyServiceUtil {
         return aclType != null && aclType.isAssignableFrom(PolicyAcl.class);
     }
 
+    @Nonnull
     public List<DpnToInterface> getUnderlayNetworkDpnToInterfaces(String underlayNetwork) {
         InstanceIdentifier<UnderlayNetwork> identifier = InstanceIdentifier.create(UnderlayNetworks.class)
                 .child(UnderlayNetwork.class, new UnderlayNetworkKey(underlayNetwork));
         try {
-            Optional<UnderlayNetwork> optUnderlayNetwork = SingleTransactionDataBroker.syncReadOptional(dataBroker,
-                    LogicalDatastoreType.OPERATIONAL, identifier);
-            return optUnderlayNetwork.isPresent() ? optUnderlayNetwork.get().getDpnToInterface()
-                    : Collections.emptyList();
+            return SingleTransactionDataBroker
+                    .syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL, identifier)
+                    .toJavaUtil().map(UnderlayNetwork::getDpnToInterface)
+                    .orElse(Collections.emptyList());
         } catch (ReadFailedException e) {
             LOG.warn("Failed to get DPNs for underlay network {}", underlayNetwork);
             return Collections.emptyList();
         }
     }
 
-    private InstanceIdentifier<UnderlayNetwork> getUnderlyNetworkIdentifier(String underlayNetwork) {
+    public Optional<DpnToInterface> getUnderlayNetworkDpnToInterfaces(String underlayNetwork, BigInteger dpId) {
+        InstanceIdentifier<DpnToInterface> identifier = getUnderlayNetworkDpnIdentifier(underlayNetwork, dpId);
+        try {
+            Optional<DpnToInterface> dpnToInterfaceOpt = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+                    LogicalDatastoreType.OPERATIONAL, identifier);
+            return dpnToInterfaceOpt;
+        } catch (ReadFailedException e) {
+            LOG.warn("Failed to get DPN {} for underlay network {}", dpId, underlayNetwork);
+            return Optional.absent();
+        }
+    }
+
+    private InstanceIdentifier<UnderlayNetwork> getUnderlayNetworkIdentifier(String underlayNetwork) {
         return InstanceIdentifier.create(UnderlayNetworks.class).child(UnderlayNetwork.class,
                 new UnderlayNetworkKey(underlayNetwork));
     }
 
-    private InstanceIdentifier<TunnelInterface> getUnderlyNetworkTunnelIdentifier(String underlayNetwork,
+    private InstanceIdentifier<DpnToInterface> getUnderlayNetworkDpnIdentifier(String underlayNetwork,
+            BigInteger dpId) {
+        return InstanceIdentifier.create(UnderlayNetworks.class)
+                .child(UnderlayNetwork.class, new UnderlayNetworkKey(underlayNetwork))
+                .child(DpnToInterface.class, new DpnToInterfaceKey(dpId));
+    }
+
+    private InstanceIdentifier<TunnelInterface> getUnderlayNetworkTunnelIdentifier(String underlayNetwork,
             BigInteger dpId, String tunnelInterface) {
         return InstanceIdentifier.create(UnderlayNetworks.class)
                 .child(UnderlayNetwork.class, new UnderlayNetworkKey(underlayNetwork))
@@ -450,4 +483,30 @@ public class PolicyServiceUtil {
 
         return Optional.absent();
     }
+
+
+    public Optional<String> getVlanMemberInterface(String trunkInterface, VlanId vlanId) {
+        List<Interface> vlanMemberInterfaces = interfaceManager.getChildInterfaces(trunkInterface);
+        if (vlanMemberInterfaces == null || vlanMemberInterfaces.isEmpty()) {
+            LOG.debug("No child interfaces found for trunk {}", trunkInterface);
+            return Optional.absent();
+        }
+
+        return vlanMemberInterfaces.stream()
+                .filter(iface -> isVlanMemberInterface(iface, vlanId))
+                .findFirst()
+                .map(Interface::getName)
+                .map(Optional::of)
+                .orElseGet(Optional::absent);
+    }
+
+    private boolean isVlanMemberInterface(Interface iface, VlanId vlanId) {
+        IfL2vlan l2vlan = iface.getAugmentation(IfL2vlan.class);
+        if (l2vlan == null || !L2vlanMode.TrunkMember.equals(l2vlan.getL2vlanMode())) {
+            LOG.warn("Interface {} is not VLAN member", iface.getName());
+            return false;
+        }
+
+        return Objects.equals(vlanId, l2vlan.getVlanId());
+    }
 }