Remove dummy VLAN from double tagged pipeline

NOTE: This patch will break double tag termination support on OF-DPA.
      The pipelier needs to be re-implemented to understand the new objectives.

Before:
  NextObj: ETH_DST, ETH_SRC, OUTPUT, VLAN_ID (dummy)
  FwdObj.EGRESS: OUTPUT, VLAN_ID (c-tag), PUSH_VLAN, VLAN_ID (s-tag)

After:
  NextObj: ETH_DST, ETH_SRC, OUTPUT, VLAN_ID (c-tag), PUSH_VLAN, VLAN_ID (s-tag)
  No FwdObj.EGRESS

Also remove NextObj when the host is removed

Change-Id: I4ccdfa1d20701d9b2451ea0f3b4e761006746120
diff --git a/app/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java b/app/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
index f456e66..f18143f 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
@@ -39,7 +39,6 @@
 import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
 import org.onosproject.segmentrouting.config.DeviceConfiguration;
 import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
-import org.onosproject.segmentrouting.storekey.DummyVlanIdStoreKey;
 import org.onosproject.store.serializers.KryoNamespaces;
 import org.onosproject.store.service.Serializer;
 import org.slf4j.Logger;
@@ -1229,17 +1228,10 @@
     void populateDoubleTaggedRoute(DeviceId deviceId, IpPrefix prefix, MacAddress hostMac, VlanId innerVlan,
                                    VlanId outerVlan, EthType outerTpid, PortNumber outPort) {
         if (srManager.mastershipService.isLocalMaster(deviceId)) {
-            VlanId dummyVlan = srManager.allocateDummyVlanId(
-                    new ConnectPoint(deviceId, outPort), prefix.address());
-            if (!dummyVlan.equals(VlanId.NONE)) {
-                srManager.routingRulePopulator.populateDoubleTaggedRoute(
-                        deviceId, prefix, hostMac, dummyVlan, innerVlan, outerVlan, outerTpid, outPort);
-                srManager.routingRulePopulator.processDoubleTaggedFilter(
-                        deviceId, outPort, outerVlan, innerVlan, true);
-            } else {
-                log.error("Failed to allocate dummy VLAN ID for host {} at {}/{}",
-                          prefix.address(), deviceId, outPort);
-            }
+            srManager.routingRulePopulator.populateDoubleTaggedRoute(
+                    deviceId, prefix, hostMac, innerVlan, outerVlan, outerTpid, outPort);
+            srManager.routingRulePopulator.processDoubleTaggedFilter(
+                    deviceId, outPort, outerVlan, innerVlan, true);
         }
     }
 
@@ -1276,17 +1268,9 @@
             }
         }
 
-        VlanId dummyVlan = srManager.dummyVlanIdStore().get(new DummyVlanIdStoreKey(
-                new ConnectPoint(deviceId, outPort), prefix.address()));
-        if (dummyVlan == null) {
-            log.error("Failed to get dummyVlanId for host {} at {}/{}.",
-                      prefix.address(), deviceId, outPort);
-        } else {
-            srManager.routingRulePopulator.revokeDoubleTaggedRoute(
-                    deviceId, prefix, hostMac, dummyVlan, innerVlan, outerVlan, outerTpid, outPort);
-            srManager.routingRulePopulator.processDoubleTaggedFilter(
-                    deviceId, outPort, outerVlan, innerVlan, false);
-        }
+        srManager.routingRulePopulator.revokeDoubleTaggedRoute(deviceId, prefix, hostMac,
+                innerVlan, outerVlan, outerTpid, outPort);
+        srManager.routingRulePopulator.processDoubleTaggedFilter(deviceId, outPort, outerVlan, innerVlan, false);
     }
 
 
diff --git a/app/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java b/app/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
index ca9ba42..2bc5b30 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
@@ -17,6 +17,7 @@
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
+import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.onlab.packet.EthType;
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.IPv6;
@@ -53,7 +54,6 @@
 import org.onosproject.net.flowobjective.ForwardingObjective;
 import org.onosproject.net.flowobjective.ForwardingObjective.Builder;
 import org.onosproject.net.flowobjective.ForwardingObjective.Flag;
