Restructuring VLAN tag net cfg, fixing ONOS-5613 and making newoptical activate automatically

- Moving VLAN tag assignment via net cfg to CarrierEthernetManager
- Modifying getVlanTag method to be used with a FC instead of a path
- S-TAG assigned to an FC via netcfg should:
	* Not be used by another FC already (otherwise tag will not be registered in the first place)
	* Be present in at least one of the LTPs (Cps) of the FC
	* No other tag should be configured in another LTP (CP) of the FC
- Removing transportVlanTag netcfg
- Updating example port configuration JSON
- Fixing ONOS-5613 cast exception issue where InternalNetworkConfigListener was trying to get connect point from CONFIG_UNREGISTERED events
- Including onos.app.requires for the new optical app so that it’s activated automatically
- Adding/enhancing commands to configure packet-optical topology status and EVC fragmentation
- Adding more app info in pom.xml

Change-Id: Ief776ed6e6f687297a73759004660baf62bc7cb6
diff --git a/ecord/carrierethernet/example/netcfg.json b/ecord/carrierethernet/example/netcfg.json
index 861e41a..e79db89 100644
--- a/ecord/carrierethernet/example/netcfg.json
+++ b/ecord/carrierethernet/example/netcfg.json
@@ -1,9 +1,23 @@
 {
     "ports": {
-        "rest:10.128.14.32:443/20": {
+        "of:0000000000000001/2": {
             "portVlan": {
-                "tag" : 100,
-                "transport-tag" : 101
+                "s-tag" : 100
+            }
+        },
+        "of:0000000000000002/2": {
+            "portVlan": {
+                "s-tag" : 200
+            }
+        },
+        "of:0000000000000003/2": {
+            "portVlan": {
+                "s-tag" : 300
+            }
+        },
+        "of:0000000000000004/2": {
+            "portVlan": {
+                "s-tag" : 400
             }
         }
     }
diff --git a/ecord/carrierethernet/pom.xml b/ecord/carrierethernet/pom.xml
index 88ab496..69aa9fd 100644
--- a/ecord/carrierethernet/pom.xml
+++ b/ecord/carrierethernet/pom.xml
@@ -30,6 +30,10 @@
         <onos.version>1.8.0-SNAPSHOT</onos.version>
         <onos.app.name>org.onosproject.ecord.carrierethernet</onos.app.name>
         <onos.app.origin>ON.Lab</onos.app.origin>
+        <onos.app.requires>org.onosproject.newoptical</onos.app.requires>
+        <onos.app.category>Traffic Steering</onos.app.category>
+        <onos.app.title>Carrier Ethernet</onos.app.title>
+        <onos.app.url>https://wiki.onosproject.org/display/ONOS/Carrier+Ethernet+Application</onos.app.url>
     </properties>
 
     <dependencies>
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetEnni.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetEnni.java
index f9d99ac..696a0aa 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetEnni.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetEnni.java
@@ -143,6 +143,7 @@
 
     /**
      * Returns the S-VLAN id associated with a service ENNI, or the first S-VLAN ID found for a global ENNI.
+     * This is assumed to be the S-TAG of another FC interconnected with this ENNI.
      *
      * @return S-VLAN id
      */
@@ -175,6 +176,7 @@
 
     /**
      * Returns the set of S-VLAN ids associated with the ENNI.
+     * Those are assumed to be the S-TAGs of other FCs interconnected with this ENNI.
      *
      * @return S-VLAN id set
      */
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetForwardingConstruct.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetForwardingConstruct.java
index c884bf9..c055837 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetForwardingConstruct.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetForwardingConstruct.java
@@ -15,7 +15,6 @@
  */
 package org.onosproject.ecord.carrierethernet.app;
 
-import com.google.common.annotations.Beta;
 import org.onlab.packet.VlanId;
 import org.onosproject.newoptical.api.OpticalConnectivityId;
 import org.onosproject.newoptical.api.OpticalPathEvent;
@@ -35,7 +34,6 @@
 
     private Set<CarrierEthernetLogicalTerminationPoint> ltpSet;
     private VlanId vlanId;
-    private VlanId transportVlanId;
     private CarrierEthernetMetroConnectivity metroConnectivity;
     private boolean congruentPaths;
     protected AtomicInteger refCount;
@@ -50,7 +48,6 @@
         super(id, cfgId, type, maxLatency);
         this.ltpSet = new HashSet<>(ltpSet);
         this.vlanId = null;
-        this.transportVlanId = null;
         this.metroConnectivity = new CarrierEthernetMetroConnectivity(null, OpticalPathEvent.Type.PATH_REMOVED);
         this.congruentPaths = CONGRUENT_PATHS;
         this.refCount = new AtomicInteger();
@@ -66,16 +63,6 @@
     }
 
     /**
-     * Returns Transport Vlan ID.
-     *
-     * @return Transport Vlan ID.
-     */
-    @Beta
-    public VlanId transportVlanId() {
-        return transportVlanId;
-    }
-
-    /**
      * Gets metro connectivity id.
      *
      * @return the metro connectivity of the service
@@ -134,16 +121,6 @@
     }
 
     /**
-     * Sets the vlanId to be used by the transport part of the FC.
-     *
-     * @param vlan the vlanId to set
-     */
-    @Beta
-    public void setTransportVlanId(VlanId vlan) {
-        this.transportVlanId = vlan;
-    }
-
-    /**
      * Sets the set of LTPs.
      *
      * @param ltpSet the set of LTPs to be set
@@ -177,7 +154,6 @@
                 .add("cfgId", cfgId)
                 .add("type", type)
                 .add("vlanId", vlanId)
-                .add("transportVlanId", transportVlanId)
                 .add("metroConnectId", (metroConnectivity.id() == null ? "null" : metroConnectivity.id().id()))
                 .add("refCount", refCount)
                 .add("LTPs", ltpSet).toString();
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetInni.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetInni.java
index 68e2caa..f92abf4 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetInni.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetInni.java
@@ -148,6 +148,7 @@
 
     /**
      * Returns the S-VLAN id associated with a service INNI, or the first S-VLAN ID found for a global INNI.
+     * This is assumed to be the S-TAG of another FC interconnected with this INNI.
      *
      * @return S-VLAN id
      */
@@ -171,6 +172,7 @@
 
     /**
      * Returns the set of S-VLAN ids associated with the INNI.
+     * Those are assumed to be the S-TAGs of other FCs interconnected with this INNI.
      *
      * @return S-VLAN id set
      */
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetManager.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetManager.java
index 8984de6..297deed 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetManager.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetManager.java
@@ -15,6 +15,7 @@
  */
 package org.onosproject.ecord.carrierethernet.app;
 
+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;
@@ -30,6 +31,11 @@
 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;
@@ -38,16 +44,19 @@
 
 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.onosproject.net.config.basics.SubjectFactories.CONNECT_POINT_SUBJECT_FACTORY;
 import static org.slf4j.LoggerFactory.getLogger;
 
 @Component(immediate = true)
@@ -69,6 +78,9 @@
     protected TopologyService topologyService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService networkConfigService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected CarrierEthernetProvisioner ceProvisioner;
 
     // Keeps track of the next S-VLAN tag the app will try to use
@@ -78,7 +90,8 @@
     // TODO: Use Identifier class instead
     private static short nextEvcShortId = 1;
 
-    private boolean evcFragmentationEnabled = true;
+    private boolean evcFragmentationEnabled = false;
+    private boolean prevEvcFragmentationStatus = evcFragmentationEnabled;
 
     // TODO: Implement distributed store for EVCs
     // The installed EVCs
@@ -98,19 +111,41 @@
     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 Set<String> removedLtpSet = Sets.newConcurrentHashSet();
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry cfgRegistry;
+
+    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() {}
+    public void activate() {
+        networkConfigService.addListener(netcfgListener);
+        factories.forEach(cfgRegistry::registerConfigFactory);
+    }
 
     /**
      * Deactivate this component.
      */
     @Deactivate
     public void deactivate() {
+        networkConfigService.removeListener(netcfgListener);
+        factories.forEach(cfgRegistry::unregisterConfigFactory);
         removeAllEvcs();
         removeAllFcs();
     }
@@ -314,14 +349,20 @@
 
         //////////////////////////////////////////////////////////////////////////////////////////////////
 
-        // Assign VLAN ids to FCs
+        // 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
-        // TODO: If network configuration is present, get FC vlanIds from corresponding ports
-        List<VlanId> tmpVlanIdList = new ArrayList<>();
+        Set<VlanId> excludedVlans = usedVlans();
         evc.fcSet().forEach(fc -> {
-            fc.setVlanId(generateVlanId(tmpVlanIdList));
-            tmpVlanIdList.add(fc.vlanId());
+            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
@@ -650,7 +691,7 @@
         // 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(null));
+            fc.setVlanId(generateVlanId(usedVlans()));
         }
         if (fc.vlanId() == null) {
             log.error("No available VLAN id found.");
@@ -800,29 +841,32 @@
     }
 
     /**
-     * Generates a unique vlanId in the context of the CE app.
+     * Returns the unique S-TAGs currently used by FCs across the CE network.
      *
-     * @param extraVlanList additional vlanIds to be excluded from the vlanId generation
-     * @return the generated vlanId or null if none found
+     * @return the S-TAGs currently used
      * */
-    // FIXME: Providing extra VLAN list as argument is probably a temporary solution
-    public VlanId generateVlanId(List<VlanId> extraVlanList) {
+    private Set<VlanId> usedVlans() {
+        return fcMap.values().stream().map(CarrierEthernetForwardingConstruct::vlanId)
+                .collect(Collectors.toSet());
+    }
 
-        List<VlanId> vlanList = fcMap.values().stream().map(CarrierEthernetForwardingConstruct::vlanId)
-                        .collect(Collectors.toList());
-        if (extraVlanList != null) {
-            vlanList.addAll(extraVlanList);
-        }
-
+    /**
+     * Generates a new vlanId excluding the provided ones.
+     *
+     * @param excludedVlans the vlanIds that are not allowed
+     * @return the generated vlanId; null if none found
+     * */
+    public VlanId generateVlanId(Set<VlanId> excludedVlans) {
         // If all vlanIds are being used return null, else try to find the next available one
-        if (vlanList.size() <  VlanId.MAX_VLAN - 1) {
-            while (vlanList.contains(VlanId.vlanId(nextVlanId))) {
+        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));
+                nextVlanId = (nextVlanId >= VlanId.MAX_VLAN || nextVlanId <= 0 ?
+                        1 : (short) (nextVlanId + 1));
             }
         }
-
-        return (vlanList.contains(VlanId.vlanId(nextVlanId)) ? null : VlanId.vlanId(nextVlanId));
+        return excludedVlans.contains(VlanId.vlanId(nextVlanId)) ?
+                null : VlanId.vlanId(nextVlanId);
     }
 
     /**
@@ -1244,7 +1288,7 @@
      *
      * @param ltpId the LTP id to search
      * @param fcSet the FC set to search
-     * @return a the first FC found in fcSet which contains an LTP with id ltpId, or null if no such FC is found
+     * @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,
@@ -1257,4 +1301,104 @@
         }
         return null;
     }
+
+    /**
+     * Utility method to enable or disable EVC fragmentation into FCs.
+     *
+     * @param evcFragmentationEnabled true to enable fragmentation; false otherwise
+     * */
+    public void setEvcFragmentation(boolean evcFragmentationEnabled) {
+        prevEvcFragmentationStatus = this.evcFragmentationEnabled;
+        this.evcFragmentationEnabled = evcFragmentationEnabled;
+    }
+
+    public boolean getEvcFragmentation() {
+        return evcFragmentationEnabled;
+    }
+
+    /**
+     * Utility method to set the EVC fragmentation flag to the value before its last change.
+     *
+     * */
+    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/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetProvisioner.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetProvisioner.java
index b0c6d8c..181cce2 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetProvisioner.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetProvisioner.java
@@ -15,24 +15,16 @@
  */
 package org.onosproject.ecord.carrierethernet.app;
 
-import com.google.common.annotations.Beta;
-import com.google.common.collect.ImmutableList;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Service;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.onlab.packet.VlanId;
 import org.onlab.util.Bandwidth;
 import org.onosproject.net.Link;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.Path;
-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.Device;
 import org.onosproject.net.topology.PathService;
@@ -50,18 +42,13 @@
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
 import java.util.Set;
 import java.util.List;
 import java.util.ArrayList;
-import java.util.EnumSet;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Stream;
 
-import static com.google.common.base.Preconditions.checkNotNull;
 import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
-import static org.onosproject.net.config.basics.SubjectFactories.CONNECT_POINT_SUBJECT_FACTORY;
+
 import static org.slf4j.LoggerFactory.getLogger;
 
 @Component(immediate = true)
@@ -83,32 +70,11 @@
     protected OpticalPathService opticalPathService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected NetworkConfigService networkConfigService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected DeviceService deviceService;
 
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected NetworkConfigRegistry cfgRegistry;
-
-    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 final Map<ConnectPoint, VlanId> transportVlanMap = new ConcurrentHashMap<>();
-
     private OpticalPathListener opticalEventListener = new OpticalEventListener();
 
-    private NetworkConfigListener netcfgListener = new InternalNetworkConfigListener();
-
-    private static final int OPTICAL_CONNECT_TIMEOUT_MILLIS = 7000;
+    private static final int OPTICAL_CONNECT_TIMEOUT_MILLIS = 5000;
 
     // If set to false, the setup of optical connectivity using the metro app is bypassed
     // TODO: Use the Component Configuration mechanism to set this parameter
@@ -120,15 +86,11 @@
     @Activate
     protected void activate() {
         opticalPathService.addListener(opticalEventListener);
-        networkConfigService.addListener(netcfgListener);
-        factories.forEach(cfgRegistry::registerConfigFactory);
     }
 
     @Deactivate
     protected void deactivate() {
         opticalPathService.removeListener(opticalEventListener);
-        networkConfigService.removeListener(netcfgListener);
-        factories.forEach(cfgRegistry::unregisterConfigFactory);
     }
 
     public void setupConnectivity(CarrierEthernetForwardingConstruct fc) {
@@ -200,20 +162,6 @@
 
                     log.info("Metro connectivity id and status for FC {}: {}, {}", fc.id(),
                             fc.metroConnectivity().id(), fc.metroConnectivity().status());
-
-                    if (opticalConnectId != null) {
-                        // TODO: find vlanIds for both CO and store to service
-                        opticalPathService.getPath(opticalConnectId).ifPresent(links -> {
-                            getVlanTag(links).ifPresent(vlan -> {
-                                log.info("VLAN ID {} is assigned to CE service {}", vlan, fc.id());
-                                fc.setVlanId(vlan);
-                            });
-                            getTransportVlanTag(links).ifPresent(vlan -> {
-                                log.info("Transport VLAN ID {} is assigned to CE service {}", vlan, fc.id());
-                                fc.setTransportVlanId(vlan);
-                            });
-                        });
-                    }
                 }
 
                 // Update the ingress-egress NI map based on the calculated paths
@@ -268,7 +216,6 @@
                                 boolean congruentPaths, CarrierEthernetVirtualConnection.Type evcType) {
 
         // Find the paths for both directions at the same time, so that we can skip the pair if needed
-        // TODO: Handle the case when ni1 and ni2 are on the same device - probably in the generateLinkList
         List<Link> forwardLinks = generateLinkList(ni1.cp(), ni2.cp(), evcType);
         List<Link> backwardLinks =
                 congruentPaths ? generateInverseLinkList(forwardLinks) : generateLinkList(ni2.cp(), ni1.cp(), evcType);
@@ -378,7 +325,6 @@
     }
 
     public void removeConnectivity(CarrierEthernetForwardingConstruct fc) {
-        // TODO: Add here the same call for all node manager types
         cePktNodeService.removeAllForwardingResources(fc);
         removeOpticalConnectivity(fc.metroConnectivity().id());
     }
