Bandwidth update to NetworkConfig

Change-Id: I26117bcbe57ec3b6c016ddaac1b9c075ff739199
diff --git a/providers/bgp/topology/BUCK b/providers/bgp/topology/BUCK
index ee79b20..d462cf7 100644
--- a/providers/bgp/topology/BUCK
+++ b/providers/bgp/topology/BUCK
@@ -4,6 +4,7 @@
     '//protocols/bgp/bgpio:onos-protocols-bgp-bgpio',
     '//incubator/store:onos-incubator-store',
     '//incubator/api:onos-incubator-api',
+    '//apps/pcep-api:onos-apps-pcep-api',
 ]
 
 TEST_DEPS = [
diff --git a/providers/bgp/topology/pom.xml b/providers/bgp/topology/pom.xml
index 863bb3a..68da025 100644
--- a/providers/bgp/topology/pom.xml
+++ b/providers/bgp/topology/pom.xml
@@ -28,5 +28,9 @@
                         <groupId>org.onosproject</groupId>
                         <artifactId>onos-bgp-api</artifactId>
                 </dependency>
+            <dependency>
+                <groupId>org.onosproject</groupId>
+                <artifactId>onos-app-pcep-api</artifactId>
+            </dependency>
         </dependencies>
 </project>
diff --git a/providers/bgp/topology/src/main/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProvider.java b/providers/bgp/topology/src/main/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProvider.java
index 9997659..7af5b3d 100644
--- a/providers/bgp/topology/src/main/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProvider.java
+++ b/providers/bgp/topology/src/main/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProvider.java
@@ -13,26 +13,13 @@
 
 package org.onosproject.provider.bgp.topology.impl;
 
-import static org.onosproject.bgp.controller.BgpDpid.uri;
-import static org.onosproject.net.DeviceId.deviceId;
-import static org.onosproject.net.Device.Type.ROUTER;
-import static org.onosproject.net.Device.Type.VIRTUAL;
-import static org.onosproject.incubator.net.resource.label.LabelResourceId.labelResourceId;
-import static java.util.stream.Collectors.toList;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import java.util.HashMap;
-
-import org.onlab.packet.ChassisId;
-import org.onlab.packet.Ip4Address;
-import org.onlab.util.Bandwidth;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.ChassisId;
+import org.onlab.packet.Ip4Address;
 import org.onosproject.bgp.controller.BgpController;
 import org.onosproject.bgp.controller.BgpDpid;
 import org.onosproject.bgp.controller.BgpLinkListener;
@@ -60,7 +47,7 @@
 import org.onosproject.bgpio.types.attr.BgpLinkAttrIgpMetric;
 import org.onosproject.bgpio.types.attr.BgpLinkAttrMaxLinkBandwidth;
 import org.onosproject.bgpio.types.attr.BgpLinkAttrTeDefaultMetric;
-import org.onosproject.core.CoreService;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrUnRsrvdLinkBandwidth;
 import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
 import org.onosproject.incubator.net.resource.label.LabelResourceId;
 import org.onosproject.mastership.MastershipService;
@@ -70,10 +57,10 @@
 import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Link;
+import org.onosproject.net.LinkKey;
 import org.onosproject.net.MastershipRole;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.config.NetworkConfigService;
-import org.onosproject.net.config.basics.BandwidthCapacity;
 import org.onosproject.net.device.DefaultDeviceDescription;
 import org.onosproject.net.device.DefaultPortDescription;
 import org.onosproject.net.device.DeviceDescription;
@@ -92,9 +79,22 @@
 import org.onosproject.net.link.LinkService;
 import org.onosproject.net.provider.AbstractProvider;
 import org.onosproject.net.provider.ProviderId;
+import org.onosproject.pcep.api.TeLinkConfig;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+
+import static java.util.stream.Collectors.toList;
+import static org.onosproject.bgp.controller.BgpDpid.uri;
+import static org.onosproject.incubator.net.resource.label.LabelResourceId.labelResourceId;
+import static org.onosproject.net.Device.Type.ROUTER;
+import static org.onosproject.net.Device.Type.VIRTUAL;
+import static org.onosproject.net.DeviceId.deviceId;
+
 /**
  * Provider which uses an BGP controller to detect network infrastructure topology.
  */
@@ -126,9 +126,6 @@
     protected DeviceService deviceService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected CoreService coreService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected MastershipService mastershipService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -316,17 +313,14 @@
 
             LinkDescription linkDes = buildLinkDes(linkNlri, details, true);
 
-            //If already link exists, return
-            if (linkService.getLink(linkDes.src(), linkDes.dst()) != null || linkProviderService == null) {
-                return;
-            }
+
 
             /*
              * Update link ports and configure bandwidth on source and destination port using networkConfig service
              * Only master of source link registers for bandwidth
              */
             if (mastershipService.isLocalMaster(linkDes.src().deviceId())) {
-                registerBandwidth(linkDes, details);
+                registerBandwidthAndTeMetric(linkDes, details);
             }
 
             //Updating ports of the link
@@ -458,8 +452,7 @@
              */
             if (networkConfigService != null && mastershipService.isLocalMaster(linkDes.src().deviceId())) {
                 // Releases registered resource for this link
-                networkConfigService.removeConfig(linkDes.src(), BandwidthCapacity.class);
-                networkConfigService.removeConfig(linkDes.dst(), BandwidthCapacity.class);
+                networkConfigService.removeConfig(LinkKey.linkKey(linkDes.src(), linkDes.dst()), TeLinkConfig.class);
             }
 
             linkProviderService.linkVanished(linkDes);
@@ -467,6 +460,11 @@
             linkDes = new DefaultLinkDescription(linkDes.dst(), linkDes.src(), Link.Type.DIRECT,
                     false, linkDes.annotations());
             linkProviderService.linkVanished(linkDes);
+            if (networkConfigService != null && mastershipService.isLocalMaster(linkDes.src().deviceId())) {
+                // Releases registered resource for this link
+                networkConfigService.removeConfig(LinkKey.linkKey(linkDes.src(), linkDes.dst()), TeLinkConfig.class);
+            }
+
         }
     }
 
