CORD-180 Changed the way how learnt hosts are suppressed in gerrit 9195

Change-Id: I086ba82147ef716c076cb6140b03da2886515c32
diff --git a/apps/segmentrouting/BUCK b/apps/segmentrouting/BUCK
index 7cb8d69..f532bea 100644
--- a/apps/segmentrouting/BUCK
+++ b/apps/segmentrouting/BUCK
@@ -5,7 +5,6 @@
     '//cli:onos-cli',
     '//core/store/serializers:onos-core-serializers',
     '//incubator/api:onos-incubator-api',
-    '//providers/netcfghost:onos-providers-netcfghost',
     '//utils/rest:onlab-rest',
 ]
 
diff --git a/apps/segmentrouting/pom.xml b/apps/segmentrouting/pom.xml
index a80cbe9..ffc2362 100644
--- a/apps/segmentrouting/pom.xml
+++ b/apps/segmentrouting/pom.xml
@@ -76,11 +76,6 @@
             <version>${project.version}</version>
         </dependency>
         <dependency>
-            <groupId>org.onosproject</groupId>
-            <artifactId>onos-netcfg-host-provider</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
             <groupId>javax.ws.rs</groupId>
             <artifactId>javax.ws.rs-api</artifactId>
             <version>2.0.1</version>
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/HostHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/HostHandler.java
index 132bff5..d5c93fd 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/HostHandler.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/HostHandler.java
@@ -38,7 +38,6 @@
 import org.onosproject.net.flowobjective.ObjectiveContext;
 import org.onosproject.net.host.HostEvent;
 import org.onosproject.net.host.HostService;
-import org.onosproject.provider.netcfghost.NetworkConfigHostProvider;
 import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -351,16 +350,12 @@
      * @return true if segment routing accepts the host
      */
     private boolean accepted(Host host) {
-        // Always accept configured hosts
-        if (host.providerId().equals(NetworkConfigHostProvider.PROVIDER_ID)) {
-            return true;
-        }
-
         SegmentRoutingAppConfig appConfig = srManager.cfgService
                 .getConfig(srManager.appId, SegmentRoutingAppConfig.class);
-        boolean accepted = appConfig != null &&
-                appConfig.hostLearning() &&
-                !appConfig.suppressHost().contains(host.location());
+
+        boolean accepted = appConfig == null ||
+                (!appConfig.suppressHostByProvider().contains(host.providerId().id()) &&
+                !appConfig.suppressHostByPort().contains(host.location()));
         if (!accepted) {
             log.info("Ignore suppressed host {}", host.id());
         }
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingAppConfig.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingAppConfig.java
index 9bbcaa6..0eb2c8e 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingAppConfig.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingAppConfig.java
@@ -37,15 +37,17 @@
     private static final String VROUTER_MACS = "vRouterMacs";
     private static final String VROUTER_ID = "vRouterId";
     private static final String SUPPRESS_SUBNET = "suppressSubnet";
-    private static final String SUPPRESS_HOST = "suppressHost";
-    private static final String HOST_LEARNING = "hostLearning";
+    private static final String SUPPRESS_HOST_BY_PORT = "suppressHostByPort";
+    // TODO We might want to move SUPPRESS_HOST_BY_PROVIDER to Component Config
+    private static final String SUPPRESS_HOST_BY_PROVIDER = "suppressHostByProvider";
 
     @Override
     public boolean isValid() {
         return hasOnlyFields(VROUTER_MACS, VROUTER_ID, SUPPRESS_SUBNET,
-                SUPPRESS_HOST, HOST_LEARNING) &&
+                SUPPRESS_HOST_BY_PORT, SUPPRESS_HOST_BY_PROVIDER) &&
                 vRouterMacs() != null && vRouterId() != null &&
-                suppressSubnet() != null && suppressHost() != null;
+                suppressSubnet() != null && suppressHostByPort() != null &&
+                suppressHostByProvider() != null;
     }
 
     /**
@@ -181,18 +183,18 @@
     }
 
     /**
-     * Gets names of ports to which SegmentRouting does not push host rules.
+     * Gets connect points to which SegmentRouting does not push host rules.
      *
-     * @return Set of port names, empty if not specified, or null
+     * @return Set of connect points, empty if not specified, or null
      *         if not valid
      */