@@ -389,7 +335,6 @@
      * @param fc the FC representation
      */
     public void createBandwidthProfiles(CarrierEthernetForwardingConstruct fc) {
-        //  TODO: Select node manager depending on device protocol
         fc.uniSet().forEach(uni -> cePktNodeService.createBandwidthProfileResources(fc, uni));
     }
 
@@ -456,86 +401,23 @@
         }
     }
 
+    /**
+     * Indicates if the CE app is meant to control a packet-optical topology.
+     *
+     * @param pktOpticalTopo true if CE app controls a packet-optical topology;
+     *                       false otherwise
+     */
     public void setPktOpticalTopo(boolean pktOpticalTopo) {
         this.pktOpticalTopo = pktOpticalTopo;
     }
 
     /**
-     * Returns VLAN tag assigned to given path.
-     * @param links List of links that composes path
-     * @return VLAN tag if found any. empty if not found.
+     * Determines it the CE app is meant to control a packet-optical topology.
+     *
+     * @return true if CE app is meant to control a packet-optical topology;
+     * false otherwise
      */
-    private Optional<VlanId> getVlanTag(List<Link> links) {
-        checkNotNull(links);
-        Optional<ConnectPoint> edge = links.stream().flatMap(l -> Stream.of(l.src(), l.dst()))
-                .filter(portVlanMap::containsKey)
-                .findAny();
-
-        if (edge.isPresent()) {
-            return Optional.of(portVlanMap.get(edge.get()));
-        }
-
-        return Optional.empty();
-    }
-
-    /**
-     * Returns transport VLAN tag assigned to given path.
-     * @param links List of links that composes path
-     * @return VLAN transport tag if found any. empty if not found.
-     */
-    @Beta
-    private Optional<VlanId> getTransportVlanTag(List<Link> links) {
-        checkNotNull(links);
-        return links.stream().flatMap(l -> Stream.of(l.src(), l.dst()))
-                .map(transportVlanMap::get)
-                .filter(Objects::nonNull)
-                .findAny();
-    }
-
-    private class InternalNetworkConfigListener implements NetworkConfigListener {
-
-        /**
-         * Negative events.
-         */
-        private final EnumSet<NetworkConfigEvent.Type> negative
-            = EnumSet.of(NetworkConfigEvent.Type.CONFIG_UNREGISTERED,
-                         NetworkConfigEvent.Type.CONFIG_REMOVED);
-
-        @Override
-        public boolean isRelevant(NetworkConfigEvent event) {
-            return event.configClass().equals(PortVlanConfig.class);
-        }
-
-        @Override
-        public void event(NetworkConfigEvent event) {
-
-            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);
-                transportVlanMap.remove(cp);
-                return;
-            }
-
-            if (config.portVlanId().isPresent() && !negative.contains(event.type())) {
-                log.info("VLAN tag {} is assigned to port {}", config.portVlanId().get(), cp);
-                portVlanMap.put(cp, config.portVlanId().get());
-            } else {
-                log.info("VLAN tag is removed from port {}", cp);
-                portVlanMap.remove(cp);
-            }
-
-            if (config.transportVlanId().isPresent() && !negative.contains(event.type())) {
-                log.info("transport VLAN tag {} is assigned to port {}",
-                         config.transportVlanId().get(), cp);
-                transportVlanMap.put(cp, config.transportVlanId().get());
-            } else {
-                log.info("transport VLAN tag is removed from port {}", cp);
-                transportVlanMap.remove(cp);
-            }
-        }
-
+    public boolean getPktOpticalTopo() {
+        return pktOpticalTopo;
     }
 }
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetVirtualConnection.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetVirtualConnection.java
index fb58a8b..0eed7f3 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetVirtualConnection.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetVirtualConnection.java
@@ -135,6 +135,7 @@
                 .add("id", id)
                 .add("cfgId", cfgId)
                 .add("type", type)
