ONOS-7066 ONOS-7067 PI abstractions refactoring and P4Info model parser
Includes changes previously reviewed in #15607, #15877, and #15955.
Change-Id: Ie2ff62e415f2099832ebfe05961a879b7b188fc3
diff --git a/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4ActionModel.java b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4ActionModel.java
new file mode 100644
index 0000000..dec4d1c
--- /dev/null
+++ b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4ActionModel.java
@@ -0,0 +1,75 @@
+/*
+ * 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.p4runtime.model;
+
+import com.google.common.collect.ImmutableMap;
+import org.onosproject.net.pi.model.PiActionId;
+import org.onosproject.net.pi.model.PiActionModel;
+import org.onosproject.net.pi.model.PiActionParamId;
+import org.onosproject.net.pi.model.PiActionParamModel;
+
+import java.util.Collection;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * Implementation of PiActionModel for P4Runtime.
+ */
+final class P4ActionModel implements PiActionModel {
+
+ private final PiActionId id;
+ private final ImmutableMap<PiActionParamId, PiActionParamModel> params;
+
+ P4ActionModel(PiActionId id,
+ ImmutableMap<PiActionParamId, PiActionParamModel> params) {
+ this.id = id;
+ this.params = params;
+ }
+
+ @Override
+ public PiActionId id() {
+ return id;
+ }
+
+ @Override
+ public Optional<PiActionParamModel> param(PiActionParamId paramId) {
+ return Optional.ofNullable(params.get(paramId));
+ }
+
+ @Override
+ public Collection<PiActionParamModel> params() {
+ return params.values();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, params);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final P4ActionModel other = (P4ActionModel) obj;
+ return Objects.equals(this.id, other.id)
+ && Objects.equals(this.params, other.params);
+ }
+}
diff --git a/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4ActionParamModel.java b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4ActionParamModel.java
new file mode 100644
index 0000000..1c1f0a5
--- /dev/null
+++ b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4ActionParamModel.java
@@ -0,0 +1,64 @@
+/*
+ * 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.p4runtime.model;
+
+import org.onosproject.net.pi.model.PiActionParamId;
+import org.onosproject.net.pi.model.PiActionParamModel;
+
+import java.util.Objects;
+
+/**
+ * Implementation of PiActionParamModel for P4Runtime.
+ */
+final class P4ActionParamModel implements PiActionParamModel {
+
+ private final PiActionParamId id;
+ private final int bitWidth;
+
+ P4ActionParamModel(PiActionParamId id, int bitWidth) {
+ this.id = id;
+ this.bitWidth = bitWidth;
+ }
+
+ @Override
+ public PiActionParamId id() {
+ return id;
+ }
+
+ @Override
+ public int bitWidth() {
+ return bitWidth;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, bitWidth);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final P4ActionParamModel other = (P4ActionParamModel) obj;
+ return Objects.equals(this.id, other.id)
+ && Objects.equals(this.bitWidth, other.bitWidth);
+ }
+}
diff --git a/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4ActionProfileModel.java b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4ActionProfileModel.java
new file mode 100644
index 0000000..5417d44
--- /dev/null
+++ b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4ActionProfileModel.java
@@ -0,0 +1,84 @@
+/*
+ * 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.p4runtime.model;
+
+import com.google.common.collect.ImmutableSet;
+import org.onosproject.net.pi.model.PiActionProfileId;
+import org.onosproject.net.pi.model.PiActionProfileModel;
+import org.onosproject.net.pi.model.PiTableId;
+
+import java.util.Collection;
+import java.util.Objects;
+
+/**
+ * Implementation of PiActionProfileModel for P4Runtime.
+ */
+final class P4ActionProfileModel implements PiActionProfileModel {
+
+ private final PiActionProfileId id;
+ private final ImmutableSet<PiTableId> tables;
+ private final boolean hasSelector;
+ private final long maxSize;
+
+ P4ActionProfileModel(PiActionProfileId id,
+ ImmutableSet<PiTableId> tables, boolean hasSelector, long maxSize) {
+ this.id = id;
+ this.tables = tables;
+ this.hasSelector = hasSelector;
+ this.maxSize = maxSize;
+ }
+
+ @Override
+ public PiActionProfileId id() {
+ return id;
+ }
+
+ @Override
+ public Collection<PiTableId> tables() {
+ return tables;
+ }
+
+ @Override
+ public boolean hasSelector() {
+ return hasSelector;
+ }
+
+ @Override
+ public long maxSize() {
+ return maxSize;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, tables, hasSelector, maxSize);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final P4ActionProfileModel other = (P4ActionProfileModel) obj;
+ return Objects.equals(this.id, other.id)
+ && Objects.equals(this.tables, other.tables)
+ && Objects.equals(this.hasSelector, other.hasSelector)
+ && Objects.equals(this.maxSize, other.maxSize);
+ }
+}
diff --git a/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4ControlMetadataModel.java b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4ControlMetadataModel.java
new file mode 100644
index 0000000..45e7edc
--- /dev/null
+++ b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4ControlMetadataModel.java
@@ -0,0 +1,64 @@
+/*
+ * 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.p4runtime.model;
+
+import org.onosproject.net.pi.model.PiControlMetadataId;
+import org.onosproject.net.pi.model.PiControlMetadataModel;
+
+import java.util.Objects;
+
+/**
+ * Implementation of PiControlMetadataModel for P4Runtime.
+ */
+final class P4ControlMetadataModel implements PiControlMetadataModel {
+
+ private final PiControlMetadataId id;
+ private final int bitWidth;
+
+ P4ControlMetadataModel(PiControlMetadataId id, int bitWidth) {
+ this.id = id;
+ this.bitWidth = bitWidth;
+ }
+
+ @Override
+ public PiControlMetadataId id() {
+ return id;
+ }
+
+ @Override
+ public int bitWidth() {
+ return bitWidth;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, bitWidth);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final P4ControlMetadataModel other = (P4ControlMetadataModel) obj;
+ return Objects.equals(this.id, other.id)
+ && Objects.equals(this.bitWidth, other.bitWidth);
+ }
+}
diff --git a/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4CounterModel.java b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4CounterModel.java
new file mode 100644
index 0000000..de6e755
--- /dev/null
+++ b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4CounterModel.java
@@ -0,0 +1,91 @@
+/*
+ * 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.p4runtime.model;
+
+import org.onosproject.net.pi.model.PiCounterId;
+import org.onosproject.net.pi.model.PiCounterModel;
+import org.onosproject.net.pi.model.PiCounterType;
+import org.onosproject.net.pi.model.PiTableId;
+
+import java.util.Objects;
+
+/**
+ * Implementation of PiCounterModel for P4Runtime.
+ */
+final class P4CounterModel implements PiCounterModel {
+
+ private final PiCounterId id;
+ private final PiCounterType counterType;
+ private final Unit unit;
+ private final PiTableId table;
+ private final long size;
+
+ P4CounterModel(PiCounterId id, PiCounterType counterType,
+ Unit unit, PiTableId table, long size) {
+ this.id = id;
+ this.counterType = counterType;
+ this.unit = unit;
+ this.table = table;
+ this.size = size;
+ }
+
+ @Override
+ public PiCounterId id() {
+ return id;
+ }
+
+ @Override
+ public PiCounterType counterType() {
+ return counterType;
+ }
+
+ @Override
+ public Unit unit() {
+ return unit;
+ }
+
+ @Override
+ public PiTableId table() {
+ return table;
+ }
+
+ @Override
+ public long size() {
+ return size;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, counterType, unit, table, size);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final P4CounterModel other = (P4CounterModel) obj;
+ return Objects.equals(this.id, other.id)
+ && Objects.equals(this.counterType, other.counterType)
+ && Objects.equals(this.unit, other.unit)
+ && Objects.equals(this.table, other.table)
+ && Objects.equals(this.size, other.size);
+ }
+}
diff --git a/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4InfoParser.java b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4InfoParser.java
new file mode 100644
index 0000000..dd365f6
--- /dev/null
+++ b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4InfoParser.java
@@ -0,0 +1,412 @@
+/*
+ * 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.p4runtime.model;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.protobuf.ExtensionRegistry;
+import com.google.protobuf.TextFormat;
+import org.onosproject.net.pi.model.PiActionId;
+import org.onosproject.net.pi.model.PiActionModel;
+import org.onosproject.net.pi.model.PiActionParamId;
+import org.onosproject.net.pi.model.PiActionParamModel;
+import org.onosproject.net.pi.model.PiActionProfileId;
+import org.onosproject.net.pi.model.PiActionProfileModel;
+import org.onosproject.net.pi.model.PiControlMetadataId;
+import org.onosproject.net.pi.model.PiControlMetadataModel;
+import org.onosproject.net.pi.model.PiCounterId;
+import org.onosproject.net.pi.model.PiCounterModel;
+import org.onosproject.net.pi.model.PiCounterType;
+import org.onosproject.net.pi.model.PiMatchFieldId;
+import org.onosproject.net.pi.model.PiMatchFieldModel;
+import org.onosproject.net.pi.model.PiMatchType;
+import org.onosproject.net.pi.model.PiMeterId;
+import org.onosproject.net.pi.model.PiMeterModel;
+import org.onosproject.net.pi.model.PiMeterType;
+import org.onosproject.net.pi.model.PiPacketOperationModel;
+import org.onosproject.net.pi.model.PiPacketOperationType;
+import org.onosproject.net.pi.model.PiPipelineModel;
+import org.onosproject.net.pi.model.PiTableId;
+import org.onosproject.net.pi.model.PiTableModel;
+import org.onosproject.net.pi.model.PiTableType;
+import p4.config.P4InfoOuterClass.Action;
+import p4.config.P4InfoOuterClass.ActionProfile;
+import p4.config.P4InfoOuterClass.ActionRef;
+import p4.config.P4InfoOuterClass.ControllerPacketMetadata;
+import p4.config.P4InfoOuterClass.Counter;
+import p4.config.P4InfoOuterClass.CounterSpec;
+import p4.config.P4InfoOuterClass.DirectCounter;
+import p4.config.P4InfoOuterClass.DirectMeter;
+import p4.config.P4InfoOuterClass.MatchField;
+import p4.config.P4InfoOuterClass.Meter;
+import p4.config.P4InfoOuterClass.MeterSpec;
+import p4.config.P4InfoOuterClass.P4Info;
+import p4.config.P4InfoOuterClass.Table;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import static java.lang.String.format;
+
+/**
+ * Parser of P4Info to PI pipeline model instances.
+ */
+public final class P4InfoParser {
+
+ private static final String PACKET_IN = "packet_in";
+ private static final String PACKET_OUT = "packet_out";
+
+ private static final Map<CounterSpec.Unit, PiCounterModel.Unit> COUNTER_UNIT_MAP =
+ new ImmutableMap.Builder<CounterSpec.Unit, PiCounterModel.Unit>()
+ .put(CounterSpec.Unit.BYTES, PiCounterModel.Unit.BYTES)
+ .put(CounterSpec.Unit.PACKETS, PiCounterModel.Unit.PACKETS)
+ .put(CounterSpec.Unit.BOTH, PiCounterModel.Unit.PACKETS_AND_BYTES)
+ // Don't map UNSPECIFIED as we don't support it at the moment.
+ .build();
+
+ private static final Map<MeterSpec.Unit, PiMeterModel.Unit> METER_UNIT_MAP =
+ new ImmutableMap.Builder<MeterSpec.Unit, PiMeterModel.Unit>()
+ .put(MeterSpec.Unit.BYTES, PiMeterModel.Unit.BYTES)
+ .put(MeterSpec.Unit.PACKETS, PiMeterModel.Unit.PACKETS)
+ // Don't map UNSPECIFIED as we don't support it at the moment.
+ .build();
+
+ private static final Map<String, PiPacketOperationType> PACKET_OPERATION_TYPE_MAP =
+ new ImmutableMap.Builder<String, PiPacketOperationType>()
+ .put(PACKET_IN, PiPacketOperationType.PACKET_IN)
+ .put(PACKET_OUT, PiPacketOperationType.PACKET_OUT)
+ .build();
+
+ private static final Map<MatchField.MatchType, PiMatchType> MATCH_TYPE_MAP =
+ new ImmutableMap.Builder<MatchField.MatchType, PiMatchType>()
+ .put(MatchField.MatchType.VALID, PiMatchType.VALID)
+ .put(MatchField.MatchType.EXACT, PiMatchType.EXACT)
+ .put(MatchField.MatchType.LPM, PiMatchType.LPM)
+ .put(MatchField.MatchType.TERNARY, PiMatchType.TERNARY)
+ .put(MatchField.MatchType.RANGE, PiMatchType.RANGE)
+ // Don't map UNSPECIFIED as we don't support it at the moment.
+ .build();
+ public static final int NO_SIZE = -1;
+
+ private P4InfoParser() {
+ // Utility class, hides constructor.
+ }
+
+ /**
+ * Parse the given URL pointing to a P4Info file (in text format) to a PI pipeline model.
+ *
+ * @param p4InfoUrl URL to P4Info in text form
+ * @return PI pipeline model
+ * @throws P4InfoParserException if the P4Info file cannot be parsed (see message)
+ */
+ public static PiPipelineModel parse(URL p4InfoUrl) throws P4InfoParserException {
+
+ final P4Info p4info;
+ try {
+ p4info = getP4InfoMessage(p4InfoUrl);
+ } catch (IOException e) {
+ throw new P4InfoParserException("Unable to parse protobuf " + p4InfoUrl.toString(), e);
+ }
+
+ // Start by parsing and mapping instances to to their integer P4Info IDs.
+ // Convenient to build the table model at the end.
+
+ // Counters.
+ final Map<Integer, PiCounterModel> counterMap = Maps.newHashMap();
+ counterMap.putAll(parseCounters(p4info));
+ counterMap.putAll(parseDirectCounters(p4info));
+
+ // Meters.
+ final Map<Integer, PiMeterModel> meterMap = Maps.newHashMap();
+ meterMap.putAll(parseMeters(p4info));
+ meterMap.putAll(parseDirectMeters(p4info));
+
+ // Action profiles.
+ final Map<Integer, PiActionProfileModel> actProfileMap = parseActionProfiles(p4info);
+
+ // Actions.
+ final Map<Integer, PiActionModel> actionMap = parseActions(p4info);
+
+ // Controller packet metadatas.
+ final Map<PiPacketOperationType, PiPacketOperationModel> pktOpMap = parseCtrlPktMetadatas(p4info);
+
+ // Finally, parse tables.
+ final ImmutableMap.Builder<PiTableId, PiTableModel> tableImmMapBuilder =
+ ImmutableMap.builder();
+ for (Table tableMsg : p4info.getTablesList()) {
+ final PiTableId tableId = PiTableId.of(tableMsg.getPreamble().getName());
+ // Parse match fields.
+ final ImmutableMap.Builder<PiMatchFieldId, PiMatchFieldModel> tableFieldMapBuilder =
+ ImmutableMap.builder();
+ for (MatchField fieldMsg : tableMsg.getMatchFieldsList()) {
+ final PiMatchFieldId fieldId = PiMatchFieldId.of(fieldMsg.getName());
+ tableFieldMapBuilder.put(
+ fieldId,
+ new P4MatchFieldModel(fieldId,
+ fieldMsg.getBitwidth(),
+ mapMatchFieldType(fieldMsg.getMatchType())));
+
+ }
+ // Retrieve action models by inter IDs.
+ final ImmutableMap.Builder<PiActionId, PiActionModel> tableActionMapBuilder =
+ ImmutableMap.builder();
+ tableMsg.getActionRefsList().stream()
+ .map(ActionRef::getId)
+ .map(actionMap::get)
+ .forEach(actionModel -> tableActionMapBuilder.put(actionModel.id(), actionModel));
+ // Retrieve direct meters by integer IDs.
+ final ImmutableMap.Builder<PiMeterId, PiMeterModel> tableMeterMapBuilder =
+ ImmutableMap.builder();
+ tableMsg.getDirectResourceIdsList()
+ .stream()
+ .map(meterMap::get)
+ // Direct resource ID might be that of a counter.
+ // Filter out missed mapping.
+ .filter(Objects::nonNull)
+ .forEach(meterModel -> tableMeterMapBuilder.put(meterModel.id(), meterModel));
+ // Retrieve direct counters by integer IDs.
+ final ImmutableMap.Builder<PiCounterId, PiCounterModel> tableCounterMapBuilder =
+ ImmutableMap.builder();
+ tableMsg.getDirectResourceIdsList()
+ .stream()
+ .map(counterMap::get)
+ // As before, resource ID might be that of a meter.
+ // Filter out missed mapping.
+ .filter(Objects::nonNull)
+ .forEach(counterModel -> tableCounterMapBuilder.put(counterModel.id(), counterModel));
+ tableImmMapBuilder.put(
+ tableId,
+ new P4TableModel(
+ PiTableId.of(tableMsg.getPreamble().getName()),
+ tableMsg.getImplementationId() == 0 ? PiTableType.DIRECT : PiTableType.INDIRECT,
+ actProfileMap.get(tableMsg.getImplementationId()),
+ tableMsg.getSize(),
+ tableCounterMapBuilder.build(),
+ tableMeterMapBuilder.build(),
+ tableMsg.getWithEntryTimeout(),
+ tableFieldMapBuilder.build(),
+ tableActionMapBuilder.build(),
+ actionMap.get(tableMsg.getConstDefaultActionId()),
+ tableMsg.getConstDefaultActionHasMutableParams()));
+
+ }
+
+ // Get a map with proper PI IDs for some of those maps we created at the beginning.
+ ImmutableMap<PiCounterId, PiCounterModel> counterImmMap = ImmutableMap.copyOf(
+ counterMap.values().stream()
+ .collect(Collectors.toMap(PiCounterModel::id, c -> c)));
+ ImmutableMap<PiMeterId, PiMeterModel> meterImmMap = ImmutableMap.copyOf(
+ meterMap.values().stream()
+ .collect(Collectors.toMap(PiMeterModel::id, m -> m)));
+ ImmutableMap<PiActionProfileId, PiActionProfileModel> actProfileImmMap = ImmutableMap.copyOf(
+ actProfileMap.values().stream()
+ .collect(Collectors.toMap(PiActionProfileModel::id, a -> a)));
+
+ return new P4PipelineModel(
+ tableImmMapBuilder.build(),
+ counterImmMap,
+ meterImmMap,
+ actProfileImmMap,
+ ImmutableMap.copyOf(pktOpMap));
+ }
+
+
+ private static Map<Integer, PiCounterModel> parseCounters(P4Info p4info)
+ throws P4InfoParserException {
+ final Map<Integer, PiCounterModel> counterMap = Maps.newHashMap();
+ for (Counter counterMsg : p4info.getCountersList()) {
+ counterMap.put(
+ counterMsg.getPreamble().getId(),
+ new P4CounterModel(
+ PiCounterId.of(counterMsg.getPreamble().getName()),
+ PiCounterType.INDIRECT,
+ mapCounterSpecUnit(counterMsg.getSpec()),
+ null,
+ counterMsg.getSize()));
+ }
+ return counterMap;
+ }
+
+ private static Map<Integer, PiCounterModel> parseDirectCounters(P4Info p4info)
+ throws P4InfoParserException {
+ final Map<Integer, PiCounterModel> counterMap = Maps.newHashMap();
+ for (DirectCounter dirCounterMsg : p4info.getDirectCountersList()) {
+ counterMap.put(
+ dirCounterMsg.getPreamble().getId(),
+ new P4CounterModel(
+ PiCounterId.of(dirCounterMsg.getPreamble().getName()),
+ PiCounterType.DIRECT,
+ mapCounterSpecUnit(dirCounterMsg.getSpec()),
+ PiTableId.of(getTableName(dirCounterMsg.getDirectTableId(), p4info)),
+ NO_SIZE));
+ }
+ return counterMap;
+ }
+
+ private static Map<Integer, PiMeterModel> parseMeters(P4Info p4info)
+ throws P4InfoParserException {
+ final Map<Integer, PiMeterModel> meterMap = Maps.newHashMap();
+ for (Meter meterMsg : p4info.getMetersList()) {
+ meterMap.put(
+ meterMsg.getPreamble().getId(),
+ new P4MeterModel(
+ PiMeterId.of(meterMsg.getPreamble().getName()),
+ PiMeterType.INDIRECT,
+ mapMeterSpecUnit(meterMsg.getSpec()),
+ null,
+ meterMsg.getSize()));
+ }
+ return meterMap;
+ }
+
+ private static Map<Integer, PiMeterModel> parseDirectMeters(P4Info p4info)
+ throws P4InfoParserException {
+ final Map<Integer, PiMeterModel> meterMap = Maps.newHashMap();
+ for (DirectMeter dirMeterMsg : p4info.getDirectMetersList()) {
+ meterMap.put(
+ dirMeterMsg.getPreamble().getId(),
+ new P4MeterModel(
+ PiMeterId.of(dirMeterMsg.getPreamble().getName()),
+ PiMeterType.DIRECT,
+ mapMeterSpecUnit(dirMeterMsg.getSpec()),
+ PiTableId.of(getTableName(dirMeterMsg.getDirectTableId(), p4info)),
+ NO_SIZE));
+ }
+ return meterMap;
+ }
+
+ private static Map<Integer, PiActionProfileModel> parseActionProfiles(P4Info p4info)
+ throws P4InfoParserException {
+ final Map<Integer, PiActionProfileModel> actProfileMap = Maps.newHashMap();
+ for (ActionProfile actProfileMsg : p4info.getActionProfilesList()) {
+ final ImmutableSet.Builder<PiTableId> tableIdSetBuilder = ImmutableSet.builder();
+ for (int tableId : actProfileMsg.getTableIdsList()) {
+ tableIdSetBuilder.add(PiTableId.of(getTableName(tableId, p4info)));
+ }
+ actProfileMap.put(
+ actProfileMsg.getPreamble().getId(),
+ new P4ActionProfileModel(
+ PiActionProfileId.of(actProfileMsg.getPreamble().getName()),
+ tableIdSetBuilder.build(),
+ actProfileMsg.getWithSelector(),
+ actProfileMsg.getSize()));
+ }
+ return actProfileMap;
+ }
+
+ private static Map<Integer, PiActionModel> parseActions(P4Info p4info) {
+ final Map<Integer, PiActionModel> actionMap = Maps.newHashMap();
+ for (Action actionMsg : p4info.getActionsList()) {
+ final ImmutableMap.Builder<PiActionParamId, PiActionParamModel> paramMapBuilder =
+ ImmutableMap.builder();
+ actionMsg.getParamsList().forEach(paramMsg -> {
+ final PiActionParamId paramId = PiActionParamId.of(paramMsg.getName());
+ paramMapBuilder.put(paramId,
+ new P4ActionParamModel(PiActionParamId.of(paramMsg.getName()),
+ paramMsg.getBitwidth()));
+ });
+ actionMap.put(
+ actionMsg.getPreamble().getId(),
+ new P4ActionModel(
+ PiActionId.of(actionMsg.getPreamble().getName()),
+ paramMapBuilder.build()));
+
+ }
+ return actionMap;
+ }
+
+ private static Map<PiPacketOperationType, PiPacketOperationModel> parseCtrlPktMetadatas(P4Info p4info)
+ throws P4InfoParserException {
+ final Map<PiPacketOperationType, PiPacketOperationModel> packetOpMap = Maps.newHashMap();
+ for (ControllerPacketMetadata ctrlPktMetaMsg : p4info.getControllerPacketMetadataList()) {
+ final ImmutableList.Builder<PiControlMetadataModel> metadataListBuilder =
+ ImmutableList.builder();
+ ctrlPktMetaMsg.getMetadataList().forEach(metadataMsg -> metadataListBuilder.add(
+ new P4ControlMetadataModel(PiControlMetadataId.of(metadataMsg.getName()),
+ metadataMsg.getBitwidth())));
+ packetOpMap.put(
+ mapPacketOpType(ctrlPktMetaMsg.getPreamble().getName()),
+ new P4PacketOperationModel(mapPacketOpType(ctrlPktMetaMsg.getPreamble().getName()),
+ metadataListBuilder.build()));
+
+ }
+ return packetOpMap;
+ }
+
+ private static P4Info getP4InfoMessage(URL p4InfoUrl) throws IOException {
+ InputStream p4InfoStream = p4InfoUrl.openStream();
+ P4Info.Builder p4InfoBuilder = P4Info.newBuilder();
+ TextFormat.getParser().merge(new InputStreamReader(p4InfoStream),
+ ExtensionRegistry.getEmptyRegistry(),
+ p4InfoBuilder);
+ return p4InfoBuilder.build();
+ }
+
+ private static String getTableName(int id, P4Info p4info)
+ throws P4InfoParserException {
+ return p4info.getTablesList().stream()
+ .filter(t -> t.getPreamble().getId() == id)
+ .findFirst()
+ .orElseThrow(() -> new P4InfoParserException(format(
+ "Not such table with ID %d", id)))
+ .getPreamble()
+ .getName();
+ }
+
+ private static PiCounterModel.Unit mapCounterSpecUnit(CounterSpec spec)
+ throws P4InfoParserException {
+ if (!COUNTER_UNIT_MAP.containsKey(spec.getUnit())) {
+ throw new P4InfoParserException(format(
+ "Unrecognized counter unit '%s'", spec.getUnit()));
+ }
+ return COUNTER_UNIT_MAP.get(spec.getUnit());
+ }
+
+ private static PiMeterModel.Unit mapMeterSpecUnit(MeterSpec spec)
+ throws P4InfoParserException {
+ if (!METER_UNIT_MAP.containsKey(spec.getUnit())) {
+ throw new P4InfoParserException(format(
+ "Unrecognized meter unit '%s'", spec.getUnit()));
+ }
+ return METER_UNIT_MAP.get(spec.getUnit());
+ }
+
+ private static PiPacketOperationType mapPacketOpType(String name)
+ throws P4InfoParserException {
+ if (!PACKET_OPERATION_TYPE_MAP.containsKey(name)) {
+ throw new P4InfoParserException(format(
+ "Unrecognized controller packet metadata name '%s'", name));
+ }
+ return PACKET_OPERATION_TYPE_MAP.get(name);
+ }
+
+ private static PiMatchType mapMatchFieldType(MatchField.MatchType type)
+ throws P4InfoParserException {
+ if (!MATCH_TYPE_MAP.containsKey(type)) {
+ throw new P4InfoParserException(format(
+ "Unrecognized match field type '%s'", type));
+ }
+ return MATCH_TYPE_MAP.get(type);
+ }
+}
diff --git a/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4InfoParserException.java b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4InfoParserException.java
new file mode 100644
index 0000000..f01f999
--- /dev/null
+++ b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4InfoParserException.java
@@ -0,0 +1,42 @@
+/*
+ * 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.p4runtime.model;
+
+/**
+ * Signals an error occurred while parsing a P4Info object.
+ */
+public final class P4InfoParserException extends Exception {
+
+ /**
+ * Creates a new exception for the given message.
+ *
+ * @param message explanation
+ */
+ P4InfoParserException(String message) {
+ super(message);
+ }
+
+ /**
+ * Creates a new exception for the given message and cause.
+ *
+ * @param message message
+ * @param cause cause
+ */
+ P4InfoParserException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4MatchFieldModel.java b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4MatchFieldModel.java
new file mode 100644
index 0000000..f3b5ddc
--- /dev/null
+++ b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4MatchFieldModel.java
@@ -0,0 +1,73 @@
+/*
+ * 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.p4runtime.model;
+
+import org.onosproject.net.pi.model.PiMatchFieldId;
+import org.onosproject.net.pi.model.PiMatchFieldModel;
+import org.onosproject.net.pi.model.PiMatchType;
+
+import java.util.Objects;
+
+/**
+ * Implementation of PiMatchFieldModel for P4Runtime.
+ */
+final class P4MatchFieldModel implements PiMatchFieldModel {
+
+ private final PiMatchFieldId id;
+ private final int bitWidth;
+ private final PiMatchType matchType;
+
+ P4MatchFieldModel(PiMatchFieldId id, int bitWidth, PiMatchType matchType) {
+ this.id = id;
+ this.bitWidth = bitWidth;
+ this.matchType = matchType;
+ }
+
+ @Override
+ public PiMatchFieldId id() {
+ return id;
+ }
+
+ @Override
+ public int bitWidth() {
+ return bitWidth;
+ }
+
+ @Override
+ public PiMatchType matchType() {
+ return matchType;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, bitWidth, matchType);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final P4MatchFieldModel other = (P4MatchFieldModel) obj;
+ return Objects.equals(this.id, other.id)
+ && Objects.equals(this.bitWidth, other.bitWidth)
+ && Objects.equals(this.matchType, other.matchType);
+ }
+}
diff --git a/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4MeterModel.java b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4MeterModel.java
new file mode 100644
index 0000000..93827cc
--- /dev/null
+++ b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4MeterModel.java
@@ -0,0 +1,90 @@
+/*
+ * 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.p4runtime.model;
+
+import org.onosproject.net.pi.model.PiMeterId;
+import org.onosproject.net.pi.model.PiMeterModel;
+import org.onosproject.net.pi.model.PiMeterType;
+import org.onosproject.net.pi.model.PiTableId;
+
+import java.util.Objects;
+
+/**
+ * Implementation of PiMeterModel for P4Runtime.
+ */
+final class P4MeterModel implements PiMeterModel {
+
+ private final PiMeterId id;
+ private final PiMeterType meterType;
+ private final Unit unit;
+ private final PiTableId table;
+ private final long size;
+
+ P4MeterModel(PiMeterId id, PiMeterType meterType, Unit unit, PiTableId table, long size) {
+ this.id = id;
+ this.meterType = meterType;
+ this.unit = unit;
+ this.table = table;
+ this.size = size;
+ }
+
+ @Override
+ public PiMeterId id() {
+ return id;
+ }
+
+ @Override
+ public PiMeterType meterType() {
+ return meterType;
+ }
+
+ @Override
+ public Unit unit() {
+ return unit;
+ }
+
+ @Override
+ public PiTableId table() {
+ return table;
+ }
+
+ @Override
+ public long size() {
+ return size;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, meterType, unit, table, size);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final P4MeterModel other = (P4MeterModel) obj;
+ return Objects.equals(this.id, other.id)
+ && Objects.equals(this.meterType, other.meterType)
+ && Objects.equals(this.unit, other.unit)
+ && Objects.equals(this.table, other.table)
+ && Objects.equals(this.size, other.size);
+ }
+}
diff --git a/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4PacketOperationModel.java b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4PacketOperationModel.java
new file mode 100644
index 0000000..84e2fe4
--- /dev/null
+++ b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4PacketOperationModel.java
@@ -0,0 +1,68 @@
+/*
+ * 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.p4runtime.model;
+
+import com.google.common.collect.ImmutableList;
+import org.onosproject.net.pi.model.PiControlMetadataModel;
+import org.onosproject.net.pi.model.PiPacketOperationModel;
+import org.onosproject.net.pi.model.PiPacketOperationType;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Implementation of PiPacketOperationModel for P4Runtime.
+ */
+final class P4PacketOperationModel implements PiPacketOperationModel {
+
+ private final PiPacketOperationType type;
+ private final ImmutableList<PiControlMetadataModel> metadatas;
+
+ P4PacketOperationModel(PiPacketOperationType type,
+ ImmutableList<PiControlMetadataModel> metadatas) {
+ this.type = type;
+ this.metadatas = metadatas;
+ }
+
+ @Override
+ public PiPacketOperationType type() {
+ return type;
+ }
+
+ @Override
+ public List<PiControlMetadataModel> metadatas() {
+ return metadatas;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type, metadatas);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final P4PacketOperationModel other = (P4PacketOperationModel) obj;
+ return Objects.equals(this.type, other.type)
+ && Objects.equals(this.metadatas, other.metadatas);
+ }
+}
diff --git a/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4PipelineModel.java b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4PipelineModel.java
new file mode 100644
index 0000000..622cc23
--- /dev/null
+++ b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4PipelineModel.java
@@ -0,0 +1,126 @@
+/*
+ * 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.p4runtime.model;
+
+import com.google.common.collect.ImmutableMap;
+import org.onosproject.net.pi.model.PiActionProfileId;
+import org.onosproject.net.pi.model.PiActionProfileModel;
+import org.onosproject.net.pi.model.PiCounterId;
+import org.onosproject.net.pi.model.PiCounterModel;
+import org.onosproject.net.pi.model.PiMeterId;
+import org.onosproject.net.pi.model.PiMeterModel;
+import org.onosproject.net.pi.model.PiPacketOperationModel;
+import org.onosproject.net.pi.model.PiPacketOperationType;
+import org.onosproject.net.pi.model.PiPipelineModel;
+import org.onosproject.net.pi.model.PiTableId;
+import org.onosproject.net.pi.model.PiTableModel;
+
+import java.util.Collection;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * Implementation of PiPipelineModel for P4Runtime.
+ */
+final class P4PipelineModel implements PiPipelineModel {
+
+ private final ImmutableMap<PiTableId, PiTableModel> tables;
+ private final ImmutableMap<PiCounterId, PiCounterModel> counters;
+ private final ImmutableMap<PiMeterId, PiMeterModel> meters;
+ private final ImmutableMap<PiActionProfileId, PiActionProfileModel> actionProfiles;
+ private final ImmutableMap<PiPacketOperationType, PiPacketOperationModel> packetOperations;
+
+ P4PipelineModel(
+ ImmutableMap<PiTableId, PiTableModel> tables,
+ ImmutableMap<PiCounterId, PiCounterModel> counters,
+ ImmutableMap<PiMeterId, PiMeterModel> meters,
+ ImmutableMap<PiActionProfileId, PiActionProfileModel> actionProfiles,
+ ImmutableMap<PiPacketOperationType, PiPacketOperationModel> packetOperations) {
+ this.tables = tables;
+ this.counters = counters;
+ this.meters = meters;
+ this.actionProfiles = actionProfiles;
+ this.packetOperations = packetOperations;
+ }
+
+ @Override
+ public Optional<PiTableModel> table(PiTableId tableId) {
+ return Optional.ofNullable(tables.get(tableId));
+ }
+
+ @Override
+ public Collection<PiTableModel> tables() {
+ return tables.values();
+ }
+
+ @Override
+ public Optional<PiCounterModel> counter(PiCounterId counterId) {
+ return Optional.ofNullable(counters.get(counterId));
+ }
+
+ @Override
+ public Collection<PiCounterModel> counters() {
+ return counters.values();
+ }
+
+ @Override
+ public Optional<PiMeterModel> meter(PiMeterId meterId) {
+ return Optional.ofNullable(meters.get(meterId));
+ }
+
+ @Override
+ public Collection<PiMeterModel> meters() {
+ return meters.values();
+ }
+
+ @Override
+ public Optional<PiActionProfileModel> actionProfiles(PiActionProfileId actionProfileId) {
+ return Optional.ofNullable(actionProfiles.get(actionProfileId));
+ }
+
+ @Override
+ public Collection<PiActionProfileModel> actionProfiles() {
+ return actionProfiles.values();
+ }
+
+ @Override
+ public Optional<PiPacketOperationModel> packetOperationModel(PiPacketOperationType type) {
+ return Optional.ofNullable(packetOperations.get(type));
+
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(tables, counters, meters, actionProfiles, packetOperations);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final P4PipelineModel other = (P4PipelineModel) obj;
+ return Objects.equals(this.tables, other.tables)
+ && Objects.equals(this.counters, other.counters)
+ && Objects.equals(this.meters, other.meters)
+ && Objects.equals(this.actionProfiles, other.actionProfiles)
+ && Objects.equals(this.packetOperations, other.packetOperations);
+ }
+}
diff --git a/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4TableModel.java b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4TableModel.java
new file mode 100644
index 0000000..89c4bed
--- /dev/null
+++ b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4TableModel.java
@@ -0,0 +1,167 @@
+/*
+ * 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.p4runtime.model;
+
+import com.google.common.collect.ImmutableMap;
+import org.onosproject.net.pi.model.PiActionId;
+import org.onosproject.net.pi.model.PiActionModel;
+import org.onosproject.net.pi.model.PiActionProfileModel;
+import org.onosproject.net.pi.model.PiCounterId;
+import org.onosproject.net.pi.model.PiCounterModel;
+import org.onosproject.net.pi.model.PiMatchFieldId;
+import org.onosproject.net.pi.model.PiMatchFieldModel;
+import org.onosproject.net.pi.model.PiMeterId;
+import org.onosproject.net.pi.model.PiMeterModel;
+import org.onosproject.net.pi.model.PiTableId;
+import org.onosproject.net.pi.model.PiTableModel;
+import org.onosproject.net.pi.model.PiTableType;
+
+import java.util.Collection;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * Implementation of PiTableModel for P4Runtime.
+ */
+final class P4TableModel implements PiTableModel {
+
+ private final PiTableId id;
+ private final PiTableType tableType;
+ private final PiActionProfileModel actionProfile;
+ private final long maxSize;
+ private final ImmutableMap<PiCounterId, PiCounterModel> counters;
+ private final ImmutableMap<PiMeterId, PiMeterModel> meters;
+ private final boolean supportAging;
+ private final ImmutableMap<PiMatchFieldId, PiMatchFieldModel> matchFields;
+ private final ImmutableMap<PiActionId, PiActionModel> actions;
+ private final PiActionModel defaultAction;
+ private final boolean hasDefaultMutableParams;
+
+ P4TableModel(PiTableId id, PiTableType tableType,
+ PiActionProfileModel actionProfile, long maxSize,
+ ImmutableMap<PiCounterId, PiCounterModel> counters,
+ ImmutableMap<PiMeterId, PiMeterModel> meters, boolean supportAging,
+ ImmutableMap<PiMatchFieldId, PiMatchFieldModel> matchFields,
+ ImmutableMap<PiActionId, PiActionModel> actions,
+ PiActionModel defaultAction, boolean hasDefaultMutableParams) {
+ this.id = id;
+ this.tableType = tableType;
+ this.actionProfile = actionProfile;
+ this.maxSize = maxSize;
+ this.counters = counters;
+ this.meters = meters;
+ this.supportAging = supportAging;
+ this.matchFields = matchFields;
+ this.actions = actions;
+ this.defaultAction = defaultAction;
+ this.hasDefaultMutableParams = hasDefaultMutableParams;
+ }
+
+ @Override
+ public PiTableId id() {
+ return id;
+ }
+
+ @Override
+ public PiTableType tableType() {
+ return tableType;
+ }
+
+ @Override
+ public PiActionProfileModel actionProfile() {
+ return actionProfile;
+ }
+
+ @Override
+ public long maxSize() {
+ return maxSize;
+ }
+
+ @Override
+ public Collection<PiCounterModel> counters() {
+ return counters.values();
+ }
+
+ @Override
+ public Collection<PiMeterModel> meters() {
+ return meters.values();
+ }
+
+ @Override
+ public boolean supportsAging() {
+ return supportAging;
+ }
+
+ @Override
+ public Collection<PiMatchFieldModel> matchFields() {
+ return matchFields.values();
+ }
+
+ @Override
+ public Collection<PiActionModel> actions() {
+ return actions.values();
+ }
+
+ @Override
+ public Optional<PiActionModel> defaultAction() {
+ return Optional.ofNullable(defaultAction);
+ }
+
+ @Override
+ public boolean hasDefaultMutableParams() {
+ return hasDefaultMutableParams;
+ }
+
+ @Override
+ public Optional<PiActionModel> action(PiActionId actionId) {
+ return Optional.ofNullable(actions.get(actionId));
+ }
+
+ @Override
+ public Optional<PiMatchFieldModel> matchField(PiMatchFieldId matchFieldId) {
+ return Optional.ofNullable(matchFields.get(matchFieldId));
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, tableType, actionProfile, maxSize, counters,
+ meters, supportAging, matchFields, actions,
+ defaultAction, hasDefaultMutableParams);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final P4TableModel other = (P4TableModel) obj;
+ return Objects.equals(this.id, other.id)
+ && Objects.equals(this.tableType, other.tableType)
+ && Objects.equals(this.actionProfile, other.actionProfile)
+ && Objects.equals(this.maxSize, other.maxSize)
+ && Objects.equals(this.counters, other.counters)
+ && Objects.equals(this.meters, other.meters)
+ && Objects.equals(this.supportAging, other.supportAging)
+ && Objects.equals(this.matchFields, other.matchFields)
+ && Objects.equals(this.actions, other.actions)
+ && Objects.equals(this.defaultAction, other.defaultAction)
+ && Objects.equals(this.hasDefaultMutableParams, other.hasDefaultMutableParams);
+ }
+}
diff --git a/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/package-info.java b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/package-info.java
new file mode 100644
index 0000000..f1e8a69
--- /dev/null
+++ b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Pipeline model class implementation for P4Runtime and P4Info parser.
+ */
+package org.onosproject.p4runtime.model;