@@ -479,7 +477,7 @@
         labelResourceAdminService.createDevicePool(deviceId, beginLabel, endLabel);
     }
 
-    private void registerBandwidth(LinkDescription linkDes, PathAttrNlriDetails details) {
+    private void registerBandwidthAndTeMetric(LinkDescription linkDes, PathAttrNlriDetails details) {
         if (details ==  null) {
             log.error("Couldnot able to register bandwidth ");
             return;
@@ -492,7 +490,10 @@
         }
 
         List<BgpValueType> tlvs = ((LinkStateAttributes) attribute.iterator().next()).linkStateAttributes();
-        float maxReservableBw = 0;
+        double maxReservableBw = 0;
+        List<Float>  unreservedBw = new ArrayList<>();
+        int teMetric = 0;
+        int igpMetric = 0;
 
         for (BgpValueType tlv : tlvs) {
             switch (tlv.getType()) {
@@ -501,20 +502,33 @@
                 //will get in bits/second , convert to MBPS to store in network config service
                 maxReservableBw = maxReservableBw / 1000000;
                 break;
+            case LinkStateAttributes.ATTR_LINK_UNRES_BANDWIDTH:
+                unreservedBw = ((BgpLinkAttrUnRsrvdLinkBandwidth) tlv).getLinkAttrUnRsrvdLinkBandwidth();
+                break;
+            case LinkStateAttributes.ATTR_LINK_TE_DEFAULT_METRIC:
+                teMetric = ((BgpLinkAttrTeDefaultMetric) tlv).attrLinkDefTeMetric();
+                break;
+            case LinkStateAttributes.ATTR_LINK_IGP_METRIC:
+                igpMetric = ((BgpLinkAttrIgpMetric) tlv).attrLinkIgpMetric();
+                break;
             default: // do nothing
             }
         }
 
-        if (maxReservableBw == 0.0) {
-            return;
+        //Configure bandwidth for src and dst port
+        TeLinkConfig config = networkConfigService.addConfig(LinkKey.linkKey(linkDes.src(), linkDes.dst()),
+                                                             TeLinkConfig.class);
+        Double bw = 0.0;
+        if (unreservedBw.size() > 0) {
+            bw = unreservedBw.get(0).doubleValue(); //Low priority
         }
 
-        //Configure bandwidth for src and dst port
-        BandwidthCapacity config = networkConfigService.addConfig(linkDes.src(), BandwidthCapacity.class);
-        config.capacity(Bandwidth.bps(maxReservableBw)).apply();
+        config.maxResvBandwidth(maxReservableBw)
+                .unResvBandwidth(bw).teCost(teMetric).igpCost(igpMetric);
+                //.apply();
 
-        config = networkConfigService.addConfig(linkDes.dst(), BandwidthCapacity.class);
-        config.capacity(Bandwidth.bps(maxReservableBw)).apply();
+        networkConfigService.applyConfig(LinkKey.linkKey(linkDes.src(),
+                linkDes.dst()), TeLinkConfig.class, config.node());
     }
 
     private DefaultAnnotations.Builder getAnnotations(DefaultAnnotations.Builder annotationBuilder, boolean isNode,
@@ -529,8 +543,6 @@
         boolean abrBit = false;
         boolean externalBit = false;
         boolean pseudo = false;
-        int igpMetric = 0;
-        int teMetric = 0;
         byte[] areaId = null;
         Ip4Address routerId = null;
         for (BgpValueType tlv : tlvs) {
@@ -550,12 +562,6 @@
             case LinkStateAttributes.ATTR_NODE_IPV4_LOCAL_ROUTER_ID:
                 routerId = ((BgpAttrRouterIdV4) tlv).attrRouterId();
                 break;
-            case LinkStateAttributes.ATTR_LINK_IGP_METRIC:
-                igpMetric = ((BgpLinkAttrIgpMetric) tlv).attrLinkIgpMetric();
-                break;
-            case LinkStateAttributes.ATTR_LINK_TE_DEFAULT_METRIC:
-                teMetric = ((BgpLinkAttrTeDefaultMetric) tlv).attrLinkDefTeMetric();
-                break;
             default: // do nothing
             }
         }
@@ -579,15 +585,6 @@
                 // LsrID
                 annotationBuilder.set(LSRID, String.valueOf(routerId));
             }
-        } else {
-            // Annotations for link
-            if (igpMetric != 0) {
-                annotationBuilder.set(COST, String.valueOf(igpMetric));
-            }
-
-            if (teMetric != 0) {
-                annotationBuilder.set(TE_COST, String.valueOf(teMetric));
-            }
         }
         return annotationBuilder;
     }
