blob: b2d5d2f9e1540a844d2cd2309b4b796c27a54028 [file] [log] [blame]
Andreas Pantelopouloscd339592018-02-23 14:18:00 -08001/*
2 * Copyright 2015-present Open Networking Foundation
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.segmentrouting.web;
17
Andreas Pantelopoulos5bf13662018-04-10 19:34:47 -070018import com.fasterxml.jackson.databind.JsonNode;
Andreas Pantelopoulosffe69742018-03-20 13:58:49 -070019import com.fasterxml.jackson.databind.node.ArrayNode;
Andreas Pantelopouloscd339592018-02-23 14:18:00 -080020import com.fasterxml.jackson.databind.node.ObjectNode;
Laszlo Pappc5e85bb2018-04-04 16:17:52 +010021import org.apache.commons.lang3.tuple.Pair;
Andreas Pantelopouloscd339592018-02-23 14:18:00 -080022import org.onlab.packet.MplsLabel;
23import org.onlab.packet.VlanId;
24import org.onosproject.codec.CodecContext;
25import org.onosproject.codec.JsonCodec;
26import org.onosproject.net.ConnectPoint;
27import org.onosproject.segmentrouting.pwaas.DefaultL2Tunnel;
28import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelDescription;
29import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelPolicy;
30import org.onosproject.segmentrouting.pwaas.L2Mode;
Andreas Pantelopoulos5bf13662018-04-10 19:34:47 -070031import org.onosproject.segmentrouting.pwaas.L2TunnelDescription;
Andreas Pantelopouloscd339592018-02-23 14:18:00 -080032import org.slf4j.Logger;
33import org.slf4j.LoggerFactory;
34
Andreas Pantelopoulos5bf13662018-04-10 19:34:47 -070035import java.util.ArrayList;
Andreas Pantelopoulosffe69742018-03-20 13:58:49 -070036import java.util.List;
37
Andreas Pantelopouloscd339592018-02-23 14:18:00 -080038import static org.onosproject.segmentrouting.pwaas.PwaasUtil.*;
39
40/**
41 * Codec of PseudowireCodec class.
42 */
43public final class PseudowireCodec extends JsonCodec<DefaultL2TunnelDescription> {
44
45 // JSON field names
46 private static final String PW_ID = "pwId";
47 private static final String CP1 = "cP1";
48 private static final String CP2 = "cP2";
49 private static final String CP1_INNER_TAG = "cP1InnerTag";
50 private static final String CP1_OUTER_TAG = "cP1OuterTag";
51 private static final String CP2_INNER_TAG = "cP2InnerTag";
Phaneendra Manda9587dc92018-08-12 09:39:03 -070052 private static final String CP2_OUTER_TAG = "cP2OuterTag";
Andreas Pantelopouloscd339592018-02-23 14:18:00 -080053 private static final String MODE = "mode";
54 private static final String SERVICE_DELIM_TAG = "serviceTag";
55 private static final String PW_LABEL = "pwLabel";
56
Andreas Pantelopoulosffe69742018-03-20 13:58:49 -070057 // JSON field names for error in return
58 private static final String FAILED_PWS = "failedPws";
59 private static final String FAILED_PW = "pw";
60 private static final String REASON = "reason";
61
Andreas Pantelopouloscd339592018-02-23 14:18:00 -080062 private static Logger log = LoggerFactory
63 .getLogger(PseudowireCodec.class);
64
65 @Override
66 public ObjectNode encode(DefaultL2TunnelDescription pseudowire, CodecContext context) {
67 final ObjectNode result = context.mapper().createObjectNode()
68 .put(PW_ID, pseudowire.l2Tunnel().tunnelId());
69
70 result.put(CP1, pseudowire.l2TunnelPolicy().cP1().toString());
71 result.put(CP2, pseudowire.l2TunnelPolicy().cP2().toString());
72
73 result.put(CP1_INNER_TAG, pseudowire.l2TunnelPolicy().cP1InnerTag().toString());
74 result.put(CP1_OUTER_TAG, pseudowire.l2TunnelPolicy().cP1OuterTag().toString());
Andreas Pantelopouloscd339592018-02-23 14:18:00 -080075 result.put(CP2_INNER_TAG, pseudowire.l2TunnelPolicy().cP2InnerTag().toString());
76 result.put(CP2_OUTER_TAG, pseudowire.l2TunnelPolicy().cP2OuterTag().toString());
Andreas Pantelopoulos5bf13662018-04-10 19:34:47 -070077 result.put(SERVICE_DELIM_TAG, pseudowire.l2Tunnel().sdTag().toString());
Andreas Pantelopouloscd339592018-02-23 14:18:00 -080078
79 result.put(MODE, pseudowire.l2Tunnel().pwMode() == L2Mode.RAW ? "RAW" : "TAGGED");
Andreas Pantelopouloscd339592018-02-23 14:18:00 -080080 result.put(PW_LABEL, pseudowire.l2Tunnel().pwLabel().toString());
81
82 return result;
83 }
84
85 /**
Andreas Pantelopoulosffe69742018-03-20 13:58:49 -070086 * Encoded in an Object Node the pseudowire and the specificError it failed.
87 *
88 * @param failedPW The failed pseudowire
89 * @param specificError The specificError it failed
90 * @param context Our context
91 * @return A node containing the information we provided
92 */
93 public ObjectNode encodeError(DefaultL2TunnelDescription failedPW, String specificError,
94 CodecContext context) {
95 ObjectNode result = context.mapper().createObjectNode();
96
97 ObjectNode pw = encode(failedPW, context);
98 result.set(FAILED_PW, pw);
99 result.put(REASON, specificError);
100
101 return result;
102 }
103
104 /**
Andreas Pantelopoulos5bf13662018-04-10 19:34:47 -0700105 * Encoded in an Object Node the undecoed pseudowire and the specificError it failed.
106 *
107 * @param failedPW The failed pseudowire in json format
108 * @param specificError The specificError it failed
109 * @param context Our context
110 * @return A node containing the information we provided
111 */
112 public ObjectNode encodeError(JsonNode failedPW, String specificError,
113 CodecContext context) {
114 ObjectNode result = context.mapper().createObjectNode();
115
116 result.set(FAILED_PW, failedPW);
117 result.put(REASON, specificError);
118
119 return result;
120 }
121
122 /**
123 * Returns a JSON containing the failed pseudowires and the reason that they failed.
Andreas Pantelopoulosffe69742018-03-20 13:58:49 -0700124 *
125 * @param failedPws Pairs of pws and reasons.
Andreas Pantelopoulos5bf13662018-04-10 19:34:47 -0700126 * @param undecodedPws Pairs of pws that we could not decode with reason being illegal arguments.
Andreas Pantelopoulosffe69742018-03-20 13:58:49 -0700127 * @param context The context
128 * @return ObjectNode representing the json to return
129 */
130 public ObjectNode encodeFailedPseudowires(
131 List<Pair<DefaultL2TunnelDescription, String>> failedPws,
Andreas Pantelopoulos5bf13662018-04-10 19:34:47 -0700132 List<Pair<JsonNode, String>> undecodedPws,
Andreas Pantelopoulosffe69742018-03-20 13:58:49 -0700133 CodecContext context) {
134
135 ArrayNode failedNodes = context.mapper().createArrayNode();
136 failedPws.stream()
137 .forEach(failed -> failedNodes.add(encodeError(failed.getKey(), failed.getValue(), context)));
Andreas Pantelopoulos5bf13662018-04-10 19:34:47 -0700138 undecodedPws.stream()
139 .forEach(failed -> failedNodes.add(encodeError(failed.getKey(), failed.getValue(), context)));
Andreas Pantelopoulosffe69742018-03-20 13:58:49 -0700140 final ObjectNode toReturn = context.mapper().createObjectNode();
141 toReturn.set(FAILED_PWS, failedNodes);
142 return toReturn;
143 }
144
145 /**
Andreas Pantelopoulos5bf13662018-04-10 19:34:47 -0700146 *
147 * @param json The json containing the pseudowires.
148 * @param context The context
149 * @return A pair of lists.
150 * First list contains pseudowires that we were not able to decode
151 * along with the reason we could not decode them.
152 * Second list contains successfully decoded pseudowires which we are
153 * going to instantiate.
154 */
155 public Pair<List<Pair<JsonNode, String>>, List<L2TunnelDescription>> decodePws(ArrayNode json,
156 CodecContext context) {
157
158 List<L2TunnelDescription> decodedPws = new ArrayList<>();
159 List<Pair<JsonNode, String>> notDecodedPws = new ArrayList<>();
160 for (JsonNode node : json) {
161 DefaultL2TunnelDescription l2Description;
162 try {
163 l2Description = decode((ObjectNode) node, context);
164 decodedPws.add(l2Description);
165 } catch (IllegalArgumentException e) {
166 // the reason why we could not decode this pseudowire is encoded in the
167 // exception, we need to store it now
168 notDecodedPws.add(Pair.of(node, e.getMessage()));
169 }
170 }
171
172 return Pair.of(notDecodedPws, decodedPws);
173 }
174
175 /**
Andreas Pantelopouloscd339592018-02-23 14:18:00 -0800176 * Decodes a json containg a single field with the pseudowire id.
177 *
178 * @param json Json to decode.
179 * @return The pseudowire id.
180 */
Andreas Pantelopoulosff691b72018-03-12 16:30:20 -0700181 public static Integer decodeId(ObjectNode json) {
Andreas Pantelopouloscd339592018-02-23 14:18:00 -0800182
Andreas Pantelopoulos5bf13662018-04-10 19:34:47 -0700183 Integer id;
184 try {
185 id = parsePwId(json.path(PW_ID).asText());
186 } catch (IllegalArgumentException e) {
Andreas Pantelopouloscd339592018-02-23 14:18:00 -0800187 log.error("Pseudowire id is not an integer!");
188 return null;
189 }
190
191 return id;
192 }
193
194 @Override
195 public DefaultL2TunnelDescription decode(ObjectNode json, CodecContext context) {
196
Andreas Pantelopouloscd339592018-02-23 14:18:00 -0800197 Integer id = parsePwId(json.path(PW_ID).asText());
Andreas Pantelopouloscd339592018-02-23 14:18:00 -0800198
199 ConnectPoint cP1, cP2;
Andreas Pantelopoulos5bf13662018-04-10 19:34:47 -0700200 cP1 = ConnectPoint.deviceConnectPoint(json.path(CP1).asText());
201 cP2 = ConnectPoint.deviceConnectPoint(json.path(CP2).asText());
Andreas Pantelopouloscd339592018-02-23 14:18:00 -0800202
Andreas Pantelopoulos5bf13662018-04-10 19:34:47 -0700203 VlanId cP1InnerVlan, cP1OuterVlan, cP2InnerVlan, cP2OuterVlan, sdTag;
204 cP1InnerVlan = parseVlan(json.path(CP1_INNER_TAG).asText());
205 cP1OuterVlan = parseVlan(json.path(CP1_OUTER_TAG).asText());
206 cP2InnerVlan = parseVlan(json.path(CP2_INNER_TAG).asText());
207 cP2OuterVlan = parseVlan(json.path(CP2_OUTER_TAG).asText());
208 sdTag = parseVlan(json.path(SERVICE_DELIM_TAG).asText());
Andreas Pantelopouloscd339592018-02-23 14:18:00 -0800209
210 L2Mode mode = parseMode(json.path(MODE).asText());
Andreas Pantelopouloscd339592018-02-23 14:18:00 -0800211 MplsLabel pwLabel = parsePWLabel(json.path(PW_LABEL).asText());
Andreas Pantelopouloscd339592018-02-23 14:18:00 -0800212
Andreas Pantelopoulos5bf13662018-04-10 19:34:47 -0700213 DefaultL2Tunnel l2Tunnel = new DefaultL2Tunnel(mode, sdTag, id, pwLabel);
214 DefaultL2TunnelPolicy l2Policy = new DefaultL2TunnelPolicy(id, cP1, cP1InnerVlan, cP1OuterVlan,
Andreas Pantelopouloscd339592018-02-23 14:18:00 -0800215 cP2, cP2InnerVlan, cP2OuterVlan);
Andreas Pantelopouloscd339592018-02-23 14:18:00 -0800216 return new DefaultL2TunnelDescription(l2Tunnel, l2Policy);
217
218 }
219}