diff --git a/apps/pi-demo/common/BUILD b/apps/pi-demo/common/BUILD
deleted file mode 100644
index 01d59ae..0000000
--- a/apps/pi-demo/common/BUILD
+++ /dev/null
@@ -1,3 +0,0 @@
-osgi_jar(
-    deps = CORE_DEPS,
-)
diff --git a/apps/pi-demo/common/src/main/java/org/onosproject/pi/demo/app/common/AbstractUpgradableFabricApp.java b/apps/pi-demo/common/src/main/java/org/onosproject/pi/demo/app/common/AbstractUpgradableFabricApp.java
deleted file mode 100644
index ac92028..0000000
--- a/apps/pi-demo/common/src/main/java/org/onosproject/pi/demo/app/common/AbstractUpgradableFabricApp.java
+++ /dev/null
@@ -1,555 +0,0 @@
-/*
- * Copyright 2017-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onosproject.pi.demo.app.common;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Deactivate;
-import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.component.annotations.ReferenceCardinality;
-import org.onosproject.app.ApplicationAdminService;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.Device;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Host;
-import org.onosproject.net.Port;
-import org.onosproject.net.device.DeviceEvent;
-import org.onosproject.net.device.DeviceListener;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.flow.DefaultFlowRule;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleOperations;
-import org.onosproject.net.flow.FlowRuleService;
-import org.onosproject.net.group.GroupService;
-import org.onosproject.net.host.HostService;
-import org.onosproject.net.pi.model.PiPipeconf;
-import org.onosproject.net.pi.model.PiPipeconfId;
-import org.onosproject.net.pi.model.PiPipelineInterpreter;
-import org.onosproject.net.pi.model.PiTableId;
-import org.onosproject.net.pi.service.PiPipeconfService;
-import org.onosproject.net.topology.Topology;
-import org.onosproject.net.topology.TopologyGraph;
-import org.onosproject.net.topology.TopologyService;
-import org.onosproject.net.topology.TopologyVertex;
-import org.slf4j.Logger;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.lang.String.format;
-import static java.util.stream.Collectors.toSet;
-import static java.util.stream.Stream.concat;
-import static org.onlab.util.Tools.groupedThreads;
-import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_ADDED;
-import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED;
-import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_UPDATED;
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- * Abstract implementation of an app providing fabric connectivity for a 2-stage
- * Clos topology of P4Runtime devices.
- */
-@Component(immediate = true)
-public abstract class AbstractUpgradableFabricApp {
-
-    private static final Map<String, AbstractUpgradableFabricApp>
-            APP_HANDLES = Maps.newConcurrentMap();
-
-    // TOPO_SIZE should be the same of the --size argument when running bmv2-demo.py
-    private static final int TOPO_SIZE = 2;
-    private static final boolean WITH_IMBALANCED_STRIPING = false;
-    private static final int HASHED_LINKS = TOPO_SIZE + (WITH_IMBALANCED_STRIPING ? 1 : 0);
-
-    private static final int FLOW_PRIORITY = 100;
-    private static final int CHECK_TOPOLOGY_INTERVAL_SECONDS = 5;
-
-    private static final int CLEANUP_SLEEP = 2000;
-
-    protected final Logger log = getLogger(getClass());
-
-    private final DeviceListener deviceListener = new InternalDeviceListener();
-
-    private final ExecutorService executorService = Executors
-            .newFixedThreadPool(8, groupedThreads("onos/pi-demo-app", "pi-app-task", log));
-
-    private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
-
-    private final String appName;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected TopologyService topologyService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected DeviceService deviceService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    private HostService hostService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    private FlowRuleService flowRuleService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected GroupService groupService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    private ApplicationAdminService appService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    private CoreService coreService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    private PiPipeconfService piPipeconfService;
-
-    private boolean appActive = false;
-    private boolean appFreezed = false;
-
-    private boolean otherAppFound = false;
-    private AbstractUpgradableFabricApp otherApp;
-
-    private boolean flowRuleGenerated = false;
-    protected ApplicationId appId;
-
-    private Collection<PiPipeconf> appPipeconfs;
-
-    private Set<DeviceId> leafSwitches;
-    private Set<DeviceId> spineSwitches;
-
-    private Map<DeviceId, List<FlowRule>> deviceFlowRules;
-    private Map<DeviceId, Boolean> pipeconfFlags;
-    private Map<DeviceId, Boolean> ruleFlags;
-
-    private ConcurrentMap<DeviceId, Lock> deviceLocks = Maps.newConcurrentMap();
-
-    /**
-     * Creates a new PI fabric app.
-     *
-     * @param appName      app name
-     * @param appPipeconfs collection of compatible pipeconfs
-     */
-    protected AbstractUpgradableFabricApp(String appName,
-                                          Collection<PiPipeconf> appPipeconfs) {
-        this.appName = checkNotNull(appName);
-        this.appPipeconfs = checkNotNull(appPipeconfs);
-        checkArgument(appPipeconfs.size() > 0, "appPipeconfs cannot have size 0");
-    }
-
-    @Activate
-    public void activate() {
-        log.info("Starting...");
-
-        appActive = true;
-        appFreezed = false;
-
-        if (APP_HANDLES.size() > 0) {
-            if (APP_HANDLES.size() > 1) {
-                throw new IllegalStateException(
-                        "Found more than 1 active app handles");
-            }
-            otherAppFound = true;
-            otherApp = APP_HANDLES.values().iterator().next();
-            log.info("Found other fabric app active, signaling to freeze to {}...",
-                     otherApp.appName);
-            otherApp.setAppFreezed(true);
-        }
-
-        APP_HANDLES.put(appName, this);
-
-        appId = coreService.registerApplication(appName);
-        deviceService.addListener(deviceListener);
-
-        init();
-
-        log.info("STARTED", appId.id());
-    }
-
-    @Deactivate
-    public void deactivate() {
-        log.info("Stopping...");
-        try {
-            executorService.shutdown();
-            executorService.awaitTermination(5, TimeUnit.SECONDS);
-        } catch (InterruptedException e) {
-            List<Runnable> runningTasks = executorService.shutdownNow();
-            log.warn("Unable to stop the following tasks: {}", runningTasks);
-            Thread.currentThread().interrupt();
-        }
-        scheduledExecutorService.shutdown();
-        deviceService.removeListener(deviceListener);
-        flowRuleService.removeFlowRulesById(appId);
-
-        appActive = false;
-        APP_HANDLES.remove(appName);
-
-        log.info("STOPPED");
-    }
-
-    private void init() {
-
-        // Reset any previous state
-        synchronized (this) {
-            flowRuleGenerated = Boolean.FALSE;
-            leafSwitches = Sets.newHashSet();
-            spineSwitches = Sets.newHashSet();
-            deviceFlowRules = Maps.newConcurrentMap();
-            ruleFlags = Maps.newConcurrentMap();
-            pipeconfFlags = Maps.newConcurrentMap();
-        }
-
-        // Schedules a thread that periodically checks the topology, as soon as
-        // it corresponds to the expected one, it generates the necessary flow
-        // rules and starts the deploy process on each device.
-        scheduledExecutorService.scheduleAtFixedRate(
-                this::checkTopologyAndGenerateFlowRules,
-                0, CHECK_TOPOLOGY_INTERVAL_SECONDS, TimeUnit.SECONDS);
-    }
-
-    private void setAppFreezed(boolean appFreezed) {
-        this.appFreezed = appFreezed;
-        if (appFreezed) {
-            log.info("Freezing...");
-        } else {
-            log.info("Unfreezing...!");
-        }
-    }
-
-    /**
-     * Perform device initialization. Returns true if the operation was
-     * successful, false otherwise.
-     *
-     * @param deviceId a device id
-     * @return a boolean value
-     */
-    public abstract boolean initDevice(DeviceId deviceId);
-
-    /**
-     * Generates a list of flow rules for the given leaf switch, source host,
-     * destination hosts, spine switches and topology.
-     *
-     * @param leaf     a leaf device id
-     * @param srcHost  a source host
-     * @param dstHosts a collection of destination hosts
-     * @param spines   a collection of spine device IDs
-     * @param topology a topology
-     * @return a list of flow rules
-     * @throws FlowRuleGeneratorException if flow rules cannot be generated
-     */
-    public abstract List<FlowRule> generateLeafRules(DeviceId leaf, Host srcHost,
-                                                     Set<Host> dstHosts,
-                                                     Set<DeviceId> spines,
-                                                     Topology topology)
-            throws FlowRuleGeneratorException;
-
-    /**
-     * Generates a list of flow rules for the given spine switch, destination
-     * hosts and topology.
-     *
-     * @param deviceId a spine device id
-     * @param dstHosts a collection of destination hosts
-     * @param topology a topology
-     * @return a list of flow rules
-     * @throws FlowRuleGeneratorException if flow rules cannot be generated
-     */
-    public abstract List<FlowRule> generateSpineRules(DeviceId deviceId,
-                                                      Set<Host> dstHosts,
-                                                      Topology topology)
-            throws FlowRuleGeneratorException;
-
-    private void deployAllDevices() {
-        if (otherAppFound && otherApp.appActive) {
-            log.info("Deactivating other app...");
-            appService.deactivate(otherApp.appId);
-            try {
-                Thread.sleep(CLEANUP_SLEEP);
-            } catch (InterruptedException e) {
-                log.warn("Cleanup sleep interrupted!");
-                Thread.currentThread().interrupt();
-            }
-        }
-
-        Stream.concat(leafSwitches.stream(), spineSwitches.stream())
-                .map(deviceService::getDevice)
-                .forEach(device -> spawnTask(() -> deployDevice(device)));
-    }
-
-    private boolean matchPipeconf(PiPipeconfId piPipeconfId) {
-        return appPipeconfs.stream()
-                .anyMatch(p -> p.id().equals(piPipeconfId));
-    }
-
-    /**
-     * Executes a device deploy.
-     *
-     * @param device a device
-     */
-    private void deployDevice(Device device) {
-
-        DeviceId deviceId = device.id();
-
-        // Synchronize executions over the same device.
-        Lock lock = deviceLocks.computeIfAbsent(deviceId, k -> new ReentrantLock());
-        lock.lock();
-
-        try {
-            // Set pipeconf flag if not already done.
-            if (!pipeconfFlags.getOrDefault(deviceId, false)) {
-                if (piPipeconfService.ofDevice(deviceId).isPresent() &&
-                        matchPipeconf(piPipeconfService.ofDevice(deviceId).get())) {
-                    pipeconfFlags.put(device.id(), true);
-                } else {
-                    log.warn("Wrong pipeconf for {}, expecting {}, but found {}, aborting deploy",
-                             deviceId, Arrays.toString(appPipeconfs.toArray()),
-                             piPipeconfService.ofDevice(deviceId).get());
-                    return;
-                }
-            }
-
-            // Initialize device.
-            if (!initDevice(deviceId)) {
-                log.warn("Failed to initialize device {}", deviceId);
-            }
-
-            // Install rules.
-            if (!ruleFlags.getOrDefault(deviceId, false) &&
-                    deviceFlowRules.containsKey(deviceId)) {
-                log.info("Installing {} rules for {}...",
-                         deviceFlowRules.get(deviceId).size(), deviceId);
-                installFlowRules(deviceFlowRules.get(deviceId));
-                ruleFlags.put(deviceId, true);
-            }
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    private void spawnTask(Runnable task) {
-        executorService.execute(task);
-    }
-
-
-    private void installFlowRules(Collection<FlowRule> rules) {
-        FlowRuleOperations.Builder opsBuilder = FlowRuleOperations.builder();
-        rules.forEach(opsBuilder::add);
-        flowRuleService.apply(opsBuilder.build());
-    }
-
-    /**
-     * Generates flow rules to provide host-to-host connectivity for the given
-     * topology and hosts.
-     */
-    private synchronized void checkTopologyAndGenerateFlowRules() {
-
-        Topology topo = topologyService.currentTopology();
-        Set<Host> hosts = Sets.newHashSet(hostService.getHosts());
-
-        if (flowRuleGenerated) {
-            log.debug("Flow rules have been already generated, aborting...");
-            return;
-        }
-
-        log.debug("Starting flow rules generator...");
-
-        TopologyGraph graph = topologyService.getGraph(topo);
-        Set<DeviceId> spines = Sets.newHashSet();
-        Set<DeviceId> leafs = Sets.newHashSet();
-        graph.getVertexes().stream()
-                .map(TopologyVertex::deviceId)
-                .forEach(did -> (isSpine(did, topo) ? spines : leafs).add(did));
-
-        if (spines.size() != TOPO_SIZE || leafs.size() != TOPO_SIZE) {
-            log.info("Invalid leaf/spine count, aborting... > leafCount={}, spineCount={}",
-                     spines.size(), leafs.size());
-            return;
-        }
-
-        for (DeviceId did : spines) {
-            int portCount = deviceService.getPorts(did).size();
-            // Expected port count: num leafs + 1 redundant leaf link (if imbalanced)
-            if (portCount != HASHED_LINKS) {
-                log.info("Invalid port count for spine, aborting... > deviceId={}, portCount={}",
-                         did, portCount);
-                return;
-            }
-        }
-        for (DeviceId did : leafs) {
-            int portCount = deviceService.getPorts(did).size();
-            // Expected port count: num spines + host port + 1 redundant spine link
-            if (portCount != HASHED_LINKS + 1) {
-                log.info("Invalid port count for leaf, aborting... > deviceId={}, portCount={}",
-                         did, portCount);
-                return;
-            }
-        }
-
-        // Check hosts, number and exactly one per leaf
-        Map<DeviceId, Host> hostMap = Maps.newHashMap();
-        hosts.forEach(h -> hostMap.put(h.location().deviceId(), h));
-        if (hosts.size() != TOPO_SIZE || !leafs.equals(hostMap.keySet())) {
-            log.info("Wrong host configuration, aborting... > hostCount={}, hostMapz={}",
-                     hosts.size(), hostMap);
-            return;
-        }
-
-        List<FlowRule> newFlowRules = Lists.newArrayList();
-
-        try {
-            for (DeviceId deviceId : leafs) {
-                Host srcHost = hostMap.get(deviceId);
-                Set<Host> dstHosts = hosts.stream()
-                        .filter(h -> h != srcHost)
-                        .collect(toSet());
-                newFlowRules.addAll(generateLeafRules(deviceId, srcHost,
-                                                      dstHosts, spines, topo));
-            }
-            for (DeviceId deviceId : spines) {
-                newFlowRules.addAll(generateSpineRules(deviceId, hosts, topo));
-            }
-        } catch (FlowRuleGeneratorException e) {
-            log.warn("Exception while executing flow rule generator: {}",
-                     e.getMessage());
-            return;
-        }
-
-        if (newFlowRules.size() == 0) {
-            // Something went wrong
-            log.error("0 flow rules generated, BUG?");
-            return;
-        }
-
-        // All good!
-        // Divide flow rules per device id...
-        ImmutableMap.Builder<DeviceId, List<FlowRule>> mapBuilder =
-                ImmutableMap.builder();
-        concat(spines.stream(), leafs.stream())
-                .map(deviceId -> ImmutableList.copyOf(
-                        newFlowRules.stream()
-                                .filter(fr -> fr.deviceId().equals(deviceId))
-                                .iterator()))
-                .forEach(frs -> mapBuilder.put(frs.get(0).deviceId(), frs));
-        this.deviceFlowRules = mapBuilder.build();
-
-        this.leafSwitches = ImmutableSet.copyOf(leafs);
-        this.spineSwitches = ImmutableSet.copyOf(spines);
-
-        // Avoid other executions to modify the generated flow rules.
-        flowRuleGenerated = true;
-
-        log.info("Generated {} flow rules for {} devices",
-                 newFlowRules.size(), spines.size() + leafs.size());
-
-        spawnTask(this::deployAllDevices);
-    }
-
-    /**
-     * Returns a new, pre-configured flow rule builder.
-     *
-     * @param did     a device id
-     * @param tableId a table id
-     * @return a new flow rule builder
-     * @throws FlowRuleGeneratorException if device has no pipeline interpreter
-     */
-    protected FlowRule.Builder flowRuleBuilder(DeviceId did, PiTableId tableId)
-            throws FlowRuleGeneratorException {
-
-        final Device device = deviceService.getDevice(did);
-        if (!device.is(PiPipelineInterpreter.class)) {
-            throw new FlowRuleGeneratorException(format(
-                    "Device %s has no PiPipelineInterpreter", did));
-        }
-
-        return DefaultFlowRule.builder()
-                .forDevice(did)
-                .forTable(tableId)
-                .fromApp(appId)
-                .withPriority(FLOW_PRIORITY)
-                .makePermanent();
-    }
-
-    private List<Port> getHostPorts(DeviceId deviceId, Topology topology) {
-        // Get all non-fabric ports.
-        return deviceService
-                .getPorts(deviceId)
-                .stream()
-                .filter(p -> !isFabricPort(p, topology))
-                .collect(Collectors.toList());
-    }
-
-    private boolean isSpine(DeviceId deviceId, Topology topology) {
-        // True if all ports are fabric.
-        return getHostPorts(deviceId, topology).size() == 0;
-    }
-
-    protected boolean isFabricPort(Port port, Topology topology) {
-        // True if the port connects this device to another infrastructure device.
-        return topologyService.isInfrastructure(
-                topology, new ConnectPoint(port.element().id(), port.number()));
-    }
-
-    /**
-     * A listener of device events that executes a device deploy task each time
-     * a device is added, updated or re-connects.
-     */
-    private class InternalDeviceListener implements DeviceListener {
-        @Override
-        public void event(DeviceEvent event) {
-            spawnTask(() -> deployDevice(event.subject()));
-        }
-
-        @Override
-        public boolean isRelevant(DeviceEvent event) {
-            return !appFreezed &&
-                    (event.type() == DEVICE_ADDED ||
-                            event.type() == DEVICE_UPDATED ||
-                            (event.type() == DEVICE_AVAILABILITY_CHANGED &&
-                                    deviceService.isAvailable(event.subject().id())));
-        }
-    }
-
-    /**
-     * An exception occurred while generating flow rules for this fabric.
-     */
-    public static class FlowRuleGeneratorException extends Exception {
-
-        public FlowRuleGeneratorException() {
-        }
-
-        FlowRuleGeneratorException(String msg) {
-            super(msg);
-        }
-    }
-}
diff --git a/apps/pi-demo/common/src/main/java/org/onosproject/pi/demo/app/common/package-info.java b/apps/pi-demo/common/src/main/java/org/onosproject/pi/demo/app/common/package-info.java
deleted file mode 100644
index 8b4570d..0000000
--- a/apps/pi-demo/common/src/main/java/org/onosproject/pi/demo/app/common/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2017-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * PI demo app common classes.
- */
-package org.onosproject.pi.demo.app.common;
\ No newline at end of file
diff --git a/apps/pi-demo/ecmp/BUILD b/apps/pi-demo/ecmp/BUILD
deleted file mode 100644
index 2d2be99..0000000
--- a/apps/pi-demo/ecmp/BUILD
+++ /dev/null
@@ -1,26 +0,0 @@
-COMPILE_DEPS = CORE_DEPS + [
-    "@minimal_json//jar",
-    "//apps/pi-demo/common:onos-apps-pi-demo-common",
-    "//pipelines/basic:onos-pipelines-basic",
-]
-
-osgi_jar(
-    deps = COMPILE_DEPS,
-)
-
-BUNDLES = [
-    "//apps/pi-demo/common:onos-apps-pi-demo-common",
-    "//apps/pi-demo/ecmp:onos-apps-pi-demo-ecmp",
-]
-
-onos_app(
-    app_name = "org.onosproject.pi-ecmp",
-    category = "Traffic Engineering",
-    description = "Provides ECMP support for a 2-stage clos fabric topology of PI-enabled devices",
-    included_bundles = BUNDLES,
-    required_apps = [
-        "org.onosproject.pipelines.basic",
-    ],
-    title = "PI Demo ECMP Fabric",
-    url = "http://onosproject.org",
-)
diff --git a/apps/pi-demo/ecmp/src/main/java/org/onosproject/pi/demo/app/ecmp/EcmpFabricApp.java b/apps/pi-demo/ecmp/src/main/java/org/onosproject/pi/demo/app/ecmp/EcmpFabricApp.java
deleted file mode 100644
index d8d7a1d..0000000
--- a/apps/pi-demo/ecmp/src/main/java/org/onosproject/pi/demo/app/ecmp/EcmpFabricApp.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright 2017-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onosproject.pi.demo.app.ecmp;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import org.apache.commons.lang3.tuple.ImmutablePair;
-import org.apache.commons.lang3.tuple.Pair;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Deactivate;
-import org.onlab.packet.IpAddress;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Host;
-import org.onosproject.net.Path;
-import org.onosproject.net.Port;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.criteria.PiCriterion;
-import org.onosproject.net.group.DefaultGroupBucket;
-import org.onosproject.net.group.DefaultGroupDescription;
-import org.onosproject.net.group.GroupBucket;
-import org.onosproject.net.group.GroupBuckets;
-import org.onosproject.net.group.GroupDescription;
-import org.onosproject.net.group.GroupKey;
-import org.onosproject.net.pi.runtime.PiAction;
-import org.onosproject.net.pi.runtime.PiActionGroupId;
-import org.onosproject.net.pi.runtime.PiActionParam;
-import org.onosproject.net.pi.runtime.PiGroupKey;
-import org.onosproject.net.pi.runtime.PiTableAction;
-import org.onosproject.net.topology.DefaultTopologyVertex;
-import org.onosproject.net.topology.Topology;
-import org.onosproject.net.topology.TopologyGraph;
-import org.onosproject.pi.demo.app.common.AbstractUpgradableFabricApp;
-import org.onosproject.pipelines.basic.PipeconfLoader;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import static java.util.Collections.singleton;
-import static java.util.stream.Collectors.toSet;
-import static org.onlab.util.ImmutableByteSequence.copyFrom;
-import static org.onosproject.pipelines.basic.BasicConstants.ACT_PRF_WCMP_SELECTOR_ID;
-import static org.onosproject.pipelines.basic.BasicConstants.ACT_PRM_NEXT_HOP_ID;
-import static org.onosproject.pipelines.basic.BasicConstants.ACT_SET_NEXT_HOP_ID;
-import static org.onosproject.pipelines.basic.BasicConstants.HDR_NEXT_HOP_ID;
-import static org.onosproject.pipelines.basic.BasicConstants.TBL_TABLE0_ID;
-import static org.onosproject.pipelines.basic.BasicConstants.TBL_WCMP_TABLE_ID;
-
-/**
- * Implementation of an upgradable fabric app for the Basic pipeconf (basic.p4)
- * with ECMP support.
- */
-@Component(immediate = true)
-public class EcmpFabricApp extends AbstractUpgradableFabricApp {
-
-    private static final String APP_NAME = "org.onosproject.pi-ecmp";
-
-    private static final Map<DeviceId, Map<Set<PortNumber>, Short>>
-            DEVICE_GROUP_ID_MAP = Maps.newHashMap();
-
-    private final Set<Pair<DeviceId, GroupKey>> groupKeys = Sets.newHashSet();
-
-    public EcmpFabricApp() {
-        super(APP_NAME, singleton(PipeconfLoader.BASIC_PIPECONF));
-    }
-
-    @Deactivate
-    public void deactivate() {
-        groupKeys.forEach(pair -> groupService.removeGroup(
-                pair.getLeft(), pair.getRight(), appId));
-        super.deactivate();
-    }
-
-    @Override
-    public boolean initDevice(DeviceId deviceId) {
-        // Nothing to do.
-        return true;
-    }
-
-    @Override
-    public List<FlowRule> generateLeafRules(DeviceId leaf, Host localHost,
-                                            Set<Host> remoteHosts,
-                                            Set<DeviceId> availableSpines,
-                                            Topology topo)
-            throws FlowRuleGeneratorException {
-
-        // Get ports which connect this leaf switch to hosts.
-        Set<PortNumber> hostPorts = deviceService.getPorts(leaf)
-                .stream()
-                .filter(port -> !isFabricPort(port, topo))
-                .map(Port::number)
-                .collect(toSet());
-
-        // Get ports which connect this leaf to the given available spines.
-        TopologyGraph graph = topologyService.getGraph(topo);
-        Set<PortNumber> fabricPorts = graph
-                .getEdgesFrom(new DefaultTopologyVertex(leaf))
-                .stream()
-                .filter(e -> availableSpines.contains(e.dst().deviceId()))
-                .map(e -> e.link().src().port())
-                .collect(toSet());
-
-        if (hostPorts.size() != 1 || fabricPorts.size() == 0) {
-            log.error("Leaf has invalid port configuration: hostPorts={}, fabricPorts={}",
-                      hostPorts.size(), fabricPorts.size());
-            throw new FlowRuleGeneratorException();
-        }
-        PortNumber hostPort = hostPorts.iterator().next();
-
-        List<FlowRule> rules = Lists.newArrayList();
-
-        // From local host to remote ones.
-        for (Host remoteHost : remoteHosts) {
-            int groupId = provisionGroup(leaf, fabricPorts);
-
-            rules.add(groupFlowRule(leaf, groupId));
-
-            PiTableAction piTableAction = PiAction.builder()
-                    .withId(ACT_SET_NEXT_HOP_ID)
-                    .withParameter(new PiActionParam(
-                            ACT_PRM_NEXT_HOP_ID,
-                            copyFrom(groupId)))
-                    .build();
-
-            for (IpAddress ipAddr : remoteHost.ipAddresses()) {
-                FlowRule rule = flowRuleBuilder(leaf, TBL_TABLE0_ID)
-                        .withSelector(
-                                DefaultTrafficSelector.builder()
-                                        .matchIPDst(ipAddr.toIpPrefix())
-                                        .build())
-                        .withTreatment(
-                                DefaultTrafficTreatment.builder()
-                                        .piTableAction(piTableAction)
-                                        .build())
-                        .build();
-                rules.add(rule);
-            }
-        }
-
-        // From remote hosts to the local one
-        for (IpAddress dstIpAddr : localHost.ipAddresses()) {
-            FlowRule rule = flowRuleBuilder(leaf, TBL_TABLE0_ID)
-                    .withSelector(
-                            DefaultTrafficSelector.builder()
-                                    .matchIPDst(dstIpAddr.toIpPrefix())
-                                    .build())
-                    .withTreatment(
-                            DefaultTrafficTreatment.builder()
-                                    .setOutput(hostPort)
-                                    .build())
-                    .build();
-            rules.add(rule);
-        }
-
-        return rules;
-    }
-
-    @Override
-    public List<FlowRule> generateSpineRules(DeviceId spine, Set<Host> hosts,
-                                             Topology topo)
-            throws FlowRuleGeneratorException {
-
-        List<FlowRule> rules = Lists.newArrayList();
-
-        // For each host pair (src -> dst)
-        for (Host dstHost : hosts) {
-
-            Set<Path> paths = topologyService.getPaths(
-                    topo, spine, dstHost.location().deviceId());
-
-            if (paths.size() == 0) {
-                log.warn("No path between spine {} and host {}",
-                         spine, dstHost);
-                throw new FlowRuleGeneratorException();
-            }
-
-            Set<PortNumber> ports = paths.stream()
-                    .map(p -> p.src().port())
-                    .collect(toSet());
-
-            int groupId = provisionGroup(spine, ports);
-
-            rules.add(groupFlowRule(spine, groupId));
-
-            PiTableAction piTableAction = PiAction.builder()
-                    .withId(ACT_SET_NEXT_HOP_ID)
-                    .withParameter(new PiActionParam(ACT_PRM_NEXT_HOP_ID,
-                                                     copyFrom(groupId)))
-                    .build();
-
-            for (IpAddress dstIpAddr : dstHost.ipAddresses()) {
-                FlowRule rule = flowRuleBuilder(spine, TBL_TABLE0_ID)
-                        .withSelector(DefaultTrafficSelector.builder()
-                                              .matchIPDst(dstIpAddr.toIpPrefix())
-                                              .build())
-                        .withTreatment(DefaultTrafficTreatment.builder()
-                                               .piTableAction(piTableAction)
-                                               .build())
-                        .build();
-                rules.add(rule);
-            }
-        }
-
-        return rules;
-    }
-
-    /**
-     * Provisions an ECMP group for the given device and set of ports, returns
-     * the group ID.
-     */
-    private int provisionGroup(DeviceId deviceId, Set<PortNumber> ports)
-            throws FlowRuleGeneratorException {
-
-        int groupId = groupIdOf(deviceId, ports);
-
-        // Group buckets
-        List<GroupBucket> bucketList = ports.stream()
-                .map(port -> DefaultTrafficTreatment.builder()
-                        .setOutput(port)
-                        .build())
-                .map(DefaultGroupBucket::createSelectGroupBucket)
-                .collect(Collectors.toList());
-
-        // Group cookie (with action profile ID)
-        PiGroupKey groupKey = new PiGroupKey(TBL_WCMP_TABLE_ID,
-                                             ACT_PRF_WCMP_SELECTOR_ID,
-                                             groupId);
-
-        log.info("Adding group {} to {}...", groupId, deviceId);
-        groupService.addGroup(
-                new DefaultGroupDescription(deviceId,
-                                            GroupDescription.Type.SELECT,
-                                            new GroupBuckets(bucketList),
-                                            groupKey,
-                                            groupId,
-                                            appId));
-
-        groupKeys.add(ImmutablePair.of(deviceId, groupKey));
-
-        return groupId;
-    }
-
-    private FlowRule groupFlowRule(DeviceId deviceId, int groupId)
-            throws FlowRuleGeneratorException {
-        return flowRuleBuilder(deviceId, TBL_WCMP_TABLE_ID)
-                .withSelector(
-                        DefaultTrafficSelector.builder()
-                                .matchPi(
-                                        PiCriterion.builder()
-                                                .matchExact(HDR_NEXT_HOP_ID,
-                                                            groupId)
-                                                .build())
-                                .build())
-                .withTreatment(
-                        DefaultTrafficTreatment.builder()
-                                .piTableAction(PiActionGroupId.of(groupId))
-                                .build())
-                .build();
-    }
-
-    private int groupIdOf(DeviceId deviceId, Set<PortNumber> ports) {
-        DEVICE_GROUP_ID_MAP.putIfAbsent(deviceId, Maps.newHashMap());
-        // Counts the number of unique portNumber sets for each deviceId.
-        // Each distinct set of portNumbers will have a unique ID.
-        return DEVICE_GROUP_ID_MAP.get(deviceId).computeIfAbsent(ports, (pp) ->
-                (short) (DEVICE_GROUP_ID_MAP.get(deviceId).size() + 1));
-    }
-}
diff --git a/apps/pi-demo/ecmp/src/main/java/org/onosproject/pi/demo/app/ecmp/package-info.java b/apps/pi-demo/ecmp/src/main/java/org/onosproject/pi/demo/app/ecmp/package-info.java
deleted file mode 100644
index 0d70589..0000000
--- a/apps/pi-demo/ecmp/src/main/java/org/onosproject/pi/demo/app/ecmp/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2017-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * PI demo app for the ECMP configuration.
- */
-package org.onosproject.pi.demo.app.ecmp;
\ No newline at end of file
diff --git a/tools/build/bazel/modules.bzl b/tools/build/bazel/modules.bzl
index 12a54e9..1872d2b 100644
--- a/tools/build/bazel/modules.bzl
+++ b/tools/build/bazel/modules.bzl
@@ -226,7 +226,6 @@
     "//apps/l3vpn:onos-apps-l3vpn-oar",
     "//apps/openroadm:onos-apps-openroadm-oar",
     "//apps/artemis:onos-apps-artemis-oar",
-    "//apps/pi-demo/ecmp:onos-apps-pi-demo-ecmp-oar",
     "//apps/gluon:onos-apps-gluon-oar",
     "//apps/evpnopenflow:onos-apps-evpnopenflow-oar",
     "//apps/route-service:onos-apps-route-service-oar",
