Support creation of vendor-specific versions of the fabric pipeconf

We provide a new service to facilitate registration of vendor-specific
versions of the Fabric pipeconf (e.g., for Tofino) from third-party
apps. This service is designed such that third-party apps do not need to
depend on internal classes at compile time, such as the behaviour
implementations.

To make this possible, the package structure has been refactored to
separate APIs from implementation.

Change-Id: I487cb806541eb9e6877ebf398a94f057613df8cc
diff --git a/pipelines/fabric/BUILD b/pipelines/fabric/BUILD
index 11dad56..41ecec5 100644
--- a/pipelines/fabric/BUILD
+++ b/pipelines/fabric/BUILD
@@ -1,22 +1,9 @@
-COMPILE_DEPS = CORE_DEPS + KRYO + [
-    "//protocols/p4runtime/model:onos-protocols-p4runtime-model",
-    "//protocols/p4runtime/api:onos-protocols-p4runtime-api",
-    "//providers/general/device:onos-providers-general-device",
-    "//pipelines/basic:onos-pipelines-basic",
-    "//core/store/serializers:onos-core-serializers",
-    "//apps/inbandtelemetry/api:onos-apps-inbandtelemetry-api",
-]
-
 BUNDLES = [
-    "//pipelines/fabric:onos-pipelines-fabric",
+    "//pipelines/fabric/api:onos-pipelines-fabric-api",
+    "//pipelines/fabric/impl:onos-pipelines-fabric-impl",
     "//apps/inbandtelemetry/api:onos-apps-inbandtelemetry-api",
 ]
 