diff --git a/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java b/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java
index 9e1992e..babe926 100644
--- a/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java
+++ b/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java
@@ -12,22 +12,10 @@
  */
 package org.onosproject.provider.bgp.topology.impl;
 
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.Is.is;
-import static org.hamcrest.core.IsNot.not;
-import static org.onosproject.net.Link.State.ACTIVE;
-import static org.onosproject.net.MastershipRole.MASTER;
-import static org.hamcrest.Matchers.nullValue;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArraySet;
-
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -35,7 +23,6 @@
 import org.onlab.junit.TestUtils.TestUtilsException;
 import org.onlab.packet.ChassisId;
 import org.onlab.packet.Ip4Address;
-import org.onlab.util.Bandwidth;
 import org.onosproject.bgp.controller.BgpLinkListener;
 import org.onosproject.bgp.controller.BgpNodeListener;
 import org.onosproject.bgpio.exceptions.BgpParseException;
@@ -49,13 +36,8 @@
 import org.onosproject.bgpio.types.AutonomousSystemTlv;
 import org.onosproject.bgpio.types.BgpValueType;
 import org.onosproject.bgpio.types.IsIsNonPseudonode;
-import org.onosproject.bgpio.types.LinkStateAttributes;
-import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
-import org.onosproject.incubator.net.resource.label.LabelResourceId;
-import org.onosproject.incubator.net.resource.label.LabelResourcePool;
-import org.onosproject.mastership.MastershipServiceAdapter;
-import org.onosproject.net.link.LinkServiceAdapter;
 import org.onosproject.bgpio.types.LinkLocalRemoteIdentifiersTlv;
