blob: 22c50b1726166431aa5171d9bd5bc44a86cd125e [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;
Antonio Marsico4f68ec92017-03-09 11:16:32 +010032import org.onosproject.net.intent.constraint.NonDisruptiveConstraint;
Ray Milkeyb82c42b2015-06-30 09:42:20 -070033import 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;
Antonio Marsico4f68ec92017-03-09 11:16:32 +010040import static org.onosproject.net.intent.constraint.NonDisruptiveConstraint.nonDisruptive;
Ray Milkeyb82c42b2015-06-30 09:42:20 -070041
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 /**
Ray Milkeyb82c42b2015-06-30 09:42:20 -070099 * Decodes a latency constraint.
100 *
101 * @return latency constraint object.
102 */
103 private Constraint decodeLatencyConstraint() {
104 long latencyMillis = nullIsIllegal(json.get(ConstraintCodec.LATENCY_MILLIS),
105 ConstraintCodec.LATENCY_MILLIS + ConstraintCodec.MISSING_MEMBER_MESSAGE)
106 .asLong();
107
108 return new LatencyConstraint(Duration.ofMillis(latencyMillis));
109 }
110
111 /**
112 * Decodes an obstacle constraint.
113 *
114 * @return obstacle constraint object.
115 */
116 private Constraint decodeObstacleConstraint() {
117 JsonNode obstacles = nullIsIllegal(json.get(ConstraintCodec.OBSTACLES),
118 ConstraintCodec.OBSTACLES + ConstraintCodec.MISSING_MEMBER_MESSAGE);
119 if (obstacles.size() < 1) {
120 throw new IllegalArgumentException(
121 "obstacles array in obstacles constraint must have at least one value");
122 }
123
124 ArrayList<DeviceId> obstacleEntries = new ArrayList<>(obstacles.size());
125 IntStream.range(0, obstacles.size())
126 .forEach(index ->
127 obstacleEntries.add(DeviceId.deviceId(obstacles.get(index).asText())));
128
129 return new ObstacleConstraint(
130 obstacleEntries.toArray(new DeviceId[obstacles.size()]));
131 }
132
133 /**
134 * Decodes a waypoint constraint.
135 *
136 * @return waypoint constraint object.
137 */
138 private Constraint decodeWaypointConstraint() {
139 JsonNode waypoints = nullIsIllegal(json.get(ConstraintCodec.WAYPOINTS),
140 ConstraintCodec.WAYPOINTS + ConstraintCodec.MISSING_MEMBER_MESSAGE);
141 if (waypoints.size() < 1) {
142 throw new IllegalArgumentException(
143 "obstacles array in obstacles constraint must have at least one value");
144 }
145
146 ArrayList<DeviceId> waypointEntries = new ArrayList<>(waypoints.size());
147 IntStream.range(0, waypoints.size())
148 .forEach(index ->
149 waypointEntries.add(DeviceId.deviceId(waypoints.get(index).asText())));
150
151 return new WaypointConstraint(
152 waypointEntries.toArray(new DeviceId[waypoints.size()]));
153 }
154
155 /**
156 * Decodes an asymmetric path constraint.
157 *
158 * @return asymmetric path constraint object.
159 */
160 private Constraint decodeAsymmetricPathConstraint() {
161 return new AsymmetricPathConstraint();
162 }
163
164 /**
Thomas Szyrkowiec7c5f9c92017-07-12 12:42:02 +0200165 * Decodes a domain constraint.
166 *
167 * @return domain constraint object.
168 */
169 private Constraint decodeDomainConstraint() {
170 return DomainConstraint.domain();
171 }
172
173
174 /**
Ray Milkeyb82c42b2015-06-30 09:42:20 -0700175 * Decodes a bandwidth constraint.
176 *
177 * @return bandwidth constraint object.
178 */
179 private Constraint decodeBandwidthConstraint() {
180 double bandwidth = nullIsIllegal(json.get(ConstraintCodec.BANDWIDTH),
181 ConstraintCodec.BANDWIDTH + ConstraintCodec.MISSING_MEMBER_MESSAGE)
182 .asDouble();
183
Sho SHIMIZUa88db492015-11-23 13:21:04 -0800184 return new BandwidthConstraint(Bandwidth.bps(bandwidth));
Ray Milkeyb82c42b2015-06-30 09:42:20 -0700185 }
186
187 /**
Antonio Marsico4f68ec92017-03-09 11:16:32 +0100188 * Decodes a non-disruptive reallocation constraint.
189 *
190 * @return non-disruptive reallocation constraint object.
191 */
192 private Constraint decodeNonDisruptiveConstraint() {
193 return nonDisruptive();
194 }
195
196 /**
Ray Milkeyb82c42b2015-06-30 09:42:20 -0700197 * Decodes the given constraint.
198 *
199 * @return constraint object.
200 */
201 public Constraint decode() {
202 final String type = nullIsIllegal(json.get(ConstraintCodec.TYPE),
203 ConstraintCodec.TYPE + ConstraintCodec.MISSING_MEMBER_MESSAGE)
204 .asText();
205
206 if (type.equals(BandwidthConstraint.class.getSimpleName())) {
207 return decodeBandwidthConstraint();
Ray Milkeyb82c42b2015-06-30 09:42:20 -0700208 } else if (type.equals(LinkTypeConstraint.class.getSimpleName())) {
209 return decodeLinkTypeConstraint();
210 } else if (type.equals(AnnotationConstraint.class.getSimpleName())) {
211 return decodeAnnotationConstraint();
212 } else if (type.equals(LatencyConstraint.class.getSimpleName())) {
213 return decodeLatencyConstraint();
214 } else if (type.equals(ObstacleConstraint.class.getSimpleName())) {
215 return decodeObstacleConstraint();
216 } else if (type.equals(WaypointConstraint.class.getSimpleName())) {
217 return decodeWaypointConstraint();
218 } else if (type.equals(AsymmetricPathConstraint.class.getSimpleName())) {
219 return decodeAsymmetricPathConstraint();
Thomas Szyrkowiec7c5f9c92017-07-12 12:42:02 +0200220 } else if (type.equals(DomainConstraint.class.getSimpleName())) {
221 return decodeDomainConstraint();
Antonio Marsico4f68ec92017-03-09 11:16:32 +0100222 } else if (type.equals(NonDisruptiveConstraint.class.getSimpleName())) {
223 return decodeNonDisruptiveConstraint();
Ray Milkeyb82c42b2015-06-30 09:42:20 -0700224 }
225 throw new IllegalArgumentException("Instruction type "
226 + type + " is not supported");
227 }
228}