Mahesh Poojary S | d7a3692 | 2016-04-01 16:11:14 +0530 | [diff] [blame] | 1 | /* |
Brian O'Connor | a09fe5b | 2017-08-03 21:12:30 -0700 | [diff] [blame] | 2 | * Copyright 2016-present Open Networking Foundation |
Mahesh Poojary S | d7a3692 | 2016-04-01 16:11:14 +0530 | [diff] [blame] | 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 | */ |
Priyanka B | b977f56 | 2016-07-22 13:02:03 +0530 | [diff] [blame] | 16 | package org.onosproject.pcerest; |
Mahesh Poojary S | d7a3692 | 2016-04-01 16:11:14 +0530 | [diff] [blame] | 17 | |
| 18 | import static com.google.common.base.Preconditions.checkNotNull; |
Priyanka B | bae0eeb1 | 2016-11-30 11:59:48 +0530 | [diff] [blame] | 19 | import static org.onosproject.net.Link.State.ACTIVE; |
| 20 | import static org.onosproject.net.Link.Type.DIRECT; |
| 21 | |
| 22 | import com.fasterxml.jackson.databind.node.ArrayNode; |
| 23 | import com.google.common.collect.ImmutableList; |
| 24 | import com.google.common.collect.Lists; |
Mahesh Poojary S | d7a3692 | 2016-04-01 16:11:14 +0530 | [diff] [blame] | 25 | |
| 26 | import org.onosproject.codec.CodecContext; |
| 27 | import org.onosproject.codec.JsonCodec; |
Priyanka B | bae0eeb1 | 2016-11-30 11:59:48 +0530 | [diff] [blame] | 28 | import org.onosproject.net.ConnectPoint; |
| 29 | import org.onosproject.net.DefaultLink; |
| 30 | import org.onosproject.net.DeviceId; |
| 31 | import org.onosproject.net.NetworkResource; |
| 32 | import org.onosproject.net.PortNumber; |
| 33 | import org.onosproject.net.provider.ProviderId; |
| 34 | import org.onosproject.pce.pceservice.ExplicitPathInfo; |
Mahesh Poojary S | d7a3692 | 2016-04-01 16:11:14 +0530 | [diff] [blame] | 35 | import org.onosproject.pce.pceservice.PcePath; |
| 36 | import org.onosproject.pce.pceservice.DefaultPcePath; |
Priyanka B | 3fdb9dd | 2016-08-08 10:47:24 +0530 | [diff] [blame] | 37 | import org.onosproject.pce.pceservice.constraint.CostConstraint; |
Satish K | 2eb5d84 | 2017-04-04 16:28:37 +0530 | [diff] [blame] | 38 | import org.onosproject.pce.pceservice.constraint.PceBandwidthConstraint; |
Mahesh Poojary S | d7a3692 | 2016-04-01 16:11:14 +0530 | [diff] [blame] | 39 | import org.slf4j.Logger; |
| 40 | import org.slf4j.LoggerFactory; |
| 41 | |
| 42 | import com.fasterxml.jackson.databind.node.ObjectNode; |
| 43 | import com.fasterxml.jackson.databind.JsonNode; |
| 44 | |
Priyanka B | bae0eeb1 | 2016-11-30 11:59:48 +0530 | [diff] [blame] | 45 | import java.util.Collection; |
| 46 | import java.util.Collections; |
| 47 | import java.util.LinkedList; |
| 48 | import java.util.List; |
| 49 | |
Mahesh Poojary S | d7a3692 | 2016-04-01 16:11:14 +0530 | [diff] [blame] | 50 | /** |
| 51 | * PCE path json codec. |
| 52 | */ |
| 53 | public final class PcePathCodec extends JsonCodec<PcePath> { |
| 54 | private final Logger log = LoggerFactory.getLogger(PcePathCodec.class); |
| 55 | private static final String SOURCE = "source"; |
| 56 | private static final String DESTINATION = "destination"; |
| 57 | private static final String LSP_TYPE = "pathType"; |
| 58 | private static final String SYMBOLIC_PATH_NAME = "name"; |
| 59 | private static final String CONSTRAINT = "constraint"; |
| 60 | private static final String COST = "cost"; |
| 61 | private static final String BANDWIDTH = "bandwidth"; |
| 62 | private static final String PATH_ID = "pathId"; |
Priyanka B | bae0eeb1 | 2016-11-30 11:59:48 +0530 | [diff] [blame] | 63 | private static final String EXPLICIT_PATH_INFO = "explicitPathInfo"; |
Mahesh Poojary S | d7a3692 | 2016-04-01 16:11:14 +0530 | [diff] [blame] | 64 | private static final String MISSING_MEMBER_MESSAGE = " member is required in pce-path"; |
Priyanka B | bae0eeb1 | 2016-11-30 11:59:48 +0530 | [diff] [blame] | 65 | public static final String JSON_NOT_NULL = "JsonNode can not be null"; |
| 66 | public static final byte SOURCE_DEVICEID_INDEX = 0; |
| 67 | public static final byte SOURCE_PORTNO_INDEX = 1; |
| 68 | public static final byte DESTINATION_DEVICEID_INDEX = 2; |
| 69 | public static final byte DESTINATION_PORTNO_INDEX = 3; |
Mahesh Poojary S | d7a3692 | 2016-04-01 16:11:14 +0530 | [diff] [blame] | 70 | |
| 71 | @Override |
| 72 | public PcePath decode(ObjectNode json, CodecContext context) { |
| 73 | if (json == null || !json.isObject()) { |
| 74 | log.error("Empty json input"); |
| 75 | return null; |
| 76 | } |
| 77 | |
| 78 | // build pce-path |
| 79 | PcePath.Builder resultBuilder = new DefaultPcePath.Builder(); |
| 80 | |
| 81 | // retrieve source |
| 82 | JsonNode jNode = json.get(SOURCE); |
| 83 | if (jNode != null) { |
| 84 | String src = jNode.asText(); |
| 85 | resultBuilder.source(src); |
| 86 | } |
| 87 | |
| 88 | // retrieve destination |
| 89 | jNode = json.get(DESTINATION); |
| 90 | if (jNode != null) { |
| 91 | String dst = jNode.asText(); |
| 92 | resultBuilder.destination(dst); |
| 93 | } |
| 94 | |
| 95 | // retrieve lsp-type |
| 96 | jNode = json.get(LSP_TYPE); |
| 97 | if (jNode != null) { |
| 98 | String lspType = jNode.asText(); |
Priyanka B | 3fdb9dd | 2016-08-08 10:47:24 +0530 | [diff] [blame] | 99 | //Validating LSP type |
| 100 | int type = Integer.parseInt(lspType); |
| 101 | if ((type < 0) || (type > 2)) { |
| 102 | return null; |
| 103 | } |
Mahesh Poojary S | d7a3692 | 2016-04-01 16:11:14 +0530 | [diff] [blame] | 104 | resultBuilder.lspType(lspType); |
| 105 | } |
| 106 | |
| 107 | // retrieve symbolic-path-name |
| 108 | jNode = json.get(SYMBOLIC_PATH_NAME); |
| 109 | if (jNode != null) { |
| 110 | String name = jNode.asText(); |
| 111 | resultBuilder.name(name); |
| 112 | } |
| 113 | |
| 114 | // retrieve constraint |
| 115 | JsonNode constraintJNode = (JsonNode) json.path(CONSTRAINT); |
| 116 | if ((constraintJNode != null) && (!constraintJNode.isMissingNode())) { |
| 117 | // retrieve cost |
| 118 | jNode = constraintJNode.get(COST); |
| 119 | if (jNode != null) { |
| 120 | String cost = jNode.asText(); |
Priyanka B | 3fdb9dd | 2016-08-08 10:47:24 +0530 | [diff] [blame] | 121 | //Validating Cost type |
| 122 | int costType = Integer.parseInt(cost); |
| 123 | if ((costType < 1) || (costType > 2)) { |
| 124 | return null; |
| 125 | } |
Mahesh Poojary S | 3353620 | 2016-05-30 07:22:36 +0530 | [diff] [blame] | 126 | resultBuilder.costConstraint(cost); |
Mahesh Poojary S | d7a3692 | 2016-04-01 16:11:14 +0530 | [diff] [blame] | 127 | } |
| 128 | |
| 129 | // retrieve bandwidth |
| 130 | jNode = constraintJNode.get(BANDWIDTH); |
| 131 | if (jNode != null) { |
| 132 | String bandwidth = jNode.asText(); |
Priyanka B | 3fdb9dd | 2016-08-08 10:47:24 +0530 | [diff] [blame] | 133 | double bw = Double.parseDouble(bandwidth); |
| 134 | if (bw < 0) { |
| 135 | return null; |
| 136 | } |
Mahesh Poojary S | d7a3692 | 2016-04-01 16:11:14 +0530 | [diff] [blame] | 137 | resultBuilder.bandwidthConstraint(bandwidth); |
| 138 | } |
| 139 | } |
| 140 | |
Priyanka B | bae0eeb1 | 2016-11-30 11:59:48 +0530 | [diff] [blame] | 141 | // Retrieve explicit path info |
| 142 | JsonNode explicitPathInfo = json.get(EXPLICIT_PATH_INFO); |
| 143 | if (explicitPathInfo != null) { |
| 144 | List<ExplicitPathInfo> explicitPathInfoList = |
| 145 | ImmutableList.copyOf(jsonNodeToExplicitPathInfo(explicitPathInfo)); |
| 146 | if (explicitPathInfoList != null) { |
| 147 | resultBuilder.explicitPathInfo(explicitPathInfoList); |
| 148 | } |
| 149 | } |
| 150 | |
Mahesh Poojary S | d7a3692 | 2016-04-01 16:11:14 +0530 | [diff] [blame] | 151 | return resultBuilder.build(); |
| 152 | } |
| 153 | |
Priyanka B | bae0eeb1 | 2016-11-30 11:59:48 +0530 | [diff] [blame] | 154 | private ExplicitPathInfo createListOfExplicitPathObj(JsonNode node) { |
| 155 | int explicitPathType = Integer.parseInt(node.get("type").asText()); |
| 156 | DeviceId deviceId; |
| 157 | PortNumber portNo; |
| 158 | NetworkResource res; |
| 159 | LinkedList<ExplicitPathInfo> list = Lists.newLinkedList(); |
| 160 | if ((explicitPathType < 0) || (explicitPathType > 1)) { |
| 161 | return null; |
| 162 | } |
| 163 | ExplicitPathInfo.Type type = ExplicitPathInfo.Type.values()[explicitPathType]; |
| 164 | String subType = node.get("subtype").asText(); |
| 165 | if (Integer.parseInt(subType) == 0) { |
| 166 | res = DeviceId.deviceId(node.get("value").asText()); |
| 167 | } else if (Integer.parseInt(subType) == 1) { |
| 168 | |
| 169 | String[] splitted = node.get("value").asText().split("/"); |
| 170 | |
| 171 | if (splitted[SOURCE_DEVICEID_INDEX] != null |
| 172 | && splitted[SOURCE_PORTNO_INDEX] != null |
| 173 | && splitted[DESTINATION_DEVICEID_INDEX] != null |
| 174 | && splitted[DESTINATION_PORTNO_INDEX] != null) { |
| 175 | return null; |
| 176 | } |
| 177 | deviceId = DeviceId.deviceId(splitted[SOURCE_DEVICEID_INDEX]); |
| 178 | portNo = PortNumber.portNumber(splitted[SOURCE_PORTNO_INDEX]); |
| 179 | ConnectPoint cpSrc = new ConnectPoint(deviceId, portNo); |
| 180 | deviceId = DeviceId.deviceId(splitted[DESTINATION_DEVICEID_INDEX]); |
| 181 | portNo = PortNumber.portNumber(splitted[DESTINATION_PORTNO_INDEX]); |
| 182 | ConnectPoint cpDst = new ConnectPoint(deviceId, portNo); |
| 183 | res = DefaultLink.builder() |
| 184 | .providerId(ProviderId.NONE) |
| 185 | .src(cpSrc) |
| 186 | .dst(cpDst) |
| 187 | .type(DIRECT) |
| 188 | .state(ACTIVE) |
| 189 | .build(); |
| 190 | } else { |
| 191 | return null; |
| 192 | } |
| 193 | |
| 194 | return new ExplicitPathInfo(type, res); |
| 195 | } |
| 196 | |
| 197 | private Collection<ExplicitPathInfo> jsonNodeToExplicitPathInfo(JsonNode explicitPathInfo) { |
| 198 | checkNotNull(explicitPathInfo, JSON_NOT_NULL); |
| 199 | |
| 200 | Integer i = 0; |
| 201 | NetworkResource res; |
| 202 | LinkedList<ExplicitPathInfo> list = Lists.newLinkedList(); |
| 203 | if (explicitPathInfo.isArray()) { |
| 204 | for (JsonNode node : explicitPathInfo) { |
| 205 | ExplicitPathInfo obj = createListOfExplicitPathObj(node); |
| 206 | if (obj == null) { |
| 207 | return null; |
| 208 | } |
| 209 | list.add(obj); |
| 210 | } |
| 211 | } else { |
| 212 | ExplicitPathInfo obj = createListOfExplicitPathObj(explicitPathInfo); |
| 213 | if (obj == null) { |
| 214 | return null; |
| 215 | } |
| 216 | list.add(obj); |
| 217 | } |
| 218 | |
| 219 | return Collections.unmodifiableCollection(list); |
| 220 | } |
| 221 | |
Mahesh Poojary S | d7a3692 | 2016-04-01 16:11:14 +0530 | [diff] [blame] | 222 | @Override |
| 223 | public ObjectNode encode(PcePath path, CodecContext context) { |
| 224 | checkNotNull(path, "path output cannot be null"); |
| 225 | ObjectNode result = context.mapper() |
| 226 | .createObjectNode() |
| 227 | .put(PATH_ID, path.id().id()) |
| 228 | .put(SOURCE, path.source()) |
| 229 | .put(DESTINATION, path.destination()) |
| 230 | .put(LSP_TYPE, path.lspType().type()) |
| 231 | .put(SYMBOLIC_PATH_NAME, path.name()); |
| 232 | |
| 233 | ObjectNode constraintNode = context.mapper() |
| 234 | .createObjectNode() |
Priyanka B | 3fdb9dd | 2016-08-08 10:47:24 +0530 | [diff] [blame] | 235 | .put(COST, ((CostConstraint) path.costConstraint()).type().type()) |
Satish K | 2eb5d84 | 2017-04-04 16:28:37 +0530 | [diff] [blame] | 236 | .put(BANDWIDTH, ((PceBandwidthConstraint) path.bandwidthConstraint()).bandwidth().bps()); |
Mahesh Poojary S | d7a3692 | 2016-04-01 16:11:14 +0530 | [diff] [blame] | 237 | |
Priyanka B | bae0eeb1 | 2016-11-30 11:59:48 +0530 | [diff] [blame] | 238 | if (path.explicitPathInfo() != null && !path.explicitPathInfo().isEmpty()) { |
| 239 | ArrayNode arrayNode = context.mapper().createArrayNode(); |
| 240 | for (ExplicitPathInfo e : path.explicitPathInfo()) { |
| 241 | ObjectNode node = context.mapper() |
| 242 | .createObjectNode() |
| 243 | .put("type", e.type().toString()) |
| 244 | .put("value", e.value().toString()); |
| 245 | arrayNode.add(node); |
| 246 | } |
| 247 | result.set(EXPLICIT_PATH_INFO, arrayNode); |
| 248 | } |
| 249 | |
Mahesh Poojary S | d7a3692 | 2016-04-01 16:11:14 +0530 | [diff] [blame] | 250 | result.set(CONSTRAINT, constraintNode); |
| 251 | return result; |
| 252 | } |
| 253 | } |