2 * Copyright 2015 Open Networking Laboratory
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.onosproject.codec.impl;
18 import java.time.Duration;
19 import java.util.ArrayList;
20 import java.util.stream.IntStream;
22 import org.onlab.util.Bandwidth;
23 import org.onosproject.net.DeviceId;
24 import org.onosproject.net.IndexedLambda;
25 import org.onosproject.net.Link;
26 import org.onosproject.net.intent.Constraint;
27 import org.onosproject.net.intent.constraint.AnnotationConstraint;
28 import org.onosproject.net.intent.constraint.AsymmetricPathConstraint;
29 import org.onosproject.net.intent.constraint.BandwidthConstraint;
30 import org.onosproject.net.intent.constraint.LambdaConstraint;
31 import org.onosproject.net.intent.constraint.LatencyConstraint;
32 import org.onosproject.net.intent.constraint.LinkTypeConstraint;
33 import org.onosproject.net.intent.constraint.ObstacleConstraint;
34 import org.onosproject.net.intent.constraint.WaypointConstraint;
35 import org.onosproject.net.resource.link.BandwidthResource;
36 import org.onosproject.net.resource.link.LambdaResource;
38 import com.fasterxml.jackson.databind.JsonNode;
39 import com.fasterxml.jackson.databind.node.ObjectNode;
41 import static org.onlab.util.Tools.nullIsIllegal;
44 * Constraint JSON decoder.
46 public final class DecodeConstraintCodecHelper {
47 private final ObjectNode json;
50 * Constructs a constraint decoder.
52 * @param json object node to decode
54 public DecodeConstraintCodecHelper(ObjectNode json) {
59 * Decodes a link type constraint.
61 * @return link type constraint object.
63 private Constraint decodeLinkTypeConstraint() {
64 boolean inclusive = nullIsIllegal(json.get(ConstraintCodec.INCLUSIVE),
65 ConstraintCodec.INCLUSIVE + ConstraintCodec.MISSING_MEMBER_MESSAGE).asBoolean();
67 JsonNode types = nullIsIllegal(json.get(ConstraintCodec.TYPES),
68 ConstraintCodec.TYPES + ConstraintCodec.MISSING_MEMBER_MESSAGE);
69 if (types.size() < 1) {
70 throw new IllegalArgumentException(
71 "types array in link constraint must have at least one value");
74 ArrayList<Link.Type> typesEntries = new ArrayList<>(types.size());
75 IntStream.range(0, types.size())
77 typesEntries.add(Link.Type.valueOf(types.get(index).asText())));
79 return new LinkTypeConstraint(inclusive,
80 typesEntries.toArray(new Link.Type[types.size()]));
84 * Decodes an annotation constraint.
86 * @return annotation constraint object.
88 private Constraint decodeAnnotationConstraint() {
89 String key = nullIsIllegal(json.get(ConstraintCodec.KEY),
90 ConstraintCodec.KEY + ConstraintCodec.MISSING_MEMBER_MESSAGE)
92 double threshold = nullIsIllegal(json.get(ConstraintCodec.THRESHOLD),
93 ConstraintCodec.THRESHOLD + ConstraintCodec.MISSING_MEMBER_MESSAGE)
96 return new AnnotationConstraint(key, threshold);
100 * Decodes a lambda constraint.
102 * @return lambda constraint object.
104 private Constraint decodeLambdaConstraint() {
105 long lambda = nullIsIllegal(json.get(ConstraintCodec.LAMBDA),
106 ConstraintCodec.LAMBDA + ConstraintCodec.MISSING_MEMBER_MESSAGE)
109 return new LambdaConstraint(LambdaResource.valueOf(new IndexedLambda(lambda)));
113 * Decodes a latency constraint.
115 * @return latency constraint object.
117 private Constraint decodeLatencyConstraint() {
118 long latencyMillis = nullIsIllegal(json.get(ConstraintCodec.LATENCY_MILLIS),
119 ConstraintCodec.LATENCY_MILLIS + ConstraintCodec.MISSING_MEMBER_MESSAGE)
122 return new LatencyConstraint(Duration.ofMillis(latencyMillis));
126 * Decodes an obstacle constraint.
128 * @return obstacle constraint object.
130 private Constraint decodeObstacleConstraint() {
131 JsonNode obstacles = nullIsIllegal(json.get(ConstraintCodec.OBSTACLES),
132 ConstraintCodec.OBSTACLES + ConstraintCodec.MISSING_MEMBER_MESSAGE);
133 if (obstacles.size() < 1) {
134 throw new IllegalArgumentException(
135 "obstacles array in obstacles constraint must have at least one value");
138 ArrayList<DeviceId> obstacleEntries = new ArrayList<>(obstacles.size());
139 IntStream.range(0, obstacles.size())
141 obstacleEntries.add(DeviceId.deviceId(obstacles.get(index).asText())));
143 return new ObstacleConstraint(
144 obstacleEntries.toArray(new DeviceId[obstacles.size()]));
148 * Decodes a waypoint constraint.
150 * @return waypoint constraint object.
152 private Constraint decodeWaypointConstraint() {
153 JsonNode waypoints = nullIsIllegal(json.get(ConstraintCodec.WAYPOINTS),
154 ConstraintCodec.WAYPOINTS + ConstraintCodec.MISSING_MEMBER_MESSAGE);
155 if (waypoints.size() < 1) {
156 throw new IllegalArgumentException(
157 "obstacles array in obstacles constraint must have at least one value");
160 ArrayList<DeviceId> waypointEntries = new ArrayList<>(waypoints.size());
161 IntStream.range(0, waypoints.size())
163 waypointEntries.add(DeviceId.deviceId(waypoints.get(index).asText())));
165 return new WaypointConstraint(
166 waypointEntries.toArray(new DeviceId[waypoints.size()]));
170 * Decodes an asymmetric path constraint.
172 * @return asymmetric path constraint object.
174 private Constraint decodeAsymmetricPathConstraint() {
175 return new AsymmetricPathConstraint();
179 * Decodes a bandwidth constraint.
181 * @return bandwidth constraint object.
183 private Constraint decodeBandwidthConstraint() {
184 double bandwidth = nullIsIllegal(json.get(ConstraintCodec.BANDWIDTH),
185 ConstraintCodec.BANDWIDTH + ConstraintCodec.MISSING_MEMBER_MESSAGE)
188 return new BandwidthConstraint(new BandwidthResource(Bandwidth.bps(bandwidth)));
192 * Decodes the given constraint.
194 * @return constraint object.
196 public Constraint decode() {
197 final String type = nullIsIllegal(json.get(ConstraintCodec.TYPE),
198 ConstraintCodec.TYPE + ConstraintCodec.MISSING_MEMBER_MESSAGE)
201 if (type.equals(BandwidthConstraint.class.getSimpleName())) {
202 return decodeBandwidthConstraint();
203 } else if (type.equals(LambdaConstraint.class.getSimpleName())) {
204 return decodeLambdaConstraint();
205 } else if (type.equals(LinkTypeConstraint.class.getSimpleName())) {
206 return decodeLinkTypeConstraint();
207 } else if (type.equals(AnnotationConstraint.class.getSimpleName())) {
208 return decodeAnnotationConstraint();
209 } else if (type.equals(LatencyConstraint.class.getSimpleName())) {
210 return decodeLatencyConstraint();
211 } else if (type.equals(ObstacleConstraint.class.getSimpleName())) {
212 return decodeObstacleConstraint();
213 } else if (type.equals(WaypointConstraint.class.getSimpleName())) {
214 return decodeWaypointConstraint();
215 } else if (type.equals(AsymmetricPathConstraint.class.getSimpleName())) {
216 return decodeAsymmetricPathConstraint();
217 } else if (type.equals(LinkTypeConstraint.class.getSimpleName())) {
218 return decodeLinkTypeConstraint();
219 } else if (type.equals(AnnotationConstraint.class.getSimpleName())) {
220 return decodeAnnotationConstraint();
222 throw new IllegalArgumentException("Instruction type "
223 + type + " is not supported");