blob: 40c553d96409906bfd406c195fc97e2521dee9ae [file] [log] [blame]
Ray Milkeyb82c42b2015-06-30 09:42:20 -07001/*
2 * Copyright 2015 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 */
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;
24import org.onosproject.net.IndexedLambda;
25import org.onosproject.net.Link;
26import org.onosproject.net.intent.Constraint;
27import org.onosproject.net.intent.constraint.AnnotationConstraint;
28import org.onosproject.net.intent.constraint.AsymmetricPathConstraint;
29import org.onosproject.net.intent.constraint.BandwidthConstraint;
30import org.onosproject.net.intent.constraint.LambdaConstraint;
31import org.onosproject.net.intent.constraint.LatencyConstraint;
32import org.onosproject.net.intent.constraint.LinkTypeConstraint;
33import org.onosproject.net.intent.constraint.ObstacleConstraint;
34import org.onosproject.net.intent.constraint.WaypointConstraint;
Ray Milkeyb82c42b2015-06-30 09:42:20 -070035
36import com.fasterxml.jackson.databind.JsonNode;
37import com.fasterxml.jackson.databind.node.ObjectNode;
38
39import static org.onlab.util.Tools.nullIsIllegal;
40
41/**
42 * Constraint JSON decoder.
43 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070044public final class DecodeConstraintCodecHelper {
Ray Milkeyb82c42b2015-06-30 09:42:20 -070045 private final ObjectNode json;
46
47 /**
48 * Constructs a constraint decoder.
49 *
50 * @param json object node to decode
51 */
Ray Milkey6d7968e2015-07-06 14:30:02 -070052 public DecodeConstraintCodecHelper(ObjectNode json) {
Ray Milkeyb82c42b2015-06-30 09:42:20 -070053 this.json = json;
54 }
55
56 /**
57 * Decodes a link type constraint.
58 *
59 * @return link type constraint object.
60 */
61 private Constraint decodeLinkTypeConstraint() {
62 boolean inclusive = nullIsIllegal(json.get(ConstraintCodec.INCLUSIVE),
63 ConstraintCodec.INCLUSIVE + ConstraintCodec.MISSING_MEMBER_MESSAGE).asBoolean();
64
65 JsonNode types = nullIsIllegal(json.get(ConstraintCodec.TYPES),
66 ConstraintCodec.TYPES + ConstraintCodec.MISSING_MEMBER_MESSAGE);
67 if (types.size() < 1) {
68 throw new IllegalArgumentException(
69 "types array in link constraint must have at least one value");
70 }
71
72 ArrayList<Link.Type> typesEntries = new ArrayList<>(types.size());
73 IntStream.range(0, types.size())
74 .forEach(index ->
75 typesEntries.add(Link.Type.valueOf(types.get(index).asText())));
76
77 return new LinkTypeConstraint(inclusive,
78 typesEntries.toArray(new Link.Type[types.size()]));
79 }
80
81 /**
82 * Decodes an annotation constraint.
83 *
84 * @return annotation constraint object.
85 */
86 private Constraint decodeAnnotationConstraint() {
87 String key = nullIsIllegal(json.get(ConstraintCodec.KEY),
88 ConstraintCodec.KEY + ConstraintCodec.MISSING_MEMBER_MESSAGE)
89 .asText();
90 double threshold = nullIsIllegal(json.get(ConstraintCodec.THRESHOLD),
91 ConstraintCodec.THRESHOLD + ConstraintCodec.MISSING_MEMBER_MESSAGE)
92 .asDouble();
93
94 return new AnnotationConstraint(key, threshold);
95 }
96
97 /**
98 * Decodes a lambda constraint.
99 *
100 * @return lambda constraint object.
101 */
102 private Constraint decodeLambdaConstraint() {
103 long lambda = nullIsIllegal(json.get(ConstraintCodec.LAMBDA),
104 ConstraintCodec.LAMBDA + ConstraintCodec.MISSING_MEMBER_MESSAGE)
105 .asLong();
106
Sho SHIMIZU03d42532015-11-23 17:16:30 -0800107 return new LambdaConstraint(new IndexedLambda(lambda));
Ray Milkeyb82c42b2015-06-30 09:42:20 -0700108 }
109
110 /**
111 * Decodes a latency constraint.
112 *
113 * @return latency constraint object.
114 */
115 private Constraint decodeLatencyConstraint() {
116 long latencyMillis = nullIsIllegal(json.get(ConstraintCodec.LATENCY_MILLIS),
117 ConstraintCodec.LATENCY_MILLIS + ConstraintCodec.MISSING_MEMBER_MESSAGE)
118 .asLong();
119
120 return new LatencyConstraint(Duration.ofMillis(latencyMillis));
121 }
122
123 /**
124 * Decodes an obstacle constraint.
125 *
126 * @return obstacle constraint object.
127 */
128 private Constraint decodeObstacleConstraint() {
129 JsonNode obstacles = nullIsIllegal(json.get(ConstraintCodec.OBSTACLES),
130 ConstraintCodec.OBSTACLES + ConstraintCodec.MISSING_MEMBER_MESSAGE);
131 if (obstacles.size() < 1) {
132 throw new IllegalArgumentException(
133 "obstacles array in obstacles constraint must have at least one value");
134 }
135
136 ArrayList<DeviceId> obstacleEntries = new ArrayList<>(obstacles.size());
137 IntStream.range(0, obstacles.size())
138 .forEach(index ->
139 obstacleEntries.add(DeviceId.deviceId(obstacles.get(index).asText())));
140
141 return new ObstacleConstraint(
142 obstacleEntries.toArray(new DeviceId[obstacles.size()]));
143 }
144
145 /**
146 * Decodes a waypoint constraint.
147 *
148 * @return waypoint constraint object.
149 */
150 private Constraint decodeWaypointConstraint() {
151 JsonNode waypoints = nullIsIllegal(json.get(ConstraintCodec.WAYPOINTS),
152 ConstraintCodec.WAYPOINTS + ConstraintCodec.MISSING_MEMBER_MESSAGE);
153 if (waypoints.size() < 1) {
154 throw new IllegalArgumentException(
155 "obstacles array in obstacles constraint must have at least one value");
156 }
157
158 ArrayList<DeviceId> waypointEntries = new ArrayList<>(waypoints.size());
159 IntStream.range(0, waypoints.size())
160 .forEach(index ->
161 waypointEntries.add(DeviceId.deviceId(waypoints.get(index).asText())));
162
163 return new WaypointConstraint(
164 waypointEntries.toArray(new DeviceId[waypoints.size()]));
165 }
166
167 /**
168 * Decodes an asymmetric path constraint.
169 *
170 * @return asymmetric path constraint object.
171 */
172 private Constraint decodeAsymmetricPathConstraint() {
173 return new AsymmetricPathConstraint();
174 }
175
176 /**
177 * 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 /**
190 * Decodes the given constraint.
191 *
192 * @return constraint object.
193 */
194 public Constraint decode() {
195 final String type = nullIsIllegal(json.get(ConstraintCodec.TYPE),
196 ConstraintCodec.TYPE + ConstraintCodec.MISSING_MEMBER_MESSAGE)
197 .asText();
198
199 if (type.equals(BandwidthConstraint.class.getSimpleName())) {
200 return decodeBandwidthConstraint();
201 } else if (type.equals(LambdaConstraint.class.getSimpleName())) {
202 return decodeLambdaConstraint();
203 } else if (type.equals(LinkTypeConstraint.class.getSimpleName())) {
204 return decodeLinkTypeConstraint();
205 } else if (type.equals(AnnotationConstraint.class.getSimpleName())) {
206 return decodeAnnotationConstraint();
207 } else if (type.equals(LatencyConstraint.class.getSimpleName())) {
208 return decodeLatencyConstraint();
209 } else if (type.equals(ObstacleConstraint.class.getSimpleName())) {
210 return decodeObstacleConstraint();
211 } else if (type.equals(WaypointConstraint.class.getSimpleName())) {
212 return decodeWaypointConstraint();
213 } else if (type.equals(AsymmetricPathConstraint.class.getSimpleName())) {
214 return decodeAsymmetricPathConstraint();
215 } else if (type.equals(LinkTypeConstraint.class.getSimpleName())) {
216 return decodeLinkTypeConstraint();
217 } else if (type.equals(AnnotationConstraint.class.getSimpleName())) {
218 return decodeAnnotationConstraint();
219 }
220 throw new IllegalArgumentException("Instruction type "
221 + type + " is not supported");
222 }
223}