Changed ProxyArpManager to make use of EdgeManager.

Change-Id: I05193146490aba6736c1815bf0d9022df8628973
diff --git a/core/net/src/main/java/org/onosproject/net/proxyarp/impl/ProxyArpManager.java b/core/net/src/main/java/org/onosproject/net/proxyarp/impl/ProxyArpManager.java
index 6411a4d..ecfb71c 100644
--- a/core/net/src/main/java/org/onosproject/net/proxyarp/impl/ProxyArpManager.java
+++ b/core/net/src/main/java/org/onosproject/net/proxyarp/impl/ProxyArpManager.java
@@ -15,9 +15,6 @@
  */
 package org.onosproject.net.proxyarp.impl;
 
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Multimap;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -38,22 +35,15 @@
 import org.onlab.packet.ndp.NeighborSolicitation;
 import org.onosproject.core.Permission;
 import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.Device;
 import org.onosproject.net.Host;
 import org.onosproject.net.HostId;
-import org.onosproject.net.Link;
-import org.onosproject.net.Port;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.device.DeviceEvent;
-import org.onosproject.net.device.DeviceListener;
 import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.edge.EdgePortService;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.host.HostService;
 import org.onosproject.net.host.InterfaceIpAddress;
 import org.onosproject.net.host.PortAddresses;
-import org.onosproject.net.link.LinkEvent;
-import org.onosproject.net.link.LinkListener;
 import org.onosproject.net.link.LinkService;
 import org.onosproject.net.packet.DefaultOutboundPacket;
 import org.onosproject.net.packet.InboundPacket;
@@ -64,14 +54,13 @@
 
 import java.nio.ByteBuffer;
 import java.util.HashSet;
-import java.util.List;
-import java.util.Map.Entry;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
-import static org.slf4j.LoggerFactory.getLogger;
 import static org.onosproject.security.AppGuard.checkPermission;
+import static org.slf4j.LoggerFactory.getLogger;
 
 
 @Component(immediate = true)
@@ -87,6 +76,9 @@
     private static final String NOT_ARP_REPLY = "ARP is not a reply.";
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected EdgePortService edgeService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected HostService hostService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -98,29 +90,18 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected DeviceService deviceService;
 
-    private final Multimap<Device, PortNumber> internalPorts = HashMultimap.create();
-    private final Multimap<Device, PortNumber> externalPorts = HashMultimap.create();
-
-    private final DeviceListener deviceListener = new InternalDeviceListener();
-    private final InternalLinkListener linkListener = new InternalLinkListener();
-
     /**
      * Listens to both device service and link service to determine
      * whether a port is internal or external.
      */
     @Activate
     public void activate() {
-        deviceService.addListener(deviceListener);
-        linkService.addListener(linkListener);
-        determinePortLocations();
         log.info("Started");
     }
 
 
     @Deactivate
     public void deactivate() {
-        deviceService.removeListener(deviceListener);
-        linkService.removeListener(linkListener);
         log.info("Stopped");
     }
 
@@ -243,7 +224,7 @@
                 for (InterfaceIpAddress ia : addresses.ipAddresses()) {
                     if (ia.ipAddress().equals(targetAddress)) {
                         Ethernet ndpReply =
-                            buildNdpReply(targetAddress, addresses.mac(), eth);
+                                buildNdpReply(targetAddress, addresses.mac(), eth);
                         sendTo(ndpReply, inPort);
                     }
                 }
@@ -303,16 +284,16 @@
         Ethernet ndpReply = buildNdpReply(targetAddress, dst.mac(), eth);
         sendTo(ndpReply, inPort);
     }