+                .add("state", state)
                 .add("UNIs", uniSet)
                 .add("FCs", fcSet).toString();
     }
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/PortVlanConfig.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/PortVlanConfig.java
index c0c3d71..b7a47f4 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/PortVlanConfig.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/PortVlanConfig.java
@@ -29,13 +29,10 @@
 public class PortVlanConfig extends Config<ConnectPoint> {
     public static final String CONFIG_KEY = "portVlan";
 
-    public static final String CE_VLAN_TAG_KEY = "tag";
-
-    @Beta
-    public static final String TRANSPORT_VLAN_TAG_KEY = "transport-tag";
+    public static final String S_TAG_KEY = "s-tag";
 
     public Optional<VlanId> portVlanId() {
-        String s = get(CE_VLAN_TAG_KEY, null);
+        String s = get(S_TAG_KEY, null);
         if (s == null) {
             return Optional.empty();
         }
@@ -44,26 +41,8 @@
 
     public PortVlanConfig portVlanId(VlanId vlanId) {
         if (vlanId == null) {
-            return (PortVlanConfig) setOrClear(CE_VLAN_TAG_KEY, (String) null);
+            return (PortVlanConfig) setOrClear(S_TAG_KEY, (String) null);
         }
-        return (PortVlanConfig) setOrClear(CE_VLAN_TAG_KEY, String.valueOf(vlanId.toShort()));
+        return (PortVlanConfig) setOrClear(S_TAG_KEY, String.valueOf(vlanId.toShort()));
     }
-
-    @Beta
-    public Optional<VlanId> transportVlanId() {
-        String s = get(TRANSPORT_VLAN_TAG_KEY, null);
-        if (s == null) {
-            return Optional.empty();
-        }
-        return Optional.of(VlanId.vlanId(Short.valueOf(s)));
-    }
-
-    @Beta
-    public PortVlanConfig transportVlanId(VlanId vlanId) {
-        if (vlanId == null) {
-            return (PortVlanConfig) setOrClear(TRANSPORT_VLAN_TAG_KEY, (String) null);
-        }
-        return (PortVlanConfig) setOrClear(TRANSPORT_VLAN_TAG_KEY, String.valueOf(vlanId.toShort()));
-    }
-
 }
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetEvcFragmentationCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetEvcFragmentationCommand.java
new file mode 100644
index 0000000..7d2bd4a
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetEvcFragmentationCommand.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ecord.carrierethernet.cli.commands;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetProvisioner;
+
+/**
+ * CLI command for indicating whether EVCs will be fragmented into FCs.
+ */
+@Command(scope = "onos", name = "ce-evc-fragmentation",
+        description = "Carrier Ethernet EVC fragmentation setup command. " +
+                "When used without argument it shows the current fragmentation status.")
+public class CarrierEthernetEvcFragmentationCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "evcFragArg", description = "Set to true if CE app " +
+            "should fragment EVCs into FCs", required = false, multiValued = false)
+    String evcFragArg = null;
+
+    @Override
+    protected void execute() {
+        CarrierEthernetManager ceManager = get(CarrierEthernetManager.class);
+        if (evcFragArg != null) {
+            ceManager.setEvcFragmentation(Boolean.parseBoolean(evcFragArg));
+        } else {
+            print("  %s", ceManager.getEvcFragmentation());
+        }
+    }
+}
\ No newline at end of file
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetPktOpticalTopoCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetPktOpticalTopoCommand.java
index 8985ff3..a6a9341 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetPktOpticalTopoCommand.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetPktOpticalTopoCommand.java
@@ -18,22 +18,41 @@
 import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
 import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
 import org.onosproject.ecord.carrierethernet.app.CarrierEthernetProvisioner;
 
 /**
  * CLI command for indicating whether CE app controls a packet optical topology.
  */
 @Command(scope = "onos", name = "ce-pkt-optical-topo",
-        description = "Carrier Ethernet packet-optical topology setup command.")
+        description = "Carrier Ethernet packet-optical topology setup command. " +
+        "When used without argument it shows the current pkt-optical topology status.")
 public class CarrierEthernetPktOpticalTopoCommand extends AbstractShellCommand {
 
     @Argument(index = 0, name = "pktOptTopoArg", description = "Set to true if CE app " +
-            "controls a packet-optical topology", required = true, multiValued = false)
+            "controls a packet-optical topology", required = false, multiValued = false)
     String pktOptTopoArg = null;
 
     @Override
     protected void execute() {
         CarrierEthernetProvisioner ceProvisioner = get(CarrierEthernetProvisioner.class);
-        ceProvisioner.setPktOpticalTopo(Boolean.parseBoolean(pktOptTopoArg));
+        if (pktOptTopoArg != null) {
+            boolean pktOpticalTopo = Boolean.parseBoolean(pktOptTopoArg);
+            // Change pkt-optical topology flag only if needed
+            if (pktOpticalTopo ^ ceProvisioner.getPktOpticalTopo()) {
+                ceProvisioner.setPktOpticalTopo(pktOpticalTopo);
+                // FIXME: Temporary hack - disable EVC fragmentation for pkt-optical
+                // This is needed because CarrierEthernetManager performs path computation
+                // during the fragmentation process
+                CarrierEthernetManager ceManager = get(CarrierEthernetManager.class);
+                if (pktOpticalTopo) {
+                    ceManager.setEvcFragmentation(false);
+                } else {
+                    ceManager.resetEvcFragmentation();
+                }
+            }
+        } else {
+            print("  %s", ceProvisioner.getPktOpticalTopo());
+        }
     }
 }
