[ONOS-7602]Implement support for P4Data in PI framework and P4Runtime southbound
Change-Id: I9c0c76fb29b8c3aa36f39bde62e825f0f0094253
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiData.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiData.java
new file mode 100644
index 0000000..97d5290
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiData.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2018-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.net.pi.model;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Representation of data that can be used for runtime operations of a protocol-independent pipeline.
+ */
+@Beta
+public interface PiData {
+ /**
+ * Types of data in a protocol-independent pipeline.
+ */
+ enum Type {
+ /**
+ * Bit String.
+ */
+ BITSTRING,
+
+ /**
+ * Bool.
+ */
+ BOOL,
+
+ /**
+ * Tuple.
+ */
+ TUPLE,
+
+ /**
+ * Struct.
+ */
+ STRUCT,
+
+ /**
+ * Header.
+ */
+ HEADER,
+
+ /**
+ * Header Stack.
+ */
+ HEADERSTACK,
+
+ /**
+ * Header Union.
+ */
+ HEADERUNION,
+
+ /**
+ * Header Union Stack.
+ */
+ HEADERUNIONSTACK,
+
+ /**
+ * Enum String.
+ */
+ ENUMSTRING,
+
+ /**
+ * Error String.
+ */
+ ERRORSTRING
+ }
+
+ /**
+ * Returns the type of this protocol-independent data.
+ * @return the type of this instance
+ */
+ Type type();
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiBitString.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiBitString.java
new file mode 100644
index 0000000..544f5df
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiBitString.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2018-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.net.pi.runtime.data;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.net.pi.model.PiData;
+
+/**
+ * BitString entity in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiBitString implements PiData {
+ private final ImmutableByteSequence bitString;
+
+ /**
+ * Creates a new protocol-independent bit string instance.
+ *
+ * @param bitString bitString
+ */
+ private PiBitString(ImmutableByteSequence bitString) {
+ this.bitString = bitString;
+ }
+
+ /**
+ * Returns a new protocol-independent BitString.
+ * @param bitString bitString
+ * @return BitString
+ */
+ public static PiBitString of(ImmutableByteSequence bitString) {
+ return new PiBitString(bitString);
+ }
+
+ /**
+ * Return protocol-independent bitString instance.
+ *
+ * @return bitString
+ */
+ public ImmutableByteSequence bitString() {
+ return this.bitString;
+ }
+
+ @Override
+ public Type type() {
+ return Type.BITSTRING;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiBitString bitStr = (PiBitString) o;
+ return Objects.equal(bitString, bitStr.bitString);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(bitString);
+ }
+
+ @Override
+ public String toString() {
+ return bitString.toString();
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiBool.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiBool.java
new file mode 100644
index 0000000..e100f03
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiBool.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2018-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.net.pi.runtime.data;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import org.onosproject.net.pi.model.PiData;
+
+/**
+ * Boolean entity in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiBool implements PiData {
+ private final Boolean bool;
+
+ /**
+ * Creates a new protocol-independent Bool instance.
+ *
+ * @param bool boolean
+ */
+ private PiBool(Boolean bool) {
+ this.bool = bool;
+ }
+
+ /**
+ * Returns a new protocol-independent Bool.
+ * @param bool boolean
+ * @return protocol-independent Bool
+ */
+ public static PiBool of(Boolean bool) {
+ return new PiBool(bool);
+ }
+
+ /**
+ * Return protocol-independent Boolean instance.
+ *
+ * @return bool
+ */
+ public Boolean bool() {
+ return this.bool;
+ }
+
+ @Override
+ public Type type() {
+ return Type.BOOL;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiBool boolValue = (PiBool) o;
+ return Objects.equal(bool, boolValue.bool);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(bool);
+ }
+
+ @Override
+ public String toString() {
+ return bool.toString();
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiEnumString.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiEnumString.java
new file mode 100644
index 0000000..74481ea
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiEnumString.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2018-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.net.pi.runtime.data;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import org.onosproject.net.pi.model.PiData;
+
+/**
+ * EnumString entity in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiEnumString implements PiData {
+ private final String enumString;
+
+ /**
+ * Creates a new protocol-independent enum string instance.
+ *
+ * @param enumString enum string
+ */
+ private PiEnumString(String enumString) {
+ this.enumString = enumString;
+ }
+
+ /**
+ * Returns a new protocol-independent enum string.
+ * @param enumString enum string
+ * @return enum string
+ */
+ public static PiEnumString of(String enumString) {
+ return new PiEnumString(enumString);
+ }
+
+ /**
+ * Return protocol-independent enum string instance.
+ *
+ * @return enum string
+ */
+ public String enumString() {
+ return this.enumString;
+ }
+
+ @Override
+ public Type type() {
+ return Type.ENUMSTRING;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiEnumString enumStr = (PiEnumString) o;
+ return Objects.equal(enumString, enumStr.enumString);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(enumString);
+ }
+
+ @Override
+ public String toString() {
+ return enumString;
+ }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiErrorString.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiErrorString.java
new file mode 100644
index 0000000..ff4e172
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiErrorString.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2018-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.net.pi.runtime.data;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import org.onosproject.net.pi.model.PiData;
+
+/**
+ * ErrorString entity in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiErrorString implements PiData {
+ private final String errorString;
+
+ /**
+ * Creates a new protocol-independent error string instance.
+ *
+ * @param errorString error string
+ */
+ private PiErrorString(String errorString) {
+ this.errorString = errorString;
+ }
+
+ /**
+ * Returns a new protocol-independent error string.
+ * @param errorString error string
+ * @return error string
+ */
+ public static PiErrorString of(String errorString) {
+ return new PiErrorString(errorString);
+ }
+
+ /**
+ * Return protocol-independent error string instance.
+ *
+ * @return error string
+ */
+ public String errorString() {
+ return this.errorString;
+ }
+
+ @Override
+ public Type type() {
+ return Type.ERRORSTRING;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiErrorString errorStr = (PiErrorString) o;
+ return Objects.equal(errorString, errorStr.errorString);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(errorString);
+ }
+
+ @Override
+ public String toString() {
+ return errorString;
+ }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeader.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeader.java
new file mode 100644
index 0000000..bbc0f8e
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeader.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2018-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.net.pi.runtime.data;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.net.pi.model.PiData;
+
+import java.util.List;
+import java.util.StringJoiner;
+
+/**
+ * Instance of a PiHeader in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiHeader implements PiData {
+ private final Boolean isValid;
+ private final ImmutableList<ImmutableByteSequence> bitStrings;
+
+ /**
+ * Creates a new protocol-independent header instance.
+ *
+ * @param isValid whether the header is valid
+ * @param bitStrings bitstrings
+ */
+ private PiHeader(Boolean isValid, List<ImmutableByteSequence> bitStrings) {
+ this.isValid = isValid;
+ this.bitStrings = ImmutableList.copyOf(bitStrings);
+ }
+
+ /**
+ * Returns a new protocol-independent header.
+ * @param isValid whether the header is valid
+ * @param bitStrings bitstrings
+ * @return header
+ */
+ public static PiHeader of(Boolean isValid, List<ImmutableByteSequence> bitStrings) {
+ return new PiHeader(isValid, bitStrings);
+ }
+
+ /**
+ * Return whether the header is valid.
+ *
+ * @return bool
+ */
+ public Boolean isValid() {
+ return this.isValid;
+ }
+
+ /**
+ * Return the header bit strings.
+ *
+ * @return the list of bit string
+ */
+ public List<ImmutableByteSequence> bitStrings() {
+ return this.bitStrings;
+ }
+
+ @Override
+ public Type type() {
+ return Type.HEADER;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiHeader header = (PiHeader) o;
+ return Objects.equal(isValid, header.isValid) &&
+ Objects.equal(bitStrings, header.bitStrings);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(isValid, bitStrings);
+ }
+
+ @Override
+ public String toString() {
+ StringJoiner stringParams = new StringJoiner(", ", "(", ")");
+ this.bitStrings().forEach(p -> stringParams.add(p.toString()));
+ return MoreObjects.toStringHelper(getClass())
+ .add("bitString", stringParams)
+ .add("isValid", isValid)
+ .toString();
+ }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeaderStack.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeaderStack.java
new file mode 100644
index 0000000..ccf8af8
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeaderStack.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2018-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.net.pi.runtime.data;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import org.onosproject.net.pi.model.PiData;
+
+import java.util.List;
+import java.util.StringJoiner;
+
+/**
+ * Instance of a PiHeaderStack in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiHeaderStack implements PiData {
+ private final ImmutableList<PiHeader> headers;
+
+ /**
+ * Creates a new protocol-independent header stack instance for the given collection of Header.
+ *
+ * @param headers the collection of header
+ */
+ private PiHeaderStack(List<PiHeader> headers) {
+ this.headers = ImmutableList.copyOf(headers);
+ }
+
+ /**
+ * Returns a new protocol-independent header stack.
+ * @param headers the list of header
+ * @return header stack
+ */
+ public static PiHeaderStack of(List<PiHeader> headers) {
+ return new PiHeaderStack(headers);
+ }
+
+ /**
+ * Return the list of header.
+ *
+ * @return the list of header
+ */
+ public List<PiHeader> headers() {
+ return this.headers;
+ }
+
+ @Override
+ public Type type() {
+ return Type.HEADERSTACK;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiHeaderStack stack = (PiHeaderStack) o;
+ return Objects.equal(headers, stack.headers);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(headers);
+ }
+
+ @Override
+ public String toString() {
+ StringJoiner stringParams = new StringJoiner(", ", "(", ")");
+ this.headers().forEach(p -> stringParams.add(p.toString()));
+ return stringParams.toString();
+ }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeaderUnion.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeaderUnion.java
new file mode 100644
index 0000000..189318c
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeaderUnion.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2018-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.net.pi.runtime.data;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import org.onosproject.net.pi.model.PiData;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * PiHeaderUnion entity in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiHeaderUnion implements PiData {
+ private final String validHeaderName;
+ private final PiHeader header;
+ private final boolean isValid;
+
+ /**
+ * Creates a new protocol-independent header union instance for the given header name and header.
+ *
+ * @param isValid indicates whether this header union is valid
+ * @param validHeaderName header name
+ * @param header the header
+ */
+ private PiHeaderUnion(boolean isValid, String validHeaderName, PiHeader header) {
+ this.isValid = isValid;
+ this.validHeaderName = validHeaderName;
+ this.header = header;
+ }
+
+ /**
+ * Returns a new invalid protocol-independent header union.
+ *
+ * @return header union
+ */
+ public static PiHeaderUnion ofInvalid() {
+ return new PiHeaderUnion(false, null, null);
+ }
+
+ /**
+ * Returns a new valid protocol-independent header union.
+ * @param validHeaderName header name
+ * @param header the header
+ * @return header union
+ */
+ public static PiHeaderUnion of(String validHeaderName, PiHeader header) {
+ checkNotNull(validHeaderName);
+ checkArgument(!validHeaderName.isEmpty(), "The header name must not be empty");
+ checkNotNull(header);
+ return new PiHeaderUnion(true, validHeaderName, header);
+ }
+
+ /**
+ * Returns true if this header is valid, false otherwise.
+ *
+ * @return a boolean value
+ */
+ public boolean isValid() {
+ return this.isValid;
+ }
+
+ /**
+ * Return the header name.
+ *
+ * @return header name, return null if the header union invalid
+ */
+ public String headerName() {
+ return this.validHeaderName;
+ }
+
+ /**
+ * Return the header.
+ *
+ * @return header, return null if the header union invalid
+ */
+ public PiHeader header() {
+ return this.header;
+ }
+
+ @Override
+ public Type type() {
+ return Type.HEADERUNION;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiHeaderUnion headerUnion = (PiHeaderUnion) o;
+ return Objects.equal(validHeaderName, headerUnion.validHeaderName) &&
+ Objects.equal(header, headerUnion.header);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(validHeaderName, header);
+ }
+
+ @Override
+ public String toString() {
+ return !isValid ? "INVALID" : validHeaderName + ":" + header.toString();
+ }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeaderUnionStack.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeaderUnionStack.java
new file mode 100644
index 0000000..a1e39b8
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiHeaderUnionStack.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2018-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.net.pi.runtime.data;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import org.onosproject.net.pi.model.PiData;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.StringJoiner;
+
+/**
+ * PiHeaderUnionStack entity in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiHeaderUnionStack implements PiData {
+ private final ImmutableList<PiHeaderUnion> headerUnions;
+
+ /**
+ * Creates a new protocol-independent header union stack instance for the given collection of HeaderUnion.
+ *
+ * @param headerUnions the collection of headerUnion
+ */
+ private PiHeaderUnionStack(List<PiHeaderUnion> headerUnions) {
+ this.headerUnions = ImmutableList.copyOf(headerUnions);
+ }
+
+ /**
+ * Returns a new protocol-independent header union stack.
+ * @param headerUnions the list of headerUnion
+ * @return header union stack
+ */
+ public static PiHeaderUnionStack of(List<PiHeaderUnion> headerUnions) {
+ return new PiHeaderUnionStack(headerUnions);
+ }
+
+ /**
+ * Return the collection of header union.
+ *
+ * @return the collection header union
+ */
+ public Collection<PiHeaderUnion> headerUnions() {
+ return this.headerUnions;
+ }
+
+ @Override
+ public Type type() {
+ return Type.HEADERUNIONSTACK;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiHeaderUnionStack headerUnionStack = (PiHeaderUnionStack) o;
+ return Objects.equal(headerUnions, headerUnionStack.headerUnions);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(headerUnions);
+ }
+
+ @Override
+ public String toString() {
+ StringJoiner stringParams = new StringJoiner(", ", "(", ")");
+ this.headerUnions().forEach(p -> stringParams.add(p.toString()));
+ return stringParams.toString();
+ }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiStruct.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiStruct.java
new file mode 100644
index 0000000..7c60c16
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiStruct.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2018-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.net.pi.runtime.data;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import org.onosproject.net.pi.model.PiData;
+
+import java.util.List;
+import java.util.StringJoiner;
+
+/**
+ * Struct entity in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiStruct implements PiData {
+ private final ImmutableList<PiData> struct;
+
+ /**
+ * Creates a new protocol-independent struct instance for the given collection of PiData.
+ *
+ * @param struct the collection of PiData
+ */
+ private PiStruct(List<PiData> struct) {
+ this.struct = ImmutableList.copyOf(struct);
+ }
+
+ /**
+ * Returns a new protocol-independent struct.
+ * @param struct the list of PiData
+ * @return struct
+ */
+ public static PiStruct of(List<PiData> struct) {
+ return new PiStruct(struct);
+ }
+
+ /**
+ * Return protocol-independent struct instance.
+ *
+ * @return the list of PiData
+ */
+ public List<PiData> struct() {
+ return this.struct;
+ }
+
+ @Override
+ public Type type() {
+ return Type.STRUCT;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiStruct st = (PiStruct) o;
+ return Objects.equal(struct, st.struct);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(struct);
+ }
+
+ @Override
+ public String toString() {
+ StringJoiner stringParams = new StringJoiner(", ", "(", ")");
+ this.struct().forEach(p -> stringParams.add(p.toString()));
+ return stringParams.toString();
+ }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiTuple.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiTuple.java
new file mode 100644
index 0000000..e88fede
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/PiTuple.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2018-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.net.pi.runtime.data;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import org.onosproject.net.pi.model.PiData;
+
+import java.util.List;
+import java.util.StringJoiner;
+
+/**
+ * Tuple entity in a protocol-independent pipeline.
+ */
+@Beta
+public final class PiTuple implements PiData {
+ private final ImmutableList<PiData> tuple;
+
+ /**
+ * Creates a new protocol-independent tuple instance for the given collection of PiData.
+ *
+ * @param tuple the collection of PiData
+ */
+ private PiTuple(List<PiData> tuple) {
+ this.tuple = ImmutableList.copyOf(tuple);
+ }
+
+ /**
+ * Returns a new protocol-independent tuple.
+ * @param tuple the list of PiData
+ * @return tuple
+ */
+ public static PiTuple of(List<PiData> tuple) {
+ return new PiTuple(tuple);
+ }
+
+ /**
+ * Return protocol-independent tuple instance.
+ *
+ * @return the list of PiData
+ */
+ public List<PiData> tuple() {
+ return this.tuple;
+ }
+
+ @Override
+ public Type type() {
+ return Type.TUPLE;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ PiTuple tp = (PiTuple) o;
+ return Objects.equal(tuple, tp.tuple);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(tuple);
+ }
+
+ @Override
+ public String toString() {
+ StringJoiner stringParams = new StringJoiner(", ", "(", ")");
+ this.tuple().forEach(p -> stringParams.add(p.toString()));
+ return stringParams.toString();
+ }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/data/package-info.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/package-info.java
new file mode 100644
index 0000000..86fa76b
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/data/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2018-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.
+ */
+
+/**
+ * Classes abstracting data that can be used for runtime operations of a protocol-independent pipeline.
+ */
+
+package org.onosproject.net.pi.runtime.data;
\ No newline at end of file
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiDataTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiDataTest.java
new file mode 100644
index 0000000..2915156
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiDataTest.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2018-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.net.pi.runtime;
+
+import com.google.common.collect.Lists;
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.net.pi.model.PiData;
+import org.onosproject.net.pi.runtime.data.PiBitString;
+import org.onosproject.net.pi.runtime.data.PiBool;
+import org.onosproject.net.pi.runtime.data.PiEnumString;
+import org.onosproject.net.pi.runtime.data.PiErrorString;
+import org.onosproject.net.pi.runtime.data.PiHeader;
+import org.onosproject.net.pi.runtime.data.PiHeaderStack;
+import org.onosproject.net.pi.runtime.data.PiHeaderUnion;
+import org.onosproject.net.pi.runtime.data.PiHeaderUnionStack;
+import org.onosproject.net.pi.runtime.data.PiStruct;
+import org.onosproject.net.pi.runtime.data.PiTuple;
+
+import static org.junit.Assert.assertEquals;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+/**
+ * Unit tests for PiData class.
+ */
+public class PiDataTest {
+ private final PiData bitString1 = PiBitString.of(ImmutableByteSequence.copyFrom(10));
+ private final PiData sameAsBitString1 = PiBitString.of(ImmutableByteSequence.copyFrom(10));
+ private final PiData bitString2 = PiBitString.of(ImmutableByteSequence.copyFrom(20));
+
+ private final PiData bool1 = PiBool.of(true);
+ private final PiData sameAsBool1 = PiBool.of(true);
+ private final PiData bool2 = PiBool.of(false);
+
+ private final PiData tuple1 = PiTuple.of(Lists.newArrayList(bool1));
+ private final PiData sameAsTuple1 = PiTuple.of(Lists.newArrayList(bool1));
+ private final PiData tuple2 = PiTuple.of(Lists.newArrayList(bitString1));
+
+ private final PiData struct1 = PiStruct.of(Lists.newArrayList(bool1));
+ private final PiData sameAsStruct1 = PiStruct.of(Lists.newArrayList(bool1));
+ private final PiData struct2 = PiStruct.of(Lists.newArrayList(bitString1));
+
+ private final PiData header1 = PiHeader.of(true,
+ Lists.newArrayList(ImmutableByteSequence.copyFrom(10)));
+ private final PiData sameAsHeader1 = PiHeader.of(true,
+ Lists.newArrayList(ImmutableByteSequence.copyFrom(10)));
+ private final PiData header2 = PiHeader.of(true,
+ Lists.newArrayList(ImmutableByteSequence.copyFrom(20)));
+
+ private final PiData headerUnion1 = PiHeaderUnion.of("port", (PiHeader) header1);
+ private final PiData sameAsHeaderUnion1 = PiHeaderUnion.of("port", (PiHeader) header1);
+ private final PiData headerUnion2 = PiHeaderUnion.of("port", (PiHeader) header2);
+
+ private final PiData inValidHeaderUnion1 = PiHeaderUnion.ofInvalid();
+ private final PiData sameAsInvalidHeaderUnion1 = PiHeaderUnion.ofInvalid();
+
+ private final PiData headerStack1 = PiHeaderStack.of(Lists.newArrayList((PiHeader) header1));
+ private final PiData sameAsHeaderStack1 = PiHeaderStack.of(Lists.newArrayList((PiHeader) header1));
+ private final PiData headerStack2 = PiHeaderStack.of(Lists.newArrayList((PiHeader) header2));
+
+ private final PiData headerUnionStack1 = PiHeaderUnionStack.of(Lists.newArrayList(
+ (PiHeaderUnion) headerUnion1));
+ private final PiData sameAsHeaderUnionStack1 = PiHeaderUnionStack.of(Lists.newArrayList(
+ (PiHeaderUnion) headerUnion1));
+ private final PiData headerUnionStack2 = PiHeaderUnionStack.of(Lists.newArrayList(
+ (PiHeaderUnion) headerUnion2));
+
+ private final PiData enumString1 = PiEnumString.of("test");
+ private final PiData sameAsEnumString1 = PiEnumString.of("test");
+ private final PiData enumString2 = PiEnumString.of("test1");
+
+ private final PiData errorString1 = PiErrorString.of("failed");
+ private final PiData sameAsErrorString1 = PiErrorString.of("failed");
+ private final PiData errorString2 = PiErrorString.of("success");
+
+ /**
+ * Checks that the PiData classes is immutable.
+ */
+ @Test
+ public void testImmutability() {
+ assertThatClassIsImmutable(PiBitString.class);
+ assertThatClassIsImmutable(PiBool.class);
+ assertThatClassIsImmutable(PiTuple.class);
+ assertThatClassIsImmutable(PiStruct.class);
+ assertThatClassIsImmutable(PiHeader.class);
+ assertThatClassIsImmutable(PiHeaderStack.class);
+ assertThatClassIsImmutable(PiHeaderUnion.class);
+ assertThatClassIsImmutable(PiHeaderUnionStack.class);
+ assertThatClassIsImmutable(PiEnumString.class);
+ assertThatClassIsImmutable(PiErrorString.class);
+ }
+
+ /**
+ * Checks the PiData type.
+ */
+ @Test
+ public void testPiDataType() {
+ assertEquals(bitString1.type(), PiData.Type.BITSTRING);
+ assertEquals(bool1.type(), PiData.Type.BOOL);
+ assertEquals(tuple1.type(), PiData.Type.TUPLE);
+ assertEquals(struct1.type(), PiData.Type.STRUCT);
+ assertEquals(header1.type(), PiData.Type.HEADER);
+ assertEquals(headerUnion1.type(), PiData.Type.HEADERUNION);
+ assertEquals(headerStack1.type(), PiData.Type.HEADERSTACK);
+ assertEquals(headerUnionStack1.type(), PiData.Type.HEADERUNIONSTACK);
+ assertEquals(enumString1.type(), PiData.Type.ENUMSTRING);
+ assertEquals(errorString1.type(), PiData.Type.ERRORSTRING);
+ }
+
+ /**
+ * Checks the operation of equals(), hashCode() and toString() methods.
+ */
+ @Test
+ public void testEquals() {
+ new EqualsTester()
+ .addEqualityGroup(bitString1, sameAsBitString1)
+ .addEqualityGroup(bitString2)
+ .testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(bool1, sameAsBool1)
+ .addEqualityGroup(bool2)
+ .testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(tuple1, sameAsTuple1)
+ .addEqualityGroup(tuple2)
+ .testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(struct1, sameAsStruct1)
+ .addEqualityGroup(struct2)
+ .testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(header1, sameAsHeader1)
+ .addEqualityGroup(header2)
+ .testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(headerUnion1, sameAsHeaderUnion1)
+ .addEqualityGroup(headerUnion2)
+ .testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(inValidHeaderUnion1, sameAsInvalidHeaderUnion1)
+ .testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(headerStack1, sameAsHeaderStack1)
+ .addEqualityGroup(headerStack2)
+ .testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(headerUnionStack1, sameAsHeaderUnionStack1)
+ .addEqualityGroup(headerUnionStack2)
+ .testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(enumString1, sameAsEnumString1)
+ .addEqualityGroup(enumString2)
+ .testEquals();
+
+ new EqualsTester()
+ .addEqualityGroup(errorString1, sameAsErrorString1)
+ .addEqualityGroup(errorString2)
+ .testEquals();
+ }
+
+}