blob: 74c68d6771e3f0dc7e67c738bc4bc477fd380e0e [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 Cascone87892e22017-11-13 16:01:29 -080024import org.onosproject.net.DeviceId;
25import org.onosproject.net.pi.model.PiControlMetadataId;
26import org.onosproject.net.pi.model.PiPacketOperationType;
Andrea Campanella432f7182017-07-14 18:43:27 +020027
28import java.util.Collection;
29import java.util.HashMap;
30import java.util.Map;
31import java.util.Set;
32
33import static com.google.common.base.Preconditions.checkNotNull;
34
35/**
Carmelo Cascone87892e22017-11-13 16:01:29 -080036 * Instance of a packet I/O operation, and its control metadatas, for a protocol-independent pipeline.
Andrea Campanella432f7182017-07-14 18:43:27 +020037 */
38@Beta
39public final class PiPacketOperation {
40
Carmelo Cascone87892e22017-11-13 16:01:29 -080041 private final DeviceId deviceId;
Andrea Campanella432f7182017-07-14 18:43:27 +020042 private final ImmutableByteSequence data;
Carmelo Cascone87892e22017-11-13 16:01:29 -080043 private final Set<PiControlMetadata> packetMetadatas;
44 private final PiPacketOperationType type;
Andrea Campanella432f7182017-07-14 18:43:27 +020045
46 /**
Carmelo Cascone87892e22017-11-13 16:01:29 -080047 * Creates a new packet I/O operation for the given device ID, data, control metadatas and operation type.
Andrea Campanella432f7182017-07-14 18:43:27 +020048 *
Carmelo Cascone87892e22017-11-13 16:01:29 -080049 * @param deviceId device ID
Andrea Campanella432f7182017-07-14 18:43:27 +020050 * @param data the packet raw data
Carmelo Cascone87892e22017-11-13 16:01:29 -080051 * @param packetMetadatas collection of control metadata
Andrea Campanella432f7182017-07-14 18:43:27 +020052 * @param type type of this packet operation
53 */
Carmelo Cascone87892e22017-11-13 16:01:29 -080054 private PiPacketOperation(DeviceId deviceId, ImmutableByteSequence data,
55 Collection<PiControlMetadata> packetMetadatas,
56 PiPacketOperationType type) {
57 this.deviceId = deviceId;
Andrea Campanella432f7182017-07-14 18:43:27 +020058 this.data = data;
59 this.packetMetadatas = ImmutableSet.copyOf(packetMetadatas);
60 this.type = type;
61 }
62
63 /**
Carmelo Cascone87892e22017-11-13 16:01:29 -080064 * Returns the device ID of this packet operation.
65 *
66 * @return device ID
67 */
68 public DeviceId deviceId() {
69 return deviceId;
70 }
71
72 /**
Andrea Campanella432f7182017-07-14 18:43:27 +020073 * Return the type of this packet.
74 *
75 * @return packet type
76 */
Carmelo Cascone87892e22017-11-13 16:01:29 -080077 public PiPacketOperationType type() {
Andrea Campanella432f7182017-07-14 18:43:27 +020078 return type;
79 }
80
81 /**
82 * Returns the data of this packet.
83 *
84 * @return packet data
85 */
86 public ImmutableByteSequence data() {
87 return data;
88 }
89
90 /**
Carmelo Cascone87892e22017-11-13 16:01:29 -080091 * Returns all metadatas of this packet. Returns an empty collection if the packet doesn't have any metadata.
Andrea Campanella432f7182017-07-14 18:43:27 +020092 *
93 * @return collection of metadatas
94 */
Carmelo Cascone87892e22017-11-13 16:01:29 -080095 public Collection<PiControlMetadata> metadatas() {
Andrea Campanella432f7182017-07-14 18:43:27 +020096 return packetMetadatas;
97 }
98
99 @Override
100 public boolean equals(Object o) {
101 if (this == o) {
102 return true;
103 }
104 if (o == null || getClass() != o.getClass()) {
105 return false;
106 }
107 PiPacketOperation that = (PiPacketOperation) o;
108 return Objects.equal(packetMetadatas, that.packetMetadatas) &&
Carmelo Cascone87892e22017-11-13 16:01:29 -0800109 Objects.equal(deviceId, that.deviceId) &&
Andrea Campanella432f7182017-07-14 18:43:27 +0200110 Objects.equal(data, that.data()) &&
111 Objects.equal(type, that.type());
112 }
113
114 @Override
115 public int hashCode() {
Carmelo Cascone87892e22017-11-13 16:01:29 -0800116 return Objects.hashCode(deviceId, data, packetMetadatas, type);
Andrea Campanella432f7182017-07-14 18:43:27 +0200117 }
118
119 @Override
120 public String toString() {
121 return MoreObjects.toStringHelper(this)
Carmelo Cascone87892e22017-11-13 16:01:29 -0800122 .add("deviceId", deviceId)
Andrea Campanella432f7182017-07-14 18:43:27 +0200123 .addValue(type.toString())
Carmelo Cascone87892e22017-11-13 16:01:29 -0800124 .addValue(packetMetadatas)
Andrea Campanella432f7182017-07-14 18:43:27 +0200125 .toString();
126 }
127
128 /**
Carmelo Cascone87892e22017-11-13 16:01:29 -0800129 * Returns a new builder of packet operations.
Andrea Campanella432f7182017-07-14 18:43:27 +0200130 *
131 * @return a new builder
132 */
133 public static Builder builder() {
134 return new Builder();
135 }
136
137 /**
Carmelo Cascone87892e22017-11-13 16:01:29 -0800138 * Builder of packet operations.
Andrea Campanella432f7182017-07-14 18:43:27 +0200139 */
140 public static final class Builder {
141
Carmelo Cascone87892e22017-11-13 16:01:29 -0800142 private DeviceId deviceId;
143 private Map<PiControlMetadataId, PiControlMetadata> packetMetadatas = new HashMap<>();
144 private PiPacketOperationType type;
Andrea Campanella432f7182017-07-14 18:43:27 +0200145 private ImmutableByteSequence data;
146
147 private Builder() {
148 // hides constructor.
149 }
150
151 /**
Carmelo Cascone87892e22017-11-13 16:01:29 -0800152 * Sets the device ID.
153 *
154 * @param deviceId device ID
155 * @return this
156 */
157 public Builder forDevice(DeviceId deviceId) {
158 checkNotNull(deviceId);
159 this.deviceId = deviceId;
160 return this;
161 }
162
163 /**
164 * Sets the raw packet data.
Andrea Campanella432f7182017-07-14 18:43:27 +0200165 *
166 * @param data the packet raw data
167 * @return this
168 */
169 public Builder withData(ImmutableByteSequence data) {
170 checkNotNull(data);
171 this.data = data;
172 return this;
173 }
174
175 /**
Carmelo Cascone87892e22017-11-13 16:01:29 -0800176 * Adds a control metadata. Only one metadata is allowed for a given metadata id. If a metadata with same id
177 * already exists it will be replaced by the given one.
Andrea Campanella432f7182017-07-14 18:43:27 +0200178 *
179 * @param metadata packet metadata
180 * @return this
181 */
Carmelo Cascone87892e22017-11-13 16:01:29 -0800182 public Builder withMetadata(PiControlMetadata metadata) {
Andrea Campanella432f7182017-07-14 18:43:27 +0200183 checkNotNull(metadata);
184 packetMetadatas.put(metadata.id(), metadata);
185
186 return this;
187 }
188
189 /**
190 * Adds many packet metadatas.
191 *
192 * @param metadatas collection of metadata
193 * @return this
194 */
Carmelo Cascone87892e22017-11-13 16:01:29 -0800195 public Builder withMetadatas(Collection<PiControlMetadata> metadatas) {
Andrea Campanella432f7182017-07-14 18:43:27 +0200196 checkNotNull(metadatas);
197 metadatas.forEach(this::withMetadata);
198 return this;
199 }
200
201 /**
202 * Sets the type of this packet.
203 *
204 * @param type type of the packet
205 * @return this
206 */
Carmelo Cascone87892e22017-11-13 16:01:29 -0800207 public Builder withType(PiPacketOperationType type) {
Andrea Campanella432f7182017-07-14 18:43:27 +0200208 this.type = type;
209 return this;
210 }
211
212 /**
Carmelo Cascone87892e22017-11-13 16:01:29 -0800213 * Builds a new instance of a packet operation.
Andrea Campanella432f7182017-07-14 18:43:27 +0200214 *
Carmelo Cascone87892e22017-11-13 16:01:29 -0800215 * @return packet operation
Andrea Campanella432f7182017-07-14 18:43:27 +0200216 */
217 public PiPacketOperation build() {
Carmelo Cascone87892e22017-11-13 16:01:29 -0800218 checkNotNull(deviceId);
Andrea Campanella432f7182017-07-14 18:43:27 +0200219 checkNotNull(data);
220 checkNotNull(packetMetadatas);
221 checkNotNull(type);
Carmelo Cascone87892e22017-11-13 16:01:29 -0800222 return new PiPacketOperation(deviceId, data, packetMetadatas.values(), type);
Andrea Campanella432f7182017-07-14 18:43:27 +0200223 }
224 }
225}