diff --git a/ecord/carrierethernet/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/ecord/carrierethernet/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index 117e7c1..3a35f08 100644
--- a/ecord/carrierethernet/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/ecord/carrierethernet/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -25,9 +25,6 @@
                 <ref component-id="carrierEthernetValidUniCompleter"/>
             </completers>
         </command>
-    </command-bundle>
-
-    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
         <command>
             <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetCreateFcCommand"/>
             <completers>
@@ -37,63 +34,36 @@
                 <ref component-id="carrierEthernetValidLtpCompleter"/>
             </completers>
         </command>
-    </command-bundle>
-
-    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
         <command>
             <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetRemoveEvcCommand"/>
             <completers>
                 <ref component-id="carrierEthernetEvcCompleter"/>
             </completers>
         </command>
-    </command-bundle>
-
-    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
         <command>
             <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetRemoveAllEvcsCommand"/>
         </command>
-    </command-bundle>
-
-    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
         <command>
             <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetListEvcsCommand"/>
         </command>
-    </command-bundle>
-
-    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
         <command>
             <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetListLtpsCommand"/>
         </command>
-    </command-bundle>
-
-    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
         <command>
             <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetListUnisCommand"/>
         </command>
-    </command-bundle>
-
-    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
         <command>
             <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetListFcsCommand"/>
         </command>
