blob: 4eac49d5fde665b708050030f628d3f41d79b4d7 [file] [log] [blame]
/*
* Copyright 2015-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.codec.impl;
import java.time.Duration;
import java.util.ArrayList;
import java.util.stream.IntStream;
import org.onlab.util.Bandwidth;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.intent.Constraint;
import org.onosproject.net.intent.constraint.AnnotationConstraint;
import org.onosproject.net.intent.constraint.AsymmetricPathConstraint;
import org.onosproject.net.intent.constraint.BandwidthConstraint;
import org.onosproject.net.intent.constraint.LatencyConstraint;
import org.onosproject.net.intent.constraint.LinkTypeConstraint;
import org.onosproject.net.intent.constraint.ObstacleConstraint;
import org.onosproject.net.intent.constraint.WaypointConstraint;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import static org.onlab.util.Tools.nullIsIllegal;
/**
* Constraint JSON decoder.
*/
public final class DecodeConstraintCodecHelper {
private final ObjectNode json;
/**
* Constructs a constraint decoder.
*
* @param json object node to decode
*/
public DecodeConstraintCodecHelper(ObjectNode json) {
this.json = json;
}
/**
* Decodes a link type constraint.
*
* @return link type constraint object.
*/
private Constraint decodeLinkTypeConstraint() {
boolean inclusive = nullIsIllegal(json.get(ConstraintCodec.INCLUSIVE),
ConstraintCodec.INCLUSIVE + ConstraintCodec.MISSING_MEMBER_MESSAGE).asBoolean();
JsonNode types = nullIsIllegal(json.get(ConstraintCodec.TYPES),
ConstraintCodec.TYPES + ConstraintCodec.MISSING_MEMBER_MESSAGE);
if (types.size() < 1) {
throw new IllegalArgumentException(
"types array in link constraint must have at least one value");
}
ArrayList<Link.Type> typesEntries = new ArrayList<>(types.size());
IntStream.range(0, types.size())
.forEach(index ->
typesEntries.add(Link.Type.valueOf(types.get(index).asText())));
return new LinkTypeConstraint(inclusive,
typesEntries.toArray(new Link.Type[types.size()]));
}
/**
* Decodes an annotation constraint.
*
* @return annotation constraint object.
*/
private Constraint decodeAnnotationConstraint() {
String key = nullIsIllegal(json.get(ConstraintCodec.KEY),
ConstraintCodec.KEY + ConstraintCodec.MISSING_MEMBER_MESSAGE)
.asText();
double threshold = nullIsIllegal(json.get(ConstraintCodec.THRESHOLD),
ConstraintCodec.THRESHOLD + ConstraintCodec.MISSING_MEMBER_MESSAGE)
.asDouble();
return new AnnotationConstraint(key, threshold);
}
/**
* Decodes a latency constraint.
*
* @return latency constraint object.
*/
private Constraint decodeLatencyConstraint() {
long latencyMillis = nullIsIllegal(json.get(ConstraintCodec.LATENCY_MILLIS),
ConstraintCodec.LATENCY_MILLIS + ConstraintCodec.MISSING_MEMBER_MESSAGE)
.asLong();
return new LatencyConstraint(Duration.ofMillis(latencyMillis));
}
/**
* Decodes an obstacle constraint.
*
* @return obstacle constraint object.
*/
private Constraint decodeObstacleConstraint() {
JsonNode obstacles = nullIsIllegal(json.get(ConstraintCodec.OBSTACLES),
ConstraintCodec.OBSTACLES + ConstraintCodec.MISSING_MEMBER_MESSAGE);
if (obstacles.size() < 1) {
throw new IllegalArgumentException(
"obstacles array in obstacles constraint must have at least one value");
}
ArrayList<DeviceId> obstacleEntries = new ArrayList<>(obstacles.size());
IntStream.range(0, obstacles.size())
.forEach(index ->
obstacleEntries.add(DeviceId.deviceId(obstacles.get(index).asText())));
return new ObstacleConstraint(
obstacleEntries.toArray(new DeviceId[obstacles.size()]));
}
/**
* Decodes a waypoint constraint.
*
* @return waypoint constraint object.
*/
private Constraint decodeWaypointConstraint() {
JsonNode waypoints = nullIsIllegal(json.get(ConstraintCodec.WAYPOINTS),
ConstraintCodec.WAYPOINTS + ConstraintCodec.MISSING_MEMBER_MESSAGE);
if (waypoints.size() < 1) {
throw new IllegalArgumentException(
"obstacles array in obstacles constraint must have at least one value");
}
ArrayList<DeviceId> waypointEntries = new ArrayList<>(waypoints.size());
IntStream.range(0, waypoints.size())
.forEach(index ->
waypointEntries.add(DeviceId.deviceId(waypoints.get(index).asText())));
return new WaypointConstraint(
waypointEntries.toArray(new DeviceId[waypoints.size()]));
}
/**
* Decodes an asymmetric path constraint.
*
* @return asymmetric path constraint object.
*/
private Constraint decodeAsymmetricPathConstraint() {
return new AsymmetricPathConstraint();
}
/**
* Decodes a bandwidth constraint.
*
* @return bandwidth constraint object.
*/
private Constraint decodeBandwidthConstraint() {
double bandwidth = nullIsIllegal(json.get(ConstraintCodec.BANDWIDTH),
ConstraintCodec.BANDWIDTH + ConstraintCodec.MISSING_MEMBER_MESSAGE)
.asDouble();
return new BandwidthConstraint(Bandwidth.bps(bandwidth));
}
/**
* Decodes the given constraint.
*
* @return constraint object.
*/
public Constraint decode() {
final String type = nullIsIllegal(json.get(ConstraintCodec.TYPE),
ConstraintCodec.TYPE + ConstraintCodec.MISSING_MEMBER_MESSAGE)
.asText();
if (type.equals(BandwidthConstraint.class.getSimpleName())) {
return decodeBandwidthConstraint();
} else if (type.equals(LinkTypeConstraint.class.getSimpleName())) {
return decodeLinkTypeConstraint();
} else if (type.equals(AnnotationConstraint.class.getSimpleName())) {
return decodeAnnotationConstraint();
} else if (type.equals(LatencyConstraint.class.getSimpleName())) {
return decodeLatencyConstraint();
} else if (type.equals(ObstacleConstraint.class.getSimpleName())) {
return decodeObstacleConstraint();
} else if (type.equals(WaypointConstraint.class.getSimpleName())) {
return decodeWaypointConstraint();
} else if (type.equals(AsymmetricPathConstraint.class.getSimpleName())) {
return decodeAsymmetricPathConstraint();
} else if (type.equals(LinkTypeConstraint.class.getSimpleName())) {
return decodeLinkTypeConstraint();
} else if (type.equals(AnnotationConstraint.class.getSimpleName())) {
return decodeAnnotationConstraint();
}
throw new IllegalArgumentException("Instruction type "
+ type + " is not supported");
}
}