diff --git a/global/app/app.xml b/global/app/app.xml
new file mode 100644
index 0000000..37f2a35
--- /dev/null
+++ b/global/app/app.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ Copyright 2017-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.
+  -->
+<app name="org.opencord.ce.global.app" origin="ON.Lab" version="${project.version}"
+     category="Utility" url="http://opencord.org" title="Enterprise CORD"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/orchestration/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/global-channel/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/virtualprovider/${project.version}</artifact>
+    <!--   <artifact>mvn:${project.groupId}/onos-app-icona-driver/${project.version}</artifact> -->
+</app>
diff --git a/global/app/features.xml b/global/app/features.xml
new file mode 100644
index 0000000..bcc7471
--- /dev/null
+++ b/global/app/features.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+
+<!--
+  ~ Copyright 2017-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.
+  -->
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
+    <feature name="${project.artifactId}" version="${project.version}"
+             description="${project.description}">
+        <bundle>mvn:${project.groupId}/orchestration/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/global-channel/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/virtualprovider/${project.version}</bundle>
+        <!--  <bundle>mvn:${project.groupId}/onos-app-icona-driver/${project.version}</bundle> -->
+    </feature>
+</features>
\ No newline at end of file
diff --git a/global/app/pom.xml b/global/app/pom.xml
new file mode 100644
index 0000000..0c6f282
--- /dev/null
+++ b/global/app/pom.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2017-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.
+  -->
+<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/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opencord.ce</groupId>
+        <artifactId>global</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>ecord-global-app</artifactId>
+    <packaging>pom</packaging>
+    <version>1.0.0-SNAPSHOT</version>
+
+    <description>Java application bundling orchestration,
+        HTTP communication and topology provider component
+    </description>
+
+    <properties>
+        <onos.app.name>org.opencord.ce.global</onos.app.name>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.opencord.ce</groupId>
+            <artifactId>orchestration</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opencord.ce</groupId>
+            <artifactId>global-channel</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opencord.ce</groupId>
+            <artifactId>virtualprovider</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/global/ce-orchestration/pom.xml b/global/ce-orchestration/pom.xml
new file mode 100644
index 0000000..fb2ed3c
--- /dev/null
+++ b/global/ce-orchestration/pom.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2015-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.
+  -->
+<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">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opencord.ce</groupId>
+        <artifactId>global</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>orchestration</artifactId>
+    <packaging>bundle</packaging>
+
+    <description>Orchestration logic of Carrier Ethernet Forwarding Constructs</description>
+
+    <properties>
+        <web.context>/carrierethernet</web.context>
+        <onos.app.name>org.opencord.ce.global.orchestration</onos.app.name>
+        <onos.version>1.10.6</onos.version>
+        <onos.app.url>http://opencord.org</onos.app.url>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+            <version>${onos.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-rest</artifactId>
+            <version>${onos.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-cli</artifactId>
+            <version>${onos.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.shell</groupId>
+            <artifactId>org.apache.karaf.shell.console</artifactId>
+            <version>3.0.5</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <_wab>src/main/webapp/</_wab>
+                        <Bundle-SymbolicName>
+                            ${project.groupId}.${project.artifactId}
+                        </Bundle-SymbolicName>
+                        <Import-Package>
+                            *,org.glassfish.jersey.servlet
+                        </Import-Package>
+                        <Web-ContextPath>${web.context}</Web-ContextPath>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.onosproject</groupId>
+                <artifactId>onos-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+
+    <repositories>
+        <repository>
+            <id>snapshots</id>
+            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+            <releases><enabled>false</enabled></releases>
+        </repository>
+    </repositories>
+
+    <pluginRepositories>
+        <pluginRepository>
+            <id>snapshots</id>
+            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+            <releases><enabled>false</enabled></releases>
+        </pluginRepository>
+    </pluginRepositories>
+
+</project>
diff --git a/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/MetroNetworkProvisioner.java b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/MetroNetworkProvisioner.java
new file mode 100644
index 0000000..99c7c05
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/MetroNetworkProvisioner.java
@@ -0,0 +1,317 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.orchestration;
+
+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.apache.felix.scr.annotations.Service;
+import org.opencord.ce.api.services.channel.ControlChannelListenerService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.topology.PathService;
+import org.onosproject.net.topology.TopologyService;
+import org.opencord.ce.api.models.CarrierEthernetConnection;
+import org.opencord.ce.api.models.CarrierEthernetForwardingConstruct;
+import org.opencord.ce.api.models.CarrierEthernetGenericNi;
+import org.opencord.ce.api.models.CarrierEthernetLogicalTerminationPoint;
+import org.opencord.ce.api.models.CarrierEthernetNetworkInterface;
+import org.opencord.ce.api.models.CarrierEthernetSpanningTreeWeight;
+import org.opencord.ce.api.models.CarrierEthernetUni;
+import org.opencord.ce.api.models.CarrierEthernetVirtualConnection;
+import org.opencord.ce.api.services.MetroNetworkProvisionerService;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
+import static org.slf4j.LoggerFactory.getLogger;
+import static org.opencord.ce.api.models.CarrierEthernetLogicalTerminationPoint.Role;
+import static org.opencord.ce.api.models.CarrierEthernetVirtualConnection.Type;
+
+/**
+ * Carrier Ethernet provisioner of connectivity for forwarding constructs and bandwidth profiles.
+ */
+@Component(immediate = true)
+@Service
+public class MetroNetworkProvisioner implements MetroNetworkProvisionerService {
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PathService pathService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected TopologyService topologyService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ControlChannelListenerService channelListenerService;
+
+    @Activate
+    protected void activate() {
+        log.info("Started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        log.info("Stopped");
+    }
+
+    @Override
+    public void setupConnectivity(CarrierEthernetForwardingConstruct fc) {
+        boolean allPairsConnected = true;
+
+        HashMap<CarrierEthernetNetworkInterface, HashSet<CarrierEthernetNetworkInterface>> ingressEgressNiMap =
+                new HashMap<>();
+
+        // Temporary set for iterating through LTP pairs
+        Set<CarrierEthernetLogicalTerminationPoint> tempLtpSet = new HashSet<>(fc.ltpSet());
+
+        // Temporary set for indicating which LTPs were finally included
+        Set<CarrierEthernetLogicalTerminationPoint> usedLtpSet = new HashSet<>();
+
+        Iterator<CarrierEthernetLogicalTerminationPoint> ltpIt1 = tempLtpSet.iterator();
+        while (ltpIt1.hasNext()) {
+
+            CarrierEthernetLogicalTerminationPoint ltp1 = ltpIt1.next();
+
+            // Iterate through all the remaining NIs
+            Iterator<CarrierEthernetLogicalTerminationPoint> ltpIt2 = tempLtpSet.iterator();
+            while (ltpIt2.hasNext()) {
+
+                CarrierEthernetLogicalTerminationPoint ltp2 = ltpIt2.next();
+
+                // Skip equals
+                if (ltp1.equals(ltp2)) {
+                    continue;
+                }
+
+                // Do not establish connectivity between leaf NIs (applies to Rooted_Multipoint)
+                // FIXME: Use proper LTP roles
+                if (ltp1.role().equals(Role.LEAF)
+                        && ltp2.role().equals(Role.LEAF)) {
+                    continue;
+                }
+
+                // Update the ingress-egress NI map based on the calculated paths
+                if (!updateIngressEgressNiMap(ltp1.ni(), ltp2.ni(), ingressEgressNiMap,
+                        fc.congruentPaths(), fc.type())) {
+                    allPairsConnected = false;
+                    continue;
+                }
+
+                // Indicate that connection for at least one NI pair has been established
+                fc.setState(CarrierEthernetForwardingConstruct.State.ACTIVE);
+
+                // Add NIs to the set of NIs used by the EVC
+                usedLtpSet.add(ltp1);
+                usedLtpSet.add(ltp2);
+            }
+            // Remove NI from temporary set so that each pair is visited only once
+            ltpIt1.remove();
+        }
+
+        // Establish connectivity using the ingressEgressNiMap
+        ingressEgressNiMap.keySet().forEach(srcNi -> {
+            // only the listener that communicates with the domain associated to this fc will
+            // accomplish the request
+            channelListenerService.listeners().forEach(
+                    listener -> listener.setNodeForwarding(fc, srcNi, ingressEgressNiMap.get(srcNi))
+            );
+        });
+
+        // Update the NI set, based on the NIs actually used
+        fc.setLtpSet(usedLtpSet);
+
+        if (fc.isActive()) {
+            if (!allPairsConnected) {
+                fc.setState(CarrierEthernetConnection.State.PARTIAL);
+            }
+        }
+    }
+
+    /**
+     * Select feasible link paths between two NIs in both directions and update
+     * ingressEgressNiMap accordingly.
+     *
+     * @param ni1 the first NI
+     * @param ni2 the second NI
+     * @param ingressEgressNiMap the method will add here any ingress-egress NI associations
+     * @param congruentPaths if true indicates that n1->n2 will follow the same path as n2->n1
+     * @return true if the path was updated and false if a path could not be found in any of the directions
+     */
+    private boolean updateIngressEgressNiMap(CarrierEthernetNetworkInterface ni1, CarrierEthernetNetworkInterface ni2,
+                                             HashMap<CarrierEthernetNetworkInterface,
+                                                     HashSet<CarrierEthernetNetworkInterface>> ingressEgressNiMap,
+                                             boolean congruentPaths, CarrierEthernetVirtualConnection.Type evcType) {
+
+        // Find the paths for both directions at the same time, so that we can skip the pair if needed
+        List<Link> forwardLinks = generateLinkList(ni1.cp(), ni2.cp(), evcType);
+        List<Link> backwardLinks =
+                congruentPaths ? generateInverseLinkList(forwardLinks) : generateLinkList(ni2.cp(), ni1.cp(), evcType);
+
+        // Skip this UNI pair if no feasible path could be found
+        if (forwardLinks == null || (backwardLinks == null)) {
+            log.warn("There are no feasible paths between {} and {}.",
+                    ni1.cp().deviceId(), ni2.cp().deviceId());
+            return false;
+        }
+
+        // Populate the ingress/egress NI map for the forward and backward paths
+        populateIngressEgressNiMap(ni1, ni2, forwardLinks, ingressEgressNiMap);
+        populateIngressEgressNiMap(ni2, ni1, backwardLinks, ingressEgressNiMap);
+
+        return true;
+    }
+
+    private void populateIngressEgressNiMap(CarrierEthernetNetworkInterface srcNi,
+                                            CarrierEthernetNetworkInterface dstNi,
+                                            List<Link> linkList,
+                                            HashMap<CarrierEthernetNetworkInterface,
+                                                    HashSet<CarrierEthernetNetworkInterface>> ingressEgressNiMap
+    ) {
+        // FIXME: Fix the method - avoid generating GENERIC NIs if not needed
+        // Add the src and destination NIs as well as the associated Generic NIs
+        ingressEgressNiMap.putIfAbsent(srcNi, new HashSet<>());
+        // Add last hop entry only if srcNi, dstNi aren't on same device (in which case srcNi, ingressNi would coincide)
+        if (!srcNi.cp().deviceId().equals(dstNi.cp().deviceId())) {
+            // If srcNi, dstNi are not on the same device, create mappings to/from new GENERIC NIs
+            ingressEgressNiMap.get(srcNi).add(new CarrierEthernetGenericNi(linkList.get(1).src(), null));
+            CarrierEthernetGenericNi ingressNi =
+                    new CarrierEthernetGenericNi(linkList.get(linkList.size() - 2).dst(), null);
+            ingressEgressNiMap.putIfAbsent(ingressNi, new HashSet<>());
+            ingressEgressNiMap.get(ingressNi).add(dstNi);
+        } else {
+            // If srcNi, dstNi are on the same device, this is the only mapping that will be created
+            ingressEgressNiMap.get(srcNi).add(dstNi);
+        }
+
+        // Go through the links and
+        //
+        // create/add the intermediate NIs
+        for (int i = 1; i < linkList.size() - 2; i++) {
+            CarrierEthernetGenericNi ingressNi = new CarrierEthernetGenericNi(linkList.get(i).dst(), null);
+            ingressEgressNiMap.putIfAbsent(ingressNi, new HashSet<>());
+            ingressEgressNiMap.get(ingressNi).add(new CarrierEthernetGenericNi(linkList.get(i + 1).src(), null));
+        }
+    }
+
+    private List<Link> generateLinkList(ConnectPoint cp1, ConnectPoint cp2,
+                                        Type evcType) {
+        Set<Path> paths;
+        Path path = null;
+
+        if (!cp1.deviceId().equals(cp2.deviceId())) {
+            // If cp1 and cp2 are not on the same device a path must be found
+            if (evcType.equals(Type.POINT_TO_POINT)) {
+                // For point-to-point connectivity use pre-calculated paths to make sure the shortest paths are chosen
+                paths = pathService.getPaths(cp1.deviceId(), cp2.deviceId());
+            } else {
+                // Recalculate path so that it's over the pre-calculated spanning tree
+                // FIXME: Find a more efficient way (avoid recalculating paths)
+                paths = pathService.getPaths(cp1.deviceId(), cp2.deviceId(),
+                        new CarrierEthernetSpanningTreeWeight(topologyService));
+            }
+
+            // Just select any of the returned paths
+            // TODO: Select path in more sophisticated way and return null if any of the constraints cannot be met
+            path = paths.iterator().hasNext() ? paths.iterator().next() : null;
+
+            if (path == null) {
+                return null;
+            }
+        }
+
+        List<Link> links = new ArrayList<>();
+        links.add(createEdgeLink(cp1, true));
+        if (!cp1.deviceId().equals(cp2.deviceId())) {
+            links.addAll(path.links());
+        }
+        links.add(createEdgeLink(cp2, false));
+
+        return links;
+    }
+
+    private List<Link> generateInverseLinkList(List<Link> originalLinks) {
+
+        if (originalLinks == null) {
+            return null;
+        }
+
+        List<Link> inverseLinks = new ArrayList<>();
+
+        inverseLinks.add(createEdgeLink(originalLinks.get(originalLinks.size() - 1).src(), true));
+
+        for (int i = originalLinks.size() - 2; i > 0; i--) {
+            // FIXME: Check again the Link creation parameters
+            inverseLinks.add(DefaultLink.builder()
+                    .src(originalLinks.get(i).dst())
+                    .dst(originalLinks.get(i).src())
+                    .type(Link.Type.DIRECT)
+                    .providerId(new ProviderId("none", "none"))
+                    .build());
+        }
+        inverseLinks.add(createEdgeLink(originalLinks.get(0).dst(), false));
+
+        return inverseLinks;
+    }
+
+    @Override
+    public void removeConnectivity(CarrierEthernetForwardingConstruct fc) {
+        channelListenerService.listeners()
+                .forEach(listener -> listener.removeAllForwardingResources(fc.id()));
+    }
+
+    @Override
+    public void createBandwidthProfiles(CarrierEthernetForwardingConstruct fc) {
+        fc.uniSet().forEach(uni -> channelListenerService.listeners()
+                .forEach(listener -> listener.createBandwidthProfileResources(fc, uni)));
+    }
+
+    @Override
+    public void applyBandwidthProfiles(CarrierEthernetForwardingConstruct fc) {
+        //  TODO: Select node manager depending on device protocol
+        fc.uniSet().forEach(uni -> channelListenerService.listeners()
+                .forEach(listener -> listener.applyBandwidthProfileResources(fc, uni)));
+    }
+
+    @Override
+    public void removeBandwidthProfiles(CarrierEthernetForwardingConstruct fc) {
+        //  TODO: Select node manager depending on device protocol
+        fc.ltpSet().forEach((ltp -> {
+            if (ltp.ni().type().equals(CarrierEthernetNetworkInterface.Type.UNI)) {
+                channelListenerService.listeners()
+                        .forEach(listener ->
+                                listener.removeBandwidthProfileResources(fc, (CarrierEthernetUni) ltp.ni()));
+            }
+        }));
+    }
+}
diff --git a/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/MetroOrchestrationManager.java b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/MetroOrchestrationManager.java
new file mode 100644
index 0000000..fc118ed
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/MetroOrchestrationManager.java
@@ -0,0 +1,1327 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.orchestration;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Sets;
+import org.apache.commons.lang3.tuple.Pair;
+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.apache.felix.scr.annotations.Service;
+import org.onlab.packet.VlanId;
+import org.onosproject.codec.CodecService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.net.Port;
+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.config.NetworkConfigService;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.net.topology.PathService;
+import org.onosproject.net.topology.TopologyService;
+import org.opencord.ce.api.models.CarrierEthernetBandwidthProfile;
+import org.opencord.ce.api.models.CarrierEthernetEnni;
+import org.opencord.ce.api.models.CarrierEthernetForwardingConstruct;
+import org.opencord.ce.api.models.CarrierEthernetInni;
+import org.opencord.ce.api.models.CarrierEthernetLogicalTerminationPoint;
+import org.opencord.ce.api.models.CarrierEthernetNetworkInterface;
+import org.opencord.ce.api.models.CarrierEthernetSpanningTreeWeight;
+import org.opencord.ce.api.models.CarrierEthernetUni;
+import org.opencord.ce.api.models.CarrierEthernetVirtualConnection;
+import org.opencord.ce.api.models.EvcConnId;
+import org.opencord.ce.api.models.PortVlanConfig;
+import org.opencord.ce.api.services.MetroNetworkProvisionerService;
+import org.opencord.ce.api.services.MetroOrchestrationService;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
+import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
+import static org.opencord.ce.api.models.CarrierEthernetLogicalTerminationPoint.Role;
+import static org.opencord.ce.api.models.CarrierEthernetVirtualConnection.Type;
+import static org.onosproject.net.config.basics.SubjectFactories.CONNECT_POINT_SUBJECT_FACTORY;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Global orchestration component.
+ */
+@Component(immediate = true)
+@Service
+public class MetroOrchestrationManager implements MetroOrchestrationService {
+    private final Logger log = getLogger(getClass());
+    private static final String APP_NAME = "org.opencord.ce.global.orchestration";
+    private ApplicationId appId;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkService linkService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PathService pathService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected TopologyService topologyService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService networkConfigService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry cfgRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CodecService codecService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MetroNetworkProvisionerService  networkProvisionerService;
+
+
+    // Keeps track of the next S-VLAN tag the app will try to use
+    private static short nextVlanId = 1;
+
+    // Keeps track of the next EVC id the app will try to use
+    // TODO: Use Identifier class instead
+    private static short nextEvcShortId = 1;
+
+    private boolean evcFragmentationEnabled = false;
+    private boolean prevEvcFragmentationStatus = evcFragmentationEnabled;
+
+    // TODO: Implement distributed store for EVCs
+    // The installed EVCs
+    private final Map<EvcConnId, CarrierEthernetVirtualConnection> evcMap = new ConcurrentHashMap<>();
+
+    // TODO: Implement distributed store for Forwarding Constructs
+    // The installed Forwarding Constructs
+    private final Map<EvcConnId, CarrierEthernetForwardingConstruct> fcMap = new ConcurrentHashMap<>();
+
+    // TODO: Implement distributed store for CE UNIs
+    // The installed CE UNIs
+    private final Map<String, CarrierEthernetUni> uniMap = new ConcurrentHashMap<>();
+    private final Set<String> removedUniSet = Sets.newConcurrentHashSet();
+
+    // TODO: Implement distributed store for CE LTPs
+    // The installed CE LTPs
+    private final Map<String, CarrierEthernetLogicalTerminationPoint> ltpMap = new ConcurrentHashMap<>();
+
+    // The LTP ids that have been explicitly removed (or requested to be removed) from the global LTP map
+    private final Set<String> removedLtpSet = Sets.newConcurrentHashSet();
+
+    private final List<ConfigFactory<?, ?>> factories = ImmutableList.of(
+            new ConfigFactory<ConnectPoint, PortVlanConfig>(CONNECT_POINT_SUBJECT_FACTORY,
+                    PortVlanConfig.class, PortVlanConfig.CONFIG_KEY) {
+                @Override
+                public PortVlanConfig createConfig() {
+                    return new PortVlanConfig();
+                }
+            });
+
+    // Map of connect points and corresponding VLAN tag
+    private final Map<ConnectPoint, VlanId> portVlanMap = new ConcurrentHashMap<>();
+
+    private NetworkConfigListener netcfgListener = new InternalNetworkConfigListener();
+
+    /**
+     * Activate this component.
+     */
+    @Activate
+    public void activate() {
+        appId = coreService.registerApplication(APP_NAME);
+        networkConfigService.addListener(netcfgListener);
+        factories.forEach(cfgRegistry::registerConfigFactory);
+    }
+
+    /**
+     * Deactivate this component.
+     */
+    @Deactivate
+    public void deactivate() {
+        networkConfigService.removeListener(netcfgListener);
+        factories.forEach(cfgRegistry::unregisterConfigFactory);
+        removeAllEvcs();
+        removeAllFcs();
+    }
+
+    @Override
+    public Map<EvcConnId, CarrierEthernetVirtualConnection> evcMap() {
+        return this.evcMap;
+    }
+
+    @Override
+    public CarrierEthernetVirtualConnection getEvc(EvcConnId evcId) {
+        return evcMap.get(evcId);
+    }
+
+    @Override
+    public CarrierEthernetForwardingConstruct getFc(EvcConnId fcId) {
+        return fcMap.get(fcId);
+    }
+
+    @Override
+    public Map<EvcConnId, CarrierEthernetForwardingConstruct> fcMap() {
+        return fcMap;
+    }
+
+    @Override
+    public Map<String, CarrierEthernetLogicalTerminationPoint> ltpMap() {
+        return ltpMap;
+    }
+
+    @Override
+    public Map<String, CarrierEthernetUni> getUniMap() {
+        return uniMap;
+    }
+
+    /**
+     * Verify the validity of an EVC representation taking also into account current network status.
+     *
+     * @param originalEvc the provided EVC representation
+     * @return a valid, potentially modified EVC representation, or null if the EVC could not be validated
+     */
+    private CarrierEthernetVirtualConnection validateEvc(CarrierEthernetVirtualConnection originalEvc) {
+
+        // Make a copy of the provided EVC, since it may be modified
+        CarrierEthernetVirtualConnection evc = originalEvc;
+
+        // Try to set a unique numerical id for the EVC unless the EVC is being updated
+        // FIXME: Check again the EVC update case
+        evc.setShortId(generateEvcShortId());
+        if (evc.shortId()  == null) {
+            log.error("No available EVC id found.");
+            return null;
+        }
+
+        // Generate and set unique FC id
+        evc.setId(EvcConnId.of(generateEvcId(evc)));
+
+        // Verify that CE-VLAN ID is provided to either all UNIs or none
+        // and set the virtualEvc flag accordingly
+        // Note: Checking also that all NIs are UNIs
+        boolean isVirtual = false;
+        Iterator<CarrierEthernetUni> it = evc.uniSet().iterator();
+        while (it.hasNext()) {
+            CarrierEthernetUni ni = it.next();
+            if (ni.ceVlanId() == VlanId.NONE && isVirtual) {
+                log.error("Could not validate the virtual status of the EVC.");
+                return null;
+            } else if (ni.ceVlanId() != VlanId.NONE) {
+                isVirtual = true;
+            }
+        }
+        evc.setIsVirtual(isVirtual);
+
+        // Set unique id for the EVC unless the EVC is being updated
+        if (evc.id() == null) {
+            evc.setId(EvcConnId.of(generateEvcId(evc)));
+        }
+
+        Set<CarrierEthernetUni> validatedUniSet = new HashSet<>();
+
+        // TODO: Refactor according to the validateFc method
+        // Note: Cannot use the validateFc method here,
+        // because FCs can also be standalone
+
+        // Check the UNIs of the EVC, possibly removing UNIs that are
+        // incompatible with existing global ones
+        it = evc.uniSet().iterator();
+        while (it.hasNext()) {
+            CarrierEthernetUni uni = it.next();
+            // Change the name of the UNI's BWP to the EVC name if it is an EVC BWP
+            if (uni.bwp().type().equals(CarrierEthernetBandwidthProfile.Type.EVC)) {
+                uni.bwp().setId(evc.id().id());
+            }
+            // Check first if corresponding global UNI already exists
+            // by checking against the global UNI Map
+            if (uniMap.keySet().contains(uni.id())) {
+                CarrierEthernetUni existingUni = uniMap.get(uni.id());
+                // Check if the EVC-specific UNI is compatible with the global one
+                if (!(existingUni.validateEcNi(uni))) {
+                    // If EVC is of ROOT_MULTIPOINT type and we have removed the root, return null
+                    if (evc.type() == Type.ROOT_MULTIPOINT &&
+                            uni.role() == CarrierEthernetUni.Role.ROOT) {
+                        log.error("Root UNI could not be added to %s EVC.", evc.type().name());
+                        return null;
+                    }
+                    log.warn("UNI {} could not be added to EVC.", uni.id());
+                } else {
+                    // Add UNI to EVC
+                    validatedUniSet.add(uni);
+                }
+            } else {
+                // Add UNI to EVC
+                validatedUniSet.add(uni);
+            }
+        }
+
+        // Update the EVC UNI set, based on the validated UNIs
+        evc.setUniSet(validatedUniSet);
+
+        // TODO: Check that an ROOT_MULTIPOINT EVC has at most one ROOT
+
+        if (evc.uniSet().size() > evc.maxNumUni()) {
+            log.error("{} EVC can have at most {} UNIs.", evc.maxNumUni());
+            return null;
+        }
+
+        if ((evc.type().equals(Type.ROOT_MULTIPOINT)
+                || evc.type().equals(Type.MULTIPOINT_TO_MULTIPOINT))
+                && (evc.uniSet().size() < 2)) {
+            log.error("{} EVC requires at least two UNIs.", evc.type().name());
+            return null;
+        }
+
+        if (evc.type().equals(Type.POINT_TO_POINT) && (evc.uniSet().size() != 2)) {
+            log.error("{} EVC requires exactly two UNIs.", evc.type().name());
+            return null;
+        }
+
+        return evc;
+    }
+
+    @Override
+    public CarrierEthernetVirtualConnection installEvc(CarrierEthernetVirtualConnection evc) {
+
+        // If EVC already exists, remove it and reestablish with new parameters
+        if (evc.id() != null && evcMap.containsKey(evc.id())) {
+            return updateEvc(evc);
+        } else {
+            // id will be generated during validation below
+            evc.setId(null);
+        }
+
+        if (validateEvc(evc) == null) {
+            log.error("EVC could not be installed, please check log for details.");
+            return null;
+        }
+
+        //////////////////////////////////////////////////////////////////////////////////////////////////
+        // This is the "orchestration" part of the CE app
+        //////////////////////////////////////////////////////////////////////////////////////////////////
+
+        // TODO: Add configurable parameter to determine if fragmentation will take place
+        if (evcFragmentationEnabled) {
+            evc.setFcSet(fragmentEvc(evc));
+        } else {
+            evc.setFcSet(Collections.singleton(fcFromEvc(evc)));
+        }
+        evc.fcSet().forEach(fc -> log.info("DEBUG-EVC: {}", fc.toString()));
+        evc.fcSet().forEach(fc -> fc.ltpSet().forEach(ltp -> log.info("DEBUG-LTP: {}", ltp.toString())));
+
+        //////////////////////////////////////////////////////////////////////////////////////////////////
+
+        // Assign S-TAGs to FCs
+        // If network configuration is there, get tags from corresponding ports
+        // else generate unique tags to be used
+        // FIXME: This was supposed to be done in the validateFc method
+        // FIXME: but we need a vlanId here already, so that S-TAGs can be assigned below among paired INNIs/ENNIs
+        Set<VlanId> excludedVlans = usedVlans();
+        evc.fcSet().forEach(fc -> {
+            Optional<VlanId> cfgVlanId = getCfgVlan(fc);
+            if (cfgVlanId.isPresent()) {
+                fc.setVlanId(cfgVlanId.get());
+            } else {
+                fc.setVlanId(generateVlanId(excludedVlans));
+            }
+            excludedVlans.add(fc.vlanId());
+        });
+
+        // For each INNI/ENNI of each FC, find the paired INNI/ENNI and assign S-TAG according to the other FC's vlanId
+        for (CarrierEthernetForwardingConstruct fc : evc.fcSet()) {
+            for (CarrierEthernetLogicalTerminationPoint ltp : fc.ltpSet()) {
+                if (!ltp.ni().type().equals(CarrierEthernetNetworkInterface.Type.UNI)) {
+                    // Find the cp at the other end of the link
+                    Link link = linkService.getEgressLinks(ltp.ni().cp()).iterator().next();
+                    String ltpId = link.dst().deviceId().toString() + "/" + link.dst().port().toString();
+                    // Find the corresponding FC - assuming LTP ids are the same as connect point ids
+                    CarrierEthernetForwardingConstruct neighborFc = getFcFromLtpId(ltpId, evc.fcSet());
+                    if (neighborFc != null) {
+                        if (ltp.ni().type().equals(CarrierEthernetNetworkInterface.Type.INNI)) {
+                            ((CarrierEthernetInni) ltp.ni()).setSVlanId(neighborFc.vlanId());
+                        } else if (ltp.ni().type().equals(CarrierEthernetNetworkInterface.Type.ENNI)) {
+                            ((CarrierEthernetEnni) ltp.ni()).setSVlanId(neighborFc.vlanId());
+                        }
+                    }
+                }
+            }
+        }
+
+        // Install the constituent FCs
+        evc.fcSet().forEach(fc -> {
+            // Increment the FC refCount
+            fc.refCount().incrementAndGet();
+            installFc(fc);
+        });
+
+        // Update the EVC UNI set based on the LTPs used during FC connectivity
+        Set<CarrierEthernetUni> usedUniSet = new HashSet<>();
+        evc.fcSet().forEach(fc -> usedUniSet.addAll(fc.uniSet()));
+        evc.setUniSet(usedUniSet);
+
+        // Determine EVC state based on the state of the constituent FCs
+        evc.setState(CarrierEthernetVirtualConnection.State.ACTIVE);
+        Iterator<CarrierEthernetForwardingConstruct> fcIt = evc.fcSet().iterator();
+        while (fcIt.hasNext()) {
+            CarrierEthernetForwardingConstruct fc = fcIt.next();
+            evc.setState(CarrierEthernetVirtualConnection.State.valueOf(fc.state().name()));
+            if (!evc.isActive()) {
+                break;
+            }
+        }
+
+        if (evc.isActive()) {
+            // If EVC installation was successful, then register the EVC
+            evcMap.put(evc.id(), evc);
+        } else {
+            // If EVC installation was not successful, then do not register the EVC and rollback FC installations
+            evc.fcSet().forEach(fc -> {
+                // Decrement the FC refCount to make removal possible
+                fc.refCount().decrementAndGet();
+                removeFc(fc.id());
+            });
+        }
+
+        return evc;
+    }
+
+    /**
+     * Creates a single FC out of an EVC.
+     *
+     * @param evc the EVC representation
+     * @return the equivalent FC
+     */
+    private CarrierEthernetForwardingConstruct fcFromEvc(CarrierEthernetVirtualConnection evc) {
+        Set<CarrierEthernetLogicalTerminationPoint> ltpSet = new HashSet<>();
+        evc.uniSet().forEach(uni -> ltpSet.add(new CarrierEthernetLogicalTerminationPoint(null, uni)));
+        return CarrierEthernetForwardingConstruct.builder()
+                .type(evc.type())
+                .ltpSet(ltpSet)
+                .build();
+    }
+
+    /**
+     * Fragments an EVC into multiple FCs.
+     *
+     * @param evc the EVC representation
+     * @return the set of FCs constituting the EVC
+     */
+    private Set<CarrierEthernetForwardingConstruct> fragmentEvc(CarrierEthernetVirtualConnection evc) {
+
+        Set<CarrierEthernetForwardingConstruct> fcSet = new HashSet<>();
+
+        // Each LTP can only belong to a single FC, hence using LTP_id -> LTP_set map
+        Map<String, Set<CarrierEthernetLogicalTerminationPoint>> ltpSetMap = new HashMap<>();
+
+        // Temporary set to browse through all EVC UNI pairs
+        Set<CarrierEthernetUni> tempUniSet = new HashSet<>(evc.uniSet());
+
+        Iterator<CarrierEthernetUni> uniIt1 = tempUniSet.iterator();
+        while (uniIt1.hasNext()) {
+
+            CarrierEthernetUni uni1 = uniIt1.next();
+
+            // Iterate through all the remaining NIs
+            Iterator<CarrierEthernetUni> uniIt2 = tempUniSet.iterator();
+            while (uniIt2.hasNext()) {
+
+                CarrierEthernetUni uni2 = uniIt2.next();
+
+                // Skip equals
+                if (uni1.equals(uni2)) {
+                    continue;
+                }
+
+                // Do not establish connectivity between leaf NIs
+                // (applies to Rooted_Multipoint)
+                if (uni1.role().equals(CarrierEthernetUni.Role.LEAF)
+                        && uni2.role().equals(CarrierEthernetUni.Role.LEAF)) {
+                    continue;
+                }
+
+                // Note: INNIs should always appear in pairs
+                List<Pair<CarrierEthernetLogicalTerminationPoint,
+                        CarrierEthernetLogicalTerminationPoint>> ltpPairList
+                        = new ArrayList<>();
+
+                // If uni1 and uni2 are on same device, skip path calculation
+                // and directly generate a single LTP pair to be used below
+                if (uni1.cp().deviceId().equals(uni2.cp().deviceId())) {
+                    ltpPairList.add(Pair.of(new CarrierEthernetLogicalTerminationPoint(null, uni1),
+                            new CarrierEthernetLogicalTerminationPoint(null, uni2)));
+                } else {
+                    // Calculate path assuming return paths are the same
+                    // TODO: Handle the congruent paths case?
+                    Set<Path> paths;
+                    if (evc.type().equals(Type.POINT_TO_POINT)) {
+                        // For point-to-point connectivity use the pre-calculated paths
+                        // to make sure the shortest paths are chosen
+                        paths = pathService.getPaths(uni1.cp().deviceId(), uni2.cp().deviceId());
+                    } else {
+                        // Recalculate path so that it's over the pre-calculated spanning tree
+                        // FIXME: Find a more efficient way (avoid recalculating paths)
+                        paths = pathService.getPaths(uni1.cp().deviceId(), uni2.cp().deviceId(),
+                                new CarrierEthernetSpanningTreeWeight(topologyService));
+                    }
+
+                    // Just select any of the returned paths
+                    // TODO: Select path in more sophisticated way and return null
+                    // if any of the constraints cannot be met
+                    Path path = paths.iterator().hasNext() ? paths.iterator().next() : null;
+
+                    if (path == null) {
+                        return null;
+                    }
+
+                    List<Link> links = new ArrayList<>();
+                    links.add(createEdgeLink(uni1.cp(), true));
+                    links.addAll(path.links());
+                    links.add(createEdgeLink(uni2.cp(), false));
+
+                    ////////////////////////////////////////////////////////////
+                    // Get LTP pairs of ingress/egress NIs along the link path
+                    // (non-LTP connect points are ignored)
+                    ////////////////////////////////////////////////////////////
+
+                    CarrierEthernetLogicalTerminationPoint srcLtp = null, dstLtp = null;
+                    // These are the roles that will be used for all pairs found below
+                    Role srcLtpRole, dstLtpRole;
+                    // The source in any pair will always have the same role as the LTP from which the paths starts
+                    srcLtpRole = Role.valueOf(uni1.role().name());
+                    // The destination in any pair will always have the same role as the LTP at which the path ends
+                    dstLtpRole = Role.valueOf(uni2.role().name());
+                    for (int i = 0; i < links.size(); i++) {
+                        // Try to get the destination LTP of a pair
+                        if (srcLtp != null && i != 0) {
+                            // If this is the last, use existing EVC UNI, else create a new FC LTP and set Role
+                            dstLtp = (i == links.size() - 1) ?
+                                    new CarrierEthernetLogicalTerminationPoint(null, uni2) :
+                                    fcLtpFromCp(links.get(i).src(), dstLtpRole);
+                        }
+                        if (dstLtp != null) {
+                            // Create a new LTP pair and null the srcLtp
+                            // so that we can continue searching for a new pair
+                            ltpPairList.add(Pair.of(srcLtp, dstLtp));
+                            srcLtp = null;
+                        }
+                        // Try to get the source LTP of a pair
+                        if (srcLtp == null && i != links.size() - 1) {
+                            // If this is the first, use existing EVC UNI, else create a new FC LTP and set Role
+                            srcLtp = (i == 0) ?
+                                    new CarrierEthernetLogicalTerminationPoint(null, uni1) :
+                                    fcLtpFromCp(links.get(i).dst(), srcLtpRole);
+                        }
+                    }
+                }
+
+                ////////////////////////////////////////////////////////////////
+                // Go through all the LTP pairs found and map each LTP to a set
+                // of LTPs (create it if it doesn't exist)
+                ////////////////////////////////////////////////////////////////
+
+                // Note: Each LTP can only belong to a single set, so each set
+                // will eventually correspond to an FC
+
+                ltpPairList.forEach(ltpPair -> {
+                    CarrierEthernetLogicalTerminationPoint ltp1 = ltpPair.getLeft();
+                    CarrierEthernetLogicalTerminationPoint ltp2 = ltpPair.getRight();
+                    if (ltpSetMap.containsKey(ltp1.id()) && !ltpSetMap.containsKey(ltp2.id())) {
+                        // If one of the LTPs is already contained in a set, add the other one as well in that set
+                        ltpSetMap.get(ltp1.id()).add(ltp2);
+                        ltpSetMap.put(ltp2.id(), ltpSetMap.get(ltp1.id()));
+                    } else if (ltpSetMap.containsKey(ltp2.id()) & !ltpSetMap.containsKey(ltp1.id())) {
+                        // If one of the LTPs is already contained in a set, add the other one as well in that set
+                        ltpSetMap.get(ltp2.id()).add(ltp1);
+                        ltpSetMap.put(ltp1.id(), ltpSetMap.get(ltp2.id()));
+                    } else if (!ltpSetMap.containsKey(ltp1.id()) && !ltpSetMap.containsKey(ltp2.id())) {
+                        // Create a new LTP set containing the two LTPs and map both to it
+                        ltpSetMap.put(ltp1.id(), Sets.newHashSet(ltp1, ltp2));
+                        ltpSetMap.put(ltp2.id(), ltpSetMap.get(ltp1.id()));
+                    }
+                });
+            }
+            // Remove UNI from temporary set so that each pair is visited only once
+            uniIt1.remove();
+        }
+
+        //////////////////////////////////////////////////////////////////////////////////
+        // Go through all unique LTP sets generated above and create the corresponding FCs
+        //////////////////////////////////////////////////////////////////////////////////
+
+        new HashSet<>(ltpSetMap.values()).forEach(ltpSet -> {
+            CarrierEthernetForwardingConstruct.Builder fcBuilder =
+                    CarrierEthernetForwardingConstruct.builder().ltpSet(ltpSet);
+            // Type is determined by number and type of LTPs in each set
+            Type fcType =
+                    ltpSet.size() == 2 ? Type.POINT_TO_POINT
+                            : Type.MULTIPOINT_TO_MULTIPOINT;
+            // If one of the LTPs is LEAF, indicate FC as ROOT_MULTIPOINT
+            for (CarrierEthernetLogicalTerminationPoint ltp : ltpSet) {
+                if (ltp.role().equals(Role.LEAF)) {
+                    fcType = Type.ROOT_MULTIPOINT;
+                    break;
+                }
+            }
+            fcSet.add(fcBuilder.type(fcType).build());
+            log.info("Created ForwardingConstruct comprising LogicalTerminationPoints {}",
+                    ltpSet.stream()
+                            .map(CarrierEthernetLogicalTerminationPoint::id)
+                            .collect(Collectors.toList()));
+        });
+
+        return fcSet;
+    }
+
+    @Override
+    public CarrierEthernetVirtualConnection updateEvc(CarrierEthernetVirtualConnection evc) {
+        // Just checking again
+        if (evcMap.containsKey(evc.id())) {
+            log.info("Updating existing EVC {}", evc.id());
+            removeEvc(evc.id());
+        }
+        return installEvc(evc);
+    }
+
+    /**
+     * Applies FC- specific LTP attributes to global LTPs or adds them to the global LTP map if not there.
+     *
+     * @param ltpSet set of FC-specific LTPs the attributes of which will be applied to the global LTPs
+     */
+    private void applyFcToGlobalLtps(Set<CarrierEthernetLogicalTerminationPoint> ltpSet) {
+        ltpSet.forEach(ltp -> {
+            if (!(ltpMap.keySet().contains(ltp.id()))) {
+                // Just add the LTP as it appears at the FC
+                addGlobalLtp(ltp);
+            } else {
+                // Add LTP resources (BWP, CE-VLAN ID, S-TAG) to existing global LTP
+                ltpMap.get(ltp.id()).ni().addEcNi(ltp.ni());
+                // Update config identifier
+                ltpMap.get(ltp.id()).ni().setCfgId(ltp.ni().cfgId());
+            }
+        });
+    }
+
+    /**
+     * Removes bandwidth profiles from the UNIs of an FC.
+     *
+     * @param fc the FC representation
+     */
+    // TODO: Remove LTPs if needed from the global LTP/UNI map
+    private void removeFcFromGlobalLtps(CarrierEthernetForwardingConstruct fc) {
+        // TODO: Check if the bandwidth profile really needs to be removed (e.g. may be CoS)
+       //// ceProvisioner.removeBandwidthProfiles(fc);
+        // Remove LTP resources (BWP, CE-VLAN ID, S-TAG) from corresponding global LTPs
+        fc.ltpSet().forEach(ltp -> ltpMap.get(ltp.id()).ni().removeEcNi(ltp.ni()));
+    }
+
+    @Override
+    public void removeAllEvcs() {
+        evcMap.keySet().forEach(this::removeEvc);
+    }
+
+    @Override
+    public void removeEvc(EvcConnId evcId) {
+        if (evcMap.containsKey(evcId)) {
+            CarrierEthernetVirtualConnection evc = evcMap.get(evcId);
+            evc.fcSet().forEach(fc -> {
+                // Decrement the FC refCount to make removal possible
+                fc.refCount().decrementAndGet();
+                removeFc(fc.id());
+            });
+            // Avoid excessively incrementing EVC ids
+            nextEvcShortId = evc.shortId() < nextEvcShortId ? evc.shortId() : nextEvcShortId;
+            evcMap.remove(evcId);
+        }
+    }
+
+    /**
+     * Verify the validity of an FC representation taking also into account current network status.
+     *
+     * @param fc the provided FC representation
+     * @return a valid, potentially modified FC representation, or null if the FC could not be validated
+     */
+    private CarrierEthernetForwardingConstruct validateFc(CarrierEthernetForwardingConstruct fc) {
+
+        // Try to set a unique VLAN id for the FC unless the EVC is being updated
+        // TODO: Add different connectivity types
+        // FIXME: This is an extra check to be able to generate/set VLAN id for FC before calling installFc
+        if (fc.vlanId() == null) {
+            fc.setVlanId(generateVlanId(usedVlans()));
+        }
+        if (fc.vlanId() == null) {
+            log.error("No available VLAN id found.");
+            return null;
+        }
+
+        // Generate and set unique FC id
+        fc.setId(EvcConnId.of(generateFcId(fc)));
+
+        Set<CarrierEthernetLogicalTerminationPoint> validatedLtpSet = new HashSet<>();
+
+        // Check the NIs of the FC, possibly removing NIs that are incompatible with existing ones
+        Iterator<CarrierEthernetLogicalTerminationPoint> ltpIt = fc.ltpSet().iterator();
+        while (ltpIt.hasNext()) {
+            CarrierEthernetLogicalTerminationPoint ltp = ltpIt.next();
+            boolean ltpValidated = true;
+            if (ltp.type().equals(CarrierEthernetNetworkInterface.Type.UNI)) {
+                CarrierEthernetUni uni = (CarrierEthernetUni) ltp.ni();
+                // Change the name of the UNI's BWP to the FC name if it is an EVC BWP
+                if (uni.bwp().type().equals(CarrierEthernetBandwidthProfile.Type.EVC)) {
+                    // FIXME: Find a way to use the EVC name instead
+                    uni.bwp().setId(fc.id().id());
+                }
+            }
+            // Check first if LTP already exists by checking against the global LTP Map
+            if (ltpMap.keySet().contains(ltp.id())) {
+                CarrierEthernetNetworkInterface existingNi = ltpMap.get(ltp.id()).ni();
+                // Check if the FC-specific NI is compatible with the global one
+                if (!(existingNi.validateEcNi(ltp.ni()))) {
+                    ltpValidated = false;
+                }
+            }
+            if (!ltpValidated) {
+                // If EVC is of ROOT_MULTIPOINT type and we have removed the root, return null
+                if (fc.type() == CarrierEthernetForwardingConstruct.Type.ROOT_MULTIPOINT &&
+                        ltp.role() == Role.ROOT) {
+                    log.error("Root LTP could not be added to %s FC.", fc.type().name());
+                    return null;
+                }
+                log.warn("LTP {} could not be added to FC.", ltp.id());
+                continue;
+            } else {
+                // Add LTP to FC description
+                validatedLtpSet.add(ltp);
+            }
+        }
+
+        fc.setLtpSet(validatedLtpSet);
+
+        return fc;
+    }
+
+    @Override
+    public CarrierEthernetForwardingConstruct installFc(CarrierEthernetForwardingConstruct fc) {
+
+        // If FC already exists, remove it and reestablish with new parameters
+        if (fc.id() != null && fcMap.containsKey(fc.id())) {
+            return updateFc(fc);
+        } else {
+            fc.setId(null);
+        }
+
+        if (validateFc(fc) == null) {
+            log.error("FC could not be installed, please check log for details.");
+            return null;
+        }
+
+        // Create BW profiles first so that they will be available if needed during the connectivity phase
+        networkProvisionerService.createBandwidthProfiles(fc);
+
+        networkProvisionerService.setupConnectivity(fc);
+
+
+        // If connectivity was not successful, then do not register the FC and do not apply BW profiles
+        // If not, the BW profiles that were created earlier need to be removed
+        if (fc.state().equals(CarrierEthernetForwardingConstruct.State.ACTIVE)) {
+            // Apply BWP-related resources (e.g. Meters) to the packet switches
+            networkProvisionerService.applyBandwidthProfiles(fc);
+            // Apply the BWPs of the FC UNIs to the global UNIs, creating them if needed
+            //applyEvcToGlobalUnis(fc.uniSet());
+            applyFcToGlobalLtps(fc.ltpSet());
+            // Increment the global LTP and corresponding NI refCount
+            fc.ltpSet().forEach(ltp -> ltpMap.get(ltp.id()).refCount().incrementAndGet());
+            fcMap.put(fc.id(), fc);
+        } else {
+          networkProvisionerService.removeBandwidthProfiles(fc);
+        }
+
+        return fc;
+    }
+
+    @Override
+    public CarrierEthernetForwardingConstruct updateFc(CarrierEthernetForwardingConstruct fc) {
+        // Just checking again
+        if (fcMap.containsKey(fc.id())) {
+            log.info("Updating existing FC {}", fc.id());
+            // Keep the VLAN ID of the original FC
+            fc.setVlanId(fcMap.get(fc.id()).vlanId());
+            // FIXME: Currently FC update only possible for standalone FCs
+            removeFc(fc.id());
+        }
+        return installFc(fc);
+    }
+
+    @Override
+    public void removeAllFcs() {
+        fcMap.keySet().forEach(fcId -> removeFc(fcId));
+    }
+
+    @Override
+    public CarrierEthernetForwardingConstruct removeFc(EvcConnId fcId) {
+        if (fcMap.containsKey(fcId)) {
+            CarrierEthernetForwardingConstruct fc = fcMap.get(fcId);
+            if (fc.refCount().get() != 0) {
+                log.warn("Could not remove FC {}: RefCount is not zero", fc.id());
+                return null;
+            }
+            networkProvisionerService.removeConnectivity(fc);
+            networkProvisionerService.removeBandwidthProfiles(fc);
+            removeFcFromGlobalLtps(fc);
+            // Avoid excessively incrementing FC VLAN ids
+            nextVlanId = (fcMap.get(fcId).vlanId().toShort() < nextVlanId ?
+                    fcMap.get(fcId).vlanId().toShort() :
+                    nextVlanId);
+            // Decrement the global LTP and corresponding NI refCount
+            fcMap.get(fcId).ltpSet().forEach(ltp -> ltpMap.get(ltp.id()).refCount().decrementAndGet());
+            fcMap.remove(fcId);
+            return fc;
+        }
+        return null;
+    }
+
+    /**
+     * Returns the unique S-TAGs currently used by FCs across the CE network.
+     *
+     * @return the S-TAGs currently used
+     */
+    private Set<VlanId> usedVlans() {
+        return fcMap.values().stream().map(CarrierEthernetForwardingConstruct::vlanId)
+                .collect(Collectors.toSet());
+    }
+
+    /**
+     * Generates a new vlanId excluding the provided ones.
+     *
+     * @param excludedVlans the vlanIds that are not allowed
+     * @return the generated vlanId; null if none found
+     */
+    private VlanId generateVlanId(Set<VlanId> excludedVlans) {
+        // If all vlanIds are being used return null, else try to find the next available one
+        if (excludedVlans.size() <  VlanId.MAX_VLAN - 1) {
+            while (excludedVlans.contains(VlanId.vlanId(nextVlanId))) {
+                // Get next valid short
+                nextVlanId = (nextVlanId >= VlanId.MAX_VLAN || nextVlanId <= 0 ?
+                        1 : (short) (nextVlanId + 1));
+            }
+        }
+        return excludedVlans.contains(VlanId.vlanId(nextVlanId)) ?
+                null : VlanId.vlanId(nextVlanId);
+    }
+
+    /**
+     * Generates a unique vlanId in the context of the CE app.
+     *
+     * @return the generated vlanId or null if none found
+     */
+    private Short generateEvcShortId() {
+
+        List<Short> evcShortIdList = evcMap.values()
+                .stream()
+                .map(evc -> evc.shortId())
+                .collect(Collectors.toList());
+
+        // If all vlanIds are being used return null, else try to find the next available one
+        if (evcShortIdList.size() <  Short.MAX_VALUE - 1) {
+            while (evcShortIdList.contains(nextEvcShortId)) {
+                // Get next valid short
+                nextEvcShortId =
+                        (nextEvcShortId >= Short.MAX_VALUE || nextEvcShortId <= 0 ? 1 : (short) (nextEvcShortId + 1));
+            }
+        }
+
+        return evcShortIdList.contains(nextEvcShortId) ? null : nextEvcShortId;
+    }
+
+    /**
+     * Generates a unique EVC id in the context of the CE app.
+     *
+     * @param evc the EVC representation
+     * @return the generated EVC id or null if none found
+     */
+    private String generateEvcId(CarrierEthernetVirtualConnection evc) {
+
+        // TODO: Add different connectivity types
+
+        String tmpType;
+
+        if (evc.type().equals(Type.POINT_TO_POINT)) {
+            tmpType = "Line";
+        } else if (evc.type().equals(Type.MULTIPOINT_TO_MULTIPOINT)) {
+            tmpType = "LAN";
+        } else {
+            tmpType = "Tree";
+        }
+
+        return "E" + (evc.isVirtual() ? "V" : "") + "P-" + tmpType + "-" +
+                evc.shortId().toString();
+    }
+
+    /**
+     * Generates a unique FC id in the context of the CE app.
+     *
+     * @param fc the FC representation
+     * @return the generated FC id or null if none found
+     */
+    private String generateFcId(CarrierEthernetForwardingConstruct fc) {
+
+        // TODO: Add different connectivity types
+
+        return "FC-" + fc.vlanId().toString();
+    }
+
+    @Override
+    public CarrierEthernetLogicalTerminationPoint removeGlobalLtp(String ltpId) {
+
+        if (!ltpMap.containsKey(ltpId)) {
+            log.warn("Could not remove LTP {}: Does not exist", ltpId);
+            return null;
+        }
+
+        if (ltpMap.get(ltpId).refCount().get() != 0) {
+            log.warn("Could not remove LTP {}: RefCount is not zero", ltpId);
+            return null;
+        }
+
+        // Remove LTP from ltpMap and (if needed) UNI from uniMap
+        CarrierEthernetLogicalTerminationPoint ltp = ltpMap.remove(ltpId);
+        // Add LTP to removed set
+        removedLtpSet.add(ltpId);
+        if (ltp.ni().type().equals(CarrierEthernetNetworkInterface.Type.UNI)) {
+            removeGlobalUni(ltp.ni().id());
+            // Add UNI to removed set
+            // TODO: Check if this is right
+            removedUniSet.add(ltp.ni().id());
+        }
+
+        // Find cp at other end of link and try to remove both LTPs - assuming LTP ids are the same as connect point ids
+        if (ltp.ni().type().equals(CarrierEthernetNetworkInterface.Type.INNI)) {
+            Link link = linkService.getEgressLinks(ltp.ni().cp()).iterator().next();
+            String pairLtpId = link.dst().deviceId().toString() + "/" + link.dst().port().toString();
+            ltpMap.remove(pairLtpId);
+            // Add LTP to removed set
+            removedLtpSet.add(pairLtpId);
+        }
+
+        return ltp;
+    }
+
+    @Override
+    public CarrierEthernetUni removeGlobalUni(String uniId) {
+
+        if (!uniMap.containsKey(uniId)) {
+            log.warn("Could not remove UNI {}: Does not exist", uniId);
+            return null;
+        }
+        if (uniMap.get(uniId).refCount().get() != 0) {
+            log.warn("Could not remove UNI {}: RefCount is not zero", uniId);
+            return null;
+        }
+
+        // Remove UNI from uniMap and corresponding LTP (if any) from ltpMp
+        CarrierEthernetUni uni = uniMap.remove(uniId);
+        // FIXME: For now, find LTP assuming ltpId is the same as uniId
+        // Note: If refCount for UNI is not zero, then it should be for the corresponding LTP as well
+        ltpMap.remove(uniId);
+
+        // Add UNI and LTP to removed set
+        removedUniSet.add(uniId);
+        removedLtpSet.add(uniId);
+
+        return uni;
+    }
+
+    @Override
+    public Set<CarrierEthernetUni> getUnisFromTopo(boolean excludeAdded, boolean includeRemoved) {
+
+        CarrierEthernetUni uni;
+        Set<CarrierEthernetUni> uniSet = new HashSet<>();
+        // Generate the device ID/port number identifiers
+        for (Device device : deviceService.getDevices()) {
+            for (Port port : deviceService.getPorts(device.id())) {
+                if (!port.number().isLogical()) {
+                    String cpString = device.id().toString() + "/" + port.number();
+                    ConnectPoint cp = ConnectPoint.deviceConnectPoint(cpString);
+                    uni = generateUni(cp);
+                    // Check if UNI was generated and whether it's currently removed
+                    if (uni != null
+                            && (includeRemoved || !removedUniSet.contains(uni.id()))
+                            && (!excludeAdded || !uniMap.containsKey(uni.id()))) {
+                        uniSet.add(uni);
+                    }
+                }
+            }
+        }
+        return uniSet;
+    }
+
+    @Override
+    public CarrierEthernetUni generateUni(ConnectPoint cp) {
+
+        String uniId = cp.deviceId().toString() + "/" + cp.port().toString();
+
+        if (deviceService.getDevice(cp.deviceId()) == null) {
+            log.error("Could not generate UNI {}: Invalid deviceId {}", uniId, cp.deviceId());
+            return null;
+        }
+        if (deviceService.getPort(cp.deviceId(), cp.port()) == null) {
+            log.error("Could not generate UNI {}: Invalid port {} at device {}", uniId, cp.port(), cp.deviceId());
+            return null;
+        }
+        if (!deviceService.getDevice(cp.deviceId()).type().equals(Device.Type.SWITCH)) {
+            log.debug("Could not generate UNI {}: Device {} is not a switch", uniId, cp.deviceId());
+            return null;
+        }
+
+        Port port = deviceService.getPort(cp.deviceId(), cp.port());
+
+        if (!port.isEnabled())  {
+            log.debug("Could not generate UNI {}: Port {} is not enabled", uniId, port.number().toString());
+            return null;
+        }
+
+        if (validateLtpType(cp, CarrierEthernetNetworkInterface.Type.UNI) == null) {
+            return null;
+        }
+
+        return CarrierEthernetUni.builder()
+                .cp(cp)
+                .cfgId(uniId)
+                .build();
+    }
+
+    @Override
+    public CarrierEthernetUni addGlobalUni(CarrierEthernetUni uni) {
+        // Add UNI only if it's not already there. If corresponding LTP already exists, link them, otherwise create it
+        if (!uniMap.containsKey(uni.id())) {
+            // Add LTP only if it's not already there
+            // FIXME: Assumes LTP and UNI id are the same
+            if (!ltpMap.containsKey(uni.id())) {
+                ltpMap.put(uni.id(), new CarrierEthernetLogicalTerminationPoint(uni.id(), uni));
+                // Remove LTP from deleted set
+                removedLtpSet.remove(uni.id());
+            }
+            uniMap.put(uni.id(), uni);
+            // Remove UNI from deleted set
+            removedUniSet.remove(uni.id());
+            return  uni;
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public Set<CarrierEthernetLogicalTerminationPoint> getLtpsFromTopo(boolean excludeAdded, boolean includeRemoved) {
+
+        CarrierEthernetLogicalTerminationPoint ltp;
+        Set<CarrierEthernetLogicalTerminationPoint> ltpSet = new HashSet<>();
+        // Generate the device ID/port number identifiers
+        for (Device device : deviceService.getDevices()) {
+            for (Port port : deviceService.getPorts(device.id())) {
+                if (!port.number().isLogical()) {
+                    String cpString = device.id().toString() + "/" + port.number();
+                    ConnectPoint cp = ConnectPoint.deviceConnectPoint(cpString);
+                    ltp = generateLtp(cp, null);
+                    // Check if LTP was generated and whether it's currently removed
+                    if (ltp != null
+                            && (includeRemoved || !removedLtpSet.contains(ltp.id()))
+                            && (!excludeAdded || !ltpMap.containsKey(ltp.id()))) {
+                        // Check additionally if associated UNI is currently removed
+                        if (!(ltp.ni() instanceof CarrierEthernetUni) || !removedUniSet.contains(ltp.ni().id())) {
+                            ltpSet.add(ltp);
+                        }
+                    }
+                }
+            }
+        }
+        return ltpSet;
+    }
+
+    @Override
+    public CarrierEthernetLogicalTerminationPoint generateLtp(ConnectPoint cp,
+                                                              CarrierEthernetNetworkInterface.Type ltpType) {
+
+        String ltpId = cp.deviceId().toString() + "/" + cp.port().toString();
+
+        if (deviceService.getDevice(cp.deviceId()) == null) {
+            log.error("Could not generate LTP {}: Invalid deviceId {}", ltpId, cp.deviceId());
+            return null;
+        }
+        if (deviceService.getPort(cp.deviceId(), cp.port()) == null) {
+            log.error("Could not generate LTP {}: Invalid port {} at device {}", ltpId, cp.port(), cp.deviceId());
+            return null;
+        }
+        if (!deviceService.getDevice(cp.deviceId()).type().equals(Device.Type.SWITCH)) {
+            log.debug("Could not generate LTP {}: Device {} is not a switch", ltpId, cp.deviceId());
+            return null;
+        }
+
+        Port port = deviceService.getPort(cp.deviceId(), cp.port());
+
+        if (!port.isEnabled())  {
+            log.debug("Could not generate LTP {}: Port {} is not enabled", ltpId, port.number().toString());
+            return null;
+        }
+
+        ltpType = validateLtpType(cp, ltpType);
+
+        if (ltpType == null) {
+            log.warn("Could not generate LTP {}: Type could not be validated", ltpId, port.number().toString());
+            return null;
+        }
+
+        return new CarrierEthernetLogicalTerminationPoint(cp, ltpId, ltpType, null);
+    }
+
+    /**
+     * Validates whether the provided connect point can be associated with an LTP of the provided type.
+     *
+     * Conditions for validating the LTP type:
+     * - If UNI: ConnectPoint is not associated with any link
+     * - If INNI/ENNI: ConnectPoint is associated with a link
+     *
+     * @param cp the connect point associated with the LTP to be validated
+     * @param ltpType the type of the LTP to be validated or null in case a type is to be decided by the method
+     * @return the ltpType if validation succeeded, a new type depending on cp and topo, or null if validation failed
+     */
+    private CarrierEthernetNetworkInterface.Type validateLtpType(
+            ConnectPoint cp, CarrierEthernetNetworkInterface.Type ltpType) {
+        if (linkService.getEgressLinks(cp).isEmpty() && linkService.getIngressLinks(cp).isEmpty()) {
+            // A connect point can be a UNI only if it doesn't belong to any link
+            if (ltpType == null) {
+                // If provided type is null, decide about the LTP type based on connectivity
+                return CarrierEthernetNetworkInterface.Type.UNI;
+            } else if (ltpType.equals(CarrierEthernetNetworkInterface.Type.UNI)) {
+                // Validate type
+                return ltpType;
+            } else {
+                return null;
+            }
+        } else {
+            // A connect point can be an INNI or ENNI only if it belongs to a link
+            if (ltpType == null) {
+                // If provided type is null, decide about the LTP type based on connectivity
+                return CarrierEthernetNetworkInterface.Type.INNI;
+            } else if (ltpType.equals(CarrierEthernetNetworkInterface.Type.INNI) ||
+                    ltpType.equals(CarrierEthernetNetworkInterface.Type.ENNI)) {
+                // Validate type
+                return ltpType;
+            } else {
+                return null;
+            }
+        }
+    }
+
+    @Override
+    public CarrierEthernetLogicalTerminationPoint addGlobalLtp(CarrierEthernetLogicalTerminationPoint ltp) {
+        // If LTP contains a UNI, add it only if it's not already there, else point to the existing UNI
+        // FIXME: Assumes LTP and UNI id are the same
+        if (ltp.ni() != null &&
+                ltp.ni().type().equals(CarrierEthernetNetworkInterface.Type.UNI)) {
+
+            if (!uniMap.containsKey(ltp.ni().id())) {
+                uniMap.put(ltp.ni().id(), (CarrierEthernetUni) ltp.ni());
+                // Remove UNI from deleted set
+                removedUniSet.remove(ltp.id());
+            } else {
+                ltp.setNi(uniMap.get(ltp.ni().id()));
+            }
+        }
+        // Add LTP only if it's not already there
+        if (!ltpMap.containsKey(ltp.id())) {
+            // Try to create and add INNI LTP at other end of link as well
+            if (ltp.ni().type().equals(CarrierEthernetNetworkInterface.Type.INNI)) {
+                Link link = linkService.getEgressLinks(ltp.ni().cp()).iterator().next();
+                CarrierEthernetLogicalTerminationPoint pairLtp =
+                        generateLtp(link.dst(), CarrierEthernetNetworkInterface.Type.INNI);
+                if (pairLtp == null) {
+                    return null;
+                }
+                if (!ltpMap.containsKey(pairLtp.id())) {
+                    ltpMap.put(pairLtp.id(), pairLtp);
+                } else {
+                    return null;
+                }
+            }
+            ltpMap.put(ltp.id(), ltp);
+            // Remove LTP from deleted set
+            removedLtpSet.remove(ltp.id());
+            return ltp;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Utility method to obtain an FC-specific LTP (UNI/INNI or ENNI) associated with a connect point.
+     *
+     * @param cp the connect point to check
+     * @return a new FC-specific LTP associated with cp if the corresponding global LTP exists or null otherwise
+     */
+    private CarrierEthernetLogicalTerminationPoint fcLtpFromCp(ConnectPoint cp,
+                                                               Role ltpRole) {
+        // Check first if cp is associated with a device
+        if (cp.deviceId() == null) {
+            return null;
+        }
+        // Assuming LTP id is the same as the connect point id
+        String cpId = cp.deviceId().toString() + "/" + cp.port().toString();
+        if (ltpMap.containsKey(cpId)) {
+            return new CarrierEthernetLogicalTerminationPoint(cp, cpId,
+                    ltpMap.get(cpId).type(), ltpRole);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Utility method to obtain the first FC in a set which contains the LTP with the provided id.
+     *
+     * @param ltpId the LTP id to search
+     * @param fcSet the FC set to search
+     * @return the first FC found in fcSet which contains an LTP with id ltpId, or null if no such FC is found
+     */
+    // FIXME: Find more efficient way to do that
+    private CarrierEthernetForwardingConstruct getFcFromLtpId(String ltpId,
+                                                              Set<CarrierEthernetForwardingConstruct> fcSet) {
+        // Get the first FC that contains the LTP with the provided id
+        for (CarrierEthernetForwardingConstruct fc : fcSet) {
+            if (!fc.ltpSet().stream().filter(ltp -> ltp.id().equals(ltpId)).collect(Collectors.toList()).isEmpty()) {
+                return fc;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public void setEvcFragmentation(boolean evcFragmentationEnabled) {
+        prevEvcFragmentationStatus = this.evcFragmentationEnabled;
+        this.evcFragmentationEnabled = evcFragmentationEnabled;
+    }
+
+    @Override
+    public boolean getEvcFragmentation() {
+        return evcFragmentationEnabled;
+    }
+
+    @Override
+    public void resetEvcFragmentation() {
+        this.evcFragmentationEnabled = prevEvcFragmentationStatus;
+    }
+
+    /**
+     * Returns the VLAN tag associated with an FC via network configuration.
+     *
+     * The VLAN tag to be selected should be configured in at least one of the
+     * FC LTPs and no different tag should be present in the rest of the FC LTPs.
+     *
+     * @param fc the FC to check
+     * @return an Optional object with the VLAN to be associated with the FC if
+     * one was found; an empty Optional object otherwise
+     */
+    private Optional<VlanId> getCfgVlan(CarrierEthernetForwardingConstruct fc) {
+        VlanId cfgVlan = null;
+        for (CarrierEthernetLogicalTerminationPoint ltp : fc.ltpSet()) {
+            VlanId tmpVlan = portVlanMap.get(ltp.cp());
+            if (tmpVlan == null) {
+                continue;
+            } else if (cfgVlan != null && cfgVlan != tmpVlan) {
+                log.warn("Multiple configured S-TAGs for the same FC");
+                return Optional.empty();
+            } else {
+                cfgVlan = tmpVlan;
+            }
+        }
+        return cfgVlan == null ? Optional.empty() : Optional.of(cfgVlan);
+    }
+
+    private class InternalNetworkConfigListener implements NetworkConfigListener {
+
+        /**
+         * Negative events.
+         */
+        private final EnumSet<NetworkConfigEvent.Type> negative
+                = EnumSet.of(NetworkConfigEvent.Type.CONFIG_UNREGISTERED,
+                NetworkConfigEvent.Type.CONFIG_REMOVED);
+
+        /**
+         * Actual configuration events.
+         */
+        private final EnumSet<NetworkConfigEvent.Type> actualConfig
+                = EnumSet.of(NetworkConfigEvent.Type.CONFIG_ADDED,
+                NetworkConfigEvent.Type.CONFIG_REMOVED,
+                NetworkConfigEvent.Type.CONFIG_UPDATED);
+
+        @Override
+        public boolean isRelevant(NetworkConfigEvent event) {
+            return event.configClass().equals(PortVlanConfig.class) &&
+                    actualConfig.contains(event.type());
+        }
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+
+            if (!isRelevant(event)) {
+                return;
+            }
+
+            ConnectPoint cp = (ConnectPoint) event.subject();
+            PortVlanConfig config = networkConfigService.getConfig(cp, PortVlanConfig.class);
+
+            if (config == null) {
+                log.info("VLAN tag config is removed from port {}", cp);
+                portVlanMap.remove(cp);
+                return;
+            }
+
+            if (config.portVlanId().isPresent() && !negative.contains(event.type())) {
+                VlanId assignedVlan = config.portVlanId().get();
+                if (usedVlans().contains(assignedVlan)) {
+                    log.warn("VLAN tag {} is already used in the CE network", assignedVlan);
+                } else {
+                    log.info("VLAN tag {} is assigned to port {}", assignedVlan, cp);
+                    portVlanMap.put(cp, assignedVlan);
+                }
+            } else {
+                log.info("VLAN tag is removed from port {}", cp);
+                portVlanMap.remove(cp);
+            }
+        }
+    }
+}
+
diff --git a/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/channel/ControlChannelManager.java b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/channel/ControlChannelManager.java
new file mode 100644
index 0000000..4bce91f
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/channel/ControlChannelManager.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.orchestration.channel;
+
+import com.google.common.collect.ImmutableSet;
+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.Service;
+import org.opencord.ce.api.services.channel.ControlChannelListenerService;
+import org.opencord.ce.api.services.MetroNetworkVirtualNodeService;
+import org.slf4j.Logger;
+
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+
+/**
+ * Implementation o the {@link ControlChannelListenerService}.
+ */
+@Component(immediate = true)
+@Service
+public class ControlChannelManager implements ControlChannelListenerService {
+
+    private final Logger log = getLogger(getClass());
+    private Set<MetroNetworkVirtualNodeService> sbListeners = new CopyOnWriteArraySet<>();
+
+    @Activate
+    public void activate() {
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        log.info("Stopped");
+    }
+
+    @Override
+    public void addListener(MetroNetworkVirtualNodeService listener) {
+        log.debug("listener added");
+        sbListeners.add(listener);
+    }
+
+    @Override
+    public void removeListener(MetroNetworkVirtualNodeService listener) {
+        sbListeners.remove(listener);
+    }
+
+    @Override
+    public Set<MetroNetworkVirtualNodeService> listeners() {
+        return ImmutableSet.copyOf(sbListeners);
+    }
+
+}
diff --git a/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/channel/package-info.java b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/channel/package-info.java
new file mode 100644
index 0000000..9b98ec4
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/channel/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-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.
+ */
+
+/**
+ * Communication channel APIs.
+ */
+package org.opencord.ce.global.orchestration.channel;
\ No newline at end of file
diff --git a/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/commands/CarrierEthernetCreateEvcCommand.java b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/commands/CarrierEthernetCreateEvcCommand.java
new file mode 100644
index 0000000..2fc97ec
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/commands/CarrierEthernetCreateEvcCommand.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.orchestration.cli.commands;
+
+import com.google.common.collect.Lists;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.onosproject.cli.AbstractShellCommand;
+import org.opencord.ce.api.models.CarrierEthernetVirtualConnection;
+import org.opencord.ce.api.models.EvcConnId;
+import org.opencord.ce.api.services.MetroOrchestrationService;
+
+import java.util.List;
+
+import static org.opencord.ce.api.models.CarrierEthernetEvcUtils.generateEvcType;
+import static org.opencord.ce.api.models.CarrierEthernetEvcUtils.generateUniSet;
+import static org.opencord.ce.api.models.CarrierEthernetEvcUtils.generateMaxNumUni;
+
+/**
+ * CLI command for installing an Ethernet Virtual Connection.
+ */
+@Command(scope = "onos", name = "ce-evc-create",
+        description = "Carrier Ethernet EVC creation command.")
+public class CarrierEthernetCreateEvcCommand extends AbstractShellCommand {
+    @Argument(index = 0, name = "argEvcCfgId",
+            description = "EVC configuration ID", required = true, multiValued = false)
+    String argEvcCfgId = null;
+    @Argument(index = 1, name = "argEvcType", description =
+            "EVC type (defaults to POINT_TO_POINT or MULTIPOINT_TO_MULTIPOINT, depending on number of UNIs)",
+            required = false, multiValued = false)
+    String argEvcType = null;
+
+    @Argument(index = 2, name = "argUniList",
+            description = "List of UNIs (if point to multipoint, first is root, other are leaves)",
+            required = true, multiValued = true)
+    List<String> argUniList = Lists.newArrayList();
+    @Option(name = "-v", aliases = "--cevlan", description = "CE-VLAN ID (applied to all UNIs)",
+            required = false, multiValued = false)
+    short argCeVlanId = -1;
+    @Option(name = "-id", aliases = "--evc-id", description = "The ID of a evc to be updated" +
+            " (if evc does not exist, a new evc will be installed)", required = false, multiValued = false)
+    String argEvcId = null;
+    @Option(name = "-u", aliases = "--maxNumUni", description = "The maximum number of UNIs in the EVC",
+            required = false, multiValued = false)
+    int argMaxNumUni = -1;
+    @Option(name = "-c", aliases = "--cir", description = "The CIR in Mbps", required = false, multiValued = false)
+    double argCir = 0;
+    @Option(name = "-e", aliases = "--eir", description = "The EIR in Mbps", required = false, multiValued = false)
+    double argEir = 0;
+    @Option(name = "-cbs", aliases = "--cbs", description = "The CBS in Bytes", required = false, multiValued = false)
+    long argCbs = 0;
+    @Option(name = "-ebs", aliases = "--ebs", description = "The EBS in Bytes", required = false, multiValued = false)
+    long argEbs = 0;
+
+    // TODO: Add further arguments for VLAN tag preservation, CoS preservation etc.
+
+    @Override
+    protected void execute() {
+        MetroOrchestrationService ceManager = get(MetroOrchestrationService.class);
+        ceManager.installEvc(CarrierEthernetVirtualConnection.builder()
+                .id(EvcConnId.of(argEvcId == null ? argEvcCfgId : argEvcId))
+                .cfgId(argEvcCfgId)
+                .type(generateEvcType(argEvcType, argUniList))
+                .maxNumUni(generateMaxNumUni(argMaxNumUni, argEvcType, argUniList))
+                .uniSet(generateUniSet(argEvcType,  argUniList.subList(1, argUniList.size()),
+                        argCeVlanId, argUniList.get(0), argEvcCfgId, argCir,
+                        argEir, argCbs, argEbs))
+                .build());
+    }
+}
diff --git a/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/commands/CarrierEthernetListEvcsCommand.java b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/commands/CarrierEthernetListEvcsCommand.java
new file mode 100644
index 0000000..57fe6d5
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/commands/CarrierEthernetListEvcsCommand.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.orchestration.cli.commands;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.opencord.ce.api.models.CarrierEthernetVirtualConnection;
+import org.opencord.ce.api.services.MetroOrchestrationService;
+
+import java.util.Collection;
+
+
+/**
+ * CLI command for listing all installed CE services.
+ */
+@Command(scope = "onos", name = "ce-evc-list",
+        description = "Lists all installed EVCs.")
+public class CarrierEthernetListEvcsCommand extends AbstractShellCommand {
+
+    @Override
+    protected void execute() {
+        MetroOrchestrationService ceManager = get(MetroOrchestrationService.class);
+        printServices(ceManager.evcMap().values());
+    }
+
+    private void printServices(Collection<CarrierEthernetVirtualConnection> services) {
+        services.forEach(service -> print("  %s", service));
+    }
+}
diff --git a/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/commands/CarrierEthernetListUnisCommand.java b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/commands/CarrierEthernetListUnisCommand.java
new file mode 100644
index 0000000..bf92286
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/commands/CarrierEthernetListUnisCommand.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.orchestration.cli.commands;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.opencord.ce.api.models.CarrierEthernetUni;
+import org.opencord.ce.api.services.MetroOrchestrationService;
+
+import java.util.Collection;
+
+/**
+ * CLI command for listing all CE UNIs.
+ */
+@Command(scope = "onos", name = "ce-uni-list",
+        description = "Lists all Carrier Ethernet UNIs.")
+public class CarrierEthernetListUnisCommand extends AbstractShellCommand {
+
+    @Override
+    protected void execute() {
+        MetroOrchestrationService ceManager = get(MetroOrchestrationService.class);
+        // Populate global UNI map
+        ceManager.getUnisFromTopo(false, false).forEach(uni -> ceManager.addGlobalUni(uni));
+        printUnis(ceManager.getUniMap().values());
+    }
+
+    private void printUnis(Collection<CarrierEthernetUni> unis) {
+        unis.forEach(uni -> print("  %s", uni));
+    }
+}
diff --git a/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/commands/package-info.java b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/commands/package-info.java
new file mode 100644
index 0000000..471a619
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/commands/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-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.
+ */
+
+/**
+ * Command classes for the Carrier Ethernet app CLI.
+ */
+package org.opencord.ce.global.orchestration.cli.commands;
\ No newline at end of file
diff --git a/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/completers/CarrierEthernetEvcTypeCompleter.java b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/completers/CarrierEthernetEvcTypeCompleter.java
new file mode 100644
index 0000000..f5ad4bc
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/completers/CarrierEthernetEvcTypeCompleter.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.orchestration.cli.completers;
+
+import org.apache.karaf.shell.console.Completer;
+import org.apache.karaf.shell.console.completer.StringsCompleter;
+import org.opencord.ce.api.models.CarrierEthernetVirtualConnection;
+
+import java.util.List;
+import java.util.SortedSet;
+
+public class CarrierEthernetEvcTypeCompleter implements Completer {
+    @Override
+    public int complete(String buffer, int cursor, List<String> candidates) {
+
+        StringsCompleter delegate = new StringsCompleter();
+
+        SortedSet<String> strings = delegate.getStrings();
+
+        for (CarrierEthernetVirtualConnection.Type type : CarrierEthernetVirtualConnection.Type.values()) {
+            strings.add(type.name());
+        }
+
+        return delegate.complete(buffer, cursor, candidates);
+    }
+
+}
diff --git a/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/completers/CarrierEthernetUniCompleter.java b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/completers/CarrierEthernetUniCompleter.java
new file mode 100644
index 0000000..951acba
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/completers/CarrierEthernetUniCompleter.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.orchestration.cli.completers;
+
+import org.apache.karaf.shell.console.completer.StringsCompleter;
+import org.onosproject.cli.AbstractCompleter;
+import org.onosproject.cli.AbstractShellCommand;
+import org.opencord.ce.api.services.MetroOrchestrationService;
+
+import java.util.List;
+import java.util.SortedSet;
+
+/**
+ * UNI id completer, including only UNIs that have been added to the UNI map.
+ */
+public class CarrierEthernetUniCompleter extends AbstractCompleter {
+
+    @Override
+    public int complete(String buffer, int cursor, List<String> candidates) {
+
+        StringsCompleter delegate = new UniqueStringsCompleter();
+        SortedSet<String> strings = delegate.getStrings();
+
+        MetroOrchestrationService ceManager = AbstractShellCommand.get(MetroOrchestrationService.class);
+        ceManager.getUniMap().keySet().forEach(uniId -> strings.add(uniId));
+
+        return delegate.complete(buffer, cursor, candidates);
+    }
+
+}
\ No newline at end of file
diff --git a/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/completers/CarrierEthernetValidUniCompleter.java b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/completers/CarrierEthernetValidUniCompleter.java
new file mode 100644
index 0000000..51182d4
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/completers/CarrierEthernetValidUniCompleter.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.orchestration.cli.completers;
+
+import org.apache.karaf.shell.console.completer.StringsCompleter;
+import org.onosproject.cli.AbstractCompleter;
+import org.onosproject.cli.AbstractShellCommand;
+import org.opencord.ce.api.services.MetroOrchestrationService;
+
+import java.util.List;
+import java.util.SortedSet;
+
+/**
+ * UNI id completer, not including UNIs that have been removed.
+ */
+public class CarrierEthernetValidUniCompleter extends AbstractCompleter {
+
+    @Override
+    public int complete(String buffer, int cursor, List<String> candidates) {
+
+        StringsCompleter delegate = new UniqueStringsCompleter();
+        SortedSet<String> strings = delegate.getStrings();
+
+        MetroOrchestrationService ceManager = AbstractShellCommand.get(MetroOrchestrationService.class);
+        ceManager.getUnisFromTopo(false, false).forEach(uni -> strings.add(uni.id()));
+
+        return delegate.complete(buffer, cursor, candidates);
+    }
+}
diff --git a/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/completers/UniqueStringsCompleter.java b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/completers/UniqueStringsCompleter.java
new file mode 100644
index 0000000..21272be
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/completers/UniqueStringsCompleter.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.orchestration.cli.completers;
+
+import org.apache.felix.service.command.CommandSession;
+import org.apache.karaf.shell.console.CommandSessionHolder;
+import org.apache.karaf.shell.console.completer.ArgumentCompleter;
+import org.apache.karaf.shell.console.completer.StringsCompleter;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * String completer which excludes strings already included in the preceding argument list.
+ */
+public class UniqueStringsCompleter extends StringsCompleter {
+
+    @Override
+    public int complete(String buffer, int cursor, List candidates) {
+
+        // Get all preceding arguments
+        CommandSession session = CommandSessionHolder.getSession();
+        List<String> prevArgsList = Arrays.asList(((ArgumentCompleter.ArgumentList) session
+                .get("ARGUMENTS_LIST")).getArguments());
+
+        super.complete(buffer, cursor, candidates);
+
+        // Remove from candidate list all strings included in preceding arguments
+        candidates.removeAll(prevArgsList);
+
+        return candidates.isEmpty() ? -1 : 0;
+    }
+
+}
diff --git a/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/completers/package-info.java b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/completers/package-info.java
new file mode 100644
index 0000000..9e95562
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/completers/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-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.
+ */
+
+/**
+ * Completer classes for the Carrier Ethernet app CLI.
+ */
+package org.opencord.ce.global.orchestration.cli.completers;
\ No newline at end of file
diff --git a/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/package-info.java b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/package-info.java
new file mode 100644
index 0000000..0a4cf4f
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-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.
+ */
+
+/**
+ * CLI implementation for the Carrier Ethernet Application.
+ */
+package org.opencord.ce.global.orchestration.cli;
\ No newline at end of file
diff --git a/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/package-info.java b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/package-info.java
new file mode 100644
index 0000000..e68df70
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-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.
+ */
+
+/**
+ * Global metro orchestration package.
+ */
+package org.opencord.ce.global.orchestration;
\ No newline at end of file
diff --git a/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/rest/CarrierEthernetWebApplication.java b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/rest/CarrierEthernetWebApplication.java
new file mode 100644
index 0000000..85a480e
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/rest/CarrierEthernetWebApplication.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.orchestration.rest;
+
+import org.onlab.rest.AbstractWebApplication;
+
+import java.util.Set;
+
+/**
+ * CarrierEthernet REST API web application.
+ */
+public class CarrierEthernetWebApplication extends AbstractWebApplication {
+    @Override
+    public Set<Class<?>> getClasses() {
+        return getClasses(CarrierEthernetWebResource.class);
+    }
+}
diff --git a/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/rest/CarrierEthernetWebResource.java b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/rest/CarrierEthernetWebResource.java
new file mode 100644
index 0000000..39234b8
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/rest/CarrierEthernetWebResource.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.orchestration.rest;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onosproject.rest.AbstractWebResource;
+import org.opencord.ce.api.models.CarrierEthernetVirtualConnection;
+import org.opencord.ce.api.models.EvcConnId;
+import org.opencord.ce.api.services.MetroOrchestrationService;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Carrier Ethernet web resource.
+ */
+@Path("evc")
+public class CarrierEthernetWebResource extends AbstractWebResource {
+
+    private static final String EVCS = "evcs";
+    private final ObjectNode root = mapper().createObjectNode();
+    private final ArrayNode evcsNode = root.putArray(EVCS);
+
+    private MetroOrchestrationService ceManager = get(MetroOrchestrationService.class);
+
+    /**
+     * Gets all EVC entries. Returns array of all EVCs in the system.
+     *
+     * @return 200 OK with a collection of Evcs
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getEvcs() {
+        ceManager.evcMap().values().forEach(evc -> evcsNode.add(
+                        codec(CarrierEthernetVirtualConnection.class)
+                                .encode(evc, this)));
+
+
+        return ok(root).build();
+    }
+
+    /**
+     * Gets an EVC entry by deviceId.
+     * @param evcId evc ID
+     * @return 200 OK with the requested Evc.
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("{evcId}")
+    public Response getEvc(@PathParam("evcId") String evcId) {
+        ObjectNode evc = codec(CarrierEthernetVirtualConnection.class)
+                .encode(ceManager.getEvc(EvcConnId.of(evcId)), this);
+        return ok(evc).build();
+    }
+
+    /**
+     * Install an EVC with given parameters.
+     *
+     * @param stream input stream
+     * @return 200 OK if the EVC was installed
+     */
+    @POST
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response setEvc(InputStream stream) {
+        ObjectNode root = mapper().createObjectNode();
+        try {
+            ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+            CarrierEthernetVirtualConnection evc =
+                    codec(CarrierEthernetVirtualConnection.class).decode(jsonTree, this);
+            ceManager.installEvc(evc);
+            root.put("evcId", evc.id().id());
+        } catch (IOException e) {
+            throw new IllegalArgumentException(e.getMessage());
+        }
+        return ok(root).build();
+    }
+
+    /**
+     * Removes all EVCs installed in the CE app.
+     *
+     * @return 204 NO CONTENT
+     */
+    @DELETE
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response removeAllEvc() {
+        ceManager.removeAllEvcs();
+        return Response.noContent().build();
+    }
+
+    /**
+     * Removes one EVCs by evcId.
+     *
+     * @param evcId the EVC to remove.
+     * @return 204 NO CONTENT
+     */
+    @DELETE
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("{evcId}")
+    public Response removeEvcWithId(@PathParam("evcId") String evcId) {
+        ceManager.removeEvc(EvcConnId.of(evcId));
+        return Response.noContent().build();
+    }
+
+}
diff --git a/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/rest/package-info.java b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/rest/package-info.java
new file mode 100644
index 0000000..d3a0873
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/rest/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-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.
+ */
+
+/**
+ * REST API to setup Carrier Ethernet circuits.
+ */
+package org.opencord.ce.global.orchestration.rest;
\ No newline at end of file
diff --git a/global/ce-orchestration/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/global/ce-orchestration/src/main/resources/OSGI-INF/blueprint/shell-config.xml
new file mode 100644
index 0000000..ea08bbd
--- /dev/null
+++ b/global/ce-orchestration/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -0,0 +1,41 @@
+<!--
+  ~ Copyright 2017-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.
+  -->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.opencord.ce.global.orchestration.cli.commands.CarrierEthernetListUnisCommand"/>
+        </command>
+        <command>
+            <action class="org.opencord.ce.global.orchestration.cli.commands.CarrierEthernetCreateEvcCommand"/>
+            <completers>
+                <ref component-id="placeholderCompleter"/>
+                <ref component-id="carrierEthernetEvcTypeCompleter"/>
+                <ref component-id="carrierEthernetValidUniCompleter"/>
+                <ref component-id="carrierEthernetValidUniCompleter"/>
+            </completers>
+        </command>
+        <command>
+            <action class="org.opencord.ce.global.orchestration.cli.commands.CarrierEthernetListEvcsCommand"/>
+        </command>
+    </command-bundle>
+
+    <bean id="placeholderCompleter" class="org.onosproject.cli.PlaceholderCompleter"/>
+    <bean id="carrierEthernetEvcTypeCompleter" class="org.opencord.ce.global.orchestration.cli.completers.CarrierEthernetEvcTypeCompleter"/>
+    <bean id="carrierEthernetUniCompleter" class="org.opencord.ce.global.orchestration.cli.completers.CarrierEthernetUniCompleter"/>
+    <bean id="carrierEthernetValidUniCompleter" class="org.opencord.ce.global.orchestration.cli.completers.CarrierEthernetValidUniCompleter"/>
+
+</blueprint>
diff --git a/global/ce-orchestration/src/main/webapp/WEB-INF/web.xml b/global/ce-orchestration/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..99cfcf2
--- /dev/null
+++ b/global/ce-orchestration/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2017-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.
+  -->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
+         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         id="ONOS" version="2.5">
+    <display-name>ECORD REST API v1.0</display-name>
+
+    <servlet>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
+        <init-param>
+            <param-name>javax.ws.rs.Application</param-name>
+            <param-value>org.opencord.ce.global.orchestration.rest.CarrierEthernetWebApplication</param-value>
+        </init-param>
+        <load-on-startup>10</load-on-startup>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+</web-app>
diff --git a/global/config-samples/ecord-global-config.json b/global/config-samples/ecord-global-config.json
new file mode 100644
index 0000000..5b9e72a
--- /dev/null
+++ b/global/config-samples/ecord-global-config.json
@@ -0,0 +1,57 @@
+{
+  "apps" : {
+    "org.opencord.ce.global.vprovider" : {
+      "xos" : {
+        "username" : "xosadmin@opencord.org",
+        "password" : "0Ui8QNJNCdXrjjLpF1U6",
+        "address" : "127.0.0.1",
+        "resource" : "/xosapi/v1/metronet/usernetworkinterfaces/"
+      }
+    },
+    "org.opencord.ce.global.channel.http" : {
+      "endPoints" : {
+        "port" : "8182",
+        "topics" : [
+          "ecord-domains-topic-one",
+          "ecord-domains-topic-two",
+          "ecord-domains-topic-three"
+        ],
+        "domains" :
+        [
+          {
+            "domainId" : "domain1-onos-fabric",
+            "publicIp" : "10.128.14.10",
+            "port" : "8181",
+            "username" : "sdn",
+            "password" : "rocks",
+            "topic" : "ecord-domains-topic-one"
+          },
+          {
+            "domainId" : "domain1-onos-cord",
+            "publicIp" : "10.128.14.10",
+            "port" : "8182",
+            "username" : "sdn",
+            "password" : "rocks",
+            "topic" : "ecord-domains-topic-one"
+          },
+          {
+            "domainId" : "domain2-onos-fabric",
+            "publicIp" : "10.128.14.20",
+            "port" : "8181",
+            "username" : "sdn",
+            "password" : "rocks",
+            "topic" : "ecord-domains-topic-one"
+          },
+          {
+            "domainId" : "domain2-onos-cord",
+            "publicIp" : "10.128.14.20",
+            "port" : "8182",
+            "username" : "sdn",
+            "password" : "rocks",
+            "topic" : "ecord-domains-topic-one"
+          }
+        ]
+      }
+    }
+  }
+}
diff --git a/global/http-channel/pom.xml b/global/http-channel/pom.xml
new file mode 100644
index 0000000..76f81e5
--- /dev/null
+++ b/global/http-channel/pom.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2017-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.
+  -->
+<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">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opencord.ce</groupId>
+        <artifactId>global</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>global-channel</artifactId>
+    <packaging>bundle</packaging>
+    <version>1.0.0-SNAPSHOT</version>
+
+    <description>HTTP communication channel between hierarchical ONOS controllers</description>
+
+    <properties>
+        <web.context>/ecord/global</web.context>
+        <onos.app.name>org.opencord.ce.global.channel</onos.app.name>
+        <onos.version>1.10.6</onos.version>
+        <onos.app.url>http://opencord.org</onos.app.url>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.opencord.ce</groupId>
+            <artifactId>orchestration</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+            <version>${onos.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-core-serializers</artifactId>
+            <version>${onos.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <_wab>src/main/webapp/</_wab>
+                        <Bundle-SymbolicName>
+                            ${project.groupId}.${project.artifactId}
+                        </Bundle-SymbolicName>
+                        <Import-Package>
+                            *,org.glassfish.jersey.servlet
+                        </Import-Package>
+                        <Web-ContextPath>${web.context}</Web-ContextPath>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.onosproject</groupId>
+                <artifactId>onos-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+    <repositories>
+        <repository>
+            <id>snapshots</id>
+            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+            <releases><enabled>false</enabled></releases>
+        </repository>
+    </repositories>
+
+    <pluginRepositories>
+        <pluginRepository>
+            <id>snapshots</id>
+            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+            <releases><enabled>false</enabled></releases>
+        </pluginRepository>
+    </pluginRepositories>
+
+</project>
diff --git a/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/ConnectionConfig.java b/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/ConnectionConfig.java
new file mode 100644
index 0000000..ca7388a
--- /dev/null
+++ b/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/ConnectionConfig.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.channel.client;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.Sets;
+import org.onlab.packet.IpAddress;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.domain.DomainId;
+import org.opencord.ce.api.models.DomainEndPoint;
+
+import java.util.ArrayList;
+import java.util.Set;
+
+/**
+ * Configuration class for this bundle.
+ *
+ * Look at /config-samples/ecord-global-config.json for a sample configuration
+ */
+public class ConnectionConfig extends Config<ApplicationId> {
+
+    private static final String PORT = "port";
+
+    private static final String TOPICS = "topics";
+
+    private static final String DOMAINS = "domains";
+    private static final String DOMAIN_ID = "domainId";
+    private static final String PUBLIC_IP = "publicIp";
+    private static final String USERNAME = "username";
+    private static final String PASSWD = "password";
+    private static final String TOPIC = "topic";
+
+    /**
+     * Gets listen port from configuration.
+     * @return port number
+     */
+    public int listenPort() {
+        return object.path(PORT).asInt();
+    }
+
+    /**
+     * List of topics to distribute network operations among ONOS instances.
+     * @return list of topics
+     */
+    public ArrayList<String> topics() {
+        ArrayList<String> topics = new ArrayList<>();
+        object.path(TOPICS).forEach(
+                topic -> topics.add(topic.asText())
+        );
+        return topics;
+    }
+
+    /**
+     * Returns set of domain end points.
+     * @return set of domain end points
+     */
+    public Set<DomainEndPoint> endPoints() {
+        JsonNode peersNode = object.get(DOMAINS);
+        Set<DomainEndPoint> endPoints = Sets.newHashSet();
+
+        peersNode.forEach(jsonNode -> {
+            DomainId domainId = DomainId.domainId(
+                    jsonNode.path(DOMAIN_ID).asText());
+            IpAddress publicIp = IpAddress.valueOf(jsonNode.path(PUBLIC_IP).asText());
+            int port = jsonNode.path(PORT).asInt();
+
+            String username = jsonNode.path(USERNAME).asText();
+            String password = jsonNode.path(PASSWD).asText();
+
+            String topic = jsonNode.path(TOPIC).asText();
+
+            endPoints.add(new DomainEndPoint(domainId, publicIp, port,
+                    username, password, topic));
+        });
+
+        return endPoints;
+    }
+}
diff --git a/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/HttpClientComponent.java b/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/HttpClientComponent.java
new file mode 100644
index 0000000..3939ac4
--- /dev/null
+++ b/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/HttpClientComponent.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.channel.client;
+
+
+import com.google.common.collect.Sets;
+
+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.cluster.ClusterService;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+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.config.NetworkConfigService;
+import org.onosproject.net.config.basics.SubjectFactories;
+import org.onosproject.net.domain.DomainService;
+import org.opencord.ce.api.services.channel.ControlChannelListenerService;
+import org.opencord.ce.api.models.DomainEndPoint;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+
+/**
+ * Southbound component that adds a listener to the
+ * {@link ControlChannelListenerService}.
+ *
+ * Accomplishes network tasks through HTTP requests,
+ * acting as a client that send {@link org.opencord.ce.api.models.CarrierEthernetForwardingConstruct}
+ * requests to the underlying domains
+ */
+@Component(immediate = true)
+public class HttpClientComponent {
+    private static final String APP_NAME = "org.opencord.ce.global.channel.http";
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private ApplicationId appId;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LeadershipService leadershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ClusterService clusterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry configRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService configService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ControlChannelListenerService channelListenerService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DomainService domainService;
+
+    private static boolean isRunningForLeadership = false;
+
+    private final Set<DomainEndPoint> endPoints = Sets.newHashSet();
+    private final List<String> topics = new ArrayList<>();
+
+    private final ExecutorService eventExecutor =
+            Executors.newSingleThreadExecutor();
+
+    private final ConfigFactory<ApplicationId, ConnectionConfig> configFactory =
+            new ConfigFactory<ApplicationId, ConnectionConfig>(SubjectFactories.APP_SUBJECT_FACTORY,
+                    ConnectionConfig.class, "endPoints") {
+                @Override
+                public ConnectionConfig createConfig() {
+                    return new ConnectionConfig();
+                }
+            };
+
+    private final NetworkConfigListener configListener = new InternalConfigListener();
+
+    @Activate
+    protected void activate() {
+        log.info("Started");
+
+        appId = coreService.registerApplication(APP_NAME);
+        configRegistry.registerConfigFactory(configFactory);
+        configService.addListener(configListener);
+        channelListenerService.addListener(HttpClientInstance.INSTANCE);
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        log.info("Stopped");
+        configService.removeListener(configListener);
+        configRegistry.unregisterConfigFactory(configFactory);
+        channelListenerService.removeListener(HttpClientInstance.INSTANCE);
+        if (isRunningForLeadership) {
+            topics.forEach(topic -> leadershipService.withdraw(topic));
+        }
+    }
+
+    private void runForLeadership(List<String> topics) {
+        topics.forEach(topic ->
+            leadershipService.runForLeadership(topic));
+        isRunningForLeadership = true;
+    }
+
+
+    private void readConfig() {
+        ConnectionConfig config = configRegistry.getConfig(appId, ConnectionConfig.class);
+        log.debug("Domains connections config received");
+
+        endPoints.addAll(config.endPoints());
+        topics.addAll(config.topics());
+        runForLeadership(topics);
+        HttpClientInstance.INSTANCE.configure(clusterService, leadershipService, domainService, endPoints);
+    }
+
+    private class InternalConfigListener implements NetworkConfigListener {
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+            if (!event.configClass().equals(ConnectionConfig.class)) {
+                return;
+            }
+            switch (event.type()) {
+                case CONFIG_ADDED:
+                    log.info("Network configuration added");
+                    eventExecutor.execute(HttpClientComponent.this::readConfig);
+                    break;
+                case CONFIG_UPDATED:
+                    log.info("Network configuration updated");
+                    eventExecutor.execute(HttpClientComponent.this::readConfig);
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
diff --git a/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/HttpClientInstance.java b/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/HttpClientInstance.java
new file mode 100644
index 0000000..a6687a1
--- /dev/null
+++ b/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/HttpClientInstance.java
@@ -0,0 +1,349 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.channel.client;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.Maps;
+import org.apache.commons.lang3.tuple.Pair;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.net.domain.DomainId;
+import org.onosproject.net.domain.DomainService;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.rest.AbstractWebResource;
+import org.opencord.ce.api.models.CarrierEthernetForwardingConstruct;
+import org.opencord.ce.api.models.CarrierEthernetNetworkInterface;
+import org.opencord.ce.api.models.CarrierEthernetUni;
+import org.opencord.ce.api.models.DomainEndPoint;
+import org.opencord.ce.api.models.EvcConnId;
+import org.opencord.ce.api.services.MetroNetworkVirtualNodeService;
+import org.opencord.ce.api.services.channel.RequestCallback;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+
+
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import static org.opencord.ce.api.services.channel.Symbols.BASE_URL;
+import static org.opencord.ce.api.services.channel.Symbols.COLON;
+import static org.opencord.ce.api.services.channel.Symbols.DELETE;
+import static org.opencord.ce.api.services.channel.Symbols.DOUBLESLASH;
+import static org.opencord.ce.api.services.channel.Symbols.DST_NI_LIST;
+import static org.opencord.ce.api.services.channel.Symbols.FC;
+import static org.opencord.ce.api.services.channel.Symbols.GET;
+import static org.opencord.ce.api.services.channel.Symbols.HTTP;
+import static org.opencord.ce.api.services.channel.Symbols.POST;
+import static org.opencord.ce.api.services.channel.Symbols.SRC_NI;
+import static org.opencord.ce.api.services.channel.Symbols.UNI;
+import static org.onosproject.net.domain.DomainId.LOCAL;
+
+/**
+ *  Implementation of the listener methods for requesting {@link
+ *  org.opencord.ce.api.models.CarrierEthernetForwardingConstruct} configuration.
+ */
+public enum HttpClientInstance
+        implements MetroNetworkVirtualNodeService {
+    INSTANCE;
+    private final Logger log =
+            LoggerFactory.getLogger(HttpClientInstance.class);
+
+    private static final int STATUS_OK = Response.Status.OK.getStatusCode();
+    private static final int STATUS_REQ_UNPROCESSABLE = Response.Status.NOT_ACCEPTABLE.getStatusCode();
+
+    private final Map<DomainId, Pair<Client, DomainEndPoint>> domainsEndPointsMap = Maps.newConcurrentMap();
+
+    private final AbstractWebResource codecContext = new AbstractWebResource();
+
+    private boolean configured = false;
+
+    private ClusterService clusterService;
+    private LeadershipService leadershipService;
+    private DomainService domainService;
+
+    private final ExecutorService networkExecutor =
+            newSingleThreadExecutor();
+           // newFixedThreadPool(5, groupedThreads("opencord/ecord-http", "event-handler"));
+
+    public void configure(ClusterService clusterService, LeadershipService leadershipService,
+                          DomainService domainService, Set<DomainEndPoint> endPoints) {
+
+        if (!configured) {
+            this.clusterService = clusterService;
+            this.leadershipService = leadershipService;
+            this.domainService = domainService;
+            configured = true;
+        }
+        endPoints.forEach(siteConfig -> {
+            DomainId domainId = siteConfig.domainId();
+            synchronized (this) {
+                domainsEndPointsMap.putIfAbsent(domainId,
+                        Pair.of(createClient(), siteConfig));
+                notify();
+            }
+        });
+    }
+
+    public Client getConnectionInfo(DomainId domainId) {
+        return domainsEndPointsMap.get(domainId).getLeft();
+    }
+
+    private boolean isLeader(String topic) {
+        return topic != null && leadershipService.getLeader(topic).id()
+                .equals(clusterService.getLocalNode().id().id());
+    }
+
+    private boolean checkReply(Response response) {
+        if (response != null) {
+            return checkStatusCode(response.getStatus());
+        }
+        log.error("Null reply from end point");
+        return false;
+    }
+
+    private boolean checkStatusCode(int statusCode) {
+        if (statusCode == STATUS_OK) {
+            return true;
+        } else {
+            log.error("Failed request, HTTP error code : "
+                    + statusCode);
+            return false;
+        }
+    }
+
+    private String getTopic(DomainId domainId) {
+        if (domainsEndPointsMap.get(domainId) != null) {
+            return domainsEndPointsMap.get(domainId).getRight().topic();
+        }
+        log.info("Domain ID {} not among configured domain IDs", domainId.id());
+        return null;
+    }
+
+    private Client createClient() {
+        return ClientBuilder.newClient();
+    }
+
+    @Override
+    public void setNodeForwarding(CarrierEthernetForwardingConstruct fc, CarrierEthernetNetworkInterface srcNi,
+                                  Set<CarrierEthernetNetworkInterface> dstNiSet) {
+
+        DomainId domainId = domainService.getDomain(srcNi.cp().deviceId());
+        if (domainId == LOCAL || !isLeader(getTopic(domainId))) {
+            return;
+        }
+        JsonCodec<CarrierEthernetForwardingConstruct> fcCodec =
+                codecContext.codec(CarrierEthernetForwardingConstruct.class);
+        JsonCodec<CarrierEthernetNetworkInterface> niCodec =
+                codecContext.codec(CarrierEthernetNetworkInterface.class);
+        ObjectNode body = codecContext.mapper().createObjectNode();
+
+        body.set(FC, fcCodec.encode(fc, codecContext));
+        body.set(SRC_NI, niCodec.encode(srcNi, codecContext));
+        ArrayNode dstNiJsonArrayNode = codecContext.mapper().createArrayNode();
+        dstNiSet.forEach(dstNi ->
+                dstNiJsonArrayNode.add(niCodec.encode(dstNi, codecContext)));
+        body.set(DST_NI_LIST, dstNiJsonArrayNode);
+        String resource = "/ForwardingConstruct";
+        networkExecutor.execute(new NetworkTask(domainId, POST, resource, body.toString(),
+                new RequestCallback() {
+                    @Override
+                    public void onSuccess(Response response) {
+                        log.info("FC request submit to domain: {}", domainId);
+
+                    }
+
+                    @Override
+                    public void onError(Response response) {
+                        log.error("FC call failure reason: {}", response.getStatusInfo());
+
+                    }
+                }));
+    }
+
+    @Override
+    public void createBandwidthProfileResources(CarrierEthernetForwardingConstruct fc, CarrierEthernetUni uni) {
+        DomainId domainId = domainService.getDomain(uni.cp().deviceId());
+        if (domainId == LOCAL || !isLeader(getTopic(domainId))) {
+            return;
+        }
+        String resource = "/createBwp";
+        networkExecutor.execute(new NetworkTask(domainId, POST, resource,
+                fcUniToRestBody(fc, uni).toString(),
+                new RequestCallback() {
+                    @Override
+                    public void onSuccess(Response response) {
+                        log.info("BW profile creation request submitted to domain: {}", domainId);
+                    }
+
+                    @Override
+                    public void onError(Response response) {
+                        log.error("BwProfile creation call fail: {}", response.getStatusInfo());
+
+                    }
+                }));
+    }
+
+    @Override
+    public void applyBandwidthProfileResources(CarrierEthernetForwardingConstruct fc, CarrierEthernetUni uni) {
+        DomainId domainId = domainService.getDomain(uni.cp().deviceId());
+        if (domainId == LOCAL || !isLeader(getTopic(domainId))) {
+            return;
+        }
+        String resource = "/applyBwp";
+        networkExecutor.execute(new NetworkTask(domainId, POST, resource, fcUniToRestBody(fc, uni).toString(),
+                new RequestCallback() {
+                    @Override
+                    public void onSuccess(Response response) {
+                        log.info("BW profile activation request submitted to domain: {}", domainId);
+                    }
+
+                    @Override
+                    public void onError(Response response) {
+                        log.error("FAIL BW profile activation: {}", response.getStatusInfo());
+
+                    }
+                }));
+    }
+
+    @Override
+    public void removeBandwidthProfileResources(CarrierEthernetForwardingConstruct fc, CarrierEthernetUni uni) {
+        DomainId domainId = domainService.getDomain(uni.cp().deviceId());
+        if (domainId == LOCAL || !isLeader(getTopic(domainId))) {
+            return;
+        }
+        String resource = "/deleteBwp";
+        networkExecutor.execute(new NetworkTask(domainId, POST, resource,
+                fcUniToRestBody(fc, uni).toString(),
+                new RequestCallback() {
+                    @Override
+                    public void onSuccess(Response response) {
+                        log.info("BW profile creation request submitted to domain: {}", domainId);
+                    }
+
+                    @Override
+                    public void onError(Response response) {
+                        log.info("FAIL BW profile creation: {}", response.getStatusInfo());
+
+                    }
+                }));
+    }
+
+    @Override
+    public void removeAllForwardingResources(EvcConnId fcId) {
+        Set<DomainId> domainIds = domainService.getDomainIds();
+        String resource = "/deleteFcResources/" + fcId.id();
+        domainIds.forEach(domainId -> {
+            if (isLeader(getTopic(domainId))) {
+                networkExecutor.execute(new NetworkTask(domainId, DELETE, resource,
+                        null, new RequestCallback() {
+                            @Override
+                            public void onSuccess(Response response) {
+
+                            }
+
+                            @Override
+                            public void onError(Response response) {
+
+                            }
+                }));
+            }
+        });
+
+    }
+
+    private ObjectNode fcUniToRestBody(CarrierEthernetForwardingConstruct fc, CarrierEthernetUni uni) {
+        JsonCodec<CarrierEthernetForwardingConstruct> fcCodec =
+                codecContext.codec(CarrierEthernetForwardingConstruct.class);
+        JsonCodec<CarrierEthernetNetworkInterface> niCodec =
+                codecContext.codec(CarrierEthernetNetworkInterface.class);
+        ObjectNode body = codecContext.mapper().createObjectNode();
+        body.set(FC, fcCodec.encode(fc, codecContext));
+        body.set(UNI, niCodec.encode(uni, codecContext));
+        return body;
+    }
+
+    private class NetworkTask implements Runnable {
+        private String method;
+        private String resource;
+        private String body;
+        private DomainId domainId;
+        private RequestCallback callback;
+
+        NetworkTask(DomainId domainId, String method, String resource, String body,
+                    RequestCallback callback) {
+            this.domainId = domainId;
+            this.method = method;
+            this.resource = resource;
+            this.body = body;
+            this.callback = callback;
+        }
+        @Override
+        public void run() {
+
+            synchronized (this) {
+                while (domainsEndPointsMap.get(domainId) == null) {
+                    log.info("End point object missing for domain {}." +
+                            "\nPossibly the Bundle configuration is missing ", domainId);
+                    try {
+                        wait();
+                    } catch (InterruptedException ie) {
+                        log.info("Interrupted exception: " + ie.getMessage());
+                    }
+
+                }
+            }
+            DomainEndPoint endPoint = domainsEndPointsMap.get(domainId).getRight();
+
+            Client client = domainsEndPointsMap.get(domainId).getLeft();
+
+            String url = HTTP + COLON + DOUBLESLASH + endPoint.publicIp().toString() + COLON +
+                    endPoint.port() + BASE_URL + "/carrierethernet" + resource;
+            log.info("DEBUG {}: Sending data via http: {}", url, body);
+
+            WebTarget webTarget = client.target(url);
+            Response response;
+            switch (method) {
+                case POST:
+                    response = webTarget.request(MediaType.APPLICATION_JSON)
+                            .post(Entity.entity(body, MediaType.APPLICATION_JSON));
+                    break;
+                case DELETE:
+                    response = webTarget.request(MediaType.APPLICATION_JSON).delete();
+                    break;
+                case GET:
+                default:
+                    response = webTarget.request(MediaType.APPLICATION_JSON).get();
+                    break;
+            }
+
+            if (!checkReply(response)) {
+                callback.onError(response);
+            } else {
+                callback.onSuccess(response);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/package-info.java b/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/package-info.java
new file mode 100644
index 0000000..fd18189
--- /dev/null
+++ b/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-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.
+ */
+
+/**
+ * Implementation of the client-side communication channel APIs.
+ */
+package org.opencord.ce.global.channel.client;
\ No newline at end of file
diff --git a/global/http-channel/src/main/java/org/opencord/ce/global/channel/package-info.java b/global/http-channel/src/main/java/org/opencord/ce/global/channel/package-info.java
new file mode 100644
index 0000000..a77b5a4
--- /dev/null
+++ b/global/http-channel/src/main/java/org/opencord/ce/global/channel/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-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.
+ */
+
+/**
+ * Implementation of the communication channel APIs.
+ */
+package org.opencord.ce.global.channel;
\ No newline at end of file
diff --git a/global/http-channel/src/main/java/org/opencord/ce/global/channel/server/DeviceResource.java b/global/http-channel/src/main/java/org/opencord/ce/global/channel/server/DeviceResource.java
new file mode 100644
index 0000000..96e6714
--- /dev/null
+++ b/global/http-channel/src/main/java/org/opencord/ce/global/channel/server/DeviceResource.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.channel.server;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.opencord.ce.api.services.virtualprovider.DefaultDomainVirtualDevice;
+import org.opencord.ce.api.services.virtualprovider.DomainVirtualDevice;
+import org.opencord.ce.api.services.virtualprovider.EcordDeviceProviderService;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.device.DefaultPortDescription;
+import org.onosproject.net.device.PortDescription;
+import org.onosproject.net.domain.DomainId;
+import org.onosproject.rest.AbstractWebResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Remote device REST control.
+ */
+@Path("/topology/{domainId}")
+public class DeviceResource extends AbstractWebResource {
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private EcordDeviceProviderService ecordDeviceProviderService =
+            get(EcordDeviceProviderService.class);
+
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("{deviceId}")
+    public Response postDevice(@PathParam("domainId") String domainId, @PathParam("deviceId") String deviceId,
+                               InputStream stream) {
+        log.info("Notified device from domainId {}", domainId);
+        try {
+            JsonNode responseBody = mapper().readTree(stream);
+            // the json body superfluous now. Can be used to add annotations to the device later
+            log.debug(responseBody.toString());
+            DomainVirtualDevice domainDevice = new DefaultDomainVirtualDevice(DeviceId.deviceId(deviceId),
+                    DomainId.domainId(domainId));
+            ecordDeviceProviderService.connectRemoteDevice(domainDevice);
+            return Response.status(200).build();
+        } catch (IOException io) {
+            log.info("Json parse error");
+            return Response.status(Response.Status.NOT_ACCEPTABLE).build();
+        }
+    }
+
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("{deviceId}/ports")
+    public Response postBigSwitchPorts(@PathParam("domainId") String domainId, @PathParam("deviceId") String deviceId,
+                                       InputStream stream) {
+        log.info("Notified device port from domainId {}", domainId);
+        try {
+            JsonNode responseBody = mapper().readTree(stream);
+            log.debug(responseBody.toString());
+            JsonCodec<Port> portCodec = codec(Port.class);
+            List<PortDescription> ports = new ArrayList<>();
+            responseBody.forEach(item -> {
+                Port port = portCodec.decode((ObjectNode) item, this);
+                DefaultAnnotations.Builder annot = DefaultAnnotations.builder();
+                port.annotations().keys()
+                        .forEach(k -> annot.set(k, port.annotations().value(k)));
+                ports.add(new DefaultPortDescription(port.number(), port.isEnabled(), port.type(),
+                        port.portSpeed(), annot.build()));
+            });
+
+            ecordDeviceProviderService.addOrUpdateRemotePorts(DomainId.domainId(domainId),
+                    DeviceId.deviceId(deviceId), ports);
+            return Response.status(200).build();
+
+        } catch (IOException io) {
+            log.info("Json parse error");
+            return Response.status(Response.Status.NOT_ACCEPTABLE).build();
+        }
+
+    }
+}
diff --git a/global/http-channel/src/main/java/org/opencord/ce/global/channel/server/EcordGlobalRestApp.java b/global/http-channel/src/main/java/org/opencord/ce/global/channel/server/EcordGlobalRestApp.java
new file mode 100644
index 0000000..c0d9afd
--- /dev/null
+++ b/global/http-channel/src/main/java/org/opencord/ce/global/channel/server/EcordGlobalRestApp.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.channel.server;
+
+import org.onlab.rest.AbstractWebApplication;
+
+import java.util.Set;
+
+/**
+ * Loader class for web resource APIs.
+ */
+public class EcordGlobalRestApp extends AbstractWebApplication {
+
+    @Override
+    public Set<Class<?>> getClasses() {
+        return getClasses(DeviceResource.class);
+    }
+}
diff --git a/global/http-channel/src/main/java/org/opencord/ce/global/channel/server/package-info.java b/global/http-channel/src/main/java/org/opencord/ce/global/channel/server/package-info.java
new file mode 100644
index 0000000..e82f4d2
--- /dev/null
+++ b/global/http-channel/src/main/java/org/opencord/ce/global/channel/server/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-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.
+ */
+
+/**
+ * Implementation of the server-side communication channel APIs.
+ */
+package org.opencord.ce.global.channel.server;
\ No newline at end of file
diff --git a/global/http-channel/src/main/webapp/WEB-INF/web.xml b/global/http-channel/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..07cceef
--- /dev/null
+++ b/global/http-channel/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2017-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.
+  -->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
+         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         id="ONOS" version="2.5">
+    <display-name>ECORD REST API v1.0</display-name>
+
+    <servlet>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
+        <init-param>
+            <param-name>javax.ws.rs.Application</param-name>
+            <param-value>org.opencord.ce.global.channel.server.EcordGlobalRestApp</param-value>
+        </init-param>
+        <load-on-startup>10</load-on-startup>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+</web-app>
diff --git a/global/pom.xml b/global/pom.xml
new file mode 100644
index 0000000..26f40d0
--- /dev/null
+++ b/global/pom.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2017-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.
+  -->
+<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">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opencord</groupId>
+        <artifactId>ce</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+
+    <groupId>org.opencord.ce</groupId>
+    <artifactId>global</artifactId>
+    <packaging>pom</packaging>
+    <version>1.0.0-SNAPSHOT</version>
+
+    <description>Multi-CORD orchestration of Carrier Ethernet services</description>
+
+    <properties>
+        <onos.version>1.10.6</onos.version>
+        <onos.app.title>E-CORD global orchestrator</onos.app.title>
+        <onos.app.url>http://opencord.org</onos.app.url>
+    </properties>
+
+    <modules>
+        <module>ce-orchestration</module>
+        <module>virtualprovider</module>
+        <module>http-channel</module>
+        <module>app</module>
+    </modules>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.opencord.ce</groupId>
+            <artifactId>ce-api</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.onosproject</groupId>
+                <artifactId>onos-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+    <repositories>
+        <repository>
+            <id>snapshots</id>
+            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+            <releases><enabled>false</enabled></releases>
+        </repository>
+    </repositories>
+
+    <pluginRepositories>
+        <pluginRepository>
+            <id>snapshots</id>
+            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+            <releases><enabled>false</enabled></releases>
+        </pluginRepository>
+    </pluginRepositories>
+
+</project>
diff --git a/global/virtualprovider/pom.xml b/global/virtualprovider/pom.xml
new file mode 100644
index 0000000..0438e93
--- /dev/null
+++ b/global/virtualprovider/pom.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2017-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.
+  -->
+<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">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opencord.ce</groupId>
+        <artifactId>global</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>virtualprovider</artifactId>
+    <packaging>bundle</packaging>
+
+    <description>Topology provider in the global orchestrator</description>
+
+    <properties>
+        <onos.app.name>org.opencord.ce.global.vprovider</onos.app.name>
+        <onos.version>1.10.6</onos.version>
+        <onos.app.url>http://opencord.org</onos.app.url>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+            <version>${onos.version}</version>
+        </dependency>
+    </dependencies>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.onosproject</groupId>
+                <artifactId>onos-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+    <repositories>
+        <repository>
+            <id>snapshots</id>
+            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+            <releases><enabled>false</enabled></releases>
+        </repository>
+    </repositories>
+
+    <pluginRepositories>
+        <pluginRepository>
+            <id>snapshots</id>
+            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+            <releases><enabled>false</enabled></releases>
+        </pluginRepository>
+    </pluginRepositories>
+
+</project>
diff --git a/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/VirtualDomainDeviceProvider.java b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/VirtualDomainDeviceProvider.java
new file mode 100644
index 0000000..d1bdefb
--- /dev/null
+++ b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/VirtualDomainDeviceProvider.java
@@ -0,0 +1,389 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.virtualdomain;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+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.apache.felix.scr.annotations.Service;
+import org.onosproject.net.config.basics.SubjectFactories;
+import org.opencord.ce.api.services.virtualprovider.DomainVirtualDevice;
+import org.opencord.ce.api.services.virtualprovider.EcordDeviceProviderService;
+import org.onlab.packet.ChassisId;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.mastership.MastershipAdminService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.SparseAnnotations;
+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.config.NetworkConfigService;
+import org.onosproject.net.device.DefaultDeviceDescription;
+import org.onosproject.net.device.DeviceDescription;
+import org.onosproject.net.device.DeviceProvider;
+import org.onosproject.net.device.DeviceProviderRegistry;
+import org.onosproject.net.device.DeviceProviderService;
+import org.onosproject.net.device.PortDescription;
+import org.onosproject.net.domain.DomainId;
+import org.onosproject.net.provider.ProviderId;
+import org.opencord.ce.api.models.CarrierEthernetEnni;
+import org.opencord.ce.api.models.CarrierEthernetGenericNi;
+import org.opencord.ce.api.models.CarrierEthernetInni;
+import org.opencord.ce.api.models.CarrierEthernetLogicalTerminationPoint;
+import org.opencord.ce.api.models.CarrierEthernetNetworkInterface;
+import org.opencord.ce.api.models.CarrierEthernetUni;
+import org.opencord.ce.api.services.MetroOrchestrationService;
+import org.opencord.ce.global.virtualdomain.config.EcordDriverConfig;
+import org.opencord.ce.global.virtualdomain.config.XosEndPointConfig;
+import org.slf4j.Logger;
+
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+
+import static java.util.concurrent.Executors.newFixedThreadPool;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.net.AnnotationKeys.DRIVER;
+import static org.onosproject.net.AnnotationKeys.LATITUDE;
+import static org.onosproject.net.AnnotationKeys.LONGITUDE;
+import static org.slf4j.LoggerFactory.getLogger;
+import static org.opencord.ce.api.models.CarrierEthernetNetworkInterface.Type;
+
+/**
+ * Exposes remote domain devices to the core.
+ */
+@Component(immediate = true)
+@Service(value = EcordDeviceProviderService.class)
+public class VirtualDomainDeviceProvider
+        implements DeviceProvider, EcordDeviceProviderService {
+    private final Logger log = getLogger(getClass());
+    public static final String PROVIDER_NAME = "org.opencord.ce.global.vprovider";
+    public static final ProviderId PROVIDER_ID = new ProviderId("domain", PROVIDER_NAME);
+    private static final String UNKNOWN = "unknown";
+    private static final String NO_LLDP = "no-lldp";
+    private static final String DOMAIN_ID = "domainId";
+    private static final String MEF_IF_TYPE = "mefIfType";
+
+    private ApplicationId appId;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry configRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService configService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceProviderRegistry deviceProviderRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipAdminService mastershipAdminService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ClusterService clusterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MetroOrchestrationService metroOrchestrationService;
+
+    protected DeviceProviderService deviceProviderService;
+
+    private EcordDriverConfig ecordDriverConfig;
+    private XoSHttpClient xoSHttpClient;
+
+    private final NetworkConfigListener configListener = new InternalConfigListener();
+
+    /*
+    private final ConfigFactory<ApplicationId, EcordDriverConfig> diverConfigFactory =
+            new ConfigFactory<ApplicationId, EcordDriverConfig>(APP_SUBJECT_FACTORY,
+                    EcordDriverConfig.class, "driver") {
+                @Override
+                public EcordDriverConfig createConfig() {
+                    return new EcordDriverConfig();
+                }
+            };
+            */
+
+    private final ConfigFactory<ApplicationId, XosEndPointConfig> xosEndpointConfigFactory =
+            new ConfigFactory<ApplicationId, XosEndPointConfig>(SubjectFactories.APP_SUBJECT_FACTORY,
+                    XosEndPointConfig.class, "xos") {
+                @Override
+                public XosEndPointConfig createConfig() {
+                    return new XosEndPointConfig();
+                }
+            };
+
+    private final ExecutorService eventExecutor =
+            newFixedThreadPool(3,
+                    groupedThreads("onos/ecord-sb-manager", "event-handler-%d"));
+
+    @Activate
+    public void activate() {
+        appId = coreService.registerApplication(PROVIDER_NAME);
+       // configRegistry.registerConfigFactory(diverConfigFactory);
+        configRegistry.registerConfigFactory(xosEndpointConfigFactory);
+        configService.addListener(configListener);
+        deviceProviderService = deviceProviderRegistry.register(this);
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        //configRegistry.unregisterConfigFactory(diverConfigFactory);
+        configRegistry.unregisterConfigFactory(xosEndpointConfigFactory);
+        configService.removeListener(configListener);
+        deviceProviderRegistry.unregister(this);
+        log.info("Stopped");
+    }
+
+    @Override
+    public ProviderId id() {
+        return PROVIDER_ID;
+    }
+
+    // ==== DeviceProvider ====
+    @Override
+    public void triggerProbe(DeviceId deviceId) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
+
+    }
+
+    @Override
+    public boolean isReachable(DeviceId deviceId) {
+        // TODO
+        return true;
+    }
+
+    @Override
+    public void changePortState(DeviceId deviceId, PortNumber portNumber,
+                                boolean enable) {
+        // TODO
+    }
+
+    // ===== EcordDeviceProviderService =====
+    @Override
+    public void connectRemoteDevice(DomainVirtualDevice domainDevice) {
+        DomainId domainId = domainDevice.domainId();
+        DeviceId deviceId = domainDevice.deviceId();
+        advertiseDevice(deviceId, domainId);
+       // advertiseDevicePorts(deviceId, domainDevice.ports());
+    }
+
+    @Override
+    public void addOrUpdateRemotePorts(DomainId domainId, DeviceId deviceId,
+                                       List<PortDescription> ports) {
+        advertiseDevicePorts(deviceId, ports);
+    }
+
+    @Override
+    public void addRemotePort(DomainId domainId, DeviceId deviceId, Port newPort) {
+    }
+
+    @Override
+    public void updateRemotePortState(DomainId domainId, DeviceId deviceId, Port port) {
+        // TODO
+    }
+
+    @Override
+    public void disconnectRemoteDevice(DomainId domainId, DeviceId deviceId) {
+        disconnectDevice(deviceId);
+    }
+
+    @Override
+    public void removeRemotePort(DomainId domainId, DeviceId deviceId, PortNumber portNumber) {
+        // TODO
+    }
+
+    /**
+     * Notify the core system that a new domain device is on.
+     * @param deviceId remote device identifier
+     */
+    private void advertiseDevice(DeviceId deviceId, DomainId domainId) {
+        ChassisId chassisId = new ChassisId();
+        log.info("Notifying ecord virtual device...");
+        mastershipAdminService.setRole(clusterService.getLocalNode().id(), deviceId,
+                MastershipRole.MASTER);
+
+        // disable lldp for this virtual device and annotate it with the proper driver
+       // String driverKey = ecordDriverConfig.manufacturer() + "-" + ecordDriverConfig.hwVersion() + "-" +
+         //       ecordDriverConfig.swVersion();
+        String driverKey = "onLab-1.0.0-1.0.0";
+        SparseAnnotations annotations = DefaultAnnotations.builder()
+                .set(NO_LLDP, "any")
+                .set(DOMAIN_ID, domainId.id())
+                .set(DRIVER, driverKey)
+                .build();
+
+        DeviceDescription deviceDescription = new DefaultDeviceDescription(
+                deviceId.uri(),
+                Device.Type.SWITCH,
+                "onLab", "1.0.0",
+                "1.0.0", UNKNOWN,
+                chassisId,
+                annotations);
+        deviceProviderService.deviceConnected(deviceId, deviceDescription);
+    }
+
+    /**
+     * Notify the core system of all ports of a domain device.
+     * @param deviceId device identifier
+     * @param portDescriptions description of ports
+     */
+    private void advertiseDevicePorts(DeviceId deviceId, List<PortDescription> portDescriptions) {
+        log.info("Notifying ecord virtual ports...");
+        deviceProviderService.updatePorts(deviceId, portDescriptions);
+       // addGlobalMefLtp(deviceId, portDescriptions);
+        notifyXoS(deviceId, portDescriptions);
+    }
+
+    private void disconnectDevice(DeviceId deviceId) {
+        deviceProviderService.deviceDisconnected(deviceId);
+    }
+
+    private void notifyXoS(DeviceId deviceId, List<PortDescription> portDescriptions) {
+        portDescriptions.forEach(port -> {
+            if (port.annotations().keys().contains(MEF_IF_TYPE)) {
+                Type type = Type.valueOf(
+                        port.annotations().value(MEF_IF_TYPE));
+                ConnectPoint cp = new ConnectPoint(deviceId, port.portNumber());
+                switch (type) {
+                    case UNI:
+                        ObjectNode body = xoSHttpClient.mapper().createObjectNode();
+                        body.put("tenant", port.annotations().value(DOMAIN_ID));
+                        body.put("name", "UNI:" + cp.toString());
+                        body.put("latlng", "[" + port.annotations().value(LATITUDE) + "," +
+                                port.annotations().value(LONGITUDE) + "]");
+                        body.put("cpe_id", cp.toString());
+                        xoSHttpClient.restPut(body.toString(), cp.toString());
+                        break;
+                    case ENNI:
+
+                        break;
+                    case INNI:
+
+                        break;
+                    case GENERIC:
+
+                        break;
+                    default:
+                        return;
+                }
+            }
+        });
+    }
+
+    /**
+     * Adds global {@link CarrierEthernetLogicalTerminationPoint}
+     * to {@link MetroOrchestrationService}.
+     *
+     * @param deviceId subject device ID
+     * @param portDescriptions list of notified ports
+     */
+    private void addGlobalMefLtp(DeviceId deviceId, List<PortDescription> portDescriptions) {
+        portDescriptions.forEach(port -> {
+            if (port.annotations().keys().contains(MEF_IF_TYPE)) {
+                Type type = Type.valueOf(
+                        port.annotations().value(MEF_IF_TYPE));
+                CarrierEthernetNetworkInterface ni;
+                ConnectPoint cp = new ConnectPoint(deviceId, port.portNumber());
+                switch (type) {
+                    case UNI:
+                        ni = CarrierEthernetUni.builder()
+                                .cp(cp)
+                                .annotations(port.annotations())
+                                .build();
+                        break;
+                    case ENNI:
+                        ni = CarrierEthernetEnni.builder()
+                                .cp(cp)
+                                .build();
+                        break;
+                    case INNI:
+                        ni = CarrierEthernetInni.builder()
+                                .cp(cp)
+                                .annotations(port.annotations())
+                                .build();
+                        break;
+                    case GENERIC:
+                        ni = new CarrierEthernetGenericNi(cp, null, port.annotations());
+                        break;
+                    default:
+                            return;
+                }
+                metroOrchestrationService.addGlobalLtp(
+                        new CarrierEthernetLogicalTerminationPoint(null, ni));
+            }
+        });
+    }
+
+    private void readXoSEndPointConfig() {
+        xoSHttpClient =
+                new XoSHttpClient(configRegistry.getConfig(appId, XosEndPointConfig.class).xos());
+    }
+
+    private void readDriverFromConfig() {
+        ecordDriverConfig =
+                configRegistry.getConfig(appId, EcordDriverConfig.class);
+    }
+
+    private class InternalConfigListener implements NetworkConfigListener {
+        @Override
+        public void event(NetworkConfigEvent event) {
+            if (!event.configClass().equals(EcordDriverConfig.class) ||
+                    !event.configClass().equals(XosEndPointConfig.class)) {
+                return;
+            }
+            switch (event.type()) {
+                case CONFIG_ADDED:
+                    log.info("Network configuration added");
+                    if (event.configClass().equals(EcordDriverConfig.class)) {
+                        eventExecutor.execute(VirtualDomainDeviceProvider.this::readDriverFromConfig);
+                    } else {
+                        eventExecutor.execute(VirtualDomainDeviceProvider.this::readXoSEndPointConfig);
+                    }
+
+                    break;
+                case CONFIG_UPDATED:
+                    log.info("Network configuration updated");
+                    if (event.configClass().equals(EcordDriverConfig.class)) {
+                        eventExecutor.execute(VirtualDomainDeviceProvider.this::readDriverFromConfig);
+                    } else {
+                        eventExecutor.execute(VirtualDomainDeviceProvider.this::readXoSEndPointConfig);
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
diff --git a/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/VirtualLinkProvider.java b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/VirtualLinkProvider.java
new file mode 100644
index 0000000..361d74c
--- /dev/null
+++ b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/VirtualLinkProvider.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.virtualdomain;
+
+import com.google.common.collect.Maps;
+import org.apache.commons.lang3.tuple.Pair;
+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.CoreService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.Port;
+import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.link.DefaultLinkDescription;
+import org.onosproject.net.link.LinkDescription;
+import org.onosproject.net.link.LinkEvent;
+import org.onosproject.net.link.LinkListener;
+import org.onosproject.net.link.LinkProvider;
+import org.onosproject.net.link.LinkProviderRegistry;
+import org.onosproject.net.link.LinkProviderService;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.net.provider.ProviderId;
+import org.opencord.ce.api.services.virtualprovider.LinkId;
+import org.slf4j.Logger;
+
+import java.util.Map;
+
+import static org.onosproject.net.Link.Type.INDIRECT;
+import static org.slf4j.LoggerFactory.getLogger;
+import static org.opencord.ce.global.virtualdomain.VirtualDomainDeviceProvider.PROVIDER_NAME;
+
+/**
+ * Domain interlinks provider.
+ */
+@Component(immediate = true)
+public class VirtualLinkProvider implements LinkProvider {
+    public static final ProviderId PROVIDER_ID = new ProviderId("domain", PROVIDER_NAME);
+    public static final String INTERLINK_ID = "interlinkId";
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkProviderRegistry linkProviderRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkService linkService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    private final Map<LinkId, ConnectPoint> stagedInterlinks = Maps.newConcurrentMap();
+    private final Map<LinkId, Pair<ConnectPoint, ConnectPoint>>
+            committedInterlinks = Maps.newConcurrentMap();
+    private final DeviceListener deviceListener = new InternalDeviceListener();
+    private final LinkListener linkListener = new InternalLinkListener();
+
+    protected LinkProviderService linkProviderService;
+
+    @Activate
+    public void activate() {
+        coreService.registerApplication(PROVIDER_NAME);
+        linkProviderService = linkProviderRegistry.register(this);
+        deviceService.addListener(deviceListener);
+        linkService.addListener(linkListener);
+        log.info("Started");
+
+    }
+
+    @Deactivate
+    public void deactivate() {
+        linkProviderRegistry.unregister(this);
+        deviceService.removeListener(deviceListener);
+        linkService.removeListener(linkListener);
+        log.info("Stopped");
+    }
+
+
+    @Override
+    public ProviderId id() {
+        return PROVIDER_ID;
+    }
+
+    private void addInterLink(ConnectPoint point1, ConnectPoint point2, LinkId linkId) {
+        SparseAnnotations annotations = DefaultAnnotations.builder()
+                .set(INTERLINK_ID, linkId.id())
+                .build();
+        LinkDescription linkDescription = new DefaultLinkDescription(point1, point2,
+                INDIRECT, true, annotations);
+        linkProviderService.linkDetected(linkDescription);
+    }
+
+    private class InternalLinkListener implements LinkListener {
+
+        @Override
+        public void event(LinkEvent event) {
+            Link link = event.subject();
+            switch (event.type()) {
+                case LINK_REMOVED:
+                   if (link.annotations().keys().contains(INTERLINK_ID)) {
+                       committedInterlinks.remove(LinkId.linkId(
+                               link.annotations().value(INTERLINK_ID)
+                       ));
+                   }
+                case LINK_ADDED:
+                    // not relevant for now
+                default:
+            }
+        }
+    }
+
+
+    private class InternalDeviceListener implements DeviceListener {
+        @Override
+        public boolean isRelevant(DeviceEvent event) {
+            return (event.type().equals(DeviceEvent.Type.PORT_ADDED) ||
+                    event.type().equals(DeviceEvent.Type.PORT_REMOVED) ||
+                    event.type().equals(DeviceEvent.Type.PORT_UPDATED)) &&
+                    event.port().annotations().keys().contains(INTERLINK_ID);
+        }
+
+        @Override
+        public void event(DeviceEvent event) {
+
+            Port port = event.port();
+            DeviceId subjectDeviceId = event.subject().id();
+            LinkId linkId = LinkId.linkId(port.annotations().value(INTERLINK_ID));
+
+            switch (event.type()) {
+                case PORT_ADDED:
+                case PORT_UPDATED:
+                    if (committedInterlinks.containsKey(linkId)) {
+                        // !!!! ===== !!!! //
+                        // committed interlinks cannot be subject to changes
+                        // unless a port is removed.
+                        // Possibly this is an error condition
+                        log.info("notified interlinks cannot be subject to changes," +
+                                "unless a port of the link is removed. Possibly this is" +
+                                "an error condition");
+                        return;
+                    } else {
+                        log.info("Adding virtual inter-links...");
+                        if (stagedInterlinks.containsKey(linkId)) {
+                            ConnectPoint point1 =
+                                    stagedInterlinks.get(linkId);
+                            ConnectPoint point2 =
+                                    new ConnectPoint(subjectDeviceId, port.number());
+                            if (subjectDeviceId.equals(point1.deviceId())) {
+                                return;
+                            }
+
+                            committedInterlinks.put(linkId, Pair.of(point1, point2));
+                            stagedInterlinks.remove(linkId);
+
+                            // only the master instance of the destination link can notify the link
+                            if (mastershipService.getLocalRole(point2.deviceId())
+                                    .equals(MastershipRole.MASTER)) {
+                                addInterLink(point1, point2, linkId);
+                            }
+                            if (mastershipService.getLocalRole(point1.deviceId())
+                                    .equals(MastershipRole.MASTER)) {
+                                addInterLink(point2, point1, linkId);
+                            }
+                        } else {
+                            stagedInterlinks.put(linkId,
+                                    new ConnectPoint(subjectDeviceId, port.number()));
+                        }
+                    }
+                    break;
+                case PORT_REMOVED:
+                    if (committedInterlinks.containsKey(linkId)) {
+                        Pair<ConnectPoint, ConnectPoint> points =
+                                committedInterlinks.get(linkId);
+                        committedInterlinks.remove(linkId);
+                        if (points.getLeft().deviceId().equals(subjectDeviceId)) {
+                            linkProviderService.linksVanished(points.getLeft());
+                            stagedInterlinks.put(linkId, points.getRight());
+                        } else {
+                            linkProviderService.linksVanished(points.getRight());
+                            stagedInterlinks.put(linkId, points.getLeft());
+                        }
+                    } else if (stagedInterlinks.containsKey(linkId)) {
+                        stagedInterlinks.remove(linkId);
+                    }
+                    break;
+                default:
+            }
+        }
+    }
+}
diff --git a/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/XoSHttpClient.java b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/XoSHttpClient.java
new file mode 100644
index 0000000..1d72b40
--- /dev/null
+++ b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/XoSHttpClient.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.virtualdomain;
+
+import com.fasterxml.jackson.databind.SerializationFeature;
+import org.glassfish.jersey.client.ClientProperties;
+import org.onosproject.rest.AbstractWebResource;
+import org.slf4j.Logger;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import static java.net.HttpURLConnection.HTTP_OK;
+import static org.slf4j.LoggerFactory.getLogger;
+import static org.opencord.ce.global.virtualdomain.config.XosEndPointConfig.XosEndPoint;
+
+/**
+ * Implementation of REST client for XOS Metro-net service.
+ */
+public class XoSHttpClient extends AbstractWebResource {
+    protected final Logger log = getLogger(getClass());
+
+    private static final int DEFAULT_TIMEOUT_MS = 2000;
+
+    private XosEndPoint xosEndPoint;
+    private final Client client = ClientBuilder.newClient();
+
+
+    public XoSHttpClient(XosEndPoint xosEndPoint) {
+        this.xosEndPoint = xosEndPoint;
+
+        client.property(ClientProperties.CONNECT_TIMEOUT, DEFAULT_TIMEOUT_MS);
+        client.property(ClientProperties.READ_TIMEOUT, DEFAULT_TIMEOUT_MS);
+        mapper().enable(SerializationFeature.INDENT_OUTPUT);
+    }
+
+    public void restPut(String body, String cpeId) {
+        WebTarget webTarget = client.target("http://" + xosEndPoint.ipAddress().toString() +
+                 xosEndPoint.resource() + "/" + cpeId);
+        Response response;
+        response = webTarget.request(MediaType.APPLICATION_JSON)
+                .put(Entity.entity(body, MediaType.APPLICATION_JSON));
+        try {
+            if (response.getStatus() != HTTP_OK) {
+                log.warn("Failed to put resource {}", xosEndPoint.resource());
+            }
+        } catch (javax.ws.rs.ProcessingException e) {
+            log.error("Javax process exception in XoSClientHttp: {}", e.getMessage());
+        }
+    }
+}
diff --git a/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/config/EcordDriverConfig.java b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/config/EcordDriverConfig.java
new file mode 100644
index 0000000..1077993
--- /dev/null
+++ b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/config/EcordDriverConfig.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.virtualdomain.config;
+
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.config.Config;
+
+/**
+ * ICONA driver configuration class.
+ */
+public class EcordDriverConfig extends Config<ApplicationId> {
+
+    private static final String MANUFACTURER = "manufacturer";
+    private static final String SW_VERSION = "swVersion";
+    private static final String HW_VERSION = "hwVersion";
+
+
+    public String manufacturer() {
+        return object.get(MANUFACTURER).asText();
+    }
+
+    public String swVersion() {
+        return object.get(SW_VERSION).asText();
+    }
+
+    public String hwVersion() {
+        return  object.get(HW_VERSION).asText();
+    }
+
+}
diff --git a/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/config/XosEndPointConfig.java b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/config/XosEndPointConfig.java
new file mode 100644
index 0000000..df0c59e
--- /dev/null
+++ b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/config/XosEndPointConfig.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2017-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.opencord.ce.global.virtualdomain.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.onlab.packet.IpAddress;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.config.Config;
+
+/**
+ * Global XoS endpoint.
+ */
+public class XosEndPointConfig extends Config<ApplicationId> {
+    private static final String USERNAME = "username";
+    private static final String PASSWD = "password";
+    private static final String XOS = "xos";
+    private static final String ADDRESS = "address";
+    private static final String RESOURCE = "resource";
+
+    public XosEndPoint xos() {
+        JsonNode xosNode = object.path(XOS);
+        IpAddress ipAddress = IpAddress.valueOf(xosNode.get(ADDRESS).asText());
+        String username = xosNode.get(USERNAME).asText();
+        String password = xosNode.get(PASSWD).asText();
+        String resource = xosNode.get(RESOURCE).asText();
+        return new XosEndPoint(ipAddress, username, password, resource);
+    }
+
+    public static class XosEndPoint {
+        private IpAddress ipAddress;
+        private String username;
+        private String password;
+        private String resource;
+
+        public XosEndPoint(IpAddress ipAddress, String username,
+                           String password, String resource) {
+            this.ipAddress = ipAddress;
+            this.username = username;
+            this.password = password;
+            this.resource = resource;
+        }
+
+        public IpAddress ipAddress() {
+            return ipAddress;
+        }
+
+        public String username() {
+            return username;
+        }
+
+        public String password() {
+            return password;
+        }
+
+        public String resource() {
+            return resource;
+        }
+    }
+
+}
diff --git a/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/config/package-info.java b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/config/package-info.java
new file mode 100644
index 0000000..62fbacc
--- /dev/null
+++ b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/config/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-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.
+ */
+
+/**
+ * Configuration classes.
+ */
+package org.opencord.ce.global.virtualdomain.config;
\ No newline at end of file
diff --git a/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/package-info.java b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/package-info.java
new file mode 100644
index 0000000..c71407e
--- /dev/null
+++ b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-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 for domain topology provider.
+ */
+package org.opencord.ce.global.virtualdomain;
\ No newline at end of file
