blob: dc985314f2420dfb05f34d6c8d594813acec5bde [file] [log] [blame]
karthik1977bc5ea1e2023-01-02 19:25:14 +05301/*
2 * Copyright 2023-present Open Networking Foundation
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 */
16package org.onosproject.netflow.impl;
17
18import java.nio.ByteBuffer;
19import java.util.LinkedList;
20import java.util.List;
21import java.util.Objects;
22import java.util.Optional;
23import java.util.function.Function;
24import java.util.function.Predicate;
25import java.util.stream.Collectors;
26import java.util.stream.IntStream;
27
28import com.google.common.base.MoreObjects;
29
30import org.onlab.packet.Deserializer;
31import org.onosproject.netflow.TemplateId;
32import org.onosproject.netflow.FlowTemplateField;
33
34import static com.google.common.base.Preconditions.checkNotNull;
35import static com.google.common.base.Preconditions.checkState;
36
37/**
38 * Template Record defines the structure and interpretation.
39 * of fields in an Options Data Record, including defining the scope
40 * within which the Options Data Record is relevant.
41 * Ref: https://www.ietf.org/rfc/rfc3954.txt
42 */
43public final class DataTemplateRecord extends TemplateRecord {
44
45 /*
46 0 1 2 3
47 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
48 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49 | Template ID 256 | Field Count |
50 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
51 | Field Type 1 | Field Length 1 |
52 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53 | Field Type 2 | Field Length 2 |
54 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55 */
56
57 private TemplateId templateId;
58
59 private int filedCount;
60
61 private List<FlowTemplateField> fields;
62
63 private DataTemplateRecord(Builder builder) {
64 this.templateId = builder.templateId;
65 this.filedCount = builder.filedCount;
66 this.fields = builder.fields;
67 }
68
69 /**
70 * Returns template record's template id.
71 * Template Records is given a unique Template ID.
72 * This uniqueness is local to the Observation
73 * Domain that generated the Template ID. Template IDs 0-255 are
74 * reserved for Template FlowSets, Options FlowSets, and other
75 * reserved FlowSets yet to be created.
76 *
77 * @return list of flowsets
78 */
79 @Override
80 public TemplateId getTemplateId() {
81 return templateId;
82 }
83
84 /**
85 * Returns number of fields in this Template Record.
86 *
87 * @return field count
88 */
89 public int getFiledCount() {
90 return filedCount;
91 }
92
93 /**
94 * Returns list of flow template fields.
95 *
96 * @return list of flow template fields
97 */
98 public List<FlowTemplateField> getFields() {
99 return fields;
100 }
101
102 public int getValueLength() {
103 Optional.ofNullable(fields)
104 .orElseThrow(() -> new IllegalStateException("Invalid fields"));
105 return fields.stream()
106 .filter(Objects::nonNull)
107 .map(FlowTemplateField::getLength)
108 .collect(Collectors.summingInt(Integer::intValue));
109 }
110
111 @Override
112 public String toString() {
113 return MoreObjects.toStringHelper(getClass())
114 .add("templateId", templateId)
115 .add("filedCount", filedCount)
116 .add("fields", fields)
117 .toString();
118 }
119
120 /**
121 * Data deserializer function for data template record.
122 *
123 * @return data deserializer function
124 */
125 public static Deserializer<DataTemplateRecord> deserializer() {
126 return (data, offset, length) -> {
127 Predicate<ByteBuffer> isValidBuffer = b -> b.remaining() < FlowSet.FIELD_LENTH;
128 Function<ByteBuffer, FlowTemplateField> parse = (b)
129 -> {
130 if (isValidBuffer.test(b)) {
131 throw new IllegalStateException("Invalid buffersize");
132 }
133 return new FlowTemplateField.Builder()
134 .flowField(b.getShort())
135 .length(b.getShort())
136 .build();
137 };
138
139 Builder builder = new Builder();
140 ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
141 if (isValidBuffer.test(bb)) {
142 throw new IllegalStateException("Invalid buffersize");
143 }
144 builder.templateId(bb.getShort())
145 .filedCount(bb.getShort());
146 IntStream.rangeClosed(1, builder.filedCount).forEach(i -> builder.templateField(parse.apply(bb)));
147 return builder.build();
148 };
149 }
150
151 /**
152 * Builder for data template record.
153 */
154 private static class Builder {
155
156 private TemplateId templateId;
157
158 private int filedCount;
159
160 private List<FlowTemplateField> fields = new LinkedList<>();
161
162 /**
163 * Setter for template record's template id.
164 *
165 * @param templateId template record's template id.
166 * @return this class builder.
167 */
168 public Builder templateId(int templateId) {
169 this.templateId = new TemplateId((templateId));
170 return this;
171 }
172
173 /**
174 * Setter for number of fields in this Template Record.
175 *
176 * @param filedCount number of fields in this Template Record.
177 * @return this class builder.
178 */
179 public Builder filedCount(int filedCount) {
180 this.filedCount = filedCount;
181 return this;
182 }
183
184 /**
185 * Setter for list of flow template fields.
186 *
187 * @param fields list of flow template fields.
188 * @return this class builder.
189 */
190 public Builder templateFields(List<FlowTemplateField> fields) {
191 this.fields = fields;
192 return this;
193 }
194
195 /**
196 * Setter for flow template fields.
197 *
198 * @param field flow template fields.
199 * @return this class builder.
200 */
201 public Builder templateField(FlowTemplateField field) {
202 this.fields.add(field);
203 return this;
204 }
205
206 /**
207 * Checks arguments for data template record.
208 */
209 private void checkArguments() {
210 checkState(filedCount != 0, "Invalid template filed count.");
211 checkNotNull(templateId, "Template Id cannot be null.");
212
213 }
214
215 /**
216 * Builds data template record.
217 *
218 * @return data template record.
219 */
220 public DataTemplateRecord build() {
221 checkArguments();
222 return new DataTemplateRecord(this);
223 }
224
225 }
226
227}