ONOS-7058 Refactored default pipeconfs in new pipelines directory

- Minimal refactoring of P4 programs
- Removed symlinks to BMv2 JSON/P4Info
- Bumped p4c commit (which fixes known parser bug)
- Renamed "default" pipeconf to "basic" (ONOS-6818)

Change-Id: I319f8b142ab22dba9b15457e28cd62d17f78a423
diff --git a/apps/pi-demo/ecmp/BUCK b/apps/pi-demo/ecmp/BUCK
index f268028..a584b5d 100644
--- a/apps/pi-demo/ecmp/BUCK
+++ b/apps/pi-demo/ecmp/BUCK
@@ -1,10 +1,8 @@
 COMPILE_DEPS = [
     '//lib:CORE_DEPS',
     '//lib:minimal-json',
-    '//incubator/bmv2/model:onos-incubator-bmv2-model',
     '//apps/pi-demo/common:onos-apps-pi-demo-common',
-    '//drivers/default:onos-drivers-default',
-    '//drivers/p4runtime:onos-drivers-p4runtime',
+    '//pipelines/basic:onos-pipelines-basic',
 ]
 
 osgi_jar (
@@ -12,25 +10,18 @@
 )
 
 BUNDLES = [
-    '//apps/pi-demo/ecmp:onos-apps-pi-demo-ecmp',
     '//apps/pi-demo/common:onos-apps-pi-demo-common',
-    '//drivers/default:onos-drivers-default',
-    '//incubator/bmv2/model:onos-incubator-bmv2-model',
+    '//apps/pi-demo/ecmp:onos-apps-pi-demo-ecmp',
 ]
 
 onos_app (
-    app_name = 'org.onosproject.pi-ecmp-fabric',
+    app_name = 'org.onosproject.pi-ecmp',
     title = 'PI Demo ECMP Fabric',
     category = 'Traffic Steering',
     url = 'http://onosproject.org',
     description = 'Provides ECMP support for a 2-stage clos fabric topology of PI-enabled devices',
     included_bundles = BUNDLES,
     required_apps = [
-        # FIXME: there should be no dependendcy on a driver here.
-        # However, we depend on the DefaultP4Interpreter that currently lives in the p4runtime
-        # driver. Bringing up the whole app avoids to specify all transitive runtime dependencies
-        # as bundles. DefaultP4Interpreter and other pipeconf-related stuff should leave in a
-        # separate location, outside the drivers.
-        'org.onosproject.drivers.p4runtime'
+        'org.onosproject.pipelines.basic'
     ]
 )
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
index fccbab5..5a40df4 100644
--- 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
@@ -34,15 +34,13 @@
 import org.onosproject.net.flow.criteria.Criterion;
 import org.onosproject.net.flow.criteria.PiCriterion;
 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.PiHeaderFieldId;
 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.Collection;
 import java.util.Iterator;
@@ -52,23 +50,29 @@
 import java.util.stream.Collectors;
 
 import static java.lang.String.format;
+import static java.util.Collections.singleton;
 import static java.util.stream.Collectors.toSet;
 import static org.onlab.packet.EthType.EtherType.IPV4;