+    //TODO checkpoint
 
     /**
      * Outputs the given packet out the given port.
      *
-     * @param packet the packet to send
+     * @param packet  the packet to send
      * @param outPort the port to send it out
      */
     private void sendTo(Ethernet packet, ConnectPoint outPort) {
-        if (internalPorts.containsEntry(
-                deviceService.getDevice(outPort.deviceId()), outPort.port())) {
+        if (!edgeService.isEdgePoint(outPort)) {
             // Sanity check to make sure we don't send the packet out an
             // internal port and create a loop (could happen due to
             // misconfiguration).
@@ -332,13 +313,10 @@
      * @return a set of PortAddresses describing ports in the subnet
      */
     private Set<PortAddresses> findPortsInSubnet(IpAddress target) {
-        Set<PortAddresses> result = new HashSet<PortAddresses>();
+        Set<PortAddresses> result = new HashSet<>();
         for (PortAddresses addresses : hostService.getAddressBindings()) {
-            for (InterfaceIpAddress ia : addresses.ipAddresses()) {
-                if (ia.subnetAddress().contains(target)) {
-                    result.add(addresses);
-                }
-            }
+            result.addAll(addresses.ipAddresses().stream().filter(ia -> ia.subnetAddress().contains(target)).
+                    map(ia -> addresses).collect(Collectors.toList()));
         }
         return result;
     }
@@ -432,71 +410,30 @@
      * Flood the arp request at all edges in the network.
      *
      * @param request the arp request
-     * @param inPort the connect point the arp request was received on
+     * @param inPort  the connect point the arp request was received on
      */
     private void flood(Ethernet request, ConnectPoint inPort) {
         TrafficTreatment.Builder builder = null;
         ByteBuffer buf = ByteBuffer.wrap(request.serialize());
 
-        synchronized (externalPorts) {
-            for (Entry<Device, PortNumber> entry : externalPorts.entries()) {
-                ConnectPoint cp = new ConnectPoint(entry.getKey().id(), entry.getValue());
-                if (isOutsidePort(cp) || cp.equals(inPort)) {
-                    continue;
-                }
+        for (ConnectPoint connectPoint : edgeService.getEdgePoints()) {
+            if (isOutsidePort(connectPoint) || connectPoint.equals(inPort)) {
+                continue;
+            }
 
-                builder = DefaultTrafficTreatment.builder();
-                builder.setOutput(entry.getValue());
-                packetService.emit(new DefaultOutboundPacket(entry.getKey().id(),
-                        builder.build(), buf));
-            }
-        }
-    }
-
-    /**
-     * Determines the location of all known ports in the system.
-     */
-    private void determinePortLocations() {
-        Iterable<Device> devices = deviceService.getDevices();
-        Iterable<Link> links = null;
-        List<PortNumber> ports = null;
-        for (Device d : devices) {
-            ports = buildPortNumberList(deviceService.getPorts(d.id()));
-            links = linkService.getLinks();
-            for (Link l : links) {
-                // for each link, mark the concerned ports as internal
-                // and the remaining ports are therefore external.
-                if (l.src().deviceId().equals(d.id())
-                        && ports.contains(l.src().port())) {
-                    ports.remove(l.src().port());
-                    internalPorts.put(d, l.src().port());
-                }
-                if (l.dst().deviceId().equals(d.id())
-                        && ports.contains(l.dst().port())) {
-                    ports.remove(l.dst().port());
-                    internalPorts.put(d, l.dst().port());
-                }
-            }
-            synchronized (externalPorts) {
-                externalPorts.putAll(d, ports);
-            }
+            builder = DefaultTrafficTreatment.builder();
+            builder.setOutput(connectPoint.port());
+            packetService.emit(new DefaultOutboundPacket(connectPoint.deviceId(),
+                    builder.build(), buf));
         }
 
     }
 
-    private List<PortNumber> buildPortNumberList(List<Port> ports) {
-        List<PortNumber> portNumbers = Lists.newLinkedList();
-        for (Port p : ports) {
-            portNumbers.add(p.number());
-        }
-        return portNumbers;
-    }
-
     /**
      * Builds an Neighbor Discovery reply based on a request.
      *
-     * @param srcIp the IP address to use as the reply source
-     * @param srcMac the MAC address to use as the reply source
+     * @param srcIp   the IP address to use as the reply source
+     * @param srcMac  the MAC address to use as the reply source
      * @param request the Neighbor Solicitation request we got
      * @return an Ethernet frame containing the Neighbor Advertisement reply
      */
@@ -524,91 +461,11 @@
         nadv.setSolicitedFlag((byte) 1);
         nadv.setOverrideFlag((byte) 1);
         nadv.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS,
-                       srcMac.toBytes());
+                srcMac.toBytes());
 
         icmp6.setPayload(nadv);
         ipv6.setPayload(icmp6);
         eth.setPayload(ipv6);
         return eth;
     }
-
-    public class InternalLinkListener implements LinkListener {
-
-        @Override
-        public void event(LinkEvent event) {
-            Link link = event.subject();
-            Device src = deviceService.getDevice(link.src().deviceId());
-            Device dst = deviceService.getDevice(link.dst().deviceId());
-            switch (event.type()) {
-                case LINK_ADDED:
-                    synchronized (externalPorts) {
-                        externalPorts.remove(src, link.src().port());
-                        externalPorts.remove(dst, link.dst().port());
-                        internalPorts.put(src, link.src().port());
-                        internalPorts.put(dst, link.dst().port());
-                    }
-
-                    break;
-                case LINK_REMOVED:
-                    synchronized (externalPorts) {
-                        externalPorts.put(src, link.src().port());
-                        externalPorts.put(dst, link.dst().port());
-                        internalPorts.remove(src, link.src().port());
-                        internalPorts.remove(dst, link.dst().port());
-                    }
-
-                    break;
-                case LINK_UPDATED:
-                    // don't care about links being updated.
-                    break;
-                default:
-                    break;
-            }
-
-        }
-
-    }
-
-    public class InternalDeviceListener implements DeviceListener {
-
-        @Override
-        public void event(DeviceEvent event) {
-            Device device = event.subject();
-            switch (event.type()) {
-                case DEVICE_ADDED:
-                case DEVICE_AVAILABILITY_CHANGED:
-                case DEVICE_SUSPENDED:
-                case DEVICE_UPDATED:
-                 // nothing to do in these cases; handled when links get reported
-                    break;
-                case DEVICE_REMOVED:
-                    synchronized (externalPorts) {
-                        externalPorts.removeAll(device);
-                        internalPorts.removeAll(device);
-                    }
-                    break;
-                case PORT_ADDED:
-                case PORT_UPDATED:
-                    synchronized (externalPorts) {
-                        if (event.port().isEnabled()) {
-                            externalPorts.put(device, event.port().number());
-                            internalPorts.remove(device, event.port().number());
-                        }
-                    }
-                    break;
-                case PORT_REMOVED:
-                    synchronized (externalPorts) {
-                        externalPorts.remove(device, event.port().number());
-                        internalPorts.remove(device, event.port().number());
-                    }
-                    break;
-                default:
-                    break;
-
-            }
-
-        }
-
-    }
-
 }