diff --git a/drivers/bmv2/BUCK b/drivers/bmv2/BUCK
index d9b09bb..c8224f5 100644
--- a/drivers/bmv2/BUCK
+++ b/drivers/bmv2/BUCK
@@ -9,6 +9,7 @@
     '//drivers/p4runtime:onos-drivers-p4runtime',
     '//incubator/grpc-dependencies:grpc-core-repkg-' + GRPC_VER,
     '//lib:grpc-netty-' + GRPC_VER,
+    '//pipelines/basic:onos-pipelines-basic',
 ]
 
 BUNDLES = [
@@ -29,5 +30,6 @@
     included_bundles = BUNDLES,
     required_apps = [
         'org.onosproject.drivers.p4runtime',
+        'org.onosproject.pipelines.basic',
     ],
 )
\ No newline at end of file
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DefaultPipeconfFactory.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DefaultPipeconfFactory.java
deleted file mode 100644
index 448da71..0000000
--- a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DefaultPipeconfFactory.java
+++ /dev/null
@@ -1,68 +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.drivers.bmv2;
-
-import org.onosproject.bmv2.model.Bmv2PipelineModelParser;
-import org.onosproject.driver.pipeline.DefaultSingleTablePipeline;
-import org.onosproject.drivers.p4runtime.DefaultP4Interpreter;
-import org.onosproject.drivers.p4runtime.DefaultP4PortStatisticsDiscovery;
-import org.onosproject.net.behaviour.Pipeliner;
-import org.onosproject.net.device.PortStatisticsDiscovery;
-import org.onosproject.net.pi.model.DefaultPiPipeconf;
-import org.onosproject.net.pi.model.PiPipeconf;
-import org.onosproject.net.pi.model.PiPipeconfId;
-import org.onosproject.net.pi.model.PiPipelineInterpreter;
-
-import java.net.URL;
-
-import static org.onosproject.net.pi.model.PiPipeconf.ExtensionType.BMV2_JSON;
-import static org.onosproject.net.pi.model.PiPipeconf.ExtensionType.P4_INFO_TEXT;
-
-/**
- * Factory of pipeconf implementation for the default.p4 program on BMv2.
- */
-public final class Bmv2DefaultPipeconfFactory {
-
-    private static final String PIPECONF_ID = "bmv2-default-pipeconf";
-    private static final String JSON_PATH = "/default.json";
-    private static final String P4INFO_PATH = "/default.p4info";
-
-    private static final PiPipeconf PIPECONF = buildPipeconf();
-
-    private Bmv2DefaultPipeconfFactory() {
-        // Hides constructor.
-    }
-
-    public static PiPipeconf get() {
-        return PIPECONF;
-    }
-
-    private static PiPipeconf buildPipeconf() {
-
-        final URL jsonUrl = Bmv2DefaultPipeconfFactory.class.getResource(JSON_PATH);
-        final URL p4InfoUrl = Bmv2DefaultPipeconfFactory.class.getResource(P4INFO_PATH);
-        return DefaultPiPipeconf.builder()
-                .withId(new PiPipeconfId(PIPECONF_ID))
-                .withPipelineModel(Bmv2PipelineModelParser.parse(jsonUrl))
-                .addBehaviour(PiPipelineInterpreter.class, DefaultP4Interpreter.class)
-                .addBehaviour(Pipeliner.class, DefaultSingleTablePipeline.class)
-                .addBehaviour(PortStatisticsDiscovery.class, DefaultP4PortStatisticsDiscovery.class)
-                .addExtension(P4_INFO_TEXT, p4InfoUrl)
-                .addExtension(BMV2_JSON, jsonUrl)
-                .build();
-    }
-}
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DriversLoader.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DriversLoader.java
index ff4f2d9..8ee87d4 100644
--- a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DriversLoader.java
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DriversLoader.java
@@ -17,10 +17,7 @@
 package org.onosproject.drivers.bmv2;
 
 import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.onosproject.net.driver.AbstractDriverLoader;