-import static org.onosproject.pi.demo.app.ecmp.EcmpInterpreter.*;
+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.HDR_SELECTOR_ID;
+import static org.onosproject.pipelines.basic.BasicConstants.TBL_TABLE0_ID;
+import static org.onosproject.pipelines.basic.EcmpConstants.TBL_ECMP_TABLE_ID;
 
 
 /**
- * Implementation of an upgradable fabric app for the ECMP configuration.
+ * Implementation of an upgradable fabric app for the ECMP pipeconf.
  */
 @Component(immediate = true)
 public class EcmpFabricApp extends AbstractUpgradableFabricApp {
 
-    private static final String APP_NAME = "org.onosproject.pi-ecmp-fabric";
+    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();
 
     public EcmpFabricApp() {
-        super(APP_NAME, EcmpPipeconfFactory.getAll());
+        super(APP_NAME, singleton(PipeconfLoader.ECMP_PIPECONF));
     }
 
     @Override
@@ -120,7 +124,7 @@
 
         // From srHost to dstHosts.
         for (Host dstHost : dstHosts) {
-            FlowRule rule = flowRuleBuilder(leaf, EcmpInterpreter.TABLE0)
+            FlowRule rule = flowRuleBuilder(leaf, TBL_TABLE0_ID)
                     .withSelector(
                             DefaultTrafficSelector.builder()
                                     .matchInPort(hostPort)
@@ -135,7 +139,7 @@
 
         // From fabric ports to this leaf host.
         for (PortNumber port : fabricPorts) {
-            FlowRule rule = flowRuleBuilder(leaf, EcmpInterpreter.TABLE0)
+            FlowRule rule = flowRuleBuilder(leaf, TBL_TABLE0_ID)
                     .withSelector(
                             DefaultTrafficSelector.builder()
                                     .matchInPort(port)
@@ -183,7 +187,7 @@
                 treatment = DefaultTrafficTreatment.builder().piTableAction(result.getLeft()).build();
             }
 
-            FlowRule rule = flowRuleBuilder(deviceId, EcmpInterpreter.TABLE0)
+            FlowRule rule = flowRuleBuilder(deviceId, TBL_TABLE0_ID)
                     .withSelector(
                             DefaultTrafficSelector.builder()
                                     .matchEthType(IPV4.ethType().toShort())
@@ -212,7 +216,7 @@
         Iterator<PortNumber> portIterator = fabricPorts.iterator();
         List<FlowRule> rules = Lists.newArrayList();
         for (short i = 0; i < HASHED_LINKS; i++) {
-            FlowRule rule = flowRuleBuilder(deviceId, EcmpInterpreter.ECMP_GROUP_TABLE)
+            FlowRule rule = flowRuleBuilder(deviceId, TBL_ECMP_TABLE_ID)
                     .withSelector(
                             buildEcmpTrafficSelector(groupId, i))
                     .withTreatment(
@@ -231,16 +235,16 @@
     private PiTableAction buildEcmpPiTableAction(int groupId) {
 
         return PiAction.builder()
-                .withId(PiActionId.of(ECMP_GROUP_ACTION_NAME))
-                .withParameter(new PiActionParam(PiActionParamId.of(GROUP_ID),
+                .withId(ACT_SET_NEXT_HOP_ID)
+                .withParameter(new PiActionParam(ACT_PRM_NEXT_HOP_ID,
                                                  ImmutableByteSequence.copyFrom(groupId)))
                 .build();
     }
 
     private TrafficSelector buildEcmpTrafficSelector(int groupId, int selector) {
         Criterion ecmpCriterion = PiCriterion.builder()
-                .matchExact(PiHeaderFieldId.of(ECMP_METADATA_HEADER_NAME, GROUP_ID), groupId)
-                .matchExact(PiHeaderFieldId.of(ECMP_METADATA_HEADER_NAME, SELECTOR), selector)
+                .matchExact(HDR_NEXT_HOP_ID, groupId)
+                .matchExact(HDR_SELECTOR_ID, selector)
                 .build();
 
         return DefaultTrafficSelector.builder()
@@ -248,7 +252,7 @@
                 .build();
     }
 
-    public int groupIdOf(DeviceId deviceId, Set<PortNumber> ports) {
+    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.
diff --git a/apps/pi-demo/ecmp/src/main/java/org/onosproject/pi/demo/app/ecmp/EcmpInterpreter.java b/apps/pi-demo/ecmp/src/main/java/org/onosproject/pi/demo/app/ecmp/EcmpInterpreter.java
deleted file mode 100644
index d662231..0000000
--- a/apps/pi-demo/ecmp/src/main/java/org/onosproject/pi/demo/app/ecmp/EcmpInterpreter.java
+++ /dev/null
@@ -1,50 +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.ImmutableBiMap;
-import org.onosproject.drivers.p4runtime.DefaultP4Interpreter;
-import org.onosproject.net.pi.runtime.PiTableId;
-
-import java.util.Optional;
-
-/**
- * Implementation of a PiPipeline interpreter for the ecmp.json configuration.
- */
-public class EcmpInterpreter extends DefaultP4Interpreter {
-
-    protected static final String ECMP_METADATA_HEADER_NAME = "ecmp_metadata";
-    protected static final String ECMP_GROUP_ACTION_NAME = "ecmp_group";
-    protected static final String GROUP_ID = "group_id";
-    protected static final String SELECTOR = "selector";
-    protected static final String ECMP_GROUP_TABLE = "ecmp_group_table";
-
-    private static final ImmutableBiMap<Integer, PiTableId> TABLE_MAP = new ImmutableBiMap.Builder<Integer, PiTableId>()
-            .put(0, PiTableId.of(TABLE0))
-            .put(1, PiTableId.of(ECMP_GROUP_TABLE))
-            .build();
-
-    @Override
-    public Optional<Integer> mapPiTableId(PiTableId piTableId) {
-        return Optional.ofNullable(TABLE_MAP.inverse().get(piTableId));
-    }
-
-    @Override
-    public Optional<PiTableId> mapFlowRuleTableId(int flowRuleTableId) {
-        return Optional.ofNullable(TABLE_MAP.get(flowRuleTableId));
-    }
-}
\ No newline at end of file
diff --git a/apps/pi-demo/ecmp/src/main/java/org/onosproject/pi/demo/app/ecmp/EcmpPipeconfFactory.java b/apps/pi-demo/ecmp/src/main/java/org/onosproject/pi/demo/app/ecmp/EcmpPipeconfFactory.java
deleted file mode 100644
index a6800a8..0000000
--- a/apps/pi-demo/ecmp/src/main/java/org/onosproject/pi/demo/app/ecmp/EcmpPipeconfFactory.java
+++ /dev/null
@@ -1,63 +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 org.onosproject.bmv2.model.Bmv2PipelineModelParser;
-import org.onosproject.driver.pipeline.DefaultSingleTablePipeline;
-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 java.util.Collection;
-import java.util.Collections;
-
-import static org.onosproject.net.pi.model.PiPipeconf.ExtensionType.BMV2_JSON;
-import static org.onosproject.net.pi.model.PiPipeconf.ExtensionType.P4_INFO_TEXT;
-
-final class EcmpPipeconfFactory {
-
-    private static final String BMV2_PIPECONF_ID = "pi-demo-ecmp";
-    private static final URL BMV2_P4INFO_URL = EcmpFabricApp.class.getResource("/ecmp.p4info");
-    private static final URL BMV2_JSON_URL = EcmpFabricApp.class.getResource("/ecmp.json");
-
-    private static final PiPipeconf BMV2_PIPECONF = buildBmv2Pipeconf();
-
-    private EcmpPipeconfFactory() {
-        // Hides constructor.
-    }
-
-    static Collection<PiPipeconf> getAll() {
-        return Collections.singleton(BMV2_PIPECONF);
-    }
-
-    private static PiPipeconf buildBmv2Pipeconf() {
-        return DefaultPiPipeconf.builder()
-                .withId(new PiPipeconfId(BMV2_PIPECONF_ID))
-                .withPipelineModel(Bmv2PipelineModelParser.parse(BMV2_JSON_URL))
-                .addBehaviour(PiPipelineInterpreter.class, EcmpInterpreter.class)
-                .addBehaviour(Pipeliner.class, DefaultSingleTablePipeline.class)
-                .addBehaviour(PortStatisticsDiscovery.class, DefaultP4PortStatisticsDiscovery.class)
-                .addExtension(P4_INFO_TEXT, BMV2_P4INFO_URL)
-                .addExtension(BMV2_JSON, BMV2_JSON_URL)
-                .build();
-    }
-}
diff --git a/apps/pi-demo/ecmp/src/main/resources/ecmp.json b/apps/pi-demo/ecmp/src/main/resources/ecmp.json
deleted file mode 120000
index 78ebbe0..0000000
--- a/apps/pi-demo/ecmp/src/main/resources/ecmp.json
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../tools/test/p4src/p4-16/p4c-out/ecmp.json
\ No newline at end of file
diff --git a/apps/pi-demo/ecmp/src/main/resources/ecmp.p4info b/apps/pi-demo/ecmp/src/main/resources/ecmp.p4info
deleted file mode 120000
index b4f5e4f..0000000
--- a/apps/pi-demo/ecmp/src/main/resources/ecmp.p4info
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../tools/test/p4src/p4-16/p4c-out/ecmp.p4info
\ No newline at end of file