blob: a37a13f84fe18ae09a5cc0c9e57d6e1c2ed8f3dd [file] [log] [blame]
Andrea Campanella432f7182017-07-14 18:43:27 +02001/*
2 * Copyright 2017-present Open Networking Laboratory
3 *
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;
24
25import java.util.Collection;
26import java.util.HashMap;
27import java.util.Map;
28import java.util.Set;
29
30import static com.google.common.base.Preconditions.checkNotNull;
31
32/**
33 * Instance of a packet I/O operation, and its metadatas for a protocol-independent pipeline.
34 */
35@Beta
36public final class PiPacketOperation {
37
38 enum Type {
39 /**
40 * Represents a packet out.
41 */
42 PACKET_OUT,
43
44 /**
45 * Represents a packet in.
46 */
47 PACKET_IN,
48 }
49
50 private final ImmutableByteSequence data;
51 private final Set<PiPacketMetadata> packetMetadatas;
52 private final PiPacketOperation.Type type;
53
54 /**
55 * Creates a new packet I/O operation for the given data, metadatas and operation type.
56 *
57 * @param data the packet raw data
58 * @param packetMetadatas set of packet metadata
59 * @param type type of this packet operation
60 */
61 private PiPacketOperation(ImmutableByteSequence data, Collection<PiPacketMetadata> packetMetadatas, Type type) {
62 this.data = data;
63 this.packetMetadatas = ImmutableSet.copyOf(packetMetadatas);
64 this.type = type;
65 }
66
67 /**
68 * Return the type of this packet.
69 *
70 * @return packet type
71 */
72 public Type type() {
73 return type;
74 }
75
76 /**
77 * Returns the data of this packet.
78 *
79 * @return packet data
80 */
81 public ImmutableByteSequence data() {
82 return data;
83 }
84
85 /**
86 * Returns all metadatas of this packet.
87 * Returns an empty collection if the packet doesn't have any metadata.
88 *
89 * @return collection of metadatas
90 */
91 public Collection<PiPacketMetadata> metadatas() {
92 return packetMetadatas;
93 }
94
95 @Override
96 public boolean equals(Object o) {
97 if (this == o) {
98 return true;
99 }
100 if (o == null || getClass() != o.getClass()) {
101 return false;
102 }
103 PiPacketOperation that = (PiPacketOperation) o;
104 return Objects.equal(packetMetadatas, that.packetMetadatas) &&
105 Objects.equal(data, that.data()) &&
106 Objects.equal(type, that.type());
107 }
108
109 @Override
110 public int hashCode() {
111 return Objects.hashCode(data, packetMetadatas, type);
112 }
113
114 @Override
115 public String toString() {
116 return MoreObjects.toStringHelper(this)
117 .addValue(packetMetadatas)
118 .addValue(type.toString())
119 .toString();
120 }
121
122 /**
123 * Returns an packet builder.
124 *
125 * @return a new builder
126 */
127 public static Builder builder() {
128 return new Builder();
129 }
130
131 /**
132 * Builder of protocol-independent packets.
133 */
134 public static final class Builder {
135
136 private Map<PiPacketMetadataId, PiPacketMetadata> packetMetadatas = new HashMap<>();
137 private PiPacketOperation.Type type;
138 private ImmutableByteSequence data;
139
140 private Builder() {
141 // hides constructor.
142 }
143
144 /**
145 * Adds the raw packet data.
146 *
147 * @param data the packet raw data
148 * @return this
149 */
150 public Builder withData(ImmutableByteSequence data) {
151 checkNotNull(data);
152 this.data = data;
153 return this;
154 }
155
156 /**
157 * Adds a metadata.
158 * Only one metadata is allowed for a given metadata id.
159 * If a metadata with same id already exists it will be replaced by the given one.
160 *
161 * @param metadata packet metadata
162 * @return this
163 */
164 public Builder withMetadata(PiPacketMetadata metadata) {
165 checkNotNull(metadata);
166 packetMetadatas.put(metadata.id(), metadata);
167
168 return this;
169 }
170
171 /**
172 * Adds many packet metadatas.
173 *
174 * @param metadatas collection of metadata
175 * @return this
176 */
177 public Builder withMetadatas(Collection<PiPacketMetadata> metadatas) {
178 checkNotNull(metadatas);
179 metadatas.forEach(this::withMetadata);
180 return this;
181 }
182
183 /**
184 * Sets the type of this packet.
185 *
186 * @param type type of the packet
187 * @return this
188 */
189 public Builder withType(Type type) {
190 this.type = type;
191 return this;
192 }
193
194 /**
195 * Returns a new packet instance.
196 *
197 * @return packet
198 */
199 public PiPacketOperation build() {
200 checkNotNull(data);
201 checkNotNull(packetMetadatas);
202 checkNotNull(type);
203 return new PiPacketOperation(data, packetMetadatas.values(), type);
204 }
205 }
206}