blob: 5811b971a9bd19174ba6853ee256fd7bb9c91f7e [file] [log] [blame]
Andrea Campanella432f7182017-07-14 18:43:27 +02001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Andrea Campanella432f7182017-07-14 18:43:27 +02003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.net.pi.runtime;
18
19import com.google.common.annotations.Beta;
20import com.google.common.base.MoreObjects;
21import com.google.common.base.Objects;
22import com.google.common.collect.ImmutableSet;
23import org.onlab.util.ImmutableByteSequence;
Carmelo Cascone4c289b72019-01-22 15:30:45 -080024import org.onosproject.net.pi.model.PiPacketMetadataId;
Carmelo Cascone87892e22017-11-13 16:01:29 -080025import org.onosproject.net.pi.model.PiPacketOperationType;
Andrea Campanella432f7182017-07-14 18:43:27 +020026
27import java.util.Collection;
28import java.util.HashMap;
29import java.util.Map;
30import java.util.Set;
31
32import static com.google.common.base.Preconditions.checkNotNull;
33
34/**
Carmelo Cascone4c289b72019-01-22 15:30:45 -080035 * Instance of a packet I/O operation that includes the packet body (frame) and
36 * its metadata, for a protocol-independent pipeline.
Andrea Campanella432f7182017-07-14 18:43:27 +020037 */
38@Beta
39public final class PiPacketOperation {
40
Carmelo Cascone4c289b72019-01-22 15:30:45 -080041 private final ImmutableByteSequence frame;
42 private final Set<PiPacketMetadata> packetMetadatas;
Carmelo Cascone87892e22017-11-13 16:01:29 -080043 private final PiPacketOperationType type;
Andrea Campanella432f7182017-07-14 18:43:27 +020044
45 /**
Carmelo Cascone4c289b72019-01-22 15:30:45 -080046 * Creates a new packet I/O operation for the given frame, packet metadata
47 * and operation type.
Andrea Campanella432f7182017-07-14 18:43:27 +020048 *
Carmelo Cascone4c289b72019-01-22 15:30:45 -080049 * @param frame the packet raw data
50 * @param metadatas collection of packet metadata
51 * @param type type of this packet operation
Andrea Campanella432f7182017-07-14 18:43:27 +020052 */
Carmelo Cascone4c289b72019-01-22 15:30:45 -080053 private PiPacketOperation(ImmutableByteSequence frame,
54 Collection<PiPacketMetadata> metadatas,
Carmelo Cascone87892e22017-11-13 16:01:29 -080055 PiPacketOperationType type) {
Carmelo Cascone4c289b72019-01-22 15:30:45 -080056 this.frame = frame;
57 this.packetMetadatas = ImmutableSet.copyOf(metadatas);
Andrea Campanella432f7182017-07-14 18:43:27 +020058 this.type = type;
59 }
60
61 /**
62 * Return the type of this packet.
63 *
64 * @return packet type
65 */
Carmelo Cascone87892e22017-11-13 16:01:29 -080066 public PiPacketOperationType type() {
Andrea Campanella432f7182017-07-14 18:43:27 +020067 return type;
68 }
69
70 /**
71 * Returns the data of this packet.
72 *
73 * @return packet data
74 */
75 public ImmutableByteSequence data() {
Carmelo Cascone4c289b72019-01-22 15:30:45 -080076 return frame;
Andrea Campanella432f7182017-07-14 18:43:27 +020077 }
78
79 /**
Carmelo Cascone4c289b72019-01-22 15:30:45 -080080 * Returns all metadatas of this packet. Returns an empty collection if the
81 * packet doesn't have any metadata.
Andrea Campanella432f7182017-07-14 18:43:27 +020082 *
83 * @return collection of metadatas
84 */
Carmelo Cascone4c289b72019-01-22 15:30:45 -080085 public Collection<PiPacketMetadata> metadatas() {
Andrea Campanella432f7182017-07-14 18:43:27 +020086 return packetMetadatas;
87 }
88
89 @Override
90 public boolean equals(Object o) {
91 if (this == o) {
92 return true;
93 }
94 if (o == null || getClass() != o.getClass()) {
95 return false;
96 }
97 PiPacketOperation that = (PiPacketOperation) o;
98 return Objects.equal(packetMetadatas, that.packetMetadatas) &&
Carmelo Cascone4c289b72019-01-22 15:30:45 -080099 Objects.equal(frame, that.data()) &&
Andrea Campanella432f7182017-07-14 18:43:27 +0200100 Objects.equal(type, that.type());
101 }
102
103 @Override
104 public int hashCode() {
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800105 return Objects.hashCode(frame, packetMetadatas, type);
Andrea Campanella432f7182017-07-14 18:43:27 +0200106 }
107
108 @Override
109 public String toString() {
110 return MoreObjects.toStringHelper(this)
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800111 .add("type", type)
112 .add("metadata", packetMetadatas)
113 .add("frame", frame)
Andrea Campanella432f7182017-07-14 18:43:27 +0200114 .toString();
115 }
116
117 /**
Carmelo Cascone87892e22017-11-13 16:01:29 -0800118 * Returns a new builder of packet operations.
Andrea Campanella432f7182017-07-14 18:43:27 +0200119 *
120 * @return a new builder
121 */
122 public static Builder builder() {
123 return new Builder();
124 }
125
126 /**
Carmelo Cascone87892e22017-11-13 16:01:29 -0800127 * Builder of packet operations.
Andrea Campanella432f7182017-07-14 18:43:27 +0200128 */
129 public static final class Builder {
130
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800131 private Map<PiPacketMetadataId, PiPacketMetadata> packetMetadatas = new HashMap<>();
Carmelo Cascone87892e22017-11-13 16:01:29 -0800132 private PiPacketOperationType type;
Andrea Campanella432f7182017-07-14 18:43:27 +0200133 private ImmutableByteSequence data;
134
135 private Builder() {
136 // hides constructor.
137 }
138
139 /**
Carmelo Cascone87892e22017-11-13 16:01:29 -0800140 * Sets the raw packet data.
Andrea Campanella432f7182017-07-14 18:43:27 +0200141 *
142 * @param data the packet raw data
143 * @return this
144 */
145 public Builder withData(ImmutableByteSequence data) {
146 checkNotNull(data);
147 this.data = data;
148 return this;
149 }
150
151 /**
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800152 * Adds a packet metadata. Only one metadata is allowed for a given
153 * metadata id. If a metadata with same id already exists it will be
154 * replaced by the given one.
Andrea Campanella432f7182017-07-14 18:43:27 +0200155 *
156 * @param metadata packet metadata
157 * @return this
158 */
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800159 public Builder withMetadata(PiPacketMetadata metadata) {
Andrea Campanella432f7182017-07-14 18:43:27 +0200160 checkNotNull(metadata);
161 packetMetadatas.put(metadata.id(), metadata);
162
163 return this;
164 }
165
166 /**
167 * Adds many packet metadatas.
168 *
169 * @param metadatas collection of metadata
170 * @return this
171 */
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800172 public Builder withMetadatas(Collection<PiPacketMetadata> metadatas) {
Andrea Campanella432f7182017-07-14 18:43:27 +0200173 checkNotNull(metadatas);
174 metadatas.forEach(this::withMetadata);
175 return this;
176 }
177
178 /**
179 * Sets the type of this packet.
180 *
181 * @param type type of the packet
182 * @return this
183 */
Carmelo Cascone87892e22017-11-13 16:01:29 -0800184 public Builder withType(PiPacketOperationType type) {
Andrea Campanella432f7182017-07-14 18:43:27 +0200185 this.type = type;
186 return this;
187 }
188
189 /**
Carmelo Cascone87892e22017-11-13 16:01:29 -0800190 * Builds a new instance of a packet operation.
Andrea Campanella432f7182017-07-14 18:43:27 +0200191 *
Carmelo Cascone87892e22017-11-13 16:01:29 -0800192 * @return packet operation
Andrea Campanella432f7182017-07-14 18:43:27 +0200193 */
194 public PiPacketOperation build() {
195 checkNotNull(data);
196 checkNotNull(packetMetadatas);
197 checkNotNull(type);
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800198 return new PiPacketOperation(data, packetMetadatas.values(), type);
Andrea Campanella432f7182017-07-14 18:43:27 +0200199 }
200 }
201}