[ONOS-4880][ONOS-5021]IETF TE Topology Provider

The provider introduces IETF TE Topology YANG models and interacts with RESTCONF
client and YMS to provide IETF TE Topology to TE Topology Core subsystem.

This issue implements the interaction with RESTCONF client to obtain network topology
in JSON from south bound.

Change-Id: If203a98db69a516c8b09cb9247724e49a95abe4f
diff --git a/providers/ietfte/topology/app.xml b/providers/ietfte/topology/app.xml
new file mode 100644
index 0000000..d38fac4
--- /dev/null
+++ b/providers/ietfte/topology/app.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2016-present Open Networking Laboratory
+  ~
+  ~ 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.
+  -->
+<app name="org.onosproject.teprovider.topology" origin="HUAWEI" version="${project.version}"
+     category="Provider" title="RESTCONF TE Topology Provider"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/onos-app-tenbi-yangmodel/${project.version}</artifact>    
+</app>
diff --git a/providers/ietfte/topology/features.xml b/providers/ietfte/topology/features.xml
new file mode 100644
index 0000000..b6f1008
--- /dev/null
+++ b/providers/ietfte/topology/features.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ~ Copyright 2016-present Open Networking Laboratory
+  ~
+  ~ 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.
+  -->
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
+    <repository>mvn:${project.groupId}/onos-app-tenbi-yangmodel/${project.version}/xml/features</repository>
+    <feature name="${project.artifactId}" version="${project.version}"
+             description="${project.description}">
+        <feature>onos-api</feature>
+        <feature>onos-app-tenbi-yangmodel</feature>
+        <bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-restsb-api/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-restsb-ctl/${project.version}</bundle>
+        <bundle>mvn:org.glassfish.jersey.core/jersey-client/2.22.2</bundle>
+        <bundle>mvn:commons-io/commons-io/2.4</bundle>
+        <bundle>mvn:org.apache.httpcomponents/httpclient-osgi/4.5.1</bundle>
+        <bundle>mvn:org.apache.httpcomponents/httpcore-osgi/4.4.4</bundle>
+        <bundle>mvn:${project.groupId}/onos-app-tetopology/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-app-yms-api/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-app-tenbi-utils/${project.version}</bundle>
+    </feature>
+</features>
+
diff --git a/providers/ietfte/topology/pom.xml b/providers/ietfte/topology/pom.xml
new file mode 100644
index 0000000..d8621d1
--- /dev/null
+++ b/providers/ietfte/topology/pom.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2016-present Open Networking Laboratory
+  ~
+  ~ 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>onos-ietfte-providers</artifactId>
+        <groupId>org.onosproject</groupId>
+        <version>1.8.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>onos-ietfte-provider-topology</artifactId>
+    <packaging>bundle</packaging>
+
+    <description>IETF TE topology southbound provider</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-restconf-client-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-restconf-client-ctl</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+        	<groupId>org.onosproject</groupId>
+        	<artifactId>onos-app-tetopology</artifactId>
+        	<version>${project.version}</version>
+        </dependency>
+         <dependency>
+        	<groupId>org.onosproject</groupId>
+        	<artifactId>onos-app-tenbi-yangmodel</artifactId>
+        	<version>${project.version}</version>
+        </dependency>
+        <dependency>
+        	<groupId>org.onosproject</groupId>
+        	<artifactId>onos-app-tenbi-utils</artifactId>
+        	<version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-yms-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-restconf-server-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/providers/ietfte/topology/src/main/java/org/onosproject/provider/te/topology/JsonYdtCodec.java b/providers/ietfte/topology/src/main/java/org/onosproject/provider/te/topology/JsonYdtCodec.java
new file mode 100644
index 0000000..1cb17f5
--- /dev/null
+++ b/providers/ietfte/topology/src/main/java/org/onosproject/provider/te/topology/JsonYdtCodec.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * 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.provider.te.topology;
+
+import static org.onosproject.yms.ydt.YdtContextOperationType.NONE;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.onosproject.protocol.restconf.server.utils.parser.json.ParserUtils;
+import org.onosproject.yms.ych.YangCompositeEncoding;
+import org.onosproject.yms.ych.YangDataTreeCodec;
+import org.onosproject.yms.ydt.YdtBuilder;
+import org.onosproject.yms.ydt.YmsOperationType;
+import org.onosproject.yms.ymsm.YmsService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+
+/**
+ * JSON/YDT Codec implementation.
+ */
+public class JsonYdtCodec implements YangDataTreeCodec {
+    private static final String RESTCONF_ROOT = "restconf/data";
+
+    protected final YmsService ymsService;
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    public JsonYdtCodec(YmsService service) {
+        ymsService = service;
+    }
+
+    @Override
+    public String encodeYdtToProtocolFormat(YdtBuilder builder,
+                                            YmsOperationType opType) {
+        String json = ParserUtils.convertYdtToJson(builder.getRootNode().getName(),
+                                                   builder.getRootNode(),
+                                                   ymsService.getYdtWalker())
+                                 .textValue();
+        return json;
+     }
+
+    @Override
+    public YangCompositeEncoding encodeYdtToCompositeProtocolFormat(YdtBuilder builder,
+                                                                    YmsOperationType opType) {
+        // Mainly for POST/PUT operation.
+        // YdtBuilder/YdtContext has YdtContextType NONE for URI,
+        // YdtContextType CREATE/MERGE/REPLACE for Resource data.
+
+        // TODO: Implement this method in Release Ibis for TE Tunnel.
+
+        return null;
+    }
+
+    @Override
+    public YdtBuilder decodeProtocolDataToYdt(String protocolData,
+                                              Object schemaRegistryForYdt,
+                                              YmsOperationType opType) {
+        // Get a new builder
+        YdtBuilder builder = ymsService.getYdtBuilder(RESTCONF_ROOT,
+                                                      null,
+                                                      opType,
+                                                      schemaRegistryForYdt);
+        ParserUtils.convertJsonToYdt(getObjectNode(protocolData), builder);
+        return builder;
+    }
+
+    @Override
+    public YdtBuilder decodeCompositeProtocolDataToYdt(YangCompositeEncoding protocolData,
+                                                       Object schemaRegistryForYdt,
+                                                       YmsOperationType opType) {
+        // opType should be QUERY_REPLY
+        // Get a new builder
+        YdtBuilder builder = ymsService.getYdtBuilder(RESTCONF_ROOT,
+                                                      null,
+                                                      opType,
+                                                      schemaRegistryForYdt);
+        // Convert the URI to ydtBuilder
+
+        // YdtContextOperationType should be NONE for URI in QUERY_RESPONSE.
+        ParserUtils.convertUriToYdt(protocolData.getResourceIdentifier(), builder, NONE);
+        // Set default operation type for the payload node, is this for resource data?
+        // NULL/EMPTY for Resource data
+        builder.setDefaultEditOperationType(null);
+
+        // Convert the payload json body to ydt
+        ParserUtils.convertJsonToYdt(getObjectNode(protocolData.getResourceInformation()), builder);
+        return builder;
+    }
+
+    // Returns an ObjectNode from s JSON string.
+    private ObjectNode getObjectNode(String json) {
+        InputStream stream = IOUtils.toInputStream(json);
+
+        ObjectNode rootNode;
+        ObjectMapper mapper = new ObjectMapper();
+        try {
+            rootNode = (ObjectNode) mapper.readTree(stream);
+        } catch (IOException e) {
+            log.error("Can't read stream as a JSON ObjectNode: {}", e);
+            return null;
+        }
+        return rootNode;
+    }
+
+}
diff --git a/providers/ietfte/topology/src/main/java/org/onosproject/provider/te/topology/RestconfServerConfig.java b/providers/ietfte/topology/src/main/java/org/onosproject/provider/te/topology/RestconfServerConfig.java
new file mode 100644
index 0000000..2b25358
--- /dev/null
+++ b/providers/ietfte/topology/src/main/java/org/onosproject/provider/te/topology/RestconfServerConfig.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * 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.provider.te.topology;
+
+import java.util.Set;
+
+import org.onlab.packet.IpAddress;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.incubator.net.config.basics.ConfigException;
+import org.onosproject.net.config.Config;
+import org.onosproject.protocol.rest.DefaultRestSBDevice;
+import org.onosproject.protocol.rest.RestSBDevice;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.Sets;
+
+/**
+ * Configuration for Restconf Server.
+ */
+public class RestconfServerConfig extends Config<ApplicationId> {
+    private static final String CONFIG_VALUE_ERROR = "Error parsing config value";
+    private static final String IP = "ip";
+    private static final int DEFAULT_HTTP_PORT = 80;
+    private static final String PORT = "port";
+    private static final String USERNAME = "username";
+    private static final String PASSWORD = "password";
+    private static final String PROTOCOL = "protocol";
+    private static final String URL = "url";
+
+    /**
+     * Returns the device addresses from JSON.
+     *
+     * @return A set of RESTCONF Server devices
+     * @throws ConfigException if there is a configuration error
+     */
+    public Set<RestSBDevice> getDevicesAddresses() throws ConfigException {
+        Set<RestSBDevice> devicesAddresses = Sets.newHashSet();
+
+        try {
+            for (JsonNode node : array) {
+                String ip = node.path(IP).asText();
+                IpAddress ipAddr = ip.isEmpty() ? null : IpAddress.valueOf(ip);
+                int port = node.path(PORT).asInt(DEFAULT_HTTP_PORT);
+                String username = node.path(USERNAME).asText();
+                String password = node.path(PASSWORD).asText();
+                String protocol = node.path(PROTOCOL).asText();
+                String url = node.path(URL).asText();
+                devicesAddresses.add(new DefaultRestSBDevice(ipAddr, port, username,
+                                                             password, protocol,
+                                                             url, false));
+
+            }
+        } catch (IllegalArgumentException e) {
+            throw new ConfigException(CONFIG_VALUE_ERROR, e);
+        }
+
+        return devicesAddresses;
+    }
+
+}
diff --git a/providers/ietfte/topology/src/main/java/org/onosproject/provider/te/topology/TeTopologyRestconfProvider.java b/providers/ietfte/topology/src/main/java/org/onosproject/provider/te/topology/TeTopologyRestconfProvider.java
new file mode 100644
index 0000000..b19795e
--- /dev/null
+++ b/providers/ietfte/topology/src/main/java/org/onosproject/provider/te/topology/TeTopologyRestconfProvider.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * 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.provider.te.topology;
+
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_ADDED;
+import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_UPDATED;
+import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.apache.commons.io.IOUtils;
+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.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.config.basics.ConfigException;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.device.DeviceProviderRegistry;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.protocol.rest.RestSBDevice;
+import org.onosproject.protocol.restconf.RestConfSBController;
+import org.onosproject.tetopology.management.api.TeTopologyProvider;
+import org.onosproject.tetopology.management.api.TeTopologyProviderRegistry;
+import org.onosproject.tetopology.management.api.TeTopologyProviderService;
+import org.onosproject.teyang.utils.topology.NetworkConverter;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208.IetfNetwork;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208.ietfnetwork.networks.Network;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208.IetfNetworkTopology;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20160708.IetfTeTopology;
+import org.onosproject.yms.ych.YangCodecHandler;
+import org.onosproject.yms.ych.YangProtocolEncodingFormat;
+import org.onosproject.yms.ych.YangResourceIdentifierType;
+import org.onosproject.yms.ydt.YmsOperationType;
+import org.onosproject.yms.ymsm.YmsService;
+import org.slf4j.Logger;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * Provider for IETF TE Topology that use RESTCONF as means of communication.
+ */
+@Component(immediate = true)
+public class TeTopologyRestconfProvider extends AbstractProvider
+        implements TeTopologyProvider {
+    private static final String APP_NAME = "org.onosproject.teprovider.topology";
+    private static final String RESTCONF = "restconf";
+    private static final String PROVIDER = "org.onosproject.teprovider.restconf.domain";
+    private static final String IETF_NETWORK_URI = "ietf-network:networks";
+    private static final String IETF_NETWORKS_PREFIX_TO_BE_REMOVED = "{\"networks\":";
+    private static final String IETF_NOTIFICATION_URI = "/streams/NETCONF";
+    private static final String JSON = "json";
+    private static final String E_DEVICE_NULL = "Restconf device is null";
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceProviderRegistry deviceProviderRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected TeTopologyProviderRegistry topologyProviderRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected RestConfSBController restconfClient;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry cfgService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected YmsService ymsService;
+
+    private YangCodecHandler codecHandler;
+
+    private TeTopologyProviderService topologyProviderService;
+
+    private final ExecutorService executor =
+            Executors.newFixedThreadPool(5, groupedThreads("onos/restconfsbprovider",
+                                               "device-installer-%d", log));
+
+    private final ConfigFactory<ApplicationId, RestconfServerConfig> factory =
+            new ConfigFactory<ApplicationId, RestconfServerConfig>(APP_SUBJECT_FACTORY,
+                                                                   RestconfServerConfig.class,
+                                                                   "restconfDevices",
+                                                                   true) {
+                @Override
+                public RestconfServerConfig createConfig() {
+                    return new RestconfServerConfig();
+                }
+            };
+
+    private final NetworkConfigListener cfgLister = new InternalNetworkConfigListener();
+    private ApplicationId appId;
+
+    private Set<DeviceId> addedDevices = new HashSet<>();
+
+    @Activate
+    public void activate() {
+        // Get the codec handler.
+        codecHandler = ymsService.getYangCodecHandler();
+        // Register all three IETF Topology YANG model schema with YMS.
+        codecHandler.addDeviceSchema(IetfNetwork.class);
+        codecHandler.addDeviceSchema(IetfNetworkTopology.class);
+        codecHandler.addDeviceSchema(IetfTeTopology.class);
+        // Register JSON CODEC functions
+        codecHandler.registerOverriddenCodec(new JsonYdtCodec(ymsService),
+                                             YangProtocolEncodingFormat.JSON_ENCODING);
+
+        appId = coreService.registerApplication(APP_NAME);
+        topologyProviderService = topologyProviderRegistry.register(this);
+        cfgService.registerConfigFactory(factory);
+        cfgService.addListener(cfgLister);
+        executor.execute(TeTopologyRestconfProvider.this::connectDevices);
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        cfgService.removeListener(cfgLister);
+        restconfClient.getDevices().keySet().forEach(this::deviceRemoved);
+        topologyProviderRegistry.unregister(this);
+        cfgService.unregisterConfigFactory(factory);
+        log.info("Stopped");
+    }
+
+    /**
+     * Creates an instance of TeTopologyRestconf provider.
+     */
+    public TeTopologyRestconfProvider() {
+        super(new ProviderId(RESTCONF, PROVIDER));
+    }
+
+    private void deviceAdded(RestSBDevice nodeId) {
+        Preconditions.checkNotNull(nodeId, E_DEVICE_NULL);
+        nodeId.setActive(true);
+        addedDevices.add(nodeId.deviceId());
+    }
+
+    private void deviceRemoved(DeviceId deviceId) {
+        Preconditions.checkNotNull(deviceId, E_DEVICE_NULL);
+        restconfClient.removeDevice(deviceId);
+    }
+
+    private void connectDevices() {
+
+        RestconfServerConfig cfg = cfgService.getConfig(appId, RestconfServerConfig.class);
+        try {
+            if (cfg != null && cfg.getDevicesAddresses() != null) {
+                //Precomputing the devices to be removed
+                Set<RestSBDevice> toBeRemoved = new HashSet<>(restconfClient.getDevices().values());
+                toBeRemoved.removeAll(cfg.getDevicesAddresses());
+                //Adding new devices
+                for (RestSBDevice device : cfg.getDevicesAddresses()) {
+                    device.setActive(false);
+                    restconfClient.addDevice(device);
+                    deviceAdded(device);
+                }
+
+                //Removing devices not wanted anymore
+                toBeRemoved.forEach(device -> deviceRemoved(device.deviceId()));
+            }
+        } catch (ConfigException e) {
+            log.error("Configuration error {}", e);
+        }
+
+        // Discover the topology from RESTCONF server
+        addedDevices.forEach(this::retrieveTopology);
+        addedDevices.clear();
+    }
+
+    private void retrieveTopology(DeviceId deviceId) {
+        // Retrieve IETF Network at top level.
+        InputStream jsonStream = restconfClient.get(deviceId, IETF_NETWORK_URI, JSON);
+        if (jsonStream == null) {
+            log.warn("Unable to retrieve network Topology from restconf server {}", deviceId);
+            return;
+        }
+
+        // Need to convert Input stream to String.
+        StringWriter writer = new StringWriter();
+        try {
+            IOUtils.copy(jsonStream, writer, StandardCharsets.UTF_8);
+        } catch (IOException e) {
+            log.warn("There is an exception {} for copy jsonStream to stringWriter for restconf {}",
+                     e.getMessage(), deviceId);
+            return;
+        }
+        String jsonString = writer.toString();
+        String networkLevelJsonString = getNetworkLevelJsonResponse(jsonString);
+
+        YangCompositeEncodingImpl yce = new YangCompositeEncodingImpl(YangResourceIdentifierType.URI,
+                                                                      IETF_NETWORK_URI,
+                                                                      networkLevelJsonString);
+
+        Object yo = codecHandler.decode(yce,
+                                        YangProtocolEncodingFormat.JSON_ENCODING,
+                                        YmsOperationType.QUERY_REPLY);
+
+        if ((yo == null)) {
+            log.error("YMS decoder returns {} for restconf {}", yo, deviceId);
+            return;
+        }
+
+        // YMS returns an ArrayList in a single Object (i.e. yo in this case)
+        // this means yo is actually an ArrayList of size 1
+        IetfNetwork ietfNetwork = ((List<IetfNetwork>) yo).get(0);
+
+        if (ietfNetwork.networks() != null &&
+                ietfNetwork.networks().network() != null) {
+            //Convert the YO to TE Core data and update TE Core.
+            for (Network nw : ietfNetwork.networks().network()) {
+                topologyProviderService.networkUpdated(
+                        NetworkConverter.yang2TeSubsystemNetwork(nw));
+            }
+        }
+
+        //TODO: Uncomment when YMS fixes the issue in NetworkState translation (network-ref)
+//        org.onosproject.tetopology.management.api.Networks networks =
+//                NetworkConverter.yang2TeSubsystemNetworks(ietfNetwork.networks(),
+//                                                          ietfNetwork.networksState());
+//        if (networks == null || networks.networks() == null) {
+//            log.error("Yang2Te returns null for restconf {}", deviceId);
+//            return;
+//        }
+//        for (org.onosproject.tetopology.management.api.Network network : networks.networks()) {
+//            topologyProviderService.networkUpdated(network);
+//        }
+
+        //TODO: Uncomment when the RESTCONF server and the RESTCONF client
+        //      both fully support notifications in Ibis Release
+//        RestConfNotificationEventListener callBackListener = new RestConfNotificationEventListenerImpl();
+//        restconfClient.enableNotifications(deviceId, IETF_NOTIFICATION_URI, JSON, callBackListener);
+    }
+
+    private String getNetworkLevelJsonResponse(String jsonString) {
+        if (jsonString.startsWith(IETF_NETWORKS_PREFIX_TO_BE_REMOVED)) {
+            log.debug("The retrieved JSON body from the RESTCONF server is in "
+                    + "networks level -- going to remove it from networks container");
+            return jsonString.substring(IETF_NETWORKS_PREFIX_TO_BE_REMOVED.length(), jsonString.length() - 1);
+        }
+        log.debug("The retrieved JSON body from the RESTCONF server is not in "
+                + "networks level -- nothing to be removed");
+        return jsonString;
+    }
+
+    //TODO: Uncomment when the RESTCONF server and the RESTCONF client
+    //      both fully support notifications in Ibis release
+//    private class RestConfNotificationEventListenerImpl implements RestConfNotificationEventListener {
+//
+//        @Override
+//        public <T> void handleNotificationEvent(DeviceId deviceId,
+//                                                T eventJsonString) {
+//            // TODO: handle the event properly once the RESTCONF server fully supports
+//            // notifications in Ibis release.
+//            log.debug("a new notification: {} is received for device {}", eventJsonString, deviceId.toString());
+//        }
+//    }
+
+    private class InternalNetworkConfigListener implements NetworkConfigListener {
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+            executor.execute(TeTopologyRestconfProvider.this::connectDevices);
+        }
+
+        @Override
+        public boolean isRelevant(NetworkConfigEvent event) {
+            return event.configClass().equals(RestconfServerConfig.class) &&
+                    (event.type() == CONFIG_ADDED ||
+                            event.type() == CONFIG_UPDATED);
+        }
+    }
+
+}
diff --git a/providers/ietfte/topology/src/main/java/org/onosproject/provider/te/topology/YangCompositeEncodingImpl.java b/providers/ietfte/topology/src/main/java/org/onosproject/provider/te/topology/YangCompositeEncodingImpl.java
new file mode 100644
index 0000000..3597536
--- /dev/null
+++ b/providers/ietfte/topology/src/main/java/org/onosproject/provider/te/topology/YangCompositeEncodingImpl.java
@@ -0,0 +1,56 @@
+package org.onosproject.provider.te.topology;
+
+import org.onosproject.yms.ych.YangCompositeEncoding;
+import org.onosproject.yms.ych.YangResourceIdentifierType;
+
+/**
+ * Represents implementation of YangCompositeEncoding interfaces.
+ */
+public class YangCompositeEncodingImpl implements YangCompositeEncoding {
+
+    /**
+     * Resource identifier for composite encoding.
+     */
+    private final String resourceIdentifier;
+
+    /**
+     * Resource information for composite encoding.
+     */
+    private final String resourceInformation;
+
+    /**
+     * Resource identifier type.
+     */
+    public final YangResourceIdentifierType resourceIdentifierType;
+
+    /**
+     * Creates an instance of YangCompositeEncodingImpl.
+     *
+     * @param resourceIdentifierType is URI
+     * @param resourceIdentifier is the URI string
+     * @param resourceInformation is the JSON body string
+     */
+    public YangCompositeEncodingImpl(YangResourceIdentifierType resourceIdentifierType,
+                                     String resourceIdentifier,
+                                     String resourceInformation) {
+        this.resourceIdentifierType = resourceIdentifierType;
+        this.resourceIdentifier = resourceIdentifier;
+        this.resourceInformation = resourceInformation;
+    }
+
+    @Override
+    public String getResourceIdentifier() {
+        return resourceIdentifier;
+    }
+
+    @Override
+    public YangResourceIdentifierType getResourceIdentifierType() {
+        return resourceIdentifierType;
+    }
+
+    @Override
+    public String getResourceInformation() {
+        return resourceInformation;
+    }
+}
+
diff --git a/providers/ietfte/topology/src/main/java/org/onosproject/provider/te/topology/package-info.java b/providers/ietfte/topology/src/main/java/org/onosproject/provider/te/topology/package-info.java
new file mode 100644
index 0000000..91cf72b
--- /dev/null
+++ b/providers/ietfte/topology/src/main/java/org/onosproject/provider/te/topology/package-info.java
@@ -0,0 +1,19 @@
+/**
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * 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.
+ */
+/**
+ * IETF TE Topology provider implementation using RESTCONF protocol.
+ */
+package org.onosproject.provider.te.topology;