-import org.onosproject.net.pi.runtime.PiPipeconfService;
 
 /**
  * Loader for P4Runtime device drivers.
@@ -28,22 +25,7 @@
 @Component(immediate = true)
 public class Bmv2DriversLoader extends AbstractDriverLoader {
 
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected PiPipeconfService pipeconfService;
-
     public Bmv2DriversLoader() {
         super("/bmv2-drivers.xml");
     }
-
-    @Override
-    public void activate() {
-        pipeconfService.register(Bmv2DefaultPipeconfFactory.get());
-        super.activate();
-    }
-
-    @Override
-    public void deactivate() {
-        pipeconfService.remove(Bmv2DefaultPipeconfFactory.get().id());
-        super.deactivate();
-    }
 }
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2PipelineProgrammable.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2PipelineProgrammable.java
index 0eef5ed..bf88238 100644
--- a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2PipelineProgrammable.java
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2PipelineProgrammable.java
@@ -23,6 +23,7 @@
 import org.onosproject.net.pi.model.PiPipelineProgrammable;
 import org.onosproject.p4runtime.api.P4RuntimeClient;
 import org.onosproject.p4runtime.api.P4RuntimeController;
+import org.onosproject.pipelines.basic.PipeconfLoader;
 import org.slf4j.Logger;
 
 import java.util.Optional;
@@ -37,8 +38,6 @@
  */
 public class Bmv2PipelineProgrammable extends AbstractHandlerBehaviour implements PiPipelineProgrammable {
 
-    private static final PiPipeconf DEFAULT_PIPECONF = Bmv2DefaultPipeconfFactory.get();
-
     private final Logger log = getLogger(getClass());
 
     @Override
@@ -87,6 +86,6 @@
 
     @Override
     public Optional<PiPipeconf> getDefaultPipeconf() {
-        return Optional.of(DEFAULT_PIPECONF);
+        return Optional.of(PipeconfLoader.BASIC_PIPECONF);
     }
 }
