Switch to JDT annotations for Nullable and NonNull
[netvirt.git] / dhcpservice / impl / src / main / java / org / opendaylight / netvirt / dhcpservice / DhcpServiceUtils.java
index 0dd255d95309b0324f3ff641e1b9b05cd27ebdac..9d52d641bc603c42c2b8ef32931a348c7efa9386 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.netvirt.dhcpservice;
 
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
+
 import com.google.common.base.Optional;
 import java.math.BigInteger;
 import java.net.InetAddress;
@@ -18,20 +20,22 @@ import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Objects;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.ExecutionException;
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
-import java.util.stream.IntStream;
 import java.util.stream.LongStream;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-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.SingleTransactionDataBroker;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.Datastore.Operational;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.mdsalutil.ActionInfo;
@@ -58,6 +62,7 @@ import org.opendaylight.netvirt.dhcpservice.api.DhcpMConstants;
 import org.opendaylight.netvirt.elanmanager.api.ElanHelper;
 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
 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.inet.types.rev130715.IpAddressBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
@@ -89,7 +94,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.NetworkKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
@@ -110,13 +114,15 @@ import org.slf4j.LoggerFactory;
 public final class DhcpServiceUtils {
 
     private static final Logger LOG = LoggerFactory.getLogger(DhcpServiceUtils.class);
+    private static List<BigInteger> connectedDpnIds = new CopyOnWriteArrayList<>();
 
     private DhcpServiceUtils() { }
 
     public static void setupDhcpFlowEntry(@Nullable BigInteger dpId, short tableId, @Nullable String vmMacAddress,
                                           int addOrRemove,
                                           IMdsalApiManager mdsalUtil, DhcpServiceCounters dhcpServiceCounters,
-                                          WriteTransaction tx) {
+                                          TypedReadWriteTransaction<Configuration> tx)
+            throws ExecutionException, InterruptedException {
         if (dpId == null || dpId.equals(DhcpMConstants.INVALID_DPID) || vmMacAddress == null) {
             return;
         }
@@ -128,20 +134,16 @@ public final class DhcpServiceUtils {
         actionsInfos.add(new ActionPuntToController());
         instructions.add(new InstructionApplyActions(actionsInfos));
         if (addOrRemove == NwConstants.DEL_FLOW) {
-            FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,
-                    getDhcpFlowRef(dpId, tableId, vmMacAddress),
-                    DhcpMConstants.DEFAULT_DHCP_FLOW_PRIORITY, "DHCP", 0, 0,
-                    DhcpMConstants.COOKIE_DHCP_BASE, matches, null);
             LOG.trace("Removing DHCP Flow DpId {}, vmMacAddress {}", dpId, vmMacAddress);
             dhcpServiceCounters.removeDhcpFlow();
-            mdsalUtil.removeFlowToTx(flowEntity, tx);
+            mdsalUtil.removeFlow(tx, dpId, getDhcpFlowRef(dpId, tableId, vmMacAddress), tableId);
         } else {
             FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,
                     getDhcpFlowRef(dpId, tableId, vmMacAddress), DhcpMConstants.DEFAULT_DHCP_FLOW_PRIORITY,
                     "DHCP", 0, 0, DhcpMConstants.COOKIE_DHCP_BASE, matches, instructions);
             LOG.trace("Installing DHCP Flow DpId {}, vmMacAddress {}", dpId, vmMacAddress);
             dhcpServiceCounters.installDhcpFlow();
-            mdsalUtil.addFlowToTx(flowEntity, tx);
+            mdsalUtil.addFlow(tx, flowEntity);
         }
     }
 
@@ -162,7 +164,8 @@ public final class DhcpServiceUtils {
 
     public static void setupDhcpDropAction(BigInteger dpId, short tableId, String vmMacAddress, int addOrRemove,
                                            IMdsalApiManager mdsalUtil, DhcpServiceCounters dhcpServiceCounters,
-                                           WriteTransaction tx) {
+                                           TypedReadWriteTransaction<Configuration> tx)
+            throws ExecutionException, InterruptedException {
         if (dpId == null || dpId.equals(DhcpMConstants.INVALID_DPID) || vmMacAddress == null) {
             return;
         }
@@ -174,40 +177,37 @@ public final class DhcpServiceUtils {
         // Drop Action
         actionsInfos.add(new ActionDrop());
         if (addOrRemove == NwConstants.DEL_FLOW) {
-            FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,
-                    getDhcpFlowRef(dpId, tableId, vmMacAddress),
-                    DhcpMConstants.DEFAULT_DHCP_FLOW_PRIORITY, "DHCP", 0, 0,
-                    DhcpMConstants.COOKIE_DHCP_BASE, matches, null);
             LOG.trace("Removing DHCP Drop Flow DpId {}, vmMacAddress {}", dpId, vmMacAddress);
             dhcpServiceCounters.removeDhcpDropFlow();
-            mdsalUtil.removeFlowToTx(flowEntity, tx);
+            mdsalUtil.removeFlow(tx, dpId, getDhcpFlowRef(dpId, tableId, vmMacAddress), tableId);
         } else {
             FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,
                     getDhcpFlowRef(dpId, tableId, vmMacAddress), DhcpMConstants.DEFAULT_DHCP_FLOW_PRIORITY,
                     "DHCP", 0, 0, DhcpMConstants.COOKIE_DHCP_BASE, matches, instructions);
             LOG.trace("Installing DHCP Drop Flow DpId {}, vmMacAddress {}", dpId, vmMacAddress);
             dhcpServiceCounters.installDhcpDropFlow();
-            mdsalUtil.addFlowToTx(flowEntity, tx);
+            mdsalUtil.addFlow(tx, flowEntity);
         }
     }
 