-osgi_jar_with_tests(
-    test_deps = TEST_ADAPTERS,
-    deps = COMPILE_DEPS,
-)
-
 onos_app(
     app_name = "org.onosproject.pipelines.fabric",
     category = "Pipeline",
diff --git a/pipelines/fabric/api/BUILD b/pipelines/fabric/api/BUILD
new file mode 100644
index 0000000..bd39481
--- /dev/null
+++ b/pipelines/fabric/api/BUILD
@@ -0,0 +1,8 @@
+TEST_DEPS = TEST + [
+    "//core/api:onos-api-tests",
+]
+
+osgi_jar_with_tests(
+    test_deps = TEST_DEPS,
+    deps = CORE_DEPS,
+)
diff --git a/pipelines/fabric/api/src/main/java/org/onosproject/pipelines/fabric/FabricPipeconfService.java b/pipelines/fabric/api/src/main/java/org/onosproject/pipelines/fabric/FabricPipeconfService.java
new file mode 100644
index 0000000..071ec43
--- /dev/null
+++ b/pipelines/fabric/api/src/main/java/org/onosproject/pipelines/fabric/FabricPipeconfService.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2019-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.pipelines.fabric;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.net.pi.model.DefaultPiPipeconf;
+import org.onosproject.net.pi.model.PiPipeconf;
+
+import java.net.URL;
+
+/**
+ * A service to build fabric.p4-related pipeconfs.
+ * <p>
+ * This service is provided such that third-party apps can build vendor-specific
+ * versions of the fabric.p4 pipeconf, without needing to depend on fabric.p4
+ * behaviour implementations at compile time.
+ */
+@Beta
+public interface FabricPipeconfService {
+
+    /**
+     * Builds a pipeconf for fabric.p4.
+     * <p>
+     * This method expects as input a pipeconf builder already populated with
+     * the pipeconf ID (i.e., {@link DefaultPiPipeconf.Builder#withId}) and
+     * target-specific extensions (i.e., {@link DefaultPiPipeconf.Builder#addExtension}.
+     * The implementation takes care of adding all the necessary behavior
+     * implementations specific to fabric.p4, depending on the profile name,
+     * e.g., adding INT-related behaviors for fabric-int profile).
+     * <p>
+     * Finally, the implementation takes care of parsing the given P4Info file
+     * (in text format) as pipeconf pipeline model, and setting the pipeconf CPU
+     * port to the one contained in the given file URL.
+     *
+     * @param builder    pipeconf builder already populated with ID and
+     *                   target-specific extensions
+     * @param profile    fabric.p4 profile name
+     * @param p4InfoUrl  URL to P4Info file in text format
+     * @param cpuPortUrl URL to txt file containing the CPU port
+     * @return pipeconf instance
+     */
+    PiPipeconf buildFabricPipeconf(DefaultPiPipeconf.Builder builder, String profile,
+                                   URL p4InfoUrl, URL cpuPortUrl);
+}
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/package-info.java b/pipelines/fabric/api/src/main/java/org/onosproject/pipelines/fabric/package-info.java
similarity index 85%
copy from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/package-info.java
copy to pipelines/fabric/api/src/main/java/org/onosproject/pipelines/fabric/package-info.java
index 2221ac3..6c3b0e8 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/package-info.java
+++ b/pipelines/fabric/api/src/main/java/org/onosproject/pipelines/fabric/package-info.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017-present Open Networking Foundation
+ * Copyright 2019-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.
@@ -15,6 +15,6 @@
  */
 
 /**
- * Trellis-compatible reference underlay pipeconf.
+ * API definitions for the fabric pipeconf.
  */
 package org.onosproject.pipelines.fabric;
diff --git a/pipelines/fabric/impl/BUILD b/pipelines/fabric/impl/BUILD
new file mode 100644
index 0000000..e4b427e
--- /dev/null
+++ b/pipelines/fabric/impl/BUILD
@@ -0,0 +1,14 @@
+COMPILE_DEPS = CORE_DEPS + KRYO + [
+    "//pipelines/fabric/api:onos-pipelines-fabric-api",
+    "//protocols/p4runtime/model:onos-protocols-p4runtime-model",
+    "//protocols/p4runtime/api:onos-protocols-p4runtime-api",
+    "//providers/general/device:onos-providers-general-device",
+    "//pipelines/basic:onos-pipelines-basic",
+    "//core/store/serializers:onos-core-serializers",
+    "//apps/inbandtelemetry/api:onos-apps-inbandtelemetry-api",
+]
+
+osgi_jar_with_tests(
+    test_deps = TEST_ADAPTERS,
+    deps = COMPILE_DEPS,
+)
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/FabricPipeconfLoader.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/FabricPipeconfLoader.java
new file mode 100644
index 0000000..1b6c2ce
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/FabricPipeconfLoader.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2019-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.pipelines.fabric.impl;
+
+import org.onosproject.core.CoreService;
+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.service.PiPipeconfService;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricPortStatisticsDiscovery;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.wiring.BundleWiring;
+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.slf4j.Logger;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import static java.lang.String.format;
+import static org.onosproject.pipelines.fabric.impl.FabricPipeconfManager.build;
+import static org.osgi.framework.wiring.BundleWiring.LISTRESOURCES_RECURSE;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Component responsible of building and registering fabric pipeconfs at app
+ * activation.
+ * <p>
+ * This implementation looks at the content of the resource path for p4c output,
+ * automatically building different pipeconfs for different profiles, target and
+ * platforms.
+ */
+@Component(immediate = true)
+public final class FabricPipeconfLoader {
+
+    public static final String PIPELINE_APP_NAME = "org.onosproject.pipelines.fabric";
+
+    private static Logger log = getLogger(FabricPipeconfLoader.class);
+
+    private static final String SEP = File.separator;
+    private static final String SPECTRUM = "spectrum";
+    private static final String BMV2 = "bmv2";
+    private static final String DEFAULT_PLATFORM = "default";
+    private static final String BMV2_JSON = "bmv2.json";
+    private static final String P4INFO_TXT = "p4info.txt";
+    private static final String CPU_PORT_TXT = "cpu_port.txt";
+    private static final String SPECTRUM_BIN = "spectrum.bin";
+
+    private static final String BASE_PIPECONF_ID = "org.onosproject.pipelines";
+    private static final String P4C_OUT_PATH = "/p4c-out";
+    // p4c-out/<profile>/<target>/<platform>
+    private static final String P4C_RES_BASE_PATH = P4C_OUT_PATH + "/%s/%s/%s/";
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    private PiPipeconfService piPipeconfService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    private CoreService coreService;
+
+    private Collection<PiPipeconf> pipeconfs;
+
+
+    @Activate
+    public void activate() {
+        coreService.registerApplication(PIPELINE_APP_NAME);
+        // Registers all pipeconf at component activation.
+        pipeconfs = buildAllPipeconfs();
+        pipeconfs.forEach(piPipeconfService::register);
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        pipeconfs.stream()
+                .map(PiPipeconf::id)
+                .forEach(piPipeconfService::unregister);
+        pipeconfs = null;
+        log.info("Stopped");
+    }
+
+    private Collection<PiPipeconf> buildAllPipeconfs() {
+        return FrameworkUtil
+                .getBundle(this.getClass())
+                .adapt(BundleWiring.class)
+                // List all resource files in /p4c-out
+                .listResources(P4C_OUT_PATH, "*", LISTRESOURCES_RECURSE)
+                .stream()
+                // Filter only directories
+                .filter(name -> name.endsWith(SEP))
+                // Derive profile, target, and platform and build pipeconf.
+                .map(this::buildPipeconfFromPath)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+    }
+
+    private PiPipeconf buildPipeconfFromPath(String path) {
+        String[] pieces = path.split(SEP);
+        // We expect a path of 4 elements, e.g.
+        // p4c-out/<profile>/<target>/<platform>
+        if (pieces.length != 4) {
+            return null;
+        }
+        String profile = pieces[1];
+        String target = pieces[2];
+        String platform = pieces[3];
+        final PiPipeconf pipeconf;
+        try {
+            switch (target) {
+                case BMV2:
+                    pipeconf = bmv2Pipeconf(profile, platform);
+                    break;
+                case SPECTRUM:
+                    pipeconf = spectrumPipeconf(profile, platform);
+                    break;
+                default:
+                    log.warn("Unknown target '{}', skipping pipeconf build...",
+                             target);
+                    return null;
+            }
+        } catch (FileNotFoundException e) {
+            log.warn("Unable to build pipeconf at {} because file is missing: {}",
+                     path, e.getMessage());
+            return null;
+        }
+
+        return pipeconf;
+    }
+
+    private PiPipeconf bmv2Pipeconf(String profile, String platform)
+            throws FileNotFoundException {
+        final URL bmv2JsonUrl = this.getClass().getResource(format(
+                P4C_RES_BASE_PATH + BMV2_JSON, profile, BMV2, platform));
+        final URL p4InfoUrl = this.getClass().getResource(format(
+                P4C_RES_BASE_PATH + P4INFO_TXT, profile, BMV2, platform));
+        final URL cpuPortUrl = this.getClass().getResource(format(
+                P4C_RES_BASE_PATH + CPU_PORT_TXT, profile, BMV2, platform));
+
+        checkFileExists(bmv2JsonUrl, BMV2_JSON);
+        checkFileExists(p4InfoUrl, P4INFO_TXT);
+        checkFileExists(cpuPortUrl, CPU_PORT_TXT);
+
+        final DefaultPiPipeconf.Builder builder = DefaultPiPipeconf.builder()
+                .withId(makePipeconfId(platform, profile))
+                .addBehaviour(PortStatisticsDiscovery.class,
+                              FabricPortStatisticsDiscovery.class)
+                .addExtension(PiPipeconf.ExtensionType.BMV2_JSON, bmv2JsonUrl);
+
+        return build(builder, profile, p4InfoUrl, cpuPortUrl);
+    }
+
+    // FIXME: this method should be removed. Instead, there should be a
+    //  third-party app using the FabricPipeconfService to register a
+    //  Mellanox-specific version of the fabric pipeconfs.
+    private PiPipeconf spectrumPipeconf(String profile, String platform)
+            throws FileNotFoundException {
+
+        final URL spectrumBinUrl = this.getClass().getResource(format(
+                P4C_RES_BASE_PATH + SPECTRUM_BIN, profile, SPECTRUM, platform));
+        final URL p4InfoUrl = this.getClass().getResource(format(
+                P4C_RES_BASE_PATH + P4INFO_TXT, profile, SPECTRUM, platform));
+        final URL cpuPortUrl = this.getClass().getResource(format(
+                P4C_RES_BASE_PATH + CPU_PORT_TXT, profile, SPECTRUM, platform));
+
+        checkFileExists(spectrumBinUrl, SPECTRUM_BIN);
+        checkFileExists(p4InfoUrl, P4INFO_TXT);
+        checkFileExists(cpuPortUrl, CPU_PORT_TXT);
+
+        final DefaultPiPipeconf.Builder builder = DefaultPiPipeconf.builder()
+                .withId(makePipeconfId(platform, profile))
+                .addExtension(PiPipeconf.ExtensionType.SPECTRUM_BIN, spectrumBinUrl);
+
+        return build(builder, profile, p4InfoUrl, cpuPortUrl);
+    }
+
+    private void checkFileExists(URL url, String name)
+            throws FileNotFoundException {
+        if (url == null) {
+            throw new FileNotFoundException(name);
+        }
+    }
+
+    private PiPipeconfId makePipeconfId(String platform, String profile) {
+        final String id = platform.equals(DEFAULT_PLATFORM)
+                // Omit platform if default, e.g. with BMv2 pipeconf
+                ? format("%s.%s", BASE_PIPECONF_ID, profile)
+                : format("%s.%s.%s", BASE_PIPECONF_ID, profile, platform);
+        return new PiPipeconfId(id);
+    }
+}
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/FabricPipeconfManager.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/FabricPipeconfManager.java
new file mode 100644
index 0000000..76122d9
--- /dev/null
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/FabricPipeconfManager.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2019-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.pipelines.fabric.impl;
+
+import org.onosproject.inbandtelemetry.api.IntProgrammable;
+import org.onosproject.net.behaviour.Pipeliner;
+import org.onosproject.net.pi.model.DefaultPiPipeconf;
+import org.onosproject.net.pi.model.PiPipeconf;
+import org.onosproject.net.pi.model.PiPipelineInterpreter;
+import org.onosproject.net.pi.model.PiPipelineModel;
+import org.onosproject.p4runtime.model.P4InfoParser;
+import org.onosproject.p4runtime.model.P4InfoParserException;
+import org.onosproject.pipelines.fabric.FabricPipeconfService;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricIntProgrammable;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricInterpreter;
+import org.onosproject.pipelines.fabric.impl.behaviour.pipeliner.FabricPipeliner;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.slf4j.Logger;
+
+import java.net.URL;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implementation of the FabricPipeconfService.
+ */
+@Component(immediate = true, service = FabricPipeconfService.class)
+public final class FabricPipeconfManager implements FabricPipeconfService {
+
+    private static final String INT_PROFILE_SUFFIX = "-int";
+    private static final String FULL_PROFILE_SUFFIX = "-full";
+
+    private static Logger log = getLogger(FabricPipeconfLoader.class);
+
+    @Activate
+    public void activate() {
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        log.info("Stopped");
+    }
+
+    @Override
+    public PiPipeconf buildFabricPipeconf(
+            DefaultPiPipeconf.Builder builder, String profile, URL p4InfoUrl, URL cpuPortUrl) {
+        return build(builder, profile, p4InfoUrl, cpuPortUrl);
+    }
+
+    static PiPipeconf build(
+            DefaultPiPipeconf.Builder pipeconfBuilder,
+            String profileName, URL p4InfoUrl, URL cpuPortUrl) {
+        checkNotNull(pipeconfBuilder,
+                     "pipeconfBuilder cannot be null");
+        checkArgument(profileName != null && !profileName.isEmpty(),
+                      "profileName cannot be null or empty");
+        checkNotNull(p4InfoUrl,
+                     "p4InfoUrl cannot be null (check if file exists)");
+        checkNotNull(cpuPortUrl,
+                     "cpuPortUrl cannot be null (check if file exists)");
+
+        pipeconfBuilder
+                .withPipelineModel(parseP4Info(p4InfoUrl))
+                .addBehaviour(PiPipelineInterpreter.class, FabricInterpreter.class)
+                .addBehaviour(Pipeliner.class, FabricPipeliner.class)
+                .addExtension(PiPipeconf.ExtensionType.P4_INFO_TEXT, p4InfoUrl)
+                .addExtension(PiPipeconf.ExtensionType.CPU_PORT_TXT, cpuPortUrl);
+
+        // Add IntProgrammable behaviour for INT-enabled profiles.
+        if (profileName.endsWith(INT_PROFILE_SUFFIX) ||
+                profileName.endsWith(FULL_PROFILE_SUFFIX)) {
+            pipeconfBuilder.addBehaviour(IntProgrammable.class, FabricIntProgrammable.class);
+        }
+
+        return pipeconfBuilder.build();
+    }
+
+    private static PiPipelineModel parseP4Info(URL p4InfoUrl) {
+        try {
+            return P4InfoParser.parse(p4InfoUrl);
+        } catch (P4InfoParserException e) {
+            // FIXME: propagate exception that can be handled by whoever is
+            //  trying to build pipeconfs.
+            throw new IllegalStateException(e);
+        }
+    }
+}
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/AbstractFabricHandlerBehavior.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/AbstractFabricHandlerBehavior.java
similarity index 97%
rename from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/AbstractFabricHandlerBehavior.java
rename to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/AbstractFabricHandlerBehavior.java
index db4da90..fe07576 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/AbstractFabricHandlerBehavior.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/AbstractFabricHandlerBehavior.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric;
+package org.onosproject.pipelines.fabric.impl.behaviour;
 
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.driver.AbstractHandlerBehaviour;
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricCapabilities.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricCapabilities.java
similarity index 96%
rename from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricCapabilities.java
rename to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricCapabilities.java
index b0ce208..6def74f 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricCapabilities.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricCapabilities.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric;
+package org.onosproject.pipelines.fabric.impl.behaviour;
 
 import org.onosproject.net.pi.model.PiPipeconf;
 import org.slf4j.Logger;
@@ -38,7 +38,7 @@
 
     private final PiPipeconf pipeconf;
 
-    FabricCapabilities(PiPipeconf pipeconf) {
+    public FabricCapabilities(PiPipeconf pipeconf) {
         this.pipeconf = checkNotNull(pipeconf);
     }
 
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricConstants.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricConstants.java
similarity index 99%
rename from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricConstants.java
rename to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricConstants.java
index 484ef5a..c10f3f5 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricConstants.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricConstants.java
@@ -14,15 +14,15 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric;
+package org.onosproject.pipelines.fabric.impl.behaviour;
 
 import org.onosproject.net.pi.model.PiActionId;
 import org.onosproject.net.pi.model.PiActionParamId;
 import org.onosproject.net.pi.model.PiActionProfileId;
-import org.onosproject.net.pi.model.PiMeterId;
-import org.onosproject.net.pi.model.PiPacketMetadataId;
 import org.onosproject.net.pi.model.PiCounterId;
 import org.onosproject.net.pi.model.PiMatchFieldId;
+import org.onosproject.net.pi.model.PiMeterId;
+import org.onosproject.net.pi.model.PiPacketMetadataId;
 import org.onosproject.net.pi.model.PiTableId;
 /**
  * Constants for fabric pipeline.
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricIntProgrammable.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricIntProgrammable.java
similarity index 98%
rename from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricIntProgrammable.java
rename to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricIntProgrammable.java
index 1770576..4fc8286 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricIntProgrammable.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricIntProgrammable.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.pipelines.fabric;
+package org.onosproject.pipelines.fabric.impl.behaviour;
 
 import com.google.common.collect.Sets;
 import org.onosproject.core.ApplicationId;
@@ -42,6 +42,7 @@
 import org.onosproject.net.pi.model.PiTableId;
 import org.onosproject.net.pi.runtime.PiAction;
 import org.onosproject.net.pi.runtime.PiActionParam;
+import org.onosproject.pipelines.fabric.impl.FabricPipeconfLoader;
 import org.osgi.service.component.annotations.Reference;
 import org.osgi.service.component.annotations.ReferenceCardinality;
 
@@ -108,7 +109,7 @@
         flowRuleService = handler().get(FlowRuleService.class);
         coreService = handler().get(CoreService.class);
         cfgService = handler().get(NetworkConfigService.class);
-        appId = coreService.getAppId(PipeconfLoader.PIPELINE_APP_NAME);
+        appId = coreService.getAppId(FabricPipeconfLoader.PIPELINE_APP_NAME);
         if (appId == null) {
             log.warn("Application ID is null. Cannot initialize behaviour.");
             return false;
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricInterpreter.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricInterpreter.java
similarity index 99%
rename from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricInterpreter.java
rename to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricInterpreter.java
index 8567a3a..816c0dd 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricInterpreter.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricInterpreter.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric;
+package org.onosproject.pipelines.fabric.impl.behaviour;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricPortStatisticsDiscovery.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricPortStatisticsDiscovery.java
similarity index 95%
rename from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricPortStatisticsDiscovery.java
rename to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricPortStatisticsDiscovery.java
index ab44040..b461ad3 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricPortStatisticsDiscovery.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricPortStatisticsDiscovery.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric;
+package org.onosproject.pipelines.fabric.impl.behaviour;
 
 
 import org.onosproject.net.pi.model.PiCounterId;
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricTreatmentInterpreter.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricTreatmentInterpreter.java
similarity index 97%
rename from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricTreatmentInterpreter.java
rename to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricTreatmentInterpreter.java
index b501f33..78ef9a7 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricTreatmentInterpreter.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricTreatmentInterpreter.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric;
+package org.onosproject.pipelines.fabric.impl.behaviour;
 
 import com.google.common.collect.ImmutableMap;
 import org.onosproject.net.PortNumber;
@@ -43,9 +43,9 @@
 import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.MPLS_PUSH;
 import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.VLAN_ID;
 import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.VLAN_POP;
-import static org.onosproject.pipelines.fabric.FabricUtils.instruction;
-import static org.onosproject.pipelines.fabric.FabricUtils.l2Instruction;
-import static org.onosproject.pipelines.fabric.FabricUtils.l2Instructions;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.instruction;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.l2Instruction;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.l2Instructions;
 
 /**
  * Treatment translation logic.
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricUtils.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricUtils.java
similarity index 98%
rename from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricUtils.java
rename to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricUtils.java
index ae000b5..655f88d 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricUtils.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric;
+package org.onosproject.pipelines.fabric.impl.behaviour;
 
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.flow.TrafficSelector;
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/package-info.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/package-info.java
similarity index 85%
copy from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/package-info.java
copy to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/package-info.java
index 2221ac3..75586a1 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/package-info.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/package-info.java
@@ -15,6 +15,6 @@
  */
 
 /**
- * Trellis-compatible reference underlay pipeconf.
+ * Fabric pipeconf behaviour implementations.
  */
-package org.onosproject.pipelines.fabric;
+package org.onosproject.pipelines.fabric.impl.behaviour;
\ No newline at end of file
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/AbstractObjectiveTranslator.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/AbstractObjectiveTranslator.java
similarity index 94%
rename from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/AbstractObjectiveTranslator.java
rename to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/AbstractObjectiveTranslator.java
index c2ca0ff..5b9671f 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/AbstractObjectiveTranslator.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/AbstractObjectiveTranslator.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric.pipeliner;
+package org.onosproject.pipelines.fabric.impl.behaviour.pipeliner;
 
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.flow.DefaultFlowRule;
@@ -28,8 +28,8 @@
 import org.onosproject.net.pi.model.PiPipelineInterpreter;
 import org.onosproject.net.pi.model.PiTableId;
 import org.onosproject.net.pi.runtime.PiAction;
-import org.onosproject.pipelines.fabric.FabricCapabilities;
-import org.onosproject.pipelines.fabric.FabricInterpreter;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricCapabilities;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricInterpreter;
 import org.slf4j.Logger;
 
 import static com.google.common.base.Preconditions.checkNotNull;
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/ForwardingFunctionTypeCommons.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/Commons.java
similarity index 90%
rename from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/ForwardingFunctionTypeCommons.java
rename to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/Commons.java
index 0c898c5..b288eb4 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/ForwardingFunctionTypeCommons.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/Commons.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric.pipeliner;
+package org.onosproject.pipelines.fabric.impl.behaviour.pipeliner;
 
 import org.onlab.packet.EthType;
 import org.onlab.packet.MacAddress;
@@ -24,7 +24,7 @@
 /**
  * Constants common to ForwardingFunctionType operations.
  */
-final class ForwardingFunctionTypeCommons {
+final class Commons {
 
     static final Criterion MATCH_ETH_TYPE_IPV4 = Criteria.matchEthType(
       EthType.EtherType.IPV4.ethType());
@@ -37,7 +37,7 @@
     static final Criterion MATCH_MPLS_BOS_TRUE = Criteria.matchMplsBos(true);
     static final Criterion MATCH_MPLS_BOS_FALSE = Criteria.matchMplsBos(false);
 
-    private ForwardingFunctionTypeCommons() {
+    private Commons() {
         // hides constructor.
     }
 }
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/FabricPipeliner.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricPipeliner.java
similarity index 96%
rename from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/FabricPipeliner.java
rename to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricPipeliner.java
index 20cafde..eac2116 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/FabricPipeliner.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricPipeliner.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric.pipeliner;
+package org.onosproject.pipelines.fabric.impl.behaviour.pipeliner;
 
 import com.google.common.collect.ImmutableList;
 import org.onlab.util.KryoNamespace;
@@ -37,8 +37,8 @@
 import org.onosproject.net.flowobjective.ObjectiveError;
 import org.onosproject.net.group.GroupDescription;
 import org.onosproject.net.group.GroupService;
-import org.onosproject.pipelines.fabric.AbstractFabricHandlerBehavior;
-import org.onosproject.pipelines.fabric.FabricCapabilities;
+import org.onosproject.pipelines.fabric.impl.behaviour.AbstractFabricHandlerBehavior;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricCapabilities;
 import org.onosproject.store.serializers.KryoNamespaces;
 import org.slf4j.Logger;
 
@@ -50,7 +50,7 @@
 import java.util.stream.Collectors;
 
 import static java.lang.String.format;
-import static org.onosproject.pipelines.fabric.FabricUtils.outputPort;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.outputPort;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/FabricPipelinerException.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricPipelinerException.java
similarity index 95%
rename from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/FabricPipelinerException.java
rename to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricPipelinerException.java
index 7f6d71e..6755e75 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/FabricPipelinerException.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricPipelinerException.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric.pipeliner;
+package org.onosproject.pipelines.fabric.impl.behaviour.pipeliner;
 
 import org.onosproject.net.flowobjective.ObjectiveError;
 
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/FilteringObjectiveTranslator.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FilteringObjectiveTranslator.java
similarity index 97%
rename from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/FilteringObjectiveTranslator.java
rename to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FilteringObjectiveTranslator.java
index e86f270..d682d8c 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/FilteringObjectiveTranslator.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FilteringObjectiveTranslator.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric.pipeliner;
+package org.onosproject.pipelines.fabric.impl.behaviour.pipeliner;
 
 import com.google.common.collect.Lists;
 import org.onlab.packet.EthType;
@@ -37,14 +37,14 @@
 import org.onosproject.net.flowobjective.ObjectiveError;
 import org.onosproject.net.pi.runtime.PiAction;
 import org.onosproject.net.pi.runtime.PiActionParam;
-import org.onosproject.pipelines.fabric.FabricCapabilities;
-import org.onosproject.pipelines.fabric.FabricConstants;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricCapabilities;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricConstants;
 
 import java.util.Collection;
 import java.util.List;
 
 import static java.lang.String.format;
-import static org.onosproject.pipelines.fabric.FabricUtils.criterion;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.criterion;
 
 /**
  * ObjectiveTranslator implementation for FilteringObjective.
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/ForwardingFunctionType.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ForwardingFunctionType.java
similarity index 92%
rename from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/ForwardingFunctionType.java
rename to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ForwardingFunctionType.java
index 4e13a74..1e33fa5 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/ForwardingFunctionType.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ForwardingFunctionType.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric.pipeliner;
+package org.onosproject.pipelines.fabric.impl.behaviour.pipeliner;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
@@ -39,12 +39,12 @@
 import static org.onosproject.net.flow.criteria.Criterion.Type.MPLS_BOS;
 import static org.onosproject.net.flow.criteria.Criterion.Type.MPLS_LABEL;
 import static org.onosproject.net.flow.criteria.Criterion.Type.VLAN_VID;
-import static org.onosproject.pipelines.fabric.pipeliner.ForwardingFunctionTypeCommons.MATCH_ETH_DST_NONE;
-import static org.onosproject.pipelines.fabric.pipeliner.ForwardingFunctionTypeCommons.MATCH_ETH_TYPE_IPV4;
-import static org.onosproject.pipelines.fabric.pipeliner.ForwardingFunctionTypeCommons.MATCH_ETH_TYPE_IPV6;
-import static org.onosproject.pipelines.fabric.pipeliner.ForwardingFunctionTypeCommons.MATCH_ETH_TYPE_MPLS;
-import static org.onosproject.pipelines.fabric.pipeliner.ForwardingFunctionTypeCommons.MATCH_MPLS_BOS_FALSE;
-import static org.onosproject.pipelines.fabric.pipeliner.ForwardingFunctionTypeCommons.MATCH_MPLS_BOS_TRUE;
+import static org.onosproject.pipelines.fabric.impl.behaviour.pipeliner.Commons.MATCH_ETH_DST_NONE;
+import static org.onosproject.pipelines.fabric.impl.behaviour.pipeliner.Commons.MATCH_ETH_TYPE_IPV4;
+import static org.onosproject.pipelines.fabric.impl.behaviour.pipeliner.Commons.MATCH_ETH_TYPE_IPV6;
+import static org.onosproject.pipelines.fabric.impl.behaviour.pipeliner.Commons.MATCH_ETH_TYPE_MPLS;
+import static org.onosproject.pipelines.fabric.impl.behaviour.pipeliner.Commons.MATCH_MPLS_BOS_FALSE;
+import static org.onosproject.pipelines.fabric.impl.behaviour.pipeliner.Commons.MATCH_MPLS_BOS_TRUE;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/ForwardingObjectiveTranslator.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ForwardingObjectiveTranslator.java
similarity index 97%
rename from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/ForwardingObjectiveTranslator.java
rename to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ForwardingObjectiveTranslator.java
index 066af7d..1d7d5c0 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/ForwardingObjectiveTranslator.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ForwardingObjectiveTranslator.java
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric.pipeliner;
+package org.onosproject.pipelines.fabric.impl.behaviour.pipeliner;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import org.onlab.packet.IpPrefix;
@@ -40,17 +40,17 @@
 import org.onosproject.net.flowobjective.Objective;
 import org.onosproject.net.flowobjective.ObjectiveError;
 import org.onosproject.net.group.DefaultGroupDescription;
+import org.onosproject.net.group.DefaultGroupKey;
 import org.onosproject.net.group.GroupBucket;
 import org.onosproject.net.group.GroupBuckets;
-import org.onosproject.net.group.DefaultGroupKey;
 import org.onosproject.net.group.GroupDescription;
 import org.onosproject.net.group.GroupKey;
 import org.onosproject.net.pi.model.PiActionId;
 import org.onosproject.net.pi.model.PiTableId;
 import org.onosproject.net.pi.runtime.PiAction;
 import org.onosproject.net.pi.runtime.PiActionParam;
-import org.onosproject.pipelines.fabric.FabricCapabilities;
-import org.onosproject.pipelines.fabric.FabricConstants;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricCapabilities;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricConstants;
 
 import java.util.List;
 import java.util.Map;
@@ -58,9 +58,9 @@
 import java.util.stream.Collectors;
 
 import static java.lang.String.format;
-import static org.onosproject.pipelines.fabric.FabricUtils.criterionNotNull;
-import static org.onosproject.pipelines.fabric.FabricUtils.outputPort;
 import static org.onosproject.net.group.DefaultGroupBucket.createCloneGroupBucket;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.criterionNotNull;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.outputPort;
 
 
 /**
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/NextObjectiveTranslator.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/NextObjectiveTranslator.java
similarity index 96%
rename from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/NextObjectiveTranslator.java
rename to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/NextObjectiveTranslator.java
index d06d383..4e3304d 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/NextObjectiveTranslator.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/NextObjectiveTranslator.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric.pipeliner;
+package org.onosproject.pipelines.fabric.impl.behaviour.pipeliner;
 
 import com.google.common.collect.Lists;
 import org.onlab.packet.VlanId;
@@ -46,9 +46,9 @@
 import org.onosproject.net.pi.runtime.PiActionParam;
 import org.onosproject.net.pi.runtime.PiActionProfileGroupId;
 import org.onosproject.net.pi.runtime.PiGroupKey;
-import org.onosproject.pipelines.fabric.FabricCapabilities;
-import org.onosproject.pipelines.fabric.FabricConstants;
-import org.onosproject.pipelines.fabric.FabricUtils;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricCapabilities;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricConstants;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils;
 
 import java.util.Collection;
 import java.util.List;
@@ -59,10 +59,10 @@
 import static java.lang.String.format;
 import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.VLAN_ID;
 import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.VLAN_POP;
-import static org.onosproject.pipelines.fabric.FabricUtils.criterion;
-import static org.onosproject.pipelines.fabric.FabricUtils.l2Instruction;
-import static org.onosproject.pipelines.fabric.FabricUtils.l2Instructions;
-import static org.onosproject.pipelines.fabric.FabricUtils.outputPort;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.criterion;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.l2Instruction;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.l2Instructions;
+import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.outputPort;
 
 /**
  * ObjectiveTranslator implementation for NextObjective.
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/ObjectiveTranslation.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ObjectiveTranslation.java
similarity index 98%
rename from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/ObjectiveTranslation.java
rename to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ObjectiveTranslation.java
index 33ffeac..31ff617 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/ObjectiveTranslation.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ObjectiveTranslation.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric.pipeliner;
+package org.onosproject.pipelines.fabric.impl.behaviour.pipeliner;
 
 import com.google.common.base.MoreObjects;
 import com.google.common.collect.ImmutableMap;
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/package-info.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/package-info.java
similarity index 90%
rename from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/package-info.java
rename to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/package-info.java
index de2d2ee..905c942 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/pipeliner/package-info.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/package-info.java
@@ -17,4 +17,4 @@
 /**
  * Pipeliner implementation classes for fabric.p4.
  */
-package org.onosproject.pipelines.fabric.pipeliner;
+package org.onosproject.pipelines.fabric.impl.behaviour.pipeliner;
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/package-info.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/package-info.java
similarity index 86%
copy from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/package-info.java
copy to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/package-info.java
index 2221ac3..257d1a3 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/package-info.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/package-info.java
@@ -15,6 +15,6 @@
  */
 
 /**
- * Trellis-compatible reference underlay pipeconf.
+ * Implementation classes for the fabric pipeconf.
  */
-package org.onosproject.pipelines.fabric;
+package org.onosproject.pipelines.fabric.impl;
\ No newline at end of file
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/package-info.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/service/package-info.java
similarity index 86%
rename from pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/package-info.java
rename to pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/service/package-info.java
index 2221ac3..c57b047 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/package-info.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/service/package-info.java
@@ -15,6 +15,6 @@
  */
 
 /**
- * Trellis-compatible reference underlay pipeconf.
+ * Fabric pipeconf service implementations.
  */
-package org.onosproject.pipelines.fabric;
+package org.onosproject.pipelines.fabric.impl.service;
diff --git a/pipelines/fabric/src/main/resources/.gitignore b/pipelines/fabric/impl/src/main/resources/.gitignore
similarity index 100%
rename from pipelines/fabric/src/main/resources/.gitignore
rename to pipelines/fabric/impl/src/main/resources/.gitignore
diff --git a/pipelines/fabric/src/main/resources/Makefile b/pipelines/fabric/impl/src/main/resources/Makefile
similarity index 80%
rename from pipelines/fabric/src/main/resources/Makefile
rename to pipelines/fabric/impl/src/main/resources/Makefile
index fc096ab..784cc6d 100644
--- a/pipelines/fabric/src/main/resources/Makefile
+++ b/pipelines/fabric/impl/src/main/resources/Makefile
@@ -23,8 +23,8 @@
 constants:
 	docker run -v $(ONOS_ROOT):/onos -w /onos/tools/dev/bin \
 		--entrypoint ./onos-gen-p4-constants opennetworking/p4mn:stable \
-		-o /onos/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricConstants.java \
-		fabric /onos/pipelines/fabric/src/main/resources/p4c-out/fabric-full/bmv2/default/p4info.txt
+		-o /onos/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricConstants.java \
+		fabric /onos/pipelines/fabric/impl/src/main/resources/p4c-out/fabric-full/bmv2/default/p4info.txt
 
 clean:
 	rm -rf p4c-out/*/bmv2
diff --git a/pipelines/fabric/src/main/resources/bmv2-compile.sh b/pipelines/fabric/impl/src/main/resources/bmv2-compile.sh
similarity index 100%
rename from pipelines/fabric/src/main/resources/bmv2-compile.sh
rename to pipelines/fabric/impl/src/main/resources/bmv2-compile.sh
diff --git a/pipelines/fabric/src/main/resources/fabric.p4 b/pipelines/fabric/impl/src/main/resources/fabric.p4
similarity index 100%
rename from pipelines/fabric/src/main/resources/fabric.p4
rename to pipelines/fabric/impl/src/main/resources/fabric.p4
diff --git a/pipelines/fabric/src/main/resources/include/bng.p4 b/pipelines/fabric/impl/src/main/resources/include/bng.p4
similarity index 100%
rename from pipelines/fabric/src/main/resources/include/bng.p4
rename to pipelines/fabric/impl/src/main/resources/include/bng.p4
diff --git a/pipelines/fabric/src/main/resources/include/checksum.p4 b/pipelines/fabric/impl/src/main/resources/include/checksum.p4
similarity index 100%
rename from pipelines/fabric/src/main/resources/include/checksum.p4
rename to pipelines/fabric/impl/src/main/resources/include/checksum.p4
diff --git a/pipelines/fabric/src/main/resources/include/control/acl.p4 b/pipelines/fabric/impl/src/main/resources/include/control/acl.p4
similarity index 100%
rename from pipelines/fabric/src/main/resources/include/control/acl.p4
rename to pipelines/fabric/impl/src/main/resources/include/control/acl.p4
diff --git a/pipelines/fabric/src/main/resources/include/control/filtering.p4 b/pipelines/fabric/impl/src/main/resources/include/control/filtering.p4
similarity index 100%
rename from pipelines/fabric/src/main/resources/include/control/filtering.p4
rename to pipelines/fabric/impl/src/main/resources/include/control/filtering.p4
diff --git a/pipelines/fabric/src/main/resources/include/control/forwarding.p4 b/pipelines/fabric/impl/src/main/resources/include/control/forwarding.p4
similarity index 100%
rename from pipelines/fabric/src/main/resources/include/control/forwarding.p4
rename to pipelines/fabric/impl/src/main/resources/include/control/forwarding.p4
diff --git a/pipelines/fabric/src/main/resources/include/control/next.p4 b/pipelines/fabric/impl/src/main/resources/include/control/next.p4
similarity index 100%
rename from pipelines/fabric/src/main/resources/include/control/next.p4
rename to pipelines/fabric/impl/src/main/resources/include/control/next.p4
diff --git a/pipelines/fabric/src/main/resources/include/control/packetio.p4 b/pipelines/fabric/impl/src/main/resources/include/control/packetio.p4
similarity index 100%
rename from pipelines/fabric/src/main/resources/include/control/packetio.p4
rename to pipelines/fabric/impl/src/main/resources/include/control/packetio.p4
diff --git a/pipelines/fabric/src/main/resources/include/control/port_counter.p4 b/pipelines/fabric/impl/src/main/resources/include/control/port_counter.p4
similarity index 100%
rename from pipelines/fabric/src/main/resources/include/control/port_counter.p4
rename to pipelines/fabric/impl/src/main/resources/include/control/port_counter.p4
diff --git a/pipelines/fabric/src/main/resources/include/define.p4 b/pipelines/fabric/impl/src/main/resources/include/define.p4
similarity index 100%
rename from pipelines/fabric/src/main/resources/include/define.p4
rename to pipelines/fabric/impl/src/main/resources/include/define.p4
diff --git a/pipelines/fabric/src/main/resources/include/header.p4 b/pipelines/fabric/impl/src/main/resources/include/header.p4
similarity index 100%
rename from pipelines/fabric/src/main/resources/include/header.p4
rename to pipelines/fabric/impl/src/main/resources/include/header.p4
diff --git a/pipelines/fabric/src/main/resources/include/int/int_header.p4 b/pipelines/fabric/impl/src/main/resources/include/int/int_header.p4
similarity index 100%
rename from pipelines/fabric/src/main/resources/include/int/int_header.p4
rename to pipelines/fabric/impl/src/main/resources/include/int/int_header.p4
diff --git a/pipelines/fabric/src/main/resources/include/int/int_main.p4 b/pipelines/fabric/impl/src/main/resources/include/int/int_main.p4
similarity index 100%
rename from pipelines/fabric/src/main/resources/include/int/int_main.p4
rename to pipelines/fabric/impl/src/main/resources/include/int/int_main.p4
diff --git a/pipelines/fabric/src/main/resources/include/int/int_report.p4 b/pipelines/fabric/impl/src/main/resources/include/int/int_report.p4
similarity index 100%
rename from pipelines/fabric/src/main/resources/include/int/int_report.p4
rename to pipelines/fabric/impl/src/main/resources/include/int/int_report.p4
diff --git a/pipelines/fabric/src/main/resources/include/int/int_sink.p4 b/pipelines/fabric/impl/src/main/resources/include/int/int_sink.p4
similarity index 100%
rename from pipelines/fabric/src/main/resources/include/int/int_sink.p4
rename to pipelines/fabric/impl/src/main/resources/include/int/int_sink.p4
diff --git a/pipelines/fabric/src/main/resources/include/int/int_source.p4 b/pipelines/fabric/impl/src/main/resources/include/int/int_source.p4
similarity index 100%
rename from pipelines/fabric/src/main/resources/include/int/int_source.p4
rename to pipelines/fabric/impl/src/main/resources/include/int/int_source.p4
diff --git a/pipelines/fabric/src/main/resources/include/int/int_transit.p4 b/pipelines/fabric/impl/src/main/resources/include/int/int_transit.p4
similarity index 100%
rename from pipelines/fabric/src/main/resources/include/int/int_transit.p4
rename to pipelines/fabric/impl/src/main/resources/include/int/int_transit.p4
diff --git a/pipelines/fabric/src/main/resources/include/parser.p4 b/pipelines/fabric/impl/src/main/resources/include/parser.p4
similarity index 100%
rename from pipelines/fabric/src/main/resources/include/parser.p4
rename to pipelines/fabric/impl/src/main/resources/include/parser.p4
diff --git a/pipelines/fabric/src/main/resources/include/size.p4 b/pipelines/fabric/impl/src/main/resources/include/size.p4
similarity index 100%
rename from pipelines/fabric/src/main/resources/include/size.p4
rename to pipelines/fabric/impl/src/main/resources/include/size.p4
diff --git a/pipelines/fabric/src/main/resources/include/spgw.p4 b/pipelines/fabric/impl/src/main/resources/include/spgw.p4
similarity index 100%
rename from pipelines/fabric/src/main/resources/include/spgw.p4
rename to pipelines/fabric/impl/src/main/resources/include/spgw.p4
diff --git a/pipelines/fabric/src/main/resources/p4c-out/fabric-bng/bmv2/default/bmv2.json b/pipelines/fabric/impl/src/main/resources/p4c-out/fabric-bng/bmv2/default/bmv2.json
similarity index 100%
rename from pipelines/fabric/src/main/resources/p4c-out/fabric-bng/bmv2/default/bmv2.json
rename to pipelines/fabric/impl/src/main/resources/p4c-out/fabric-bng/bmv2/default/bmv2.json
diff --git a/pipelines/fabric/src/main/resources/p4c-out/fabric-bng/bmv2/default/cpu_port.txt b/pipelines/fabric/impl/src/main/resources/p4c-out/fabric-bng/bmv2/default/cpu_port.txt
similarity index 100%
rename from pipelines/fabric/src/main/resources/p4c-out/fabric-bng/bmv2/default/cpu_port.txt
rename to pipelines/fabric/impl/src/main/resources/p4c-out/fabric-bng/bmv2/default/cpu_port.txt
diff --git a/pipelines/fabric/src/main/resources/p4c-out/fabric-bng/bmv2/default/p4info.txt b/pipelines/fabric/impl/src/main/resources/p4c-out/fabric-bng/bmv2/default/p4info.txt
similarity index 100%
rename from pipelines/fabric/src/main/resources/p4c-out/fabric-bng/bmv2/default/p4info.txt
rename to pipelines/fabric/impl/src/main/resources/p4c-out/fabric-bng/bmv2/default/p4info.txt
diff --git a/pipelines/fabric/src/main/resources/p4c-out/fabric-full/bmv2/default/bmv2.json b/pipelines/fabric/impl/src/main/resources/p4c-out/fabric-full/bmv2/default/bmv2.json
similarity index 100%
rename from pipelines/fabric/src/main/resources/p4c-out/fabric-full/bmv2/default/bmv2.json
rename to pipelines/fabric/impl/src/main/resources/p4c-out/fabric-full/bmv2/default/bmv2.json
diff --git a/pipelines/fabric/src/main/resources/p4c-out/fabric-full/bmv2/default/cpu_port.txt b/pipelines/fabric/impl/src/main/resources/p4c-out/fabric-full/bmv2/default/cpu_port.txt
similarity index 100%
rename from pipelines/fabric/src/main/resources/p4c-out/fabric-full/bmv2/default/cpu_port.txt
rename to pipelines/fabric/impl/src/main/resources/p4c-out/fabric-full/bmv2/default/cpu_port.txt
diff --git a/pipelines/fabric/src/main/resources/p4c-out/fabric-full/bmv2/default/p4info.txt b/pipelines/fabric/impl/src/main/resources/p4c-out/fabric-full/bmv2/default/p4info.txt
similarity index 100%
rename from pipelines/fabric/src/main/resources/p4c-out/fabric-full/bmv2/default/p4info.txt
rename to pipelines/fabric/impl/src/main/resources/p4c-out/fabric-full/bmv2/default/p4info.txt
diff --git a/pipelines/fabric/src/main/resources/p4c-out/fabric-int/bmv2/default/bmv2.json b/pipelines/fabric/impl/src/main/resources/p4c-out/fabric-int/bmv2/default/bmv2.json
similarity index 100%
rename from pipelines/fabric/src/main/resources/p4c-out/fabric-int/bmv2/default/bmv2.json
rename to pipelines/fabric/impl/src/main/resources/p4c-out/fabric-int/bmv2/default/bmv2.json
diff --git a/pipelines/fabric/src/main/resources/p4c-out/fabric-int/bmv2/default/cpu_port.txt b/pipelines/fabric/impl/src/main/resources/p4c-out/fabric-int/bmv2/default/cpu_port.txt
similarity index 100%
rename from pipelines/fabric/src/main/resources/p4c-out/fabric-int/bmv2/default/cpu_port.txt
rename to pipelines/fabric/impl/src/main/resources/p4c-out/fabric-int/bmv2/default/cpu_port.txt
diff --git a/pipelines/fabric/src/main/resources/p4c-out/fabric-int/bmv2/default/p4info.txt b/pipelines/fabric/impl/src/main/resources/p4c-out/fabric-int/bmv2/default/p4info.txt
similarity index 100%
rename from pipelines/fabric/src/main/resources/p4c-out/fabric-int/bmv2/default/p4info.txt
rename to pipelines/fabric/impl/src/main/resources/p4c-out/fabric-int/bmv2/default/p4info.txt
diff --git a/pipelines/fabric/src/main/resources/p4c-out/fabric-mlnx/spectrum/default/README.md b/pipelines/fabric/impl/src/main/resources/p4c-out/fabric-mlnx/spectrum/default/README.md
similarity index 100%
rename from pipelines/fabric/src/main/resources/p4c-out/fabric-mlnx/spectrum/default/README.md
rename to pipelines/fabric/impl/src/main/resources/p4c-out/fabric-mlnx/spectrum/default/README.md
diff --git a/pipelines/fabric/src/main/resources/p4c-out/fabric-spgw-int/bmv2/default/bmv2.json b/pipelines/fabric/impl/src/main/resources/p4c-out/fabric-spgw-int/bmv2/default/bmv2.json
similarity index 100%
rename from pipelines/fabric/src/main/resources/p4c-out/fabric-spgw-int/bmv2/default/bmv2.json
rename to pipelines/fabric/impl/src/main/resources/p4c-out/fabric-spgw-int/bmv2/default/bmv2.json
diff --git a/pipelines/fabric/src/main/resources/p4c-out/fabric-spgw-int/bmv2/default/cpu_port.txt b/pipelines/fabric/impl/src/main/resources/p4c-out/fabric-spgw-int/bmv2/default/cpu_port.txt
similarity index 100%
rename from pipelines/fabric/src/main/resources/p4c-out/fabric-spgw-int/bmv2/default/cpu_port.txt
rename to pipelines/fabric/impl/src/main/resources/p4c-out/fabric-spgw-int/bmv2/default/cpu_port.txt
diff --git a/pipelines/fabric/src/main/resources/p4c-out/fabric-spgw-int/bmv2/default/p4info.txt b/pipelines/fabric/impl/src/main/resources/p4c-out/fabric-spgw-int/bmv2/default/p4info.txt
similarity index 100%
rename from pipelines/fabric/src/main/resources/p4c-out/fabric-spgw-int/bmv2/default/p4info.txt
rename to pipelines/fabric/impl/src/main/resources/p4c-out/fabric-spgw-int/bmv2/default/p4info.txt
diff --git a/pipelines/fabric/src/main/resources/p4c-out/fabric-spgw/bmv2/default/bmv2.json b/pipelines/fabric/impl/src/main/resources/p4c-out/fabric-spgw/bmv2/default/bmv2.json
similarity index 100%
rename from pipelines/fabric/src/main/resources/p4c-out/fabric-spgw/bmv2/default/bmv2.json
rename to pipelines/fabric/impl/src/main/resources/p4c-out/fabric-spgw/bmv2/default/bmv2.json
diff --git a/pipelines/fabric/src/main/resources/p4c-out/fabric-spgw/bmv2/default/cpu_port.txt b/pipelines/fabric/impl/src/main/resources/p4c-out/fabric-spgw/bmv2/default/cpu_port.txt
similarity index 100%
rename from pipelines/fabric/src/main/resources/p4c-out/fabric-spgw/bmv2/default/cpu_port.txt
rename to pipelines/fabric/impl/src/main/resources/p4c-out/fabric-spgw/bmv2/default/cpu_port.txt
diff --git a/pipelines/fabric/src/main/resources/p4c-out/fabric-spgw/bmv2/default/p4info.txt b/pipelines/fabric/impl/src/main/resources/p4c-out/fabric-spgw/bmv2/default/p4info.txt
similarity index 100%
rename from pipelines/fabric/src/main/resources/p4c-out/fabric-spgw/bmv2/default/p4info.txt
rename to pipelines/fabric/impl/src/main/resources/p4c-out/fabric-spgw/bmv2/default/p4info.txt
diff --git a/pipelines/fabric/src/main/resources/p4c-out/fabric/bmv2/default/bmv2.json b/pipelines/fabric/impl/src/main/resources/p4c-out/fabric/bmv2/default/bmv2.json
similarity index 100%
rename from pipelines/fabric/src/main/resources/p4c-out/fabric/bmv2/default/bmv2.json
rename to pipelines/fabric/impl/src/main/resources/p4c-out/fabric/bmv2/default/bmv2.json
diff --git a/pipelines/fabric/src/main/resources/p4c-out/fabric/bmv2/default/cpu_port.txt b/pipelines/fabric/impl/src/main/resources/p4c-out/fabric/bmv2/default/cpu_port.txt
similarity index 100%
rename from pipelines/fabric/src/main/resources/p4c-out/fabric/bmv2/default/cpu_port.txt
rename to pipelines/fabric/impl/src/main/resources/p4c-out/fabric/bmv2/default/cpu_port.txt
diff --git a/pipelines/fabric/src/main/resources/p4c-out/fabric/bmv2/default/p4info.txt b/pipelines/fabric/impl/src/main/resources/p4c-out/fabric/bmv2/default/p4info.txt
similarity index 100%
rename from pipelines/fabric/src/main/resources/p4c-out/fabric/bmv2/default/p4info.txt
rename to pipelines/fabric/impl/src/main/resources/p4c-out/fabric/bmv2/default/p4info.txt
diff --git a/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/FabricInterpreterTest.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricInterpreterTest.java
similarity index 97%
rename from pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/FabricInterpreterTest.java
rename to pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricInterpreterTest.java
index bf37694..a0e6194 100644
--- a/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/FabricInterpreterTest.java
+++ b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/FabricInterpreterTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric;
+package org.onosproject.pipelines.fabric.impl.behaviour;
 
 import com.google.common.collect.ImmutableList;
 import org.junit.Before;
@@ -69,7 +69,7 @@
                 .setVlanId(VLAN_100)
                 .build();
         PiAction mappedAction = interpreter.mapTreatment(treatment,
-                                                   FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
+                                                         FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
         PiActionParam param = new PiActionParam(FabricConstants.VLAN_ID,
                                                 ImmutableByteSequence.copyFrom(VLAN_100.toShort()));
         PiAction expectedAction = PiAction.builder()
diff --git a/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricFilteringPipelinerTest.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricFilteringPipelinerTest.java
similarity index 81%
rename from pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricFilteringPipelinerTest.java
rename to pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricFilteringPipelinerTest.java
index e15b117..f40741f 100644
--- a/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricFilteringPipelinerTest.java
+++ b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricFilteringPipelinerTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric.pipeliner;
+package org.onosproject.pipelines.fabric.impl.behaviour.pipeliner;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -37,7 +37,7 @@
 import org.onosproject.net.flowobjective.ObjectiveError;
 import org.onosproject.net.pi.runtime.PiAction;
 import org.onosproject.net.pi.runtime.PiActionParam;
-import org.onosproject.pipelines.fabric.FabricConstants;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricConstants;
 
 import static org.junit.Assert.assertEquals;
 
@@ -58,8 +58,8 @@
 
     /**
      * Creates one rule for ingress_port_vlan table and 3 rules for
-     * fwd_classifier table (IPv4, IPv6 and MPLS unicast) when
-     * the condition is VLAN + MAC.
+     * fwd_classifier table (IPv4, IPv6 and MPLS unicast) when the condition is
+     * VLAN + MAC.
      */
     @Test
     public void testRouterMacAndVlanFilter() throws FabricPipelinerException {
@@ -67,33 +67,36 @@
         ObjectiveTranslation actualTranslation = translator.translate(filteringObjective);
 
         // in port vlan flow rule
-        FlowRule inportFlowRuleExpected =
-                buildExpectedVlanInPortRule(PORT_1,
-                                            VlanId.NONE,
-                                            VlanId.NONE,
-                                            VLAN_100,
-                                            FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
+        FlowRule inportFlowRuleExpected = buildExpectedVlanInPortRule(
+                PORT_1,
+                VlanId.NONE,
+                VlanId.NONE,
+                VLAN_100,
+                FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
 
         // forwarding classifier ipv4
-        FlowRule classifierV4FlowRuleExpected = buildExpectedFwdClassifierRule(PORT_1,
-                                                          ROUTER_MAC,
-                                                          null,
-                                                          Ethernet.TYPE_IPV4,
-                                                          FilteringObjectiveTranslator.FWD_IPV4_ROUTING);
+        FlowRule classifierV4FlowRuleExpected = buildExpectedFwdClassifierRule(
+                PORT_1,
+                ROUTER_MAC,
+                null,
+                Ethernet.TYPE_IPV4,
+                FilteringObjectiveTranslator.FWD_IPV4_ROUTING);
 
         // forwarding classifier ipv6
-        FlowRule classifierV6FlowRuleExpected = buildExpectedFwdClassifierRule(PORT_1,
-                                                          ROUTER_MAC,
-                                                          null,
-                                                          Ethernet.TYPE_IPV6,
-                                                          FilteringObjectiveTranslator.FWD_IPV6_ROUTING);
+        FlowRule classifierV6FlowRuleExpected = buildExpectedFwdClassifierRule(
+                PORT_1,
+                ROUTER_MAC,
+                null,
+                Ethernet.TYPE_IPV6,
+                FilteringObjectiveTranslator.FWD_IPV6_ROUTING);
 
         // forwarding classifier mpls
-        FlowRule classifierMplsFlowRuleExpected = buildExpectedFwdClassifierRule(PORT_1,
-                                                          ROUTER_MAC,
-                                                          null,
-                                                          Ethernet.MPLS_UNICAST,
-                                                          FilteringObjectiveTranslator.FWD_MPLS);
+        FlowRule classifierMplsFlowRuleExpected = buildExpectedFwdClassifierRule(
+                PORT_1,
+                ROUTER_MAC,
+                null,
+                Ethernet.MPLS_UNICAST,
+                FilteringObjectiveTranslator.FWD_MPLS);
 
         ObjectiveTranslation expectedTranslation = ObjectiveTranslation.builder()
                 .addFlowRule(inportFlowRuleExpected)
@@ -129,19 +132,20 @@
         ObjectiveTranslation actualTranslation = translator.translate(filteringObjective);
 
         // in port vlan flow rule
-        FlowRule inportFlowRuleExpected =
-                buildExpectedVlanInPortRule(PORT_1,
-                                            VlanId.NONE,
-                                            VlanId.NONE,
-                                            VLAN_100,
-                                            FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
+        FlowRule inportFlowRuleExpected = buildExpectedVlanInPortRule(
+                PORT_1,
+                VlanId.NONE,
+                VlanId.NONE,
+                VLAN_100,
+                FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
 
         // forwarding classifier
-        FlowRule classifierFlowRuleExpected = buildExpectedFwdClassifierRule(PORT_1,
-                                                          MacAddress.IPV4_MULTICAST,
-                                                          MacAddress.IPV4_MULTICAST_MASK,
-                                                          Ethernet.TYPE_IPV4,
-                                                          FilteringObjectiveTranslator.FWD_IPV4_ROUTING);
+        FlowRule classifierFlowRuleExpected = buildExpectedFwdClassifierRule(
+                PORT_1,
+                MacAddress.IPV4_MULTICAST,
+                MacAddress.IPV4_MULTICAST_MASK,
+                Ethernet.TYPE_IPV4,
+                FilteringObjectiveTranslator.FWD_IPV4_ROUTING);
 
         ObjectiveTranslation expectedTranslation = ObjectiveTranslation.builder()
                 .addFlowRule(inportFlowRuleExpected)
@@ -175,18 +179,19 @@
         ObjectiveTranslation actualTranslation = translator.translate(filteringObjective);
 
         // in port vlan flow rule
-        FlowRule inportFlowRuleExpected =
-                buildExpectedVlanInPortRule(PORT_1,
-                                            VlanId.NONE,
-                                            VlanId.NONE,
-                                            VLAN_100,
-                                            FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
+        FlowRule inportFlowRuleExpected = buildExpectedVlanInPortRule(
+                PORT_1,
+                VlanId.NONE,
+                VlanId.NONE,
+                VLAN_100,
+                FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
 
-        FlowRule classifierFlowRuleExpected = buildExpectedFwdClassifierRule(PORT_1,
-                                                          MacAddress.IPV6_MULTICAST,
-                                                          MacAddress.IPV6_MULTICAST_MASK,
-                                                          Ethernet.TYPE_IPV6,
-                                                          FilteringObjectiveTranslator.FWD_IPV6_ROUTING);
+        FlowRule classifierFlowRuleExpected = buildExpectedFwdClassifierRule(
+                PORT_1,
+                MacAddress.IPV6_MULTICAST,
+                MacAddress.IPV6_MULTICAST_MASK,
+                Ethernet.TYPE_IPV6,
+                FilteringObjectiveTranslator.FWD_IPV6_ROUTING);
 
         ObjectiveTranslation expectedTranslation = ObjectiveTranslation.builder()
                 .addFlowRule(inportFlowRuleExpected)
@@ -197,9 +202,9 @@
     }
 
     /**
-     * Creates only one rule for ingress_port_vlan table if there is no condition
-     * of destination mac address.
-     * The packet will be handled by bridging table by default.
+     * Creates only one rule for ingress_port_vlan table if there is no
+     * condition of destination mac address. The packet will be handled by
+     * bridging table by default.
      */
     @Test
     public void testFwdBridging() throws Exception {
@@ -207,12 +212,12 @@
         ObjectiveTranslation actualTranslation = translator.translate(filteringObjective);
 
         // in port vlan flow rule
-        FlowRule flowRuleExpected =
-                buildExpectedVlanInPortRule(PORT_1,
-                                            VlanId.NONE,
-                                            VlanId.NONE,
-                                            VLAN_100,
-                                            FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
+        FlowRule flowRuleExpected = buildExpectedVlanInPortRule(
+                PORT_1,
+                VlanId.NONE,
+                VlanId.NONE,
+                VLAN_100,
+                FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
 
         // No rules in forwarding classifier, will do default action: set fwd type to bridging
 
@@ -243,8 +248,8 @@
                 .matchInPort(PORT_1)
                 .matchPi(buildPiCriterionVlan(null, null));
         PiAction piAction = PiAction.builder()
-                    .withId(FabricConstants.FABRIC_INGRESS_FILTERING_DENY)
-                    .build();
+                .withId(FabricConstants.FABRIC_INGRESS_FILTERING_DENY)
+                .build();
         FlowRule expectedFlowRule = DefaultFlowRule.builder()
                 .withPriority(PRIORITY)
                 .withSelector(selector.build())
@@ -265,10 +270,9 @@
     }
 
     /**
-     * Test double VLAN pop filtering objective
-     * Creates one rule for ingress_port_vlan table and 3 rules for
-     * fwd_classifier table (IPv4, IPv6 and MPLS unicast) when
-     * the condition is MAC + VLAN + INNER_VLAN.
+     * Test double VLAN pop filtering objective Creates one rule for
+     * ingress_port_vlan table and 3 rules for fwd_classifier table (IPv4, IPv6
+     * and MPLS unicast) when the condition is MAC + VLAN + INNER_VLAN.
      */
     @Test
     public void testPopVlan() throws FabricPipelinerException {
@@ -292,13 +296,13 @@
                 FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
         // Forwarding classifier rules (ipv6, ipv4, mpls)
         FlowRule classifierV4FlowRuleExpected = buildExpectedFwdClassifierRule(
-                PORT_1, ROUTER_MAC, null,  Ethernet.TYPE_IPV4,
+                PORT_1, ROUTER_MAC, null, Ethernet.TYPE_IPV4,
                 FilteringObjectiveTranslator.FWD_IPV4_ROUTING);
         FlowRule classifierV6FlowRuleExpected = buildExpectedFwdClassifierRule(
-                PORT_1, ROUTER_MAC, null,  Ethernet.TYPE_IPV6,
+                PORT_1, ROUTER_MAC, null, Ethernet.TYPE_IPV6,
                 FilteringObjectiveTranslator.FWD_IPV6_ROUTING);
         FlowRule classifierMplsFlowRuleExpected = buildExpectedFwdClassifierRule(
-                PORT_1, ROUTER_MAC, null,  Ethernet.MPLS_UNICAST,
+                PORT_1, ROUTER_MAC, null, Ethernet.MPLS_UNICAST,
                 FilteringObjectiveTranslator.FWD_MPLS);
         ObjectiveTranslation expectedTranslation = ObjectiveTranslation.builder()
                 .addFlowRule(inportFlowRuleExpected)
diff --git a/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricForwardingPipelineTest.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricForwardingPipelineTest.java
similarity index 98%
rename from pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricForwardingPipelineTest.java
rename to pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricForwardingPipelineTest.java
index 1294b5e..3d2942f 100644
--- a/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricForwardingPipelineTest.java
+++ b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricForwardingPipelineTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric.pipeliner;
+package org.onosproject.pipelines.fabric.impl.behaviour.pipeliner;
 
 import com.google.common.collect.ImmutableList;
 import org.junit.Before;
@@ -46,7 +46,7 @@
 import org.onosproject.net.pi.model.PiTableId;
 import org.onosproject.net.pi.runtime.PiAction;
 import org.onosproject.net.pi.runtime.PiActionParam;
-import org.onosproject.pipelines.fabric.FabricConstants;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricConstants;
 
 import java.util.List;
 
diff --git a/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricNextPipelinerTest.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricNextPipelinerTest.java
similarity index 99%
rename from pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricNextPipelinerTest.java
rename to pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricNextPipelinerTest.java
index 28f699c..a7d03c2 100644
--- a/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricNextPipelinerTest.java
+++ b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricNextPipelinerTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric.pipeliner;
+package org.onosproject.pipelines.fabric.impl.behaviour.pipeliner;
 
 import com.google.common.collect.ImmutableList;
 import org.junit.Before;
@@ -39,7 +39,7 @@
 import org.onosproject.net.pi.runtime.PiActionParam;
 import org.onosproject.net.pi.runtime.PiActionProfileGroupId;
 import org.onosproject.net.pi.runtime.PiGroupKey;
-import org.onosproject.pipelines.fabric.FabricConstants;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricConstants;
 
 import java.util.List;
 import java.util.stream.Collectors;
diff --git a/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricPipelinerTest.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricPipelinerTest.java
similarity index 95%
rename from pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricPipelinerTest.java
rename to pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricPipelinerTest.java
index 6c3551b..850e21f 100644
--- a/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricPipelinerTest.java
+++ b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/FabricPipelinerTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric.pipeliner;
+package org.onosproject.pipelines.fabric.impl.behaviour.pipeliner;
 
 import org.junit.Test;
 import org.onlab.packet.IpPrefix;
@@ -27,7 +27,7 @@
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.pipelines.fabric.FabricCapabilities;
+import org.onosproject.pipelines.fabric.impl.behaviour.FabricCapabilities;
 
 import static org.easymock.EasyMock.createNiceMock;
 import static org.easymock.EasyMock.expect;
diff --git a/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/ForwardingFunctionTypeTest.java b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ForwardingFunctionTypeTest.java
similarity index 98%
rename from pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/ForwardingFunctionTypeTest.java
rename to pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ForwardingFunctionTypeTest.java
index 2121b4f..8d98d862 100644
--- a/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/ForwardingFunctionTypeTest.java
+++ b/pipelines/fabric/impl/src/test/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/ForwardingFunctionTypeTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.pipelines.fabric.pipeliner;
+package org.onosproject.pipelines.fabric.impl.behaviour.pipeliner;
 
 import org.junit.Ignore;
 import org.junit.Test;
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/PipeconfLoader.java b/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/PipeconfLoader.java
deleted file mode 100644
index 5fca57b..0000000
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/PipeconfLoader.java
+++ /dev/null
@@ -1,260 +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.pipelines.fabric;
-
-import org.onosproject.core.CoreService;
-import org.onosproject.inbandtelemetry.api.IntProgrammable;
-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 org.onosproject.net.pi.model.PiPipelineModel;
-import org.onosproject.net.pi.service.PiPipeconfService;
-import org.onosproject.p4runtime.model.P4InfoParser;
-import org.onosproject.p4runtime.model.P4InfoParserException;
-import org.onosproject.pipelines.fabric.pipeliner.FabricPipeliner;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.wiring.BundleWiring;
-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.slf4j.Logger;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.net.URL;
-import java.util.Collection;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-import static java.lang.String.format;
-import static org.onosproject.net.pi.model.PiPipeconf.ExtensionType;
-import static org.osgi.framework.wiring.BundleWiring.LISTRESOURCES_RECURSE;
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- * Pipeconf loader for fabric.p4 which uses p4c output available in the resource
- * path to automatically build pipeconfs for different profiles, target and
- * platforms.
- */
-@Component(immediate = true)
-public class PipeconfLoader {
-
-    // TODO: allow adding properties to pipeconf instead of adding it to driver
-
-    private static Logger log = getLogger(PipeconfLoader.class);
-
-    static final String PIPELINE_APP_NAME = "org.onosproject.pipelines.fabric";
-
-    private static final String BASE_PIPECONF_ID = "org.onosproject.pipelines";
-    private static final String P4C_OUT_PATH = "/p4c-out";
-
-    // profile/target/platform
-    private static final String P4C_RES_BASE_PATH = P4C_OUT_PATH + "/%s/%s/%s/";
-
-    private static final String SEP = File.separator;
-    private static final String SPECTRUM = "spectrum";
-    private static final String TOFINO = "tofino";
-    private static final String BMV2 = "bmv2";
-    private static final String DEFAULT_PLATFORM = "default";
-    private static final String BMV2_JSON = "bmv2.json";
-    private static final String P4INFO_TXT = "p4info.txt";
-    private static final String CPU_PORT_TXT = "cpu_port.txt";
-    private static final String SPECTRUM_BIN = "spectrum.bin";
-    private static final String TOFINO_BIN = "pipe/tofino.bin";
-    private static final String TOFINO_CTX_JSON = "pipe/context.json";
-    private static final String INT_PROFILE_SUFFIX = "-int";
-    private static final String FULL_PROFILE_SUFFIX = "-full";
-
-    private static final Collection<PiPipeconf> PIPECONFS = buildAllPipeconf();
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    private PiPipeconfService piPipeconfService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    private CoreService coreService;
-
-    @Activate
-    public void activate() {
-        coreService.registerApplication(PIPELINE_APP_NAME);
-        // Registers all pipeconf at component activation.
-        PIPECONFS.forEach(piPipeconfService::register);
-    }
-
-    @Deactivate
-    public void deactivate() {
-        PIPECONFS.stream().map(PiPipeconf::id).forEach(piPipeconfService::unregister);
-    }
-
-    private static Collection<PiPipeconf> buildAllPipeconf() {
-        return FrameworkUtil
-                .getBundle(PipeconfLoader.class)
-                .adapt(BundleWiring.class)
-                // List all resource files in /p4c-out
-                .listResources(P4C_OUT_PATH, "*", LISTRESOURCES_RECURSE)
-                .stream()
-                // Filter only directories
-                .filter(name -> name.endsWith(SEP))
-                // Derive profile, target, and platform and build pipeconf.
-                .map(PipeconfLoader::buildPipeconfFromPath)
-                .filter(Objects::nonNull)
-                .collect(Collectors.toList());
-    }
-
-    private static PiPipeconf buildPipeconfFromPath(String path) {
-        String[] pieces = path.split(SEP);
-        // We expect a path of 4 elements, e.g.
-        // p4c-out/<profile>/<target>/<platform>
-        if (pieces.length != 4) {
-            return null;
-        }
-        String profile = pieces[1];
-        String target = pieces[2];
-        String platform = pieces[3];
-        final DefaultPiPipeconf.Builder pipeconfBuilder;
-        try {
-            switch (target) {
-                case BMV2:
-                    pipeconfBuilder = bmv2Pipeconf(profile, platform);
-                    break;
-                case SPECTRUM:
-                    pipeconfBuilder = spectrumPipeconf(profile, platform);
-                    break;
-                case TOFINO:
-                    pipeconfBuilder = tofinoPipeconf(profile, platform);
-                    break;
-                default:
-                    log.warn("Unknown target '{}', skipping pipeconf build...",
-                             target);
-                    return null;
-            }
-        } catch (FileNotFoundException e) {
-            log.warn("Unable to build pipeconf at {} because file is missing: {}",
-                     path, e.getMessage());
-            return null;
-        }
-        // Add IntProgrammable behaviour for INT-enabled profiles.
-        if (profile.endsWith(INT_PROFILE_SUFFIX) || profile.endsWith(FULL_PROFILE_SUFFIX)) {
-            pipeconfBuilder.addBehaviour(IntProgrammable.class, FabricIntProgrammable.class);
-        }
-        return pipeconfBuilder.build();
-    }
-
-    private static DefaultPiPipeconf.Builder bmv2Pipeconf(
-            String profile, String platform)
-            throws FileNotFoundException {
-        final URL bmv2JsonUrl = PipeconfLoader.class.getResource(format(
-                P4C_RES_BASE_PATH + BMV2_JSON, profile, BMV2, platform));
-        final URL p4InfoUrl = PipeconfLoader.class.getResource(format(
-                P4C_RES_BASE_PATH + P4INFO_TXT, profile, BMV2, platform));
-        final URL cpuPortUrl = PipeconfLoader.class.getResource(format(
-                P4C_RES_BASE_PATH + CPU_PORT_TXT, profile, BMV2, platform));
-        if (bmv2JsonUrl == null) {
-            throw new FileNotFoundException(BMV2_JSON);
-        }
-        if (p4InfoUrl == null) {
-            throw new FileNotFoundException(P4INFO_TXT);
-        }
-        if (cpuPortUrl == null) {
-            throw new FileNotFoundException(CPU_PORT_TXT);
-        }
-        return basePipeconfBuilder(profile, platform, p4InfoUrl, cpuPortUrl)
-                .addBehaviour(PortStatisticsDiscovery.class,
-                              FabricPortStatisticsDiscovery.class)
-                .addExtension(ExtensionType.BMV2_JSON, bmv2JsonUrl);
-    }
-
-    private static DefaultPiPipeconf.Builder  spectrumPipeconf(String profile, String platform)
-            throws FileNotFoundException {
-        final URL spectrumBinUrl = PipeconfLoader.class.getResource(format(
-                P4C_RES_BASE_PATH + SPECTRUM_BIN, profile, SPECTRUM, platform));
-        final URL p4InfoUrl = PipeconfLoader.class.getResource(format(
-                P4C_RES_BASE_PATH + P4INFO_TXT, profile, SPECTRUM, platform));
-        final URL cpuPortUrl = PipeconfLoader.class.getResource(format(
-                P4C_RES_BASE_PATH + CPU_PORT_TXT, profile, SPECTRUM, platform));
-        if (spectrumBinUrl == null) {
-            throw new FileNotFoundException(SPECTRUM_BIN);
-        }
-        if (p4InfoUrl == null) {
-            throw new FileNotFoundException(P4INFO_TXT);
-        }
-        if (cpuPortUrl == null) {
-            throw new FileNotFoundException(CPU_PORT_TXT);
-        }
-        return basePipeconfBuilder(
-                profile, platform, p4InfoUrl, cpuPortUrl)
-                .addExtension(ExtensionType.SPECTRUM_BIN, spectrumBinUrl);
-    }
-
-    private static DefaultPiPipeconf.Builder tofinoPipeconf(
-            String profile, String platform)
-            throws FileNotFoundException {
-        final URL tofinoBinUrl = PipeconfLoader.class.getResource(format(
-                P4C_RES_BASE_PATH + TOFINO_BIN, profile, TOFINO, platform));
-        final URL contextJsonUrl = PipeconfLoader.class.getResource(format(
-                P4C_RES_BASE_PATH + TOFINO_CTX_JSON, profile, TOFINO, platform));
-        final URL p4InfoUrl = PipeconfLoader.class.getResource(format(
-                P4C_RES_BASE_PATH + P4INFO_TXT, profile, TOFINO, platform));
-        final URL cpuPortUrl = PipeconfLoader.class.getResource(format(
-                P4C_RES_BASE_PATH + CPU_PORT_TXT, profile, TOFINO, platform));
-        if (tofinoBinUrl == null) {
-            throw new FileNotFoundException(TOFINO_BIN);
-        }
-        if (contextJsonUrl == null) {
-            throw new FileNotFoundException(TOFINO_CTX_JSON);
-        }
-        if (p4InfoUrl == null) {
-            throw new FileNotFoundException(P4INFO_TXT);
-        }
-        if (cpuPortUrl == null) {
-            throw new FileNotFoundException(CPU_PORT_TXT);
-        }
-        return basePipeconfBuilder(profile, platform, p4InfoUrl, cpuPortUrl)
-                .addExtension(ExtensionType.TOFINO_BIN, tofinoBinUrl)
-                .addExtension(ExtensionType.TOFINO_CONTEXT_JSON, contextJsonUrl);
-    }
-
-    private static DefaultPiPipeconf.Builder basePipeconfBuilder(
-            String profile, String platform, URL p4InfoUrl, URL cpuPortUrl) {
-        final String pipeconfId = platform.equals(DEFAULT_PLATFORM)
-                // Omit platform if default, e.g. with BMv2 pipeconf
-                ? format("%s.%s", BASE_PIPECONF_ID, profile)
-                : format("%s.%s.%s", BASE_PIPECONF_ID, profile, platform);
-        final PiPipelineModel model = parseP4Info(p4InfoUrl);
-        return DefaultPiPipeconf.builder()
-                .withId(new PiPipeconfId(pipeconfId))
-                .withPipelineModel(model)
-                .addBehaviour(PiPipelineInterpreter.class,
-                              FabricInterpreter.class)
-                .addBehaviour(Pipeliner.class,
-                              FabricPipeliner.class)
-                .addExtension(ExtensionType.P4_INFO_TEXT, p4InfoUrl)
-                .addExtension(ExtensionType.CPU_PORT_TXT, cpuPortUrl);
-    }
-
-    private static PiPipelineModel parseP4Info(URL p4InfoUrl) {
-        try {
-            return P4InfoParser.parse(p4InfoUrl);
-        } catch (P4InfoParserException e) {
-            throw new IllegalStateException(e);
-        }
-    }
-}