-    </command-bundle>
-
-    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
         <command>
             <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetRemoveFcCommand"/>
             <completers>
                 <ref component-id="carrierEthernetFcCompleter"/>
             </completers>
         </command>
-    </command-bundle>
-
-    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
         <command>
             <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetRemoveAllFcsCommand"/>
         </command>
-    </command-bundle>
-
-    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
         <command>
             <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetCreateLtpCommand"/>
             <completers>
@@ -101,45 +71,38 @@
                 <ref component-id="carrierEthernetPotentialLtpCompleter"/>
             </completers>
         </command>
-    </command-bundle>
-
-    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
         <command>
             <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetCreateUniCommand"/>
             <completers>
                 <ref component-id="carrierEthernetPotentialUniCompleter"/>
             </completers>
         </command>
-    </command-bundle>
-
-    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
         <command>
             <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetRemoveLtpCommand"/>
             <completers>
                 <ref component-id="carrierEthernetLtpCompleter"/>
             </completers>
         </command>
-    </command-bundle>
-
-    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
         <command>
             <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetRemoveUniCommand"/>
             <completers>
                 <ref component-id="carrierEthernetUniCompleter"/>
             </completers>
         </command>
-    </command-bundle>
-
-    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
         <command>
             <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetPktOpticalTopoCommand"/>
             <completers>
                 <ref component-id="carrierEthernetBooleanCompleter"/>
             </completers>
         </command>
+        <command>
+            <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetEvcFragmentationCommand"/>
+            <completers>
+                <ref component-id="carrierEthernetBooleanCompleter"/>
+            </completers>
+        </command>
     </command-bundle>
 
-
     <bean id="placeholderCompleter" class="org.onosproject.cli.PlaceholderCompleter"/>
     <bean id="carrierEthernetEvcTypeCompleter" class="org.onosproject.ecord.carrierethernet.cli.completers.CarrierEthernetEvcTypeCompleter"/>
     <bean id="carrierEthernetEvcCompleter" class="org.onosproject.ecord.carrierethernet.cli.completers.CarrierEthernetEvcCompleter"/>
@@ -154,5 +117,4 @@
     <bean id="carrierEthernetValidLtpCompleter" class="org.onosproject.ecord.carrierethernet.cli.completers.CarrierEthernetValidLtpCompleter"/>
     <bean id="carrierEthernetBooleanCompleter" class="org.onosproject.ecord.carrierethernet.cli.completers.CarrierEthernetBooleanCompleter"/>
 
-
 </blueprint>