-import org.onosproject.segmentrouting.storekey.DummyVlanIdStoreKey;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -316,7 +316,7 @@
         ForwardingObjective.Builder fwdBuilder;
         try {
             fwdBuilder = routingFwdObjBuilder(deviceId, prefix, hostMac,
-                                              hostVlanId, outPort, directHost, false);
+                                              hostVlanId, outPort, null, null, directHost, false);
         } catch (DeviceConfigNotFoundException e) {
             log.warn(e.getMessage() + " Aborting direct populateRoute");
             return;
@@ -356,7 +356,7 @@
         ForwardingObjective.Builder fwdBuilder;
         try {
             fwdBuilder = routingFwdObjBuilder(deviceId, prefix, hostMac,
-                                              hostVlanId, outPort, directHost, true);
+                                              hostVlanId, outPort, null, null, directHost, true);
         } catch (DeviceConfigNotFoundException e) {
             log.warn(e.getMessage() + " Aborting revokeIpRuleForHost.");
             return;
@@ -390,37 +390,66 @@
      * @throws DeviceConfigNotFoundException if given device is not configured
      */
 
-    private ForwardingObjective.Builder
-
-
-    routingFwdObjBuilder(
+    private ForwardingObjective.Builder routingFwdObjBuilder(
             DeviceId deviceId, IpPrefix prefix,
             MacAddress hostMac, VlanId hostVlanId, PortNumber outPort,
+            VlanId innerVlan, EthType outerTpid,
             boolean directHost, boolean revoke)
             throws DeviceConfigNotFoundException {
-        MacAddress deviceMac;
-        deviceMac = config.getDeviceMac(deviceId);
-        int nextObjId = -1;
+        int nextObjId;
+        if (directHost) {
+            // if the objective is to revoke an existing rule, and for some reason
+            // the next-objective does not exist, then a new one should not be created
+            ImmutablePair<TrafficTreatment, TrafficSelector> treatmentAndMeta =
+                    getTreatmentAndMeta(deviceId, hostMac, hostVlanId, outPort, innerVlan, outerTpid);
+            if (treatmentAndMeta == null) {
+                // Warning log will come from getTreatmentAndMeta method
+                return null;
+            }
+            nextObjId = srManager.getPortNextObjectiveId(deviceId, outPort,
+                    treatmentAndMeta.getLeft(), treatmentAndMeta.getRight(), !revoke);
+        } else {
+          // if the objective is to revoke an existing rule, and for some reason
+          // the next-objective does not exist, then a new one should not be created
+          nextObjId = srManager.getMacVlanNextObjectiveId(deviceId, hostMac, hostVlanId,
+                                          outPort, !revoke);
+        }
+        if (nextObjId == -1) {
+            // Warning log will come from getMacVlanNextObjective method
+            return null;
+        }
+
+        return DefaultForwardingObjective.builder()
+                .withSelector(buildIpSelectorFromIpPrefix(prefix).build())
+                .nextStep(nextObjId)
+                .fromApp(srManager.appId).makePermanent()
+                .withPriority(getPriorityFromPrefix(prefix))
+                .withFlag(ForwardingObjective.Flag.SPECIFIC);
+    }
+
+    private ImmutablePair<TrafficTreatment, TrafficSelector> getTreatmentAndMeta(
+            DeviceId deviceId, MacAddress hostMac, VlanId hostVlanId, PortNumber outPort,
+            VlanId innerVlan, EthType outerTpid)
+            throws DeviceConfigNotFoundException {
+        MacAddress routerMac;
+        routerMac = config.getDeviceMac(deviceId);
 
         ConnectPoint connectPoint = new ConnectPoint(deviceId, outPort);
         VlanId untaggedVlan = srManager.interfaceService.getUntaggedVlanId(connectPoint);
         Set<VlanId> taggedVlans = srManager.interfaceService.getTaggedVlanId(connectPoint);
         VlanId nativeVlan = srManager.interfaceService.getNativeVlanId(connectPoint);
 
-        // Create route selector
-        TrafficSelector.Builder sbuilder = buildIpSelectorFromIpPrefix(prefix);
-
         // Create route treatment
         TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
         tbuilder.deferred()
                 .setEthDst(hostMac)
-                .setEthSrc(deviceMac)
+                .setEthSrc(routerMac)
                 .setOutput(outPort);
 
         // Create route meta
         TrafficSelector.Builder mbuilder = DefaultTrafficSelector.builder();
 
-        // Adjust the meta according to VLAN configuration
+        // Adjust treatment and meta according to VLAN configuration
         if (taggedVlans.contains(hostVlanId)) {
             tbuilder.setVlanId(hostVlanId);
         } else if (hostVlanId.equals(VlanId.NONE)) {
@@ -434,42 +463,21 @@
                 return null;
             }
         } else {
-            // Internally-assigned dummy VLAN id will be given as hostVlanId
-            // when destination is double-tagged.
-            VlanId vlanId = srManager.dummyVlanIdStore().get(
-                    new DummyVlanIdStoreKey(connectPoint, prefix.address()));
-            if (vlanId != null && vlanId.equals(hostVlanId)) {
-                tbuilder.setVlanId(hostVlanId);
-                mbuilder.matchVlanId(VlanId.ANY);
-            } else {
-                log.warn("Tagged nexthop {}/{} is not allowed on {} without VLAN listed"
-                                 + " in tagged vlan", hostMac, hostVlanId, connectPoint);
+            // Double tagged hosts
+            if (innerVlan == null || outerTpid == null) {
+                log.warn("Failed to construct NextObj for double tagged hosts {}/{}. {} {}",
+                        hostMac, hostVlanId,
+                        (innerVlan == null) ? "innerVlan = null." : "",
+                        (outerTpid == null) ? "outerTpid = null." : "");
                 return null;
             }
+            tbuilder.setVlanId(innerVlan);
+            tbuilder.pushVlan(outerTpid);
+            tbuilder.setVlanId(hostVlanId);
+            mbuilder.matchVlanId(VlanId.ANY);
         }
 
-        if (directHost) {
-          // if the objective is to revoke an existing rule, and for some reason
-          // the next-objective does not exist, then a new one should not be created
-          nextObjId = srManager.getPortNextObjectiveId(deviceId, outPort,
-                                          tbuilder.build(), mbuilder.build(), !revoke);
-        } else {
-          // if the objective is to revoke an existing rule, and for some reason
-          // the next-objective does not exist, then a new one should not be created
-          nextObjId = srManager.getMacVlanNextObjectiveId(deviceId, hostMac, hostVlanId,
-                                          outPort, !revoke);
-        }
-        if (nextObjId == -1) {
-            // Warning log will come from getMacVlanNextObjective method
-            return null;
-        }
-
-        return DefaultForwardingObjective.builder()
-                .withSelector(sbuilder.build())
-                .nextStep(nextObjId)
-                .fromApp(srManager.appId).makePermanent()
-                .withPriority(getPriorityFromPrefix(prefix))
-                .withFlag(ForwardingObjective.Flag.SPECIFIC);
+        return ImmutablePair.of(tbuilder.build(), mbuilder.build());
     }
 
     /**
@@ -1716,30 +1724,20 @@
      * @param deviceId device ID of the device that next hop attaches to
      * @param prefix IP prefix of the route
      * @param hostMac MAC address of the next hop
-     * @param dummyVlan Dummy Vlan ID allocated for this route
      * @param innerVlan inner Vlan ID of the next hop
      * @param outerVlan outer Vlan ID of the next hop
      * @param outerTpid outer TPID of the next hop
      * @param outPort port where the next hop attaches to
      */
-    void populateDoubleTaggedRoute(DeviceId deviceId, IpPrefix prefix, MacAddress hostMac, VlanId dummyVlan,
+    void populateDoubleTaggedRoute(DeviceId deviceId, IpPrefix prefix, MacAddress hostMac,
                                    VlanId innerVlan, VlanId outerVlan, EthType outerTpid, PortNumber outPort) {
         ForwardingObjective.Builder fwdBuilder;
         log.debug("Populate direct routing entry for double-tagged host route {} at {}:{}",
                   prefix, deviceId, outPort);
 
-        ForwardingObjective.Builder egressFwdBuilder = egressFwdObjBuilder(
-                outPort, dummyVlan, innerVlan, outerVlan, outerTpid);
-        DefaultObjectiveContext egressFwdContext = new DefaultObjectiveContext(
-                objective -> log.debug("Egress rule for IP {} is populated", prefix.address()),
-                (objective, error) -> {
-                    log.warn("Failed to populate egress rule for IP {}: {}", prefix.address(), error);
-                    srManager.dummyVlanIdStore().remove(new DummyVlanIdStoreKey(
-                            new ConnectPoint(deviceId, outPort), prefix.address()
-                    ));
-                });
         try {
-            fwdBuilder = routingFwdObjBuilder(deviceId, prefix, hostMac, dummyVlan, outPort, true, false);
+            fwdBuilder = routingFwdObjBuilder(deviceId, prefix, hostMac, outerVlan, outPort, innerVlan, outerTpid,
+                    true, false);
         } catch (DeviceConfigNotFoundException e) {
             log.error(e.getMessage() + " Aborting populateDoubleTaggedRoute");
             return;
@@ -1750,12 +1748,9 @@
             return;
         }
 
-        // Egress forwarding objective should be installed after the nextObjective for the output port is installed.
-        // Installation of routingFwdObj will ensure the installation of the nextObjective.
         int nextId = fwdBuilder.add().nextId();
         DefaultObjectiveContext context = new DefaultObjectiveContext(objective -> {
             log.debug("Direct routing rule for double-tagged host route {} populated. nextId={}", prefix, nextId);
-            srManager.flowObjectiveService.forward(deviceId, egressFwdBuilder.add(egressFwdContext));
         }, (objective, error) ->
             log.warn("Failed to populate direct routing rule for double-tagged host route {}: {}", prefix, error)
         );
@@ -1769,34 +1764,60 @@
      * @param deviceId device ID of the device that next hop attaches to
      * @param prefix IP prefix of the route
      * @param hostMac MAC address of the next hop
-     * @param hostVlan Vlan ID of the next hop
      * @param innerVlan inner Vlan ID of the next hop
      * @param outerVlan outer Vlan ID of the next hop
      * @param outerTpid outer TPID of the next hop
      * @param outPort port where the next hop attaches to
      */
     void revokeDoubleTaggedRoute(DeviceId deviceId, IpPrefix prefix, MacAddress hostMac,
-                                 VlanId hostVlan, VlanId innerVlan, VlanId outerVlan,
-                                 EthType outerTpid, PortNumber outPort) {
-        revokeRoute(deviceId, prefix, hostMac, hostVlan, outPort, false);
+                                 VlanId innerVlan, VlanId outerVlan, EthType outerTpid, PortNumber outPort) {
+        ForwardingObjective.Builder fwdBuilder;
+        log.debug("Revoking direct routing entry for double-tagged host route {} at {}:{}",
+                prefix, deviceId, outPort);
 
-        DummyVlanIdStoreKey key = new DummyVlanIdStoreKey(
-                new ConnectPoint(deviceId, outPort), prefix.address());
-        VlanId dummyVlanId = srManager.dummyVlanIdStore().get(key);
-        if (dummyVlanId == null) {
-            log.warn("Failed to retrieve dummy VLAN ID for {}/{} and {}",
-                     deviceId, outPort, prefix.address());
+        try {
+            fwdBuilder = routingFwdObjBuilder(deviceId, prefix, hostMac, outerVlan, outPort, innerVlan, outerTpid,
+                    true, true);
+        } catch (DeviceConfigNotFoundException e) {
+            log.error(e.getMessage() + " Aborting revokeDoubleTaggedRoute");
             return;
         }
-        ForwardingObjective.Builder fob = egressFwdObjBuilder(
-                outPort, dummyVlanId, innerVlan, outerVlan, outerTpid);
+        if (fwdBuilder == null) {
+            log.error("Aborting double-tagged host routing table entry due to error for dev:{} route:{}",
+                    deviceId, prefix);
+            return;
+        }
+
+        int nextId = fwdBuilder.remove().nextId();
         DefaultObjectiveContext context = new DefaultObjectiveContext(objective -> {
-            log.debug("Egress rule for IP {} revoked", prefix.address());
-            srManager.dummyVlanIdStore().remove(key);
-        }, (objective, error) -> {
-            log.warn("Failed to revoke egress rule for IP {}: {}", prefix.address(), error);
-        });
-        srManager.flowObjectiveService.forward(deviceId, fob.remove(context));
+            log.debug("Direct routing rule for double-tagged host route {} revoked. nextId={}", prefix, nextId);
+
+            // Try to remove next objective as well
+            ImmutablePair<TrafficTreatment, TrafficSelector> treatmentAndMeta;
+            try {
+                treatmentAndMeta = getTreatmentAndMeta(deviceId, hostMac, outerVlan, outPort, innerVlan, outerTpid);
+            } catch (DeviceConfigNotFoundException e) {
+                log.error(e.getMessage() + " Aborting revokeDoubleTaggedRoute");
+                return;
+            }
+
+            if (treatmentAndMeta == null) {
+                // Warning log will come from getTreatmentAndMeta method
+                return;
+            }
+
+            DefaultGroupHandler groupHandler = srManager.getGroupHandler(deviceId);
+            if (groupHandler == null) {
+                log.warn("Failed to revoke direct routing rule for double-tagged host route {}: " +
+                        "group handler not found for {}", prefix, deviceId);
+                return;
+            }
+            groupHandler.removeGroupFromPort(outPort, treatmentAndMeta.getLeft(), treatmentAndMeta.getRight());
+
+        }, (objective, error) ->
+                log.warn("Failed to revoke direct routing rule for double-tagged host route {}: {}", prefix, error)
+        );
+        srManager.flowObjectiveService.forward(deviceId, fwdBuilder.remove(context));
     }
 
     /**
diff --git a/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
index 98ee40c..6cc0e74 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
@@ -112,7 +112,6 @@
 import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
 import org.onosproject.segmentrouting.pwaas.L2TunnelPolicy;
 import org.onosproject.segmentrouting.storekey.DestinationSetNextObjectiveStoreKey;
-import org.onosproject.segmentrouting.storekey.DummyVlanIdStoreKey;
 import org.onosproject.segmentrouting.storekey.PortNextObjectiveStoreKey;
 import org.onosproject.segmentrouting.storekey.VlanNextObjectiveStoreKey;
 import org.onosproject.segmentrouting.storekey.MacVlanNextObjectiveStoreKey;
@@ -152,7 +151,6 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.Collectors;
-import java.util.stream.IntStream;
 
 import static com.google.common.base.Preconditions.checkState;
 import static org.onlab.packet.Ethernet.TYPE_ARP;
@@ -352,13 +350,6 @@
             portNextObjStore = null;
 
     /**
-     * Per port dummy VLAN ID store with (connect point + ip address) as key.
-     * Used to keep track on dummy VLAN ID allocation.
-     */
-    private EventuallyConsistentMap<DummyVlanIdStoreKey, VlanId>
-            dummyVlanIdStore = null;
-
-    /**
      * Per device next objective ID store with (device id + MAC address + vlan) as key.
      * Used to keep track of L3 unicast group for indirect hosts.
      */
@@ -486,14 +477,6 @@
                 .withTimestampProvider((k, v) -> new WallClockTimestamp())
                 .build();
 
-        EventuallyConsistentMapBuilder<DummyVlanIdStoreKey, VlanId>
-                dummyVlanIdMapBuilder = storageService.eventuallyConsistentMapBuilder();
-        dummyVlanIdStore = dummyVlanIdMapBuilder
-                .withName("dummyvlanidstore")
-                .withSerializer(createSerializer())
-                .withTimestampProvider((k, v) -> new WallClockTimestamp())
-                .build();
-
         EventuallyConsistentMapBuilder<String, Tunnel> tunnelMapBuilder =
                 storageService.eventuallyConsistentMapBuilder();
         tunnelStore = tunnelMapBuilder
@@ -606,7 +589,6 @@
                           L2TunnelPolicy.class,
                           DefaultL2Tunnel.class,
                           DefaultL2TunnelPolicy.class,
-                          DummyVlanIdStoreKey.class,
                           MacVlanNextObjectiveStoreKey.class
                 );
     }
@@ -656,7 +638,6 @@
         vlanNextObjStore.destroy();
         macVlanNextObjStore.destroy();
         portNextObjStore.destroy();
-        dummyVlanIdStore.destroy();
         tunnelStore.destroy();
         policyStore.destroy();
 
@@ -1150,16 +1131,6 @@
     }
 
     /**
-     * Per port dummy VLAN ID store with (connect point + ip address) as key.
-     * Used to keep track on dummy VLAN ID allocation.
-     *
-     * @return dummy vlan id store.
-     */
-    public EventuallyConsistentMap<DummyVlanIdStoreKey, VlanId> dummyVlanIdStore() {
-        return dummyVlanIdStore;
-    }
-
-    /**
      * Returns the MPLS-ECMP configuration which indicates whether ECMP on
      * labeled packets should be programmed or not.
      *
@@ -1349,35 +1320,6 @@
         return defaultRoutingHandler;
     }
 
-    /**
-     * Returns new dummy VLAN ID.
-     * Dummy VLAN ID should be unique in each connect point.
-     *
-     * @param cp connect point
-     * @param ipAddress IP address
-     * @return new dummy VLAN ID. Returns VlanId.NONE if no VLAN ID is available.
-     */
-    public synchronized VlanId allocateDummyVlanId(ConnectPoint cp, IpAddress ipAddress) {
-        Set<VlanId> usedVlanId = Sets.union(getVlanPortMap(cp.deviceId()).keySet(),
-                                            dummyVlanIdStore.entrySet().stream().filter(entry ->
-                                                (entry.getKey()).connectPoint().equals(cp))
-                                            .map(Map.Entry::getValue)
-                                            .collect(Collectors.toSet()));
-
-        VlanId dummyVlanId = IntStream.range(MIN_DUMMY_VLAN_ID, MAX_DUMMY_VLAN_ID).mapToObj(
-                i -> VlanId.vlanId((short) (i & 0xFFFF))
-        ).filter(vlanId -> !usedVlanId.contains(vlanId)).findFirst().orElse(VlanId.NONE);
-
-        if (!dummyVlanId.equals(VlanId.NONE)) {
-            this.dummyVlanIdStore.put(new DummyVlanIdStoreKey(cp, ipAddress), dummyVlanId);
-            log.debug("Dummy VLAN ID {} is allocated to {}, {}", dummyVlanId, cp, ipAddress);
-        } else {
-            log.error("Failed to allocate dummy VLAN ID for {}, {}", cp, ipAddress);
-        }
-        return dummyVlanId;
-    }
-
-
     private class InternalPacketProcessor implements PacketProcessor {
         @Override
         public void process(PacketContext context) {
diff --git a/app/src/main/java/org/onosproject/segmentrouting/storekey/DummyVlanIdStoreKey.java b/app/src/main/java/org/onosproject/segmentrouting/storekey/DummyVlanIdStoreKey.java
deleted file mode 100644
index 65e7ca3..0000000
--- a/app/src/main/java/org/onosproject/segmentrouting/storekey/DummyVlanIdStoreKey.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.segmentrouting.storekey;
-
-import org.onlab.packet.IpAddress;
-import org.onosproject.net.ConnectPoint;
-
-import java.util.Objects;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-
-/**
- * Key of VLAN ID to DummyVlanIdStore.
- */
-public class DummyVlanIdStoreKey {
-    private final ConnectPoint connectPoint;
-    private final IpAddress ipAddress;
-
-    /**
-     * Construct the key of dummy vlan id key store.
-     *
-     * @param connectPoint connect point that this vlan id is associated
-     * @param ipAddress IP address that this vlan id is associated
-     */
-    public DummyVlanIdStoreKey(ConnectPoint connectPoint, IpAddress ipAddress) {
-        this.connectPoint = connectPoint;
-        this.ipAddress = ipAddress;
-    }
-
-    /**
-     * Returns the connect point in the key.
-     *
-     * @return connect point
-     */
-    public ConnectPoint connectPoint() {
-        return connectPoint;
-    }
-
-    /**
-     * Returns the IP address in the key.
-     *
-     * @return IP address
-     */
-    public IpAddress ipAddress() {
-        return ipAddress;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (!(o instanceof DummyVlanIdStoreKey)) {
-            return false;
-        }
-        DummyVlanIdStoreKey that = (DummyVlanIdStoreKey) o;
-        return (Objects.equals(this.connectPoint, that.connectPoint) &&
-                Objects.equals(this.ipAddress, that.ipAddress));
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(connectPoint, ipAddress);
-    }
-
-    @Override
-    public String toString() {
-        return toStringHelper(getClass())
-                .add("connectPoint", connectPoint)
-                .add("ipAddress", ipAddress)
-                .toString();
-    }
-}