+import org.onosproject.bgpio.types.LinkStateAttributes;
 import org.onosproject.bgpio.types.RouteDistinguisher;
 import org.onosproject.bgpio.types.attr.BgpAttrNodeFlagBitTlv;
 import org.onosproject.bgpio.types.attr.BgpAttrNodeIsIsAreaId;
@@ -65,6 +47,10 @@
 import org.onosproject.bgpio.types.attr.BgpLinkAttrTeDefaultMetric;
 import org.onosproject.bgpio.util.Constants;
 import org.onosproject.cluster.NodeId;
+import org.onosproject.incubator.net.resource.label.LabelResourceAdminService;
+import org.onosproject.incubator.net.resource.label.LabelResourceId;
+import org.onosproject.incubator.net.resource.label.LabelResourcePool;
+import org.onosproject.mastership.MastershipServiceAdapter;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DefaultAnnotations;
 import org.onosproject.net.DefaultDevice;
@@ -72,12 +58,14 @@
 import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Link;
+import org.onosproject.net.LinkKey;
 import org.onosproject.net.MastershipRole;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.config.Config;
 import org.onosproject.net.config.ConfigApplyDelegate;
 import org.onosproject.net.config.ConfigFactory;
 import org.onosproject.net.config.NetworkConfigRegistryAdapter;
+import org.onosproject.net.config.basics.BandwidthCapacity;
 import org.onosproject.net.device.DeviceDescription;
 import org.onosproject.net.device.DeviceEvent;
 import org.onosproject.net.device.DeviceListener;
@@ -91,16 +79,28 @@
 import org.onosproject.net.link.LinkProvider;
 import org.onosproject.net.link.LinkProviderRegistry;
 import org.onosproject.net.link.LinkProviderService;
+import org.onosproject.net.link.LinkServiceAdapter;
 import org.onosproject.net.provider.ProviderId;
-import org.onosproject.net.config.basics.BandwidthCapacity;
 import org.onosproject.net.resource.Resource;
 import org.onosproject.net.resource.ResourceAdminService;
 import org.onosproject.net.resource.ResourceId;