-    @SuppressWarnings("checkstyle:IllegalCatch")
     public static void setupDhcpArpRequest(BigInteger dpId, short tableId, BigInteger vni, String dhcpIpAddress,
-                                           int lportTag, Long elanTag, boolean add, IMdsalApiManager mdsalUtil) {
+                                           int lportTag, @Nullable Long elanTag, boolean add,
+                                           IMdsalApiManager mdsalUtil, TypedReadWriteTransaction<Configuration> tx)
+            throws ExecutionException, InterruptedException {
         List<MatchInfo> matches = getDhcpArpMatch(vni, dhcpIpAddress);
         if (add) {
             Flow flow = MDSALUtil.buildFlowNew(tableId, getDhcpArpFlowRef(dpId, tableId, lportTag, dhcpIpAddress),
                     DhcpMConstants.DEFAULT_DHCP_ARP_FLOW_PRIORITY, "DHCPArp", 0, 0,
                     generateDhcpArpCookie(lportTag, dhcpIpAddress), matches, null);
             LOG.trace("Removing DHCP ARP Flow DpId {}, DHCP Port IpAddress {}", dpId, dhcpIpAddress);
-            mdsalUtil.removeFlow(dpId, flow);
+            mdsalUtil.removeFlow(tx, dpId, flow);
         } else {
             Flow flow = MDSALUtil.buildFlowNew(tableId, getDhcpArpFlowRef(dpId, tableId, lportTag, dhcpIpAddress),
                     DhcpMConstants.DEFAULT_DHCP_ARP_FLOW_PRIORITY, "DHCPArp", 0, 0,
                     generateDhcpArpCookie(lportTag, dhcpIpAddress), matches,
                     getDhcpArpInstructions(elanTag, lportTag));
             LOG.trace("Adding DHCP ARP Flow DpId {}, DHCPPort IpAddress {}", dpId, dhcpIpAddress);
-            mdsalUtil.installFlow(dpId, flow);
+            mdsalUtil.addFlow(tx, dpId, flow);
         }
     }
 
@@ -253,25 +253,22 @@ public final class DhcpServiceUtils {
     }
 
     public static List<BigInteger> getListOfDpns(DataBroker broker) {
+        if (!connectedDpnIds.isEmpty()) {
+            return connectedDpnIds;
+        }
         return extractDpnsFromNodes(MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
                 InstanceIdentifier.builder(Nodes.class).build()));
     }
 
