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