-    public Set<ConnectPoint> suppressHost() {
-        if (!object.has(SUPPRESS_HOST)) {
+    public Set<ConnectPoint> suppressHostByPort() {
+        if (!object.has(SUPPRESS_HOST_BY_PORT)) {
             return ImmutableSet.of();
         }
 
         ImmutableSet.Builder<ConnectPoint> builder = ImmutableSet.builder();
-        ArrayNode arrayNode = (ArrayNode) object.path(SUPPRESS_HOST);
+        ArrayNode arrayNode = (ArrayNode) object.path(SUPPRESS_HOST_BY_PORT);
         for (JsonNode jsonNode : arrayNode) {
             String portName = jsonNode.asText(null);
             if (portName == null) {
@@ -208,42 +210,61 @@
     }
 
     /**
-     * Sets names of ports to which SegmentRouting does not push host rules.
+     * Sets connect points to which SegmentRouting does not push host rules.
      *
-     * @param suppressHost names of ports to which SegmentRouting does not push
+     * @param connectPoints connect points to which SegmentRouting does not push
      *                     host rules
      * @return this {@link SegmentRoutingAppConfig}
      */
-    public SegmentRoutingAppConfig setSuppressHost(Set<ConnectPoint> suppressHost) {
-        if (suppressHost == null) {
-            object.remove(SUPPRESS_HOST);
+    public SegmentRoutingAppConfig setSuppressHostByPort(Set<ConnectPoint> connectPoints) {
+        if (connectPoints == null) {
+            object.remove(SUPPRESS_HOST_BY_PORT);
         } else {
             ArrayNode arrayNode = mapper.createArrayNode();
-            suppressHost.forEach(connectPoint -> {
+            connectPoints.forEach(connectPoint -> {
                 arrayNode.add(connectPoint.deviceId() + "/" + connectPoint.port());
             });
-            object.set(SUPPRESS_HOST, arrayNode);
+            object.set(SUPPRESS_HOST_BY_PORT, arrayNode);
         }
         return this;
     }
 
     /**
-     * Gets whether host learning is enabled or not.
+     * Gets provider names from which SegmentRouting does not learn host info.
      *
-     * @return true if enabled. false if disabled or not configured
+     * @return array of provider names that need to be ignored
      */
-    public boolean hostLearning() {
-        return object.has(HOST_LEARNING) && object.path(HOST_LEARNING).asBoolean();
+    public Set<String> suppressHostByProvider() {
+        if (!object.has(SUPPRESS_HOST_BY_PROVIDER)) {
+            return ImmutableSet.of();
+        }
+
+        ImmutableSet.Builder<String> builder = ImmutableSet.builder();
+        ArrayNode arrayNode = (ArrayNode) object.path(SUPPRESS_HOST_BY_PROVIDER);
+        for (JsonNode jsonNode : arrayNode) {
+            String providerName = jsonNode.asText(null);
+            if (providerName == null) {
+                return null;
+            }
+            builder.add(providerName);
+        }
+        return builder.build();
     }
 
     /**
-     * Sets whether host learning is enabled or not.
+     * Sets provider names from which SegmentRouting does not learn host info.
      *
-     * @param enabled true if enabled
+     * @param providers set of provider names
      * @return this {@link SegmentRoutingAppConfig}
      */
-    public SegmentRoutingAppConfig setHostLearning(boolean enabled) {
-        object.put(HOST_LEARNING, enabled);
+    public SegmentRoutingAppConfig setSuppressHostByProvider(Set<String> providers) {
+        if (providers == null) {
+            object.remove(SUPPRESS_HOST_BY_PROVIDER);
+        } else {
+            ArrayNode arrayNode = mapper.createArrayNode();
+            providers.forEach(arrayNode::add);
+            object.set(SUPPRESS_HOST_BY_PROVIDER, arrayNode);
+        }
         return this;
     }
 
@@ -253,8 +274,8 @@
                 .add("vRouterMacs", vRouterMacs())
                 .add("vRouterId", vRouterId())
                 .add("suppressSubnet", suppressSubnet())
-                .add("suppressHost", suppressHost())
-                .add("hostLearning", hostLearning())
+                .add("suppressHostByPort", suppressHostByPort())
+                .add("suppressHostByProvider", suppressHostByProvider())
                 .toString();
     }
 }
diff --git a/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/config/SegmentRoutingAppConfigTest.java b/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/config/SegmentRoutingAppConfigTest.java
index d987247..e6f4912 100644
--- a/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/config/SegmentRoutingAppConfigTest.java
+++ b/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/config/SegmentRoutingAppConfigTest.java
@@ -55,6 +55,9 @@
     private static final ConnectPoint PORT_3 = ConnectPoint.deviceConnectPoint("of:1/3");
     private static final DeviceId VROUTER_ID_1 = DeviceId.deviceId("of:1");
     private static final DeviceId VROUTER_ID_2 = DeviceId.deviceId("of:2");
+    private static final String PROVIDER_1 = "org.onosproject.provider.host";
+    private static final String PROVIDER_2 = "org.onosproject.netcfghost";
+    private static final String PROVIDER_3 = "org.onosproject.anotherprovider";
 
     /**
      * Initialize test related variables.
@@ -180,55 +183,65 @@
     }
 
     /**
-     * Tests suppressHost getter.
+     * Tests suppressHostByPort getter.
      *
      * @throws Exception
      */
     @Test
-    public void testSuppressHost() throws Exception {
-        Set<ConnectPoint> suppressHost = config.suppressHost();
-        assertNotNull("suppressHost should not be null", suppressHost);
-        assertThat(suppressHost.size(), is(2));
-        assertTrue(suppressHost.contains(PORT_1));
-        assertTrue(suppressHost.contains(PORT_2));
+    public void testSuppressHostByPort() throws Exception {
+        Set<ConnectPoint> suppressHostByPort = config.suppressHostByPort();
+        assertNotNull("suppressHostByPort should not be null", suppressHostByPort);
+        assertThat(suppressHostByPort.size(), is(2));
+        assertTrue(suppressHostByPort.contains(PORT_1));
+        assertTrue(suppressHostByPort.contains(PORT_2));
     }
 
     /**
-     * Tests suppressHost setter.
+     * Tests suppressHostByPort setter.
      *
      * @throws Exception
      */
     @Test
-    public void testSetSuppressHost() throws Exception {
+    public void testSetSuppressHostByPort() throws Exception {
         ImmutableSet.Builder<ConnectPoint> builder = ImmutableSet.builder();
         builder.add(PORT_3);
-        config.setSuppressHost(builder.build());
+        config.setSuppressHostByPort(builder.build());
 
-        Set<ConnectPoint> suppressHost = config.suppressHost();
-        assertNotNull("suppressHost should not be null", suppressHost);
-        assertThat(suppressHost.size(), is(1));
-        assertTrue(suppressHost.contains(PORT_3));
+        Set<ConnectPoint> suppressHostByPort = config.suppressHostByPort();
+        assertNotNull("suppressHostByPort should not be null", suppressHostByPort);
+        assertThat(suppressHostByPort.size(), is(1));
+        assertTrue(suppressHostByPort.contains(PORT_3));
     }
 
     /**
-     * Tests hostLearning getter.
+     * Tests suppressHostByProvider getter.
      *
      * @throws Exception
      */
     @Test
-    public void testHostLearning() throws Exception {
-        assertFalse(config.hostLearning());
+    public void testSuppressHostByProvider() throws Exception {
+        Set<String> supprsuppressHostByProvider = config.suppressHostByProvider();
+        assertNotNull("suppressHostByProvider should not be null", supprsuppressHostByProvider);
+        assertThat(supprsuppressHostByProvider.size(), is(2));
+        assertTrue(supprsuppressHostByProvider.contains(PROVIDER_1));
+        assertTrue(supprsuppressHostByProvider.contains(PROVIDER_2));
     }
 
     /**
-     * Tests hostLearning setter.
+     * Tests suppressHostByProvider setter.
      *
      * @throws Exception
      */
     @Test
     public void testSetHostLearning() throws Exception {
-        config.setHostLearning(true);
-        assertTrue(config.hostLearning());
+        ImmutableSet.Builder<String> builder = ImmutableSet.builder();
+        builder.add(PROVIDER_3);
+        config.setSuppressHostByProvider(builder.build());
+
+        Set<String> supprsuppressHostByProvider = config.suppressHostByProvider();
+        assertNotNull("suppressHostByProvider should not be null", supprsuppressHostByProvider);
+        assertThat(supprsuppressHostByProvider.size(), is(1));
+        assertTrue(supprsuppressHostByProvider.contains(PROVIDER_3));
     }
 
     private class MockDelegate implements ConfigApplyDelegate {
diff --git a/apps/segmentrouting/src/test/resources/sr-app-config-invalid.json b/apps/segmentrouting/src/test/resources/sr-app-config-invalid.json
index 72def14..89b2286 100644
--- a/apps/segmentrouting/src/test/resources/sr-app-config-invalid.json
+++ b/apps/segmentrouting/src/test/resources/sr-app-config-invalid.json
@@ -8,9 +8,9 @@
       "of:1/1",
       "of:1/2"
   ],
-  "suppressHost" : [
+  "suppressHostByPort" : [
       "of:1/1",
       "wrongPort"
   ],
-  "hostLearning" : false
+  "suppressHostByProvider" : []
 }
diff --git a/apps/segmentrouting/src/test/resources/sr-app-config.json b/apps/segmentrouting/src/test/resources/sr-app-config.json
index de6d7fc..ce5a086 100644
--- a/apps/segmentrouting/src/test/resources/sr-app-config.json
+++ b/apps/segmentrouting/src/test/resources/sr-app-config.json
@@ -8,9 +8,12 @@
       "of:1/1",
       "of:1/2"
   ],
-  "suppressHost" : [
+  "suppressHostByPort" : [
       "of:1/1",
       "of:1/2"
   ],
-  "hostLearning" : false
+  "suppressHostByProvider" : [
+      "org.onosproject.provider.host",
+      "org.onosproject.netcfghost"
+  ]
 }
diff --git a/providers/netcfghost/src/main/java/org/onosproject/provider/netcfghost/NetworkConfigHostProvider.java b/providers/netcfghost/src/main/java/org/onosproject/provider/netcfghost/NetworkConfigHostProvider.java
index 5669e16..c3c8161 100644
--- a/providers/netcfghost/src/main/java/org/onosproject/provider/netcfghost/NetworkConfigHostProvider.java
+++ b/providers/netcfghost/src/main/java/org/onosproject/provider/netcfghost/NetworkConfigHostProvider.java
@@ -61,7 +61,7 @@
 
     private ApplicationId appId;
     private static final String APP_NAME = "org.onosproject.netcfghost";
-    public static final ProviderId PROVIDER_ID = new ProviderId("host", APP_NAME);
+    private static final ProviderId PROVIDER_ID = new ProviderId("host", APP_NAME);
     protected HostProviderService providerService;
 
     private final Logger log = LoggerFactory.getLogger(getClass());
@@ -95,7 +95,7 @@
     @Override
     public void triggerProbe(Host host) {
         /*
-         * Note: In CORD deployment, we assume that all hosts are configured.
+         * Note: All hosts are configured in network config host provider.
          * Therefore no probe is required.
          */
     }
diff --git a/tools/package/config/samples/network-cfg-fabric-2x2-all-readme.html b/tools/package/config/samples/network-cfg-fabric-2x2-all-readme.html
index 5dbf2e2..68a3f11 100644
--- a/tools/package/config/samples/network-cfg-fabric-2x2-all-readme.html
+++ b/tools/package/config/samples/network-cfg-fabric-2x2-all-readme.html
@@ -15,7 +15,6 @@
     p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 14.0px; font: 12.0px Menlo; color: #ff2600; -webkit-text-stroke: #ff2600}
     p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 14.0px; font: 12.0px Menlo; color: #000000; -webkit-text-stroke: #000000}
     p.p8 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 14.0px; font: 12.0px Menlo; color: #00c7fc; -webkit-text-stroke: #000000}
-    p.p9 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 14.0px; font: 12.0px Menlo; color: #78ba5b; -webkit-text-stroke: #353535}
     span.s1 {font-kerning: none}
     span.s2 {font-kerning: none; color: #0433ff; -webkit-text-stroke: 0px #0433ff}
     span.s3 {font-kerning: none; color: #000000; -webkit-text-stroke: 0px #000000}
@@ -25,8 +24,7 @@
     span.s7 {font-kerning: none; color: #ff40ff; -webkit-text-stroke: 0px #ff40ff}
     span.s8 {font-kerning: none; color: #ff2600; -webkit-text-stroke: 0px #ff2600}
     span.s9 {font-kerning: none; color: #000000}
-    span.s10 {font-kerning: none; -webkit-text-stroke: 0px #000000}
-    span.s11 {font-kerning: none; color: #669c35; -webkit-text-stroke: 0px #669c35}
+    span.s10 {font-kerning: none; color: #669c35; -webkit-text-stroke: 0px #669c35}
     span.Apple-tab-span {white-space:pre}
   </style>
 </head>
@@ -227,9 +225,10 @@
 <p class="p4"><span class="s3"><span class="Apple-converted-space">                 </span>"suppressSubnet" : [ </span><span class="s1">// Do not push subnet rules for these ports</span></p>
 <p class="p7"><span class="s1"><span class="Apple-converted-space">                    </span>"of:0000000000000002/31", "of:0000000000000002/32"</span></p>
 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>],</span></p>
-<p class="p9"><span class="s3"><span class="Apple-converted-space">                </span>"hostLearning" : true, </span><span class="s10">// </span><span class="s1">Host learning is enabled if true. Host learning is disabled if false or the config is not provided</span></p>
-<p class="p4"><span class="s3"><span class="Apple-converted-space">                </span>"suppressHost" : [ </span><span class="s1">// Hosts on these ports will be ignored. Only takes effect when hostLearning is enabled</span></p>
-<p class="p7"><span class="s1"><span class="Apple-converted-space">                    </span>"of:0000000000000001/65", "of:0000000000000001/73",</span></p>
+<p class="p4"><span class="s3"><span class="Apple-converted-space">                </span>"suppressHostByProvider" : [ </span><span class="s1">// Hosts come from these providers will be ignored.</span></p>
+<p class="p7"><span class="s1"><span class="Apple-converted-space">                    </span>"org.onosproject.provider.host"</span></p>
+<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>],</span></p>
+<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"suppressHostByPort" : [ </span><span class="s5">// Hosts on these ports will be ignored.</span></p>
 <p class="p7"><span class="s1"><span class="Apple-converted-space">                    </span>"of:0000000000000002/31", "of:0000000000000002/32"</span></p>
 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>]</span></p>
 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p>
@@ -239,7 +238,7 @@
 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"controlPlaneConnectPoint" : "of:0000000000000002/31", </span><span class="s5">// location of Quagga</span></p>
 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"ospfEnabled" : "true", </span><span class="s5">// enable OSPF</span></p>
 <p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"pimEnabled" : "true", </span><span class="s6">// enable PIM</span></p>
-<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"interfaces" : [ "external-quagga" ] </span><span class="s11">// </span><span class="s5">VR only handles peers on these ports</span></p>
+<p class="p7"><span class="s1"><span class="Apple-converted-space">                </span>"interfaces" : [ "external-quagga" ] </span><span class="s10">// </span><span class="s5">VR only handles peers on these ports</span></p>
 <p class="p7"><span class="s1"><span class="Apple-converted-space">            </span>}</span></p>
 <p class="p7"><span class="s1"><span class="Apple-converted-space">        </span>}</span></p>
 <p class="p7"><span class="s1"><span class="Apple-converted-space">    </span>}</span></p>
diff --git a/tools/package/config/samples/network-cfg-fabric-2x2-all.json b/tools/package/config/samples/network-cfg-fabric-2x2-all.json
index 499d763..2de901e 100644
--- a/tools/package/config/samples/network-cfg-fabric-2x2-all.json
+++ b/tools/package/config/samples/network-cfg-fabric-2x2-all.json
@@ -234,9 +234,10 @@
                 "suppressSubnet" : [
                     "of:0000000000000002/31", "of:0000000000000002/32"
                 ],
-                "hostLearning" : true,
-                "suppressHost" : [
-                    "of:0000000000000001/65", "of:0000000000000001/73",
+                "suppressHostByProvider" : [
+                    "org.onosproject.provider.host"
+                ],
+                "suppressHostByPort" : [
                     "of:0000000000000002/31", "of:0000000000000002/32"
                 ]
             }