blob: 1e0b35fd442017db2f5ead5290291238eb246cae [file] [log] [blame]
Ray Milkeyb82c42b2015-06-30 09:42:20 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Ray Milkeyb82c42b2015-06-30 09:42:20 -07003 *
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.codec.impl;
17
18import java.time.Duration;
19import java.util.ArrayList;
20import java.util.stream.IntStream;
21
22import org.onlab.util.Bandwidth;
23import org.onosproject.net.DeviceId;
Ray Milkeyb82c42b2015-06-30 09:42:20 -070024import org.onosproject.net.Link;
25import org.onosproject.net.intent.Constraint;
26import org.onosproject.net.intent.constraint.AnnotationConstraint;
27import org.onosproject.net.intent.constraint.AsymmetricPathConstraint;
28import org.onosproject.net.intent.constraint.BandwidthConstraint;
Thomas Szyrkowiec7c5f9c92017-07-12 12:42:02 +020029import org.onosproject.net.intent.constraint.DomainConstraint;
Ray Milkeyb82c42b2015-06-30 09:42:20 -070030import org.onosproject.net.intent.constraint.LatencyConstraint;
31import org.onosproject.net.intent.constraint.LinkTypeConstraint;
David Glantz05c6f432020-03-19 14:56:12 -050032import org.onosproject.net.intent.constraint.MeteredConstraint;
Antonio Marsico4f68ec92017-03-09 11:16:32 +010033import org.onosproject.net.intent.constraint.NonDisruptiveConstraint;
Ray Milkeyb82c42b2015-06-30 09:42:20 -070034import org.onosproject.net.intent.constraint.ObstacleConstraint;
David Glantz05c6f432020-03-19 14:56:12 -050035import org.onosproject.net.intent.constraint.TierConstraint;
Ray Milkeyb82c42b2015-06-30 09:42:20 -070036import org.onosproject.net.intent.constraint.WaypointConstraint;
Ray Milkeyb82c42b2015-06-30 09:42:20 -070037
38import com.fasterxml.jackson.databind.JsonNode;
39import com.fasterxml.jackson.databind.node.ObjectNode;
40
41import static org.onlab.util.Tools.nullIsIllegal;
Antonio Marsico4f68ec92017-03-09 11:16:32 +010042import static org.onosproject.net.intent.constraint.NonDisruptiveConstraint.nonDisruptive;
Ray Milkeyb82c42b2015-06-30 09:42:20 -070043
44/**
45 * Constraint JSON decoder.
46 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070047public final class DecodeConstraintCodecHelper {
Ray Milkeyb82c42b2015-06-30 09:42:20 -070048 private final ObjectNode json;
49
50 /**
51 * Constructs a constraint decoder.
52 *
53 * @param json object node to decode
54 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070055 public DecodeConstraintCodecHelper(ObjectNode json) {
Ray Milkeyb82c42b2015-06-30 09:42:20 -070056 this.json = json;
57 }
58
59 /**
60 * Decodes a link type constraint.
61 *
62 * @return link type constraint object.
63 */
64 private Constraint decodeLinkTypeConstraint() {
65 boolean inclusive = nullIsIllegal(json.get(ConstraintCodec.INCLUSIVE),
66 ConstraintCodec.INCLUSIVE + ConstraintCodec.MISSING_MEMBER_MESSAGE).asBoolean();
67
68 JsonNode types = nullIsIllegal(json.get(ConstraintCodec.TYPES),
69 ConstraintCodec.TYPES + ConstraintCodec.MISSING_MEMBER_MESSAGE);
70 if (types.size() < 1) {
71 throw new IllegalArgumentException(
72 "types array in link constraint must have at least one value");
73 }
74
75 ArrayList<Link.Type> typesEntries = new ArrayList<>(types.size());
76 IntStream.range(0, types.size())
77 .forEach(index ->
78 typesEntries.add(Link.Type.valueOf(types.get(index).asText())));
79
80 return new LinkTypeConstraint(inclusive,
81 typesEntries.toArray(new Link.Type[types.size()]));
82 }
83
84 /**
85 * Decodes an annotation constraint.
86 *
87 * @return annotation constraint object.
88 */
89 private Constraint decodeAnnotationConstraint() {
90 String key = nullIsIllegal(json.get(ConstraintCodec.KEY),
91 ConstraintCodec.KEY + ConstraintCodec.MISSING_MEMBER_MESSAGE)
92 .asText();
93 double threshold = nullIsIllegal(json.get(ConstraintCodec.THRESHOLD),
94 ConstraintCodec.THRESHOLD + ConstraintCodec.MISSING_MEMBER_MESSAGE)
95 .asDouble();
96
97 return new AnnotationConstraint(key, threshold);
98 }
99
100 /**
Ray Milkeyb82c42b2015-06-30 09:42:20 -0700101 * Decodes a latency constraint.
102 *
103 * @return latency constraint object.
104 */
105 private Constraint decodeLatencyConstraint() {
106 long latencyMillis = nullIsIllegal(json.get(ConstraintCodec.LATENCY_MILLIS),
107 ConstraintCodec.LATENCY_MILLIS + ConstraintCodec.MISSING_MEMBER_MESSAGE)
108 .asLong();
109
110 return new LatencyConstraint(Duration.ofMillis(latencyMillis));
111 }
112
113 /**
114 * Decodes an obstacle constraint.
115 *
116 * @return obstacle constraint object.
117 */
118 private Constraint decodeObstacleConstraint() {
119 JsonNode obstacles = nullIsIllegal(json.get(ConstraintCodec.OBSTACLES),
120 ConstraintCodec.OBSTACLES + ConstraintCodec.MISSING_MEMBER_MESSAGE);
121 if (obstacles.size() < 1) {
122 throw new IllegalArgumentException(
123 "obstacles array in obstacles constraint must have at least one value");
124 }
125
126 ArrayList<DeviceId> obstacleEntries = new ArrayList<>(obstacles.size());
127 IntStream.range(0, obstacles.size())
128 .forEach(index ->
129 obstacleEntries.add(DeviceId.deviceId(obstacles.get(index).asText())));
130
131 return new ObstacleConstraint(
132 obstacleEntries.toArray(new DeviceId[obstacles.size()]));
133 }
134
135 /**
136 * Decodes a waypoint constraint.
137 *
138 * @return waypoint constraint object.
139 */
140 private Constraint decodeWaypointConstraint() {
141 JsonNode waypoints = nullIsIllegal(json.get(ConstraintCodec.WAYPOINTS),
142 ConstraintCodec.WAYPOINTS + ConstraintCodec.MISSING_MEMBER_MESSAGE);
143 if (waypoints.size() < 1) {
144 throw new IllegalArgumentException(
145 "obstacles array in obstacles constraint must have at least one value");
146 }
147
148 ArrayList<DeviceId> waypointEntries = new ArrayList<>(waypoints.size());
149 IntStream.range(0, waypoints.size())
150 .forEach(index ->
151 waypointEntries.add(DeviceId.deviceId(waypoints.get(index).asText())));
152
153 return new WaypointConstraint(
154 waypointEntries.toArray(new DeviceId[waypoints.size()]));
155 }
156
157 /**
158 * Decodes an asymmetric path constraint.
159 *
160 * @return asymmetric path constraint object.
161 */
162 private Constraint decodeAsymmetricPathConstraint() {
163 return new AsymmetricPathConstraint();
164 }
165
166 /**
Thomas Szyrkowiec7c5f9c92017-07-12 12:42:02 +0200167 * Decodes a domain constraint.
168 *
169 * @return domain constraint object.
170 */
171 private Constraint decodeDomainConstraint() {
172 return DomainConstraint.domain();
173 }
174
175
176 /**
Ray Milkeyb82c42b2015-06-30 09:42:20 -0700177 * Decodes a bandwidth constraint.
178 *
179 * @return bandwidth constraint object.
180 */
181 private Constraint decodeBandwidthConstraint() {
182 double bandwidth = nullIsIllegal(json.get(ConstraintCodec.BANDWIDTH),
183 ConstraintCodec.BANDWIDTH + ConstraintCodec.MISSING_MEMBER_MESSAGE)
184 .asDouble();
185
Sho SHIMIZUa88db492015-11-23 13:21:04 -0800186 return new BandwidthConstraint(Bandwidth.bps(bandwidth));
Ray Milkeyb82c42b2015-06-30 09:42:20 -0700187 }
188
189 /**
Antonio Marsico4f68ec92017-03-09 11:16:32 +0100190 * Decodes a non-disruptive reallocation constraint.
191 *
192 * @return non-disruptive reallocation constraint object.
193 */
194 private Constraint decodeNonDisruptiveConstraint() {
195 return nonDisruptive();
196 }
197
David Glantz05c6f432020-03-19 14:56:12 -0500198 private Constraint decodeMeteredConstraint() {
199 boolean metered = nullIsIllegal(json.get(ConstraintCodec.METERED),
200 ConstraintCodec.METERED + ConstraintCodec.MISSING_MEMBER_MESSAGE).asBoolean();
201 return new MeteredConstraint(metered);
202 }
203
204 /**
205 * Decodes a link type constraint.
206 *
207 * @return link type constraint object.
208 */
209 private Constraint decodeTierConstraint() {
210 boolean inclusive = nullIsIllegal(json.get(ConstraintCodec.INCLUSIVE),
211 ConstraintCodec.INCLUSIVE + ConstraintCodec.MISSING_MEMBER_MESSAGE).asBoolean();
212
213 TierConstraint.CostType costType = TierConstraint.CostType.valueOf(nullIsIllegal(
214 json.get(ConstraintCodec.COST_TYPE), ConstraintCodec.COST_TYPE + ConstraintCodec.MISSING_MEMBER_MESSAGE
215 ).asText());
216
217 JsonNode tiers = nullIsIllegal(json.get(ConstraintCodec.TIERS),
218 ConstraintCodec.TIERS + ConstraintCodec.MISSING_MEMBER_MESSAGE);
219 if (tiers.size() < 1) {
220 throw new IllegalArgumentException(
221 ConstraintCodec.TIERS + " array in tier constraint must have at least one value");
222 }
223
224 ArrayList<Integer> tierEntries = new ArrayList<>(tiers.size());
225 IntStream.range(0, tiers.size())
226 .forEach(index ->
227 tierEntries.add(new Integer(tiers.get(index).asText())));
228
229 return new TierConstraint(inclusive, costType,
230 tierEntries.toArray(new Integer[tiers.size()]));
231 }
232
Antonio Marsico4f68ec92017-03-09 11:16:32 +0100233 /**
Ray Milkeyb82c42b2015-06-30 09:42:20 -0700234 * Decodes the given constraint.
235 *
236 * @return constraint object.
237 */
238 public Constraint decode() {
239 final String type = nullIsIllegal(json.get(ConstraintCodec.TYPE),
240 ConstraintCodec.TYPE + ConstraintCodec.MISSING_MEMBER_MESSAGE)
241 .asText();
242
243 if (type.equals(BandwidthConstraint.class.getSimpleName())) {
244 return decodeBandwidthConstraint();
Ray Milkeyb82c42b2015-06-30 09:42:20 -0700245 } else if (type.equals(LinkTypeConstraint.class.getSimpleName())) {
246 return decodeLinkTypeConstraint();
247 } else if (type.equals(AnnotationConstraint.class.getSimpleName())) {
248 return decodeAnnotationConstraint();
249 } else if (type.equals(LatencyConstraint.class.getSimpleName())) {
250 return decodeLatencyConstraint();
251 } else if (type.equals(ObstacleConstraint.class.getSimpleName())) {
252 return decodeObstacleConstraint();
253 } else if (type.equals(WaypointConstraint.class.getSimpleName())) {
254 return decodeWaypointConstraint();
255 } else if (type.equals(AsymmetricPathConstraint.class.getSimpleName())) {
256 return decodeAsymmetricPathConstraint();
Thomas Szyrkowiec7c5f9c92017-07-12 12:42:02 +0200257 } else if (type.equals(DomainConstraint.class.getSimpleName())) {
258 return decodeDomainConstraint();
Antonio Marsico4f68ec92017-03-09 11:16:32 +0100259 } else if (type.equals(NonDisruptiveConstraint.class.getSimpleName())) {
260 return decodeNonDisruptiveConstraint();
David Glantz05c6f432020-03-19 14:56:12 -0500261 } else if (type.equals(MeteredConstraint.class.getSimpleName())) {
262 return decodeMeteredConstraint();
263 } else if (type.equals(TierConstraint.class.getSimpleName())) {
264 return decodeTierConstraint();
Ray Milkeyb82c42b2015-06-30 09:42:20 -0700265 }
David Glantz05c6f432020-03-19 14:56:12 -0500266
Ray Milkeyb82c42b2015-06-30 09:42:20 -0700267 throw new IllegalArgumentException("Instruction type "
268 + type + " is not supported");
269 }
270}