diff --git a/global/app/app.xml b/global/app/app.xml
new file mode 100644
index 0000000..9169c46
--- /dev/null
+++ b/global/app/app.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ Copyright 2016-present Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<app name="org.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..ab94ece
--- /dev/null
+++ b/global/app/features.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+
+<!--
+  ~ Copyright 2016-present Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
+    <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..1684fea
--- /dev/null
+++ b/global/app/pom.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2016-present Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opencord.ce</groupId>
+        <artifactId>global</artifactId>
+        <version>1.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>ecord-global-app</artifactId>
+    <packaging>pom</packaging>
+
+    <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..ac7f64f
--- /dev/null
+++ b/global/ce-orchestration/pom.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2015-present Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opencord.ce</groupId>
+        <artifactId>global</artifactId>
+        <version>1.0.0</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.3</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..62c3fce
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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..d9aa564
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/MetroOrchestrationManager.java
@@ -0,0 +1,1343 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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.models.codecs.CarrierEthernetBwProfileCodec;
+import org.opencord.ce.api.models.codecs.CarrierEthernetNetworkInterfaceCodec;
+import org.opencord.ce.api.models.codecs.ForwardingConstructCodec;
+import org.opencord.ce.api.models.codecs.LogicalTerminationEndPointCodec;
+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() {
+        codecService.registerCodec(CarrierEthernetNetworkInterface.class,
+                new CarrierEthernetNetworkInterfaceCodec());
+        codecService.registerCodec(CarrierEthernetBandwidthProfile.class,
+                new CarrierEthernetBwProfileCodec());
+        codecService.registerCodec(CarrierEthernetLogicalTerminationPoint.class,
+                new LogicalTerminationEndPointCodec());
+        codecService.registerCodec(CarrierEthernetForwardingConstruct.class,
+                new ForwardingConstructCodec());
+        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();
+        codecService.unregisterCodec(CarrierEthernetNetworkInterface.class);
+        codecService.unregisterCodec(CarrierEthernetBandwidthProfile.class);
+        codecService.unregisterCodec(CarrierEthernetLogicalTerminationPoint.class);
+        codecService.unregisterCodec(CarrierEthernetForwardingConstruct.class);
+    }
+
+    @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..fc5bd84
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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..b2a17ef
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * 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..6e52817
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/cli/commands/CarrierEthernetCreateEvcCommand.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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)).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..301e635
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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..39931c3
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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..00b168a
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * 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..b5e8503
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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..de11682
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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..b4cea6c
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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..f5f3b96
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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..35248a8
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * 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..bb4852f
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * 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..0c891cb
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * 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..3810ea6
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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..9381cf0
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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/EvcCodec.java b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/rest/EvcCodec.java
new file mode 100644
index 0000000..a87725f
--- /dev/null
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/rest/EvcCodec.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.ce.global.orchestration.rest;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.opencord.ce.api.models.CarrierEthernetBandwidthProfile;
+import org.opencord.ce.api.models.CarrierEthernetNetworkInterface;
+import org.opencord.ce.api.models.CarrierEthernetUni;
+import org.opencord.ce.api.models.CarrierEthernetVirtualConnection;
+import org.opencord.ce.api.models.EvcConnId;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.onlab.util.Tools.nullIsIllegal;
+import static org.opencord.ce.api.models.CarrierEthernetEvcUtils.generateEvcType;
+import static org.opencord.ce.api.models.CarrierEthernetEvcUtils.generateMaxNumUni;
+import static org.opencord.ce.api.models.CarrierEthernetEvcUtils.generateUniSet;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implementation of encoder for Alarm codec.
+ */
+public class EvcCodec extends JsonCodec<CarrierEthernetVirtualConnection> {
+
+    private static final String EVC_ID_REQUIRED = "EVC Id Must be specified";
+    private static final String EVC_TYPE_REQUIRED = "EVC Type Must be specified";
+    private static final String ARRAY_REQUIRED = "UNI array was not specified";
+
+    private final Logger log = getLogger(getClass());
+
+    @Override
+    public ObjectNode encode(CarrierEthernetVirtualConnection evc, CodecContext context) {
+        ObjectNode evcRoot = context.mapper().createObjectNode();
+        evcRoot.put("evcCfgId", evc.cfgId());
+        evcRoot.put("evcId", evc.id().id());
+        ArrayNode uniList = context.mapper()
+                .valueToTree(evc.uniSet().stream()
+                        .map(CarrierEthernetNetworkInterface::id)
+                        .collect(Collectors.toList()));
+        evcRoot.putArray("uniList").addAll(uniList);
+        evcRoot.put("maxNumUni", evc.maxNumUni());
+        CarrierEthernetUni uni = evc.uniSet().iterator().next();
+        evcRoot.put("vlanId", uni.ceVlanId().toString());
+        CarrierEthernetBandwidthProfile bwp = uni.bwp();
+        if (bwp != null) {
+            evcRoot.put("cir", bwp.cir().bps());
+            evcRoot.put("eir", bwp.eir().bps());
+            evcRoot.put("cbs", bwp.cbs());
+            evcRoot.put("ebs", bwp.ebs());
+        }
+        return evcRoot;
+    }
+
+    @Override
+    public CarrierEthernetVirtualConnection decode(ObjectNode json, CodecContext context) {
+        String argEvcCfgId = json.get("evcCfgId").asText(null);
+        String argEvcId = null;
+        if (json.has("evcId")) {
+            argEvcId = json.get("evcId").asText();
+        }
+        ArrayNode uniArray = nullIsIllegal((ArrayNode) json.get("uniList"),
+                ARRAY_REQUIRED);
+        List<String> uniList = new ArrayList<>();
+        uniArray.forEach(jsonNode -> uniList.add(jsonNode.asText()));
+        String evcTypeString = nullIsIllegal(json.get("evcType").asText(),
+                EVC_TYPE_REQUIRED);
+        int maxNumUni = -1;
+        if (json.has("maxNumUni")) {
+            maxNumUni = json.get("maxNumUni").asInt(-1);
+        }
+
+        short vlanId = -1;
+        if (json.has("vlanId")) {
+            vlanId = json.get("vlanId").shortValue();
+        }
+        double cir = json.get("cir").asDouble(0.0);
+        double eir = json.get("eir").asDouble(0.0);
+        long cbs = json.get("cbs").asLong(0L);
+        long ebs = json.get("ebs").asLong(0L);
+        log.info("Received REST call with parameters: " + "evcCfgId={}, evcId={}," +
+                        " uniList={}, evcType={}, maxNumUni={}, vlanId={}, cir={}, " +
+                        "eir={}, cbs={}, ebs={}", argEvcCfgId, argEvcId, uniList,
+                evcTypeString, maxNumUni, vlanId, cir, eir, cbs, ebs);
+        return CarrierEthernetVirtualConnection.builder().id(EvcConnId.of(argEvcId)).cfgId(argEvcCfgId)
+                .type(generateEvcType(evcTypeString, uniList))
+                .maxNumUni(generateMaxNumUni(maxNumUni, evcTypeString, uniList))
+                .uniSet(generateUniSet(evcTypeString, uniList.subList(1, uniList.size()),
+                        vlanId, uniList.get(0), argEvcCfgId, cir, eir,
+                        cbs, ebs))
+                .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..547a6bb
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * 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..884297c
--- /dev/null
+++ b/global/ce-orchestration/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -0,0 +1,41 @@
+<!--
+  ~ Copyright 2017-present Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<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..cf45f69
--- /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 Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<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..9d41fb0
--- /dev/null
+++ b/global/config-samples/ecord-global-config.json
@@ -0,0 +1,46 @@
+{
+  "apps" : {
+    "org.opencord.ce.global.vprovider" : {
+      "xos" : {
+        "username" : "Alessandro",
+        "password" : "Lucrezia",
+        "address" : "127.0.0.1",
+        "resource" : "/xosapi/v1/metronet/usernetworkinterfaces/"
+      }
+    },
+    "org.opencord.ce.global.channel.http" : {
+      "endPoints" : {
+        "port" : "8181",
+        "topics" : [
+          "ecord-domains-topic-one",
+          "ecord-domains-topic-two",
+          "ecord-domains-topic-three"
+        ],
+        "domains" :
+        [
+          {
+            "domainId" : "10.128.14.50",
+            "clusterIps" : [
+              "10.128.14.50"
+            ],
+            "port" : "8181",
+            "username" : "sdn",
+            "password" : "rocks",
+            "topic" : "ecord-domains-topic-one"
+          },
+          {
+            "domainId" : "10.128.14.30",
+            "clusterIps" : [
+              "10.128.14.30"
+            ],
+            "port" : "8181",
+            "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..1ff30e9
--- /dev/null
+++ b/global/http-channel/pom.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2015-present Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opencord.ce</groupId>
+        <artifactId>global</artifactId>
+        <version>1.0.0</version>
+    </parent>
+
+    <artifactId>global-channel</artifactId>
+    <packaging>bundle</packaging>
+
+    <description>Http communication channel between hierarchic 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.3</onos.version>
+        <onos.app.url>http://opencord.org</onos.app.url>
+        <project.version>1.0.0</project.version>
+    </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/HttpClientComponent.java b/global/http-channel/src/main/java/org/opencord/ce/global/channel/HttpClientComponent.java
new file mode 100644
index 0000000..d470f9f
--- /dev/null
+++ b/global/http-channel/src/main/java/org/opencord/ce/global/channel/HttpClientComponent.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.ce.global.channel;
+
+
+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.IpAddress;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.cluster.NodeId;
+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.DomainId;
+import org.onosproject.net.domain.DomainService;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.StorageService;
+import org.opencord.ce.api.services.channel.ConnectionService;
+import org.opencord.ce.api.services.channel.ControlChannelListenerService;
+import org.opencord.ce.api.services.channel.EndPoint;
+import org.opencord.ce.global.channel.client.ConnectionConfig;
+import org.opencord.ce.global.channel.client.HttpClientInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.client.Client;
+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)
+@Service(ConnectionService.class)
+public class HttpClientComponent implements ConnectionService {
+    private static final String APP_NAME = "org.opencord.ce.global.channel.http";
+
+    // temporary
+    private static final String TOPIC_ONE = "ecord-domains-topic-one";
+    private static final String TOPIC_TWO = "ecord-domains-topic-two";
+    private static final String TOPIC_THREE = "ecord-domains-topic-three";
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private ApplicationId appId;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ClusterService clusterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LeadershipService leadershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+
+    @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 final Set<EndPoint> endPoints = Sets.newHashSet();
+
+    private ConsistentMap<EndPoint, IpAddress> endPointMasterIpMap;
+
+    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);
+        endPointMasterIpMap = storageService.<EndPoint, IpAddress>consistentMapBuilder()
+                .withName("ecord-domain-endpoints")
+                .withSerializer(Serializer.using(
+                        new KryoNamespace.Builder()
+                                .register(KryoNamespaces.API)
+                                .register(DomainId.class)
+                                .register(EndPoint.class)
+                                .build()
+                )).build();
+        configRegistry.registerConfigFactory(configFactory);
+        configService.addListener(configListener);
+        channelListenerService.addListener(HttpClientInstance.INSTANCE);
+        leadershipService.runForLeadership(TOPIC_ONE);
+        leadershipService.runForLeadership(TOPIC_TWO);
+        leadershipService.runForLeadership(TOPIC_THREE);
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        log.info("Stopped");
+
+        configService.removeListener(configListener);
+        configRegistry.unregisterConfigFactory(configFactory);
+        channelListenerService.removeListener(HttpClientInstance.INSTANCE);
+        leadershipService.withdraw(TOPIC_ONE);
+        leadershipService.withdraw(TOPIC_TWO);
+        leadershipService.withdraw(TOPIC_THREE);
+        HttpClientInstance.INSTANCE.stopNetworkTasks();
+    }
+
+    @Override
+    public IpAddress getLocalMasterIp(String domainId) {
+        synchronized (this) {
+            for (EndPoint ep : endPoints) {
+                if (ep.domainId().id().equals(domainId)) {
+                    String topic = ep.topic();
+                    String masterIp;
+                    String leaderId = leadershipService.getLeader(topic).id();
+                    log.info("local leaderId: " + leaderId);
+                    masterIp = clusterService.getNode(NodeId.nodeId(leaderId)).ip().toString();
+
+                    return IpAddress.valueOf(masterIp);
+                }
+            }
+        }
+        log.info("Found no leader for domain " + domainId +
+                "-- endPoints size: " + endPoints.size());
+        return null;
+    }
+
+    @Override
+    public IpAddress getRemoteMasterIp(String domainId) {
+        synchronized (this) {
+            for (EndPoint ep : endPoints) {
+                if (ep.domainId().id().equals(domainId)) {
+                    return HttpClientInstance.INSTANCE.getRemoteMasterIp(ep);
+                }
+            }
+        }
+        log.info("Found no master ip for domain {}", domainId);
+        return null;
+    }
+
+    @Override
+    public Pair<Client, IpAddress> getConnectionInfo(DomainId domainId) {
+        Client client = HttpClientInstance.INSTANCE
+                .getConnectionInfo(domainId);
+        return Pair.of(client, getRemoteMasterIp(domainId.id()));
+    }
+
+    private void readConfig() {
+        ConnectionConfig config = configRegistry.getConfig(appId, ConnectionConfig.class);
+        log.debug("Domains connections config received");
+
+        synchronized (this) {
+            endPoints.addAll(config.endPoints());
+        }
+
+        HttpClientInstance.INSTANCE.configure(clusterService, leadershipService, domainService,
+                endPointMasterIpMap, config);
+    }
+
+    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/ConnectionConfig.java b/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/ConnectionConfig.java
new file mode 100644
index 0000000..c9c91f7
--- /dev/null
+++ b/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/ConnectionConfig.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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.services.channel.EndPoint;
+
+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 DOMAIN_IPS = "clusterIps";
+    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<EndPoint> endPoints() {
+        JsonNode peersNode = object.get(DOMAINS);
+        Set<EndPoint> endPoints = Sets.newHashSet();
+
+        peersNode.forEach(jsonNode -> {
+            DomainId domainId = DomainId.domainId(
+                    jsonNode.path(DOMAIN_ID).asText());
+            Set<IpAddress> ipAddresses = Sets.newHashSet();
+            jsonNode.path(DOMAIN_IPS).forEach(ipAddress -> ipAddresses.add(
+                    IpAddress.valueOf(ipAddress.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 EndPoint(domainId, ipAddresses, port,
+                    username, password, topic));
+        });
+
+        return endPoints;
+    }
+}
diff --git a/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/DomainMasterIpDiscoveryTask.java b/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/DomainMasterIpDiscoveryTask.java
new file mode 100644
index 0000000..8638639
--- /dev/null
+++ b/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/DomainMasterIpDiscoveryTask.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.ce.global.channel.client;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.jboss.netty.util.Timeout;
+import org.jboss.netty.util.TimerTask;
+import org.onlab.packet.IpAddress;
+import org.onlab.util.Timer;
+import org.opencord.ce.api.services.channel.EndPoint;
+import org.slf4j.Logger;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.IOException;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+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.DOUBLESLASH;
+import static org.opencord.ce.api.services.channel.Symbols.HTTP;
+import static org.opencord.ce.api.services.channel.Symbols.MASTER;
+import static org.opencord.ce.api.services.channel.Symbols.MASTER_IP;
+import static org.opencord.ce.api.services.channel.Symbols.OK;
+import static org.opencord.ce.api.services.channel.Symbols.RESULT;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Executed periodically to find the leader node of a domain.
+ * Stops when the ip is found
+ */
+public class DomainMasterIpDiscoveryTask implements TimerTask {
+
+    private final Logger log = getLogger(getClass());
+
+    private Timeout timeout;
+    private volatile boolean isStopped;
+    private EndPoint endPoint;
+    private Client client;
+
+    ObjectMapper mapper;
+
+    public DomainMasterIpDiscoveryTask(EndPoint endPoint, Client client,
+                                       ObjectMapper mapper) {
+        this.endPoint = endPoint;
+        this.client = client;
+        this.mapper = mapper;
+
+        isStopped = true;
+        start();
+
+    }
+
+    public synchronized void stop() {
+        if (!isStopped) {
+            isStopped = true;
+            timeout.cancel();
+        } else {
+            log.warn("IpDiscovery stopped multiple times?");
+        }
+    }
+
+    public synchronized void start() {
+        if (isStopped) {
+            isStopped = false;
+            timeout = Timer.getTimer().newTimeout(this, 0, SECONDS);
+        } else {
+            log.warn("IpDiscovery started multiple times?");
+        }
+    }
+
+    public synchronized boolean isStopped() {
+        return isStopped || timeout.isCancelled();
+    }
+
+    @Override
+    public void run(Timeout t) {
+        if (isStopped()) {
+            return;
+        }
+        for (IpAddress ipAddress : endPoint.ipAddresses()) {
+            String url = HTTP + COLON + DOUBLESLASH + ipAddress.toString() + COLON +
+                    endPoint.port() + BASE_URL + MASTER;
+            log.info("masterIp url: " + url);
+            WebTarget wt = client.target(url);
+            Response response = wt.request(MediaType.APPLICATION_JSON)
+                    .get();
+            if (response.getStatus() != Response.Status.OK.getStatusCode()) {
+                continue;
+            }
+            String stringBody = response.readEntity(String.class);
+            log.info("getLocalMasterIp() response: " + stringBody);
+            try {
+                ObjectNode responseBody = (ObjectNode) mapper.readTree(stringBody);
+                if (responseBody.path(RESULT).asText().equals(OK)) {
+                    IpAddress masterIpAdress =  IpAddress.valueOf(responseBody.path(MASTER_IP).asText());
+                    HttpClientInstance.INSTANCE.setMasterIp(endPoint, masterIpAdress);
+                    this.stop();
+                    return;
+                }
+            } catch (IOException ex) {
+                log.info("getLocalMasterIp() IOException, try next endpoint ip");
+            }
+        }
+
+        if (!isStopped()) {
+            timeout = Timer.getTimer().newTimeout(this, 3, SECONDS);
+        }
+    }
+}
+
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..cf16ab5
--- /dev/null
+++ b/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/HttpClientInstance.java
@@ -0,0 +1,427 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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.onlab.packet.IpAddress;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.rest.AbstractWebResource;
+import org.onosproject.store.service.ConsistentMap;
+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.EvcConnId;
+import org.opencord.ce.api.services.MetroNetworkVirtualNodeService;
+import org.opencord.ce.api.services.channel.EndPoint;
+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, EndPoint>> domainsEndPointsMap = Maps.newConcurrentMap();
+
+    private ConsistentMap<EndPoint, IpAddress> endPointMasterIpMap;
+
+    protected final Map<EndPoint, DomainMasterIpDiscoveryTask> ipDiscoveryTaskMap = 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, ConsistentMap<EndPoint,
+            IpAddress> endPointMasterIpMap, ConnectionConfig connConfig) {
+
+        if (!configured) {
+            this.clusterService = clusterService;
+            this.leadershipService = leadershipService;
+            this.domainService = domainService;
+            this.endPointMasterIpMap = endPointMasterIpMap;
+            configured = true;
+        }
+        connConfig.endPoints().forEach(siteConfig -> {
+            DomainId domainId = siteConfig.domainId();
+            synchronized (this) {
+                domainsEndPointsMap.putIfAbsent(domainId,
+                        Pair.of(createClient(), siteConfig));
+                notify();
+            }
+            String topic = siteConfig.topic();
+            // TODO: add leadership listeners to react to changes
+            if (isLeader(topic)) {
+                log.info("I am the leader for domain: {} ", domainId);
+                probeMasterIp(siteConfig, domainsEndPointsMap.get(domainId).getLeft());
+            } else {
+                log.info("I am NOT the leader for domain: {}", domainId);
+
+            }
+        });
+    }
+
+    private void probeMasterIp(EndPoint endPoint, Client client) {
+        ipDiscoveryTaskMap.putIfAbsent(endPoint,
+                new DomainMasterIpDiscoveryTask(endPoint, client, codecContext.mapper()));
+    }
+
+    protected void setMasterIp(EndPoint endPoint, IpAddress ipAddress) {
+        synchronized (this) {
+            endPointMasterIpMap.put(endPoint, ipAddress);
+            notify();
+        }
+    }
+
+    public IpAddress getRemoteMasterIp(EndPoint endPoint) {
+        synchronized (this) {
+            return endPointMasterIpMap.get(endPoint).value();
+        }
+    }
+
+    public Client getConnectionInfo(DomainId domainId) {
+        return domainsEndPointsMap.get(domainId).getLeft();
+    }
+
+    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 boolean isLeader(String topic) {
+        return leadershipService.getLeader(topic).id()
+                .equals(clusterService.getLocalNode().id().id());
+    }
+
+    private String getTopic(DomainId domainId) {
+        return domainsEndPointsMap.get(domainId).getRight().topic();
+    }
+
+    private Client createClient() {
+        return ClientBuilder.newClient();
+    }
+
+    public void stopNetworkTasks() {
+        ipDiscoveryTaskMap.forEach((ep, task) -> task.stop());
+    }
+
+    @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 fcId = fc.id().id();
+        VlanId fcTag = fc.vlanId();
+        ConnectPoint ingressCp  = srcNi.cp();
+        CarrierEthernetNetworkInterface.Type srcType = srcNi.type();
+        VlanId sTag = srcNi.sVlanId();
+        VlanId ceTag = srcNi.ceVlanId();
+        CarrierEthernetForwardingConstruct.Type fcType = fc.type();
+        ArrayList<Pair<ConnectPoint, CarrierEthernetNetworkInterface.Type>> egressList =
+                new ArrayList<>();
+        dstNiSet.forEach(dstNi -> egressList.add(Pair.of(dstNi.cp(), dstNi.type())));
+
+        ObjectNode jsonBody = codecContext.mapper().createObjectNode()
+                .put(FC_ID, fcId)
+                .put(FC_TAG, fcTag.toShort())
+                .put(FC_TYPE, fcType.toString())
+                .put(INGRESS_NI_TYPE, srcType.toString());
+        JsonCodec<ConnectPoint> cpCodec = codecContext.codec(ConnectPoint.class);
+        jsonBody.set(FC_INGRESS_CP, cpCodec.encode(ingressCp, codecContext));
+        jsonBody.put(INGRESS_FC_TAG, sTag.toShort())
+                .put(CUSTOMER_TAG, ceTag.toShort());
+        ArrayNode egressListNode = codecContext.newArray(jsonBody, FC_EGRESS_LST);
+        dstNiSet.forEach(dstNi -> {
+            ObjectNode item = codecContext.mapper().createObjectNode()
+                    .put(FC_EGRESS_TYPE, dstNi.type().toString());
+            item.set(FC_EGRESS_CP, cpCodec.encode(dstNi.cp(), codecContext));
+            egressListNode.add(item);
+        });
+        */
+        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());
+                    }
+
+                }
+            }
+            EndPoint endPoint = domainsEndPointsMap.get(domainId).getRight();
+            IpAddress ipAddress;
+            synchronized (this) {
+                while (!endPointMasterIpMap.containsKey(endPoint) ||
+                        endPointMasterIpMap.get(endPoint).value() == null) {
+                    try {
+                        log.info("wait() master ip");
+                        wait();
+                    } catch (InterruptedException ie) {
+                        log.info("Interrupted exception: " + ie.getMessage());
+                    }
+                }
+                ipAddress = endPointMasterIpMap.get(endPoint).value();
+            }
+
+
+            Client client = domainsEndPointsMap.get(domainId).getLeft();
+
+            String url = HTTP + COLON + DOUBLESLASH + ipAddress.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..cf86254
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * 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..0645657
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * 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..377abf0
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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/DomainMasterIpResource.java b/global/http-channel/src/main/java/org/opencord/ce/global/channel/server/DomainMasterIpResource.java
new file mode 100644
index 0000000..6ba8469
--- /dev/null
+++ b/global/http-channel/src/main/java/org/opencord/ce/global/channel/server/DomainMasterIpResource.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.ce.global.channel.server;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onlab.packet.IpAddress;
+import org.onosproject.rest.AbstractWebResource;
+import org.opencord.ce.api.services.channel.ConnectionService;
+import org.slf4j.Logger;
+
+import javax.ws.rs.GET;
+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 static org.opencord.ce.api.services.channel.Symbols.MASTER_API_NO_IP_BODY;
+import static org.opencord.ce.api.services.channel.Symbols.MASTER_IP;
+import static org.opencord.ce.api.services.channel.Symbols.OK;
+import static org.opencord.ce.api.services.channel.Symbols.RESULT;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Gets the ip of the instance leader of the communication with the specified
+ * domainId.
+ */
+@Path("master/{domainId}")
+public class DomainMasterIpResource extends AbstractWebResource {
+    private final Logger log = getLogger(getClass());
+
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getMasterIp(@PathParam("domainId") String id) {
+        log.info("Domain {} asks who is the master for him", id);
+
+        IpAddress ip = get(ConnectionService.class).getLocalMasterIp(id);
+        if (ip != null) {
+            ObjectNode body = mapper().createObjectNode();
+            body.put(RESULT, OK);
+            body.put(MASTER_IP, ip.toString());
+
+            return ok(body.toString()).build();
+        } else {
+            return ok(MASTER_API_NO_IP_BODY).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..bd0691f
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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, DomainMasterIpResource.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..f75a73a
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * 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..7155765
--- /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 2016-present Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<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..73f6798
--- /dev/null
+++ b/global/pom.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2015-present Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opencord</groupId>
+        <artifactId>ce</artifactId>
+        <version>1.0.0</version>
+    </parent>
+
+    <groupId>org.opencord.ce</groupId>
+    <artifactId>global</artifactId>
+    <packaging>pom</packaging>
+
+    <description>Orchestration logic of Carrier Ethernet Forwarding Constructs</description>
+
+    <properties>
+        <onos.version>1.10.3</onos.version>
+        <onos.app.title>ECORD 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..a995b1f
--- /dev/null
+++ b/global/virtualprovider/pom.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2015-present Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opencord.ce</groupId>
+        <artifactId>global</artifactId>
+        <version>1.0.0</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.3</onos.version>
+        <onos.app.url>http://opencord.org</onos.app.url>
+        <project.version>1.0.0</project.version>
+    </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..55d89c3
--- /dev/null
+++ b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/VirtualDomainDeviceProvider.java
@@ -0,0 +1,389 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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..b284a59
--- /dev/null
+++ b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/VirtualLinkProvider.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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..7c80334
--- /dev/null
+++ b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/XoSHttpClient.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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..b47684d
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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..3ac0fcd
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.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..e59159b
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * 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..987a1b9
--- /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 Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Package for domain topology provider.
+ */
+package org.opencord.ce.global.virtualdomain;
\ No newline at end of file