-    @Nonnull
-    public static List<BigInteger> getListOfDpns(ReadTransaction tx) throws ReadFailedException {
-        return extractDpnsFromNodes(tx.read(LogicalDatastoreType.OPERATIONAL,
-                InstanceIdentifier.builder(Nodes.class).build()).checkedGet());
-    }
-
-    @Nonnull
+    @NonNull
     private static List<BigInteger> extractDpnsFromNodes(Optional<Nodes> optionalNodes) {
         return optionalNodes.toJavaUtil().map(
-            nodes -> nodes.getNode().stream().map(Node::getId).filter(Objects::nonNull).map(
+            nodes -> nodes.nonnullNode().stream().map(Node::getId).filter(Objects::nonNull).map(
                     MDSALUtil::getDpnIdFromNodeName).collect(
                     Collectors.toList())).orElse(Collections.emptyList());
     }
 
-    @Nonnull
+    @NonNull
     public static List<BigInteger> getDpnsForElan(String elanInstanceName, DataBroker broker) {
         List<BigInteger> elanDpns = new LinkedList<>();
         InstanceIdentifier<ElanDpnInterfacesList> elanDpnInstanceIdentifier =
@@ -280,7 +277,7 @@ public final class DhcpServiceUtils {
         Optional<ElanDpnInterfacesList> elanDpnOptional =
                 MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL, elanDpnInstanceIdentifier);
         if (elanDpnOptional.isPresent()) {
-            List<DpnInterfaces> dpns = elanDpnOptional.get().getDpnInterfaces();
+            List<DpnInterfaces> dpns = elanDpnOptional.get().nonnullDpnInterfaces();
             for (DpnInterfaces dpnInterfaces : dpns) {
                 elanDpns.add(dpnInterfaces.getDpId());
             }
@@ -288,8 +285,8 @@ public final class DhcpServiceUtils {
         return elanDpns;
     }
 
-    public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
-            .state.Interface getInterfaceFromOperationalDS(String interfaceName, DataBroker dataBroker) {
+    public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state
+            .@Nullable Interface getInterfaceFromOperationalDS(String interfaceName, DataBroker dataBroker) {
         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
                 .state.InterfaceKey interfaceKey =
                 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
@@ -302,6 +299,7 @@ public final class DhcpServiceUtils {
     }
 
 
+    @Nullable
     public static String getSegmentationId(Uuid networkId, DataBroker broker) {
         InstanceIdentifier<Network> inst = InstanceIdentifier.create(Neutron.class)
                 .child(Networks.class).child(Network.class, new NetworkKey(networkId));
@@ -314,27 +312,11 @@ public final class DhcpServiceUtils {
         return segmentationId;
     }
 
-    public static String getNodeIdFromDpnId(BigInteger dpnId) {
-        return MDSALUtil.NODE_PREFIX + MDSALUtil.SEPARATOR + dpnId.toString();
-    }
-
-    public static String getTrunkPortMacAddress(String parentRefName,
-            DataBroker broker) {
-        InstanceIdentifier<Port> portInstanceIdentifier =
-                InstanceIdentifier.create(Neutron.class).child(Ports.class).child(Port.class);
-        Optional<Port> trunkPort = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, portInstanceIdentifier);
-        if (!trunkPort.isPresent()) {
-            LOG.warn("Trunk port {} not available for sub-port", parentRefName);
-            return null;
-        }
-        return trunkPort.get().getMacAddress().getValue();
-    }
-
     public static String getJobKey(String interfaceName) {
         return new StringBuilder().append(DhcpMConstants.DHCP_JOB_KEY_PREFIX).append(interfaceName).toString();
     }
 
-    public static void bindDhcpService(String interfaceName, short tableId, WriteTransaction tx) {
+    public static void bindDhcpService(String interfaceName, short tableId, TypedWriteTransaction<Configuration> tx) {
         int instructionKey = 0;
         List<Instruction> instructions = new ArrayList<>();
         instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(tableId, ++instructionKey));
@@ -344,14 +326,12 @@ public final class DhcpServiceUtils {
                 getBoundServices(String.format("%s.%s", "dhcp", interfaceName),
                         serviceIndex, DhcpMConstants.DEFAULT_FLOW_PRIORITY,
                         DhcpMConstants.COOKIE_VM_INGRESS_TABLE, instructions);
-        tx.put(LogicalDatastoreType.CONFIGURATION,
-                buildServiceId(interfaceName, serviceIndex), serviceInfo, WriteTransaction.CREATE_MISSING_PARENTS);
+        tx.put(buildServiceId(interfaceName, serviceIndex), serviceInfo, CREATE_MISSING_PARENTS);
     }
 
-    public static void unbindDhcpService(String interfaceName, WriteTransaction tx) {
+    public static void unbindDhcpService(String interfaceName, TypedWriteTransaction<Configuration> tx) {
         short serviceIndex = ServiceIndex.getIndex(NwConstants.DHCP_SERVICE_NAME, NwConstants.DHCP_SERVICE_INDEX);
-        tx.delete(LogicalDatastoreType.CONFIGURATION,
-                buildServiceId(interfaceName, serviceIndex));
+        tx.delete(buildServiceId(interfaceName, serviceIndex));
     }
 
     private static InstanceIdentifier<BoundServices> buildServiceId(String interfaceName,
@@ -421,24 +401,16 @@ public final class DhcpServiceUtils {
         return java.util.Optional.empty();
     }
 
-    static IpAddress convertIntToIp(int ipn) {
-        String[] array = IntStream.of(24, 16, 8, 0) //
-                .map(x -> ipn >> x & 0xFF).boxed() //
-                .map(String::valueOf) //
-                .toArray(String[]::new);
-        return new IpAddress(String.join(".", array).toCharArray());
-    }
-
     static IpAddress convertLongToIp(long ip) {
         String[] array = LongStream.of(24, 16, 8, 0) //
                 .map(x -> ip >> x & 0xFF).boxed() //
                 .map(String::valueOf) //
                 .toArray(String[]::new);
-        return new IpAddress(String.join(".", array).toCharArray());
+        return IpAddressBuilder.getDefaultInstance(String.join(".", array));
     }
 
     static long convertIpToLong(IpAddress ipa) {
-        String[] splitIp = String.valueOf(ipa.getValue()).split("\\.");
+        String[] splitIp = ipa.stringValue().split("\\.");
         long result = 0;
         for (String part : splitIp) {
             result <<= 8;
@@ -459,10 +431,6 @@ public final class DhcpServiceUtils {
         return interfaceManager.getInterfaceInfoFromOperationalDataStore(interfaceName);
     }
 
-    static BigInteger getDpIdFromInterface(IInterfaceManager interfaceManager, String interfaceName) {
-        return interfaceManager.getDpnForInterface(interfaceName);
-    }
-
     public static java.util.Optional<String> getIpV4Address(Port port) {
         if (port.getFixedIps() == null) {
             return java.util.Optional.empty();
@@ -484,13 +452,12 @@ public final class DhcpServiceUtils {
     }
 
     @Nullable
-    public static String getAndUpdateVmMacAddress(ReadWriteTransaction tx, String interfaceName,
-            DhcpManager dhcpManager) throws ReadFailedException {
+    public static String getAndUpdateVmMacAddress(TypedReadWriteTransaction<Operational> tx, String interfaceName,
+            DhcpManager dhcpManager) throws ExecutionException, InterruptedException {
         InstanceIdentifier<InterfaceNameMacAddress> instanceIdentifier =
                 InstanceIdentifier.builder(InterfaceNameMacAddresses.class)
                         .child(InterfaceNameMacAddress.class, new InterfaceNameMacAddressKey(interfaceName)).build();
-        Optional<InterfaceNameMacAddress> existingEntry =
-                tx.read(LogicalDatastoreType.OPERATIONAL, instanceIdentifier).checkedGet();
+        Optional<InterfaceNameMacAddress> existingEntry = tx.read(instanceIdentifier).get();
         if (!existingEntry.isPresent()) {
             LOG.trace("Entry for interface {} missing in InterfaceNameVmMacAddress map", interfaceName);
             String vmMacAddress = getNeutronMacAddress(interfaceName, dhcpManager);
@@ -502,13 +469,13 @@ public final class DhcpServiceUtils {
                     new InterfaceNameMacAddressBuilder()
                             .withKey(new InterfaceNameMacAddressKey(interfaceName))
                             .setInterfaceName(interfaceName).setMacAddress(vmMacAddress).build();
-            tx.merge(LogicalDatastoreType.OPERATIONAL, instanceIdentifier, interfaceNameMacAddress,
-                    WriteTransaction.CREATE_MISSING_PARENTS);
+            tx.merge(instanceIdentifier, interfaceNameMacAddress, CREATE_MISSING_PARENTS);
             return vmMacAddress;
         }
         return existingEntry.get().getMacAddress();
     }
 
+    @Nullable
     private static String getNeutronMacAddress(String interfaceName, DhcpManager dhcpManager) {
         Port port = dhcpManager.getNeutronPort(interfaceName);
         if (port != null) {
@@ -518,19 +485,22 @@ public final class DhcpServiceUtils {
         return null;
     }
 
+    @NonNull
     public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
         InstanceIdentifier id = buildNetworkMapIdentifier(networkId);
         Optional<NetworkMap> optionalNetworkMap = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
         if (optionalNetworkMap.isPresent()) {
-            return optionalNetworkMap.get().getSubnetIdList();
+            @Nullable List<Uuid> subnetIdList = optionalNetworkMap.get().getSubnetIdList();
+            if (subnetIdList != null) {
+                return subnetIdList;
+            }
         }
-        return null;
+        return Collections.emptyList();
     }
 
     static InstanceIdentifier<NetworkMap> buildNetworkMapIdentifier(Uuid networkId) {
-        InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class).child(NetworkMap.class, new
-                NetworkMapKey(networkId)).build();
-        return id;
+        return InstanceIdentifier.builder(NetworkMaps.class).child(NetworkMap.class,
+            new NetworkMapKey(networkId)).build();
     }
 
     public static boolean isIpv4Subnet(DataBroker broker, Uuid subnetUuid) {
@@ -540,12 +510,20 @@ public final class DhcpServiceUtils {
         final Optional<Subnet> subnet = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, subnetidentifier);
         if (subnet.isPresent()) {
             Class<? extends IpVersionBase> ipVersionBase = subnet.get().getIpVersion();
-            if (ipVersionBase.equals(IpVersionV4.class)) {
-                return true;
-            }
+            return IpVersionV4.class.equals(ipVersionBase);
         }
         return false;
     }
 
+    public static void addToDpnIdCache(BigInteger dpnId) {
+        if (!connectedDpnIds.contains(dpnId)) {
+            connectedDpnIds.add(dpnId);
+        }
+    }
+
+    public static void removeFromDpnIdCache(BigInteger dpnId) {
+        connectedDpnIds.remove(dpnId);
+    }
+
 }