diff --git a/drivers/bmv2/src/main/resources/default.json b/drivers/bmv2/src/main/resources/default.json
deleted file mode 120000
index c5028d8..0000000
--- a/drivers/bmv2/src/main/resources/default.json
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../tools/test/p4src/p4-16/p4c-out/default.json
\ No newline at end of file
diff --git a/drivers/bmv2/src/main/resources/default.p4info b/drivers/bmv2/src/main/resources/default.p4info
deleted file mode 120000
index 8f71cbe..0000000
--- a/drivers/bmv2/src/main/resources/default.p4info
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../tools/test/p4src/p4-16/p4c-out/default.p4info
\ No newline at end of file
diff --git a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/DefaultP4Interpreter.java b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/DefaultP4Interpreter.java
deleted file mode 100644
index f716a63..0000000
--- a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/DefaultP4Interpreter.java
+++ /dev/null
@@ -1,331 +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.drivers.p4runtime;
-
-import com.google.common.collect.ImmutableBiMap;
-import com.google.common.collect.ImmutableList;
-import org.onlab.packet.DeserializationException;
-import org.onlab.packet.Ethernet;
-import org.onlab.util.ImmutableByteSequence;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Port;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.driver.AbstractHandlerBehaviour;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flow.criteria.Criterion;
-import org.onosproject.net.flow.instructions.Instruction;
-import org.onosproject.net.flow.instructions.Instructions;
-import org.onosproject.net.flow.instructions.PiInstruction;
-import org.onosproject.net.packet.DefaultInboundPacket;
-import org.onosproject.net.packet.InboundPacket;
-import org.onosproject.net.packet.OutboundPacket;
-import org.onosproject.net.pi.model.PiHeaderFieldModel;
-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.PiPipelineModel;
-import org.onosproject.net.pi.model.PiTableModel;
-import org.onosproject.net.pi.runtime.PiAction;
-import org.onosproject.net.pi.runtime.PiActionId;
-import org.onosproject.net.pi.runtime.PiActionParam;
-import org.onosproject.net.pi.runtime.PiActionParamId;
-import org.onosproject.net.pi.runtime.PiCounterId;
-import org.onosproject.net.pi.runtime.PiCounterType;
-import org.onosproject.net.pi.runtime.PiHeaderFieldId;
-import org.onosproject.net.pi.runtime.PiPacketMetadata;
-import org.onosproject.net.pi.runtime.PiPacketMetadataId;
-import org.onosproject.net.pi.runtime.PiPacketOperation;
-import org.onosproject.net.pi.runtime.PiPipeconfService;
-import org.onosproject.net.pi.runtime.PiTableId;
-
-import java.nio.ByteBuffer;
-import java.util.Collection;
-import java.util.List;
-import java.util.Optional;
-
-import static java.lang.String.format;
-import static java.util.stream.Collectors.toList;
-import static org.onlab.util.ImmutableByteSequence.copyFrom;
-import static org.onlab.util.ImmutableByteSequence.fit;
-import static org.onosproject.net.PortNumber.CONTROLLER;
-import static org.onosproject.net.PortNumber.FLOOD;
-import static org.onosproject.net.flow.instructions.Instruction.Type.OUTPUT;
-import static org.onosproject.net.pi.runtime.PiPacketOperation.Type.PACKET_OUT;
-
-/**
- * Implementation of an interpreter that can be used for any P4 program based on default.p4 (i.e. those under
- * onos/tools/test/p4src).
- */
-public class DefaultP4Interpreter extends AbstractHandlerBehaviour implements PiPipelineInterpreter {
-
-    // FIXME: Should move this class out of the p4runtime drivers.
-    // e.g. in a dedicated onos/pipeconf directory, along with any related P4 source code.
-
-    public static final String TABLE0 = "table0";
-    public static final String TABLE0_COUNTER = "table0_counter";
-    public static final String ECMP = "ecmp";
-    public static final String SEND_TO_CPU = "send_to_cpu";
-    public static final String PORT = "port";
-    public static final String DROP = "_drop";
-    public static final String SET_EGRESS_PORT = "set_egress_port";
-    public static final String EGRESS_PORT = "egress_port";
-    public static final String INGRESS_PORT = "ingress_port";
-
-    private static final PiTableId TABLE0_ID = PiTableId.of(TABLE0);
-    private static final PiTableId ECMP_ID = PiTableId.of(ECMP);
-
-    protected static final PiHeaderFieldId ETH_DST_ID = PiHeaderFieldId.of("ethernet", "dstAddr");
-    protected static final PiHeaderFieldId ETH_SRC_ID = PiHeaderFieldId.of("ethernet", "srcAddr");
-    protected static final PiHeaderFieldId ETH_TYPE_ID = PiHeaderFieldId.of("ethernet", "etherType");
-
-    private static final ImmutableBiMap<Integer, PiTableId> TABLE_MAP = ImmutableBiMap.of(
-            0, TABLE0_ID,
-            1, ECMP_ID);
-
-    private static final ImmutableBiMap<PiTableId, PiCounterId> TABLE_COUNTER_MAP = ImmutableBiMap.of(
-            TABLE0_ID, PiCounterId.of(TABLE0_COUNTER, PiCounterType.DIRECT));
-
-    private boolean targetAttributesInitialized = false;
-
-    /*
-    The following attributes are target-specific, i.e. they might change from one target to another.
-     */
-    private ImmutableBiMap<Criterion.Type, PiHeaderFieldId> criterionMap;
-    private int portFieldBitWidth;
-
-    /**
-     * Populates target-specific attributes based on this device's pipeline model.
-     */
-    private synchronized void initTargetSpecificAttributes() {
-        if (targetAttributesInitialized) {
-            return;
-        }
-
-        DeviceId deviceId = this.handler().data().deviceId();
-        PiPipeconfService pipeconfService = this.handler().get(PiPipeconfService.class);
-        PiPipeconfId pipeconfId = pipeconfService.ofDevice(deviceId)
-                .orElseThrow(() -> new RuntimeException(format(
-                        "Unable to get current pipeconf for device %s", this.data().deviceId())));
-        PiPipeconf pipeconf = pipeconfService.getPipeconf(pipeconfId)
-                .orElseThrow(() -> new RuntimeException(format(
-                        "Pipeconf %s is not registered", pipeconfId)));
-        PiPipelineModel model = pipeconf.pipelineModel();
-
-        this.portFieldBitWidth = extractPortFieldBitWidth(model);
-        this.criterionMap = new ImmutableBiMap.Builder<Criterion.Type, PiHeaderFieldId>()
-                .put(Criterion.Type.IN_PORT, extractInPortFieldId(model))
-                .put(Criterion.Type.ETH_DST, ETH_DST_ID)
-                .put(Criterion.Type.ETH_SRC, ETH_SRC_ID)
-                .put(Criterion.Type.ETH_TYPE, ETH_TYPE_ID)
-                .build();
-
-        this.targetAttributesInitialized = true;
-    }
-
-    private static PiHeaderFieldId extractInPortFieldId(PiPipelineModel model) {
-        /*
-        For the targets we currently support, the field name is "ingress_port", but we miss the header name, which is
-        target-specific. We know table0 defines that field as a match key, we look for it and we get the header name.
-         */
-        PiTableModel tableModel = model.table(TABLE0).orElseThrow(() -> new RuntimeException(format(
-                "No such table '%s' in pipeline model", TABLE0)));
-        PiHeaderFieldModel fieldModel = tableModel.matchFields().stream()
-                .filter(m -> m.field().type().name().equals(INGRESS_PORT))
-                .findFirst()
-                .orElseThrow(() -> new RuntimeException(format(
-                        "No such match field in table '%s' with name '%s'", TABLE0, INGRESS_PORT)))
-                .field();
-        return PiHeaderFieldId.of(fieldModel.header().name(), INGRESS_PORT);
-    }
-
-    private static int extractPortFieldBitWidth(PiPipelineModel model) {
-        /*
-        Get it form the set_egress_port action parameters.
-         */
-        return model
-                .action(SET_EGRESS_PORT).orElseThrow(() -> new RuntimeException(format(
-                        "No such action '%s' in pipeline model", SET_EGRESS_PORT)))
-                .param(PORT).orElseThrow(() -> new RuntimeException(format(
-                        "No such parameter '%s' of action '%s' in pipeline model", PORT, SET_EGRESS_PORT)))
-                .bitWidth();
-    }
-
-
-    @Override
-    public PiAction mapTreatment(TrafficTreatment treatment, PiTableId piTableId) throws PiInterpreterException {
-        initTargetSpecificAttributes();
-        if (treatment.allInstructions().size() == 0) {
-            // No instructions means drop for us.
-            return actionWithName(DROP);
-        } else if (treatment.allInstructions().size() > 1) {
-            // Otherwise, we understand treatments with only 1 instruction.
-            throw new PiPipelineInterpreter.PiInterpreterException("Treatment has multiple instructions");
-        }
-
-        Instruction instruction = treatment.allInstructions().get(0);
-
-        switch (instruction.type()) {
-            case OUTPUT:
-                Instructions.OutputInstruction outInstruction = (Instructions.OutputInstruction) instruction;
-                return outputPiAction(outInstruction);
-            case PROTOCOL_INDEPENDENT:
-                PiInstruction piInstruction = (PiInstruction) instruction;
-                return (PiAction) piInstruction.action();
-            case NOACTION:
-                return actionWithName(DROP);
-            default:
-                throw new PiInterpreterException(format("Instruction type '%s' not supported", instruction.type()));
-        }
-    }
-
-    private PiAction outputPiAction(Instructions.OutputInstruction outInstruction) throws PiInterpreterException {
-        PortNumber port = outInstruction.port();
-        if (!port.isLogical()) {
-            try {
-                return PiAction.builder()
-                        .withId(PiActionId.of(SET_EGRESS_PORT))
-                        .withParameter(new PiActionParam(PiActionParamId.of(PORT),
-                                                         fit(copyFrom(port.toLong()), portFieldBitWidth)))
-                        .build();
-            } catch (ImmutableByteSequence.ByteSequenceTrimException e) {
-                throw new PiInterpreterException(e.getMessage());
-            }
-        } else if (port.equals(CONTROLLER)) {
-            return actionWithName(SEND_TO_CPU);
-        } else {
-            throw new PiInterpreterException(format("Egress on logical port '%s' not supported", port));
-        }
-    }
-
-    @Override
-    public Optional<PiCounterId> mapTableCounter(PiTableId piTableId) {
-        return Optional.ofNullable(TABLE_COUNTER_MAP.get(piTableId));
-    }
-
-    @Override
-    public Collection<PiPacketOperation> mapOutboundPacket(OutboundPacket packet)
-            throws PiInterpreterException {
-        TrafficTreatment treatment = packet.treatment();
-
-        // default.p4 supports only OUTPUT instructions.
-        List<Instructions.OutputInstruction> outInstructions = treatment.allInstructions()
-                .stream()
-                .filter(i -> i.type().equals(OUTPUT))
-                .map(i -> (Instructions.OutputInstruction) i)
-                .collect(toList());
-
-        if (treatment.allInstructions().size() != outInstructions.size()) {
-            // There are other instructions that are not of type OUTPUT.
-            throw new PiInterpreterException("Treatment not supported: " + treatment);
-        }
-
-        ImmutableList.Builder<PiPacketOperation> builder = ImmutableList.builder();
-        for (Instructions.OutputInstruction outInst : outInstructions) {
-            if (outInst.port().isLogical() && !outInst.port().equals(FLOOD)) {
-                throw new PiInterpreterException(format("Output on logical port '%s' not supported", outInst.port()));
-            } else if (outInst.port().equals(FLOOD)) {
-                // Since default.p4 does not support flooding, we create a packet operation for each switch port.
-                for (Port port : handler().get(DeviceService.class).getPorts(packet.sendThrough())) {
-                    builder.add(createPiPacketOperation(packet.data(), port.number().toLong()));
-                }
-            } else {
-                builder.add(createPiPacketOperation(packet.data(), outInst.port().toLong()));
-            }
-        }
-        return builder.build();
-    }
-
-    @Override
-    public InboundPacket mapInboundPacket(DeviceId deviceId, PiPacketOperation packetIn)
-            throws PiInterpreterException {
-        // Assuming that the packet is ethernet, which is fine since default.p4 can deparse only ethernet packets.
-        Ethernet ethPkt;
-        try {
-            ethPkt = Ethernet.deserializer().deserialize(packetIn.data().asArray(), 0, packetIn.data().size());
-        } catch (DeserializationException dex) {
-            throw new PiInterpreterException(dex.getMessage());
-        }
-
-        // Returns the ingress port packet metadata.
-        Optional<PiPacketMetadata> packetMetadata = packetIn.metadatas()
-                .stream().filter(metadata -> metadata.id().name().equals(INGRESS_PORT))
-                .findFirst();
-
-        if (packetMetadata.isPresent()) {
-            ImmutableByteSequence portByteSequence = packetMetadata.get().value();
-            short s = portByteSequence.asReadOnlyBuffer().getShort();
-            ConnectPoint receivedFrom = new ConnectPoint(deviceId, PortNumber.portNumber(s));
-            ByteBuffer rawData = ByteBuffer.wrap(packetIn.data().asArray());
-            return new DefaultInboundPacket(receivedFrom, ethPkt, rawData);
-        } else {
-            throw new PiInterpreterException(format(
-                    "Missing metadata '%s' in packet-in received from '%s': %s", INGRESS_PORT, deviceId, packetIn));
-        }
-    }
-
-    private PiPacketOperation createPiPacketOperation(ByteBuffer data, long portNumber) throws PiInterpreterException {
-        PiPacketMetadata metadata = createPacketMetadata(portNumber);
-        return PiPacketOperation.builder()
-                .withType(PACKET_OUT)
-                .withData(copyFrom(data))
-                .withMetadatas(ImmutableList.of(metadata))
-                .build();
-    }
-
-    private PiPacketMetadata createPacketMetadata(long portNumber) throws PiInterpreterException {
-        initTargetSpecificAttributes();
-        try {
-            return PiPacketMetadata.builder()
-                    .withId(PiPacketMetadataId.of(EGRESS_PORT))
-                    .withValue(fit(copyFrom(portNumber), portFieldBitWidth))
-                    .build();
-        } catch (ImmutableByteSequence.ByteSequenceTrimException e) {
-            throw new PiInterpreterException(format("Port number %d too big, %s", portNumber, e.getMessage()));
-        }
-    }
-
-    /**
-     * Returns an action instance with no runtime parameters.
-     */
-    private PiAction actionWithName(String name) {
-        return PiAction.builder().withId(PiActionId.of(name)).build();
-    }
-
-    @Override
-    public Optional<PiHeaderFieldId> mapCriterionType(Criterion.Type type) {
-        initTargetSpecificAttributes();
-        return Optional.ofNullable(criterionMap.get(type));
-    }
-
-    @Override
-    public Optional<Criterion.Type> mapPiHeaderFieldId(PiHeaderFieldId headerFieldId) {
-        initTargetSpecificAttributes();
-        return Optional.ofNullable(criterionMap.inverse().get(headerFieldId));
-    }
-
-    @Override
-    public Optional<PiTableId> mapFlowRuleTableId(int flowRuleTableId) {
-        return Optional.ofNullable(TABLE_MAP.get(flowRuleTableId));
-    }
-
-    @Override
-    public Optional<Integer> mapPiTableId(PiTableId piTableId) {
-        return Optional.ofNullable(TABLE_MAP.inverse().get(piTableId));
-    }
-}
diff --git a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/DefaultP4PortStatisticsDiscovery.java b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/DefaultP4PortStatisticsDiscovery.java
deleted file mode 100644
index b2b3760..0000000
--- a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/DefaultP4PortStatisticsDiscovery.java
+++ /dev/null
@@ -1,133 +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.drivers.p4runtime;
-
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import org.onosproject.net.device.DefaultPortStatistics;
-import org.onosproject.net.device.PortStatistics;
-import org.onosproject.net.device.PortStatisticsDiscovery;
-import org.onosproject.net.pi.runtime.PiCounterCellData;
-import org.onosproject.net.pi.runtime.PiCounterCellId;
-import org.onosproject.net.pi.runtime.PiCounterId;
-import org.onosproject.net.pi.runtime.PiIndirectCounterCellId;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.stream.Collectors;
-
-import static org.onosproject.net.pi.runtime.PiCounterType.INDIRECT;
-
-/**
- * Implementation of a PortStatisticsBehaviour that can be used for any P4 program based on default.p4 (i.e. those
- * under onos/tools/test/p4src).
- */
-public class DefaultP4PortStatisticsDiscovery extends AbstractP4RuntimeHandlerBehaviour
-        implements PortStatisticsDiscovery {
-
-    // FIXME: hard-coding the scope here will break support for the P4_14 version of the program.
-    // With P4_14, counter names in the generated P4Info won't have any scope.
-    // A solution could be that of dynamically building counter IDs based on the P4Info (as in DefaultP4Interpreter).
-    private static final String DEFAULT_SCOPE = "port_counters_control";
-    private static final PiCounterId DEFAULT_INGRESS_COUNTER_ID = PiCounterId.of(DEFAULT_SCOPE,
-                                                                                 "ingress_port_counter",
-                                                                                 INDIRECT);
-    private static final PiCounterId DEFAULT_EGRESS_COUNTER_ID = PiCounterId.of(DEFAULT_SCOPE,
-                                                                                "egress_port_counter",
-                                                                                INDIRECT);
-
-    /**
-     * Returns the ID of the ingress port counter.
-     *
-     * @return counter ID
-     */
-    public PiCounterId ingressCounterId() {
-        return DEFAULT_INGRESS_COUNTER_ID;
-    }
-
-    /**
-     * Returns the ID of the egress port counter.
-     *
-     * @return counter ID
-     */
-    public PiCounterId egressCounterId() {
-        return DEFAULT_EGRESS_COUNTER_ID;
-    }
-
-    @Override
-    public Collection<PortStatistics> discoverPortStatistics() {
-
-        if (!super.setupBehaviour()) {
-            return Collections.emptyList();
-        }
-
-        Map<Long, DefaultPortStatistics.Builder> portStatBuilders = Maps.newHashMap();
-
-        deviceService.getPorts(deviceId)
-                .forEach(p -> portStatBuilders.put(p.number().toLong(),
-                                                   DefaultPortStatistics.builder()
-                                                           .setPort(p.number())
-                                                           .setDeviceId(deviceId)));
-
-        Set<PiCounterCellId> counterCellIds = Sets.newHashSet();
-        portStatBuilders.keySet().forEach(p -> {
-            // Counter cell/index = port number.
-            counterCellIds.add(PiIndirectCounterCellId.of(ingressCounterId(), p));
-            counterCellIds.add(PiIndirectCounterCellId.of(egressCounterId(), p));
-        });
-
-        Collection<PiCounterCellData> counterEntryResponse;
-        try {
-            counterEntryResponse = client.readCounterCells(counterCellIds, pipeconf).get();
-        } catch (InterruptedException | ExecutionException e) {
-            log.warn("Exception while reading port counters from {}: {}", deviceId, e.toString());
-            log.debug("", e);
-            return Collections.emptyList();
-        }
-
-        counterEntryResponse.forEach(counterData -> {
-            if (counterData.cellId().type() != INDIRECT) {
-                log.warn("Invalid counter data type {}, skipping", counterData.cellId().type());
-                return;
-            }
-            PiIndirectCounterCellId indCellId = (PiIndirectCounterCellId) counterData.cellId();
-            if (!portStatBuilders.containsKey(indCellId.index())) {
-                log.warn("Unrecognized counter index {}, skipping", counterData);
-                return;
-            }
-            DefaultPortStatistics.Builder statsBuilder = portStatBuilders.get(indCellId.index());
-            if (counterData.cellId().counterId().equals(ingressCounterId())) {
-                statsBuilder.setPacketsReceived(counterData.packets());
-                statsBuilder.setBytesReceived(counterData.bytes());
-            } else if (counterData.cellId().counterId().equals(egressCounterId())) {
-                statsBuilder.setPacketsSent(counterData.packets());
-                statsBuilder.setBytesSent(counterData.bytes());
-            } else {
-                log.warn("Unrecognized counter ID {}, skipping", counterData);
-            }
-        });
-
-        return portStatBuilders
-                .values()
-                .stream()
-                .map(DefaultPortStatistics.Builder::build)
-                .collect(Collectors.toList());
-    }
-}