+import org.onosproject.pcep.api.TeLinkConfig;
 
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.JsonNodeFactory;
-import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.nullValue;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNot.not;
+import static org.onosproject.net.Link.State.ACTIVE;
+import static org.onosproject.net.MastershipRole.MASTER;
 
 /**
  * Test for BGP topology provider.
@@ -201,6 +201,11 @@
     private class MockNetConfigRegistryAdapter extends NetworkConfigRegistryAdapter {
         private ConfigFactory cfgFactory;
         private Map<ConnectPoint, BandwidthCapacity> classConfig = new HashMap<>();
+        private Map<LinkKey, TeLinkConfig> teLinkConfig = new HashMap<>();
+
+        public Map<LinkKey, TeLinkConfig> getTeLinkConfig() {
+            return teLinkConfig;
+        }
 
         @Override
         public void registerConfigFactory(ConfigFactory configFactory) {
@@ -223,6 +228,15 @@
                 ConfigApplyDelegate delegate = new InternalApplyDelegate();
                 devCap.init((ConnectPoint) subject, null, node, mapper, delegate);
                 return (C) devCap;
+            } else if (configClass == TeLinkConfig.class) {
+                TeLinkConfig linkConfig = new TeLinkConfig();
+                teLinkConfig.put((LinkKey) subject, linkConfig);
+
+                JsonNode node = new ObjectNode(new MockJsonNode());
+                ObjectMapper mapper = new ObjectMapper();
+                ConfigApplyDelegate delegate = new InternalApplyDelegate();
+                linkConfig.init((LinkKey) subject, null, node, mapper, delegate);
+                return (C) linkConfig;
             }
 
             return null;
@@ -230,13 +244,19 @@
 
         @Override
         public <S, C extends Config<S>> void removeConfig(S subject, Class<C> configClass) {
-            classConfig.remove(subject);
+            if (configClass == BandwidthCapacity.class) {
+                classConfig.remove(subject);
+            } else if (configClass == TeLinkConfig.class) {
+                teLinkConfig.remove(subject);
+            }
         }
 
         @Override
         public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
             if (configClass == BandwidthCapacity.class) {
                 return (C) classConfig.get(subject);
+            } else if (configClass == TeLinkConfig.class) {
+                return (C) teLinkConfig.get(subject);
             }
             return null;
         }
@@ -387,7 +407,7 @@
     /* Class implement device test registry */
     private class TestLinkRegistry implements LinkProviderRegistry {
         LinkProvider linkProvider;
-        Set<Link> links = new HashSet<>();
+        LinkedList<Link> links = new LinkedList<>();
 
         @Override
         public LinkProviderService register(LinkProvider provider) {
@@ -790,10 +810,11 @@
         for (BgpLinkListener l : controller.linkListener) {
             l.addLink(linkNlri, details);
             assertThat(linkRegistry.links.size(), is(1));
-            assertThat(linkRegistry.links.iterator().next().annotations().value(BgpTopologyProvider.COST),
-                    is("10"));
-            assertThat(linkRegistry.links.iterator().next().annotations().value(BgpTopologyProvider.TE_COST),
-                    is("20"));
+            TeLinkConfig config = networkConfigService.getTeLinkConfig().get(LinkKey.linkKey(linkRegistry.links
+                            .getFirst().src(), linkRegistry.links.getLast().dst()));
+
+            assertThat(config.igpCost(), is(10));
+            assertThat(config.teCost(), is(20));
 
             l.deleteLink(linkNlri);
             assertThat(linkRegistry.links.size(), is(0));
@@ -1030,11 +1051,13 @@
 
         for (BgpLinkListener l : controller.linkListener) {
             l.addLink(linkNlri, details);
+            LinkKey linkKey = LinkKey.linkKey(linkRegistry.links.getFirst().src(),
+                    linkRegistry.links.getLast().dst());
             assertThat(linkRegistry.links.size(), is(1));
-            assertThat(linkRegistry.links.iterator().next().annotations().value(BgpTopologyProvider.COST),
-                    is("10"));
-            assertThat(linkRegistry.links.iterator().next().annotations().value(BgpTopologyProvider.TE_COST),
-                    is("20"));
+            TeLinkConfig config = networkConfigService.getTeLinkConfig().get(linkKey);
+
+            assertThat(config.igpCost(), is(10));
+            assertThat(config.teCost(), is(20));
 
             ConnectPoint src = new ConnectPoint(
                     DeviceId.deviceId("l3:rd=0::routinguniverse=0:asn=10:isoid=1414.1414.0014"),
@@ -1042,18 +1065,13 @@
             ConnectPoint dst = new ConnectPoint(
                     DeviceId.deviceId("l3:rd=0::routinguniverse=0:asn=10:isoid=1e1e.1e1e.001e"),
                     PortNumber.portNumber(4294967396L));
-            BandwidthCapacity bandwidth = networkConfigService.getConfig(src, BandwidthCapacity.class);
-            assertThat(bandwidth.capacity().bps(), is(70.0 * 1_000_000L));
 
-            bandwidth = networkConfigService.getConfig(dst, BandwidthCapacity.class);
-            assertThat(bandwidth.capacity(), is(Bandwidth.bps(70.0 * 1_000_000L)));
+            assertThat(config.maxResvBandwidth(), is(70.0));
 
             l.deleteLink(linkNlri);
             assertThat(linkRegistry.links.size(), is(0));
-            bandwidth = networkConfigService.getConfig(src, BandwidthCapacity.class);
-            assertThat(bandwidth, is(nullValue()));
-            bandwidth = networkConfigService.getConfig(dst, BandwidthCapacity.class);
-            assertThat(bandwidth, is(nullValue()));
+            config = networkConfigService.getTeLinkConfig().get(linkKey);
+            assertThat(config, is(nullValue()));
         }
     }
 }