blob: 00d20a776e569e31432405cb529b34b8a49c272c [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 Pantelopoulosffe69742018-03-20 13:58:49 -070018import com.fasterxml.jackson.databind.node.ArrayNode;
Andreas Pantelopouloscd339592018-02-23 14:18:00 -080019import com.fasterxml.jackson.databind.node.ObjectNode;
Laszlo Pappc5e85bb2018-04-04 16:17:52 +010020import org.apache.commons.lang3.tuple.Pair;
Andreas Pantelopouloscd339592018-02-23 14:18:00 -080021import org.onlab.packet.MplsLabel;
22import org.onlab.packet.VlanId;
23import org.onosproject.codec.CodecContext;
24import org.onosproject.codec.JsonCodec;
25import org.onosproject.net.ConnectPoint;
26import org.onosproject.segmentrouting.pwaas.DefaultL2Tunnel;
27import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelDescription;
28import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelPolicy;
29import org.onosproject.segmentrouting.pwaas.L2Mode;
30import org.slf4j.Logger;
31import org.slf4j.LoggerFactory;
32
Andreas Pantelopoulosffe69742018-03-20 13:58:49 -070033import java.util.List;
34
Andreas Pantelopouloscd339592018-02-23 14:18:00 -080035import static org.onosproject.segmentrouting.pwaas.PwaasUtil.*;
36
37/**
38 * Codec of PseudowireCodec class.
39 */
40public final class PseudowireCodec extends JsonCodec<DefaultL2TunnelDescription> {
41
42 // JSON field names
43 private static final String PW_ID = "pwId";
44 private static final String CP1 = "cP1";
45 private static final String CP2 = "cP2";
46 private static final String CP1_INNER_TAG = "cP1InnerTag";
47 private static final String CP1_OUTER_TAG = "cP1OuterTag";
48 private static final String CP2_INNER_TAG = "cP2InnerTag";
49 private static final String CP2_OUTER_TAG = "cP2OouterTag";
50 private static final String MODE = "mode";
51 private static final String SERVICE_DELIM_TAG = "serviceTag";
52 private static final String PW_LABEL = "pwLabel";
53
Andreas Pantelopoulosffe69742018-03-20 13:58:49 -070054 // JSON field names for error in return
55 private static final String FAILED_PWS = "failedPws";
56 private static final String FAILED_PW = "pw";
57 private static final String REASON = "reason";
58
Andreas Pantelopouloscd339592018-02-23 14:18:00 -080059 private static Logger log = LoggerFactory
60 .getLogger(PseudowireCodec.class);
61
62 @Override
63 public ObjectNode encode(DefaultL2TunnelDescription pseudowire, CodecContext context) {
64 final ObjectNode result = context.mapper().createObjectNode()
65 .put(PW_ID, pseudowire.l2Tunnel().tunnelId());
66
67 result.put(CP1, pseudowire.l2TunnelPolicy().cP1().toString());
68 result.put(CP2, pseudowire.l2TunnelPolicy().cP2().toString());
69
70 result.put(CP1_INNER_TAG, pseudowire.l2TunnelPolicy().cP1InnerTag().toString());
71 result.put(CP1_OUTER_TAG, pseudowire.l2TunnelPolicy().cP1OuterTag().toString());
72
73
74 result.put(CP2_INNER_TAG, pseudowire.l2TunnelPolicy().cP2InnerTag().toString());
75 result.put(CP2_OUTER_TAG, pseudowire.l2TunnelPolicy().cP2OuterTag().toString());
76
77 result.put(MODE, pseudowire.l2Tunnel().pwMode() == L2Mode.RAW ? "RAW" : "TAGGED");
78 result.put(SERVICE_DELIM_TAG, pseudowire.l2Tunnel().sdTag().toString());
79 result.put(PW_LABEL, pseudowire.l2Tunnel().pwLabel().toString());
80
81 return result;
82 }
83
84 /**
Andreas Pantelopoulosffe69742018-03-20 13:58:49 -070085 * Encoded in an Object Node the pseudowire and the specificError it failed.
86 *
87 * @param failedPW The failed pseudowire
88 * @param specificError The specificError it failed
89 * @param context Our context
90 * @return A node containing the information we provided
91 */
92 public ObjectNode encodeError(DefaultL2TunnelDescription failedPW, String specificError,
93 CodecContext context) {
94 ObjectNode result = context.mapper().createObjectNode();
95
96 ObjectNode pw = encode(failedPW, context);
97 result.set(FAILED_PW, pw);
98 result.put(REASON, specificError);
99
100 return result;
101 }
102
103 /**
104 * Returns a JSON containing the failed pseudowires and the reason that its one failed.
105 *
106 * @param failedPws Pairs of pws and reasons.
107 * @param context The context
108 * @return ObjectNode representing the json to return
109 */
110 public ObjectNode encodeFailedPseudowires(
111 List<Pair<DefaultL2TunnelDescription, String>> failedPws,
112 CodecContext context) {
113
114 ArrayNode failedNodes = context.mapper().createArrayNode();
115 failedPws.stream()
116 .forEach(failed -> failedNodes.add(encodeError(failed.getKey(), failed.getValue(), context)));
117 final ObjectNode toReturn = context.mapper().createObjectNode();
118 toReturn.set(FAILED_PWS, failedNodes);
119 return toReturn;
120 }
121
122 /**
Andreas Pantelopouloscd339592018-02-23 14:18:00 -0800123 * Decodes a json containg a single field with the pseudowire id.
124 *
125 * @param json Json to decode.
126 * @return The pseudowire id.
127 */
Andreas Pantelopoulosff691b72018-03-12 16:30:20 -0700128 public static Integer decodeId(ObjectNode json) {
Andreas Pantelopouloscd339592018-02-23 14:18:00 -0800129
130 Integer id = parsePwId(json.path(PW_ID).asText());
131 if (id == null) {
132 log.error("Pseudowire id is not an integer!");
133 return null;
134 }
135
136 return id;
137 }
138
139 @Override
140 public DefaultL2TunnelDescription decode(ObjectNode json, CodecContext context) {
141
142 String tempString;
143
144 Integer id = parsePwId(json.path(PW_ID).asText());
145 if (id == null) {
146 log.error("Pseudowire id is not an integer");
147 return null;
148 }
149
150 ConnectPoint cP1, cP2;
151 try {
152 tempString = json.path(CP1).asText();
153 cP1 = ConnectPoint.deviceConnectPoint(tempString);
154 } catch (Exception e) {
155 log.error("cP1 is not a valid connect point!");
156 return null;
157 }
158
159 try {
160 tempString = json.path(CP2).asText();
161 cP2 = ConnectPoint.deviceConnectPoint(tempString);
162 } catch (Exception e) {
163 log.error("cP2 is not a valid connect point!");
164 return null;
165 }
166
167 VlanId cP1InnerVlan = parseVlan(json.path(CP1_INNER_TAG).asText());
168 VlanId cP1OuterVlan = parseVlan(json.path(CP1_OUTER_TAG).asText());
169 VlanId cP2InnerVlan = parseVlan(json.path(CP2_INNER_TAG).asText());
170 VlanId cP2OuterVlan = parseVlan(json.path(CP2_OUTER_TAG).asText());
171 if ((cP1InnerVlan == null) || (cP1OuterVlan == null) ||
172 (cP2InnerVlan == null) || (cP2OuterVlan == null)) {
173 log.error("One or more vlan for cp1 or cp2 is malformed, it shouldbe an integer / Any / None / *");
174 return null;
175 }
176
177 L2Mode mode = parseMode(json.path(MODE).asText());
178 if (mode == null) {
179 log.error("Mode should be RAW or TAGGED!");
180 return null;
181 }
182
183 VlanId sdTag = parseVlan(json.path(SERVICE_DELIM_TAG).asText());
184 if (sdTag == null) {
185 log.error("SD tag is malformed, it should be an integer / Any / None / *");
186 return null;
187 }
188
189 MplsLabel pwLabel = parsePWLabel(json.path(PW_LABEL).asText());
190 if (pwLabel == null) {
191 log.error("PW label is malformed, should be an integer!");
192 return null;
193 }
194
195 DefaultL2Tunnel l2Tunnel;
196 DefaultL2TunnelPolicy l2Policy;
197
198 l2Tunnel = new DefaultL2Tunnel(mode, sdTag, id, pwLabel);
199 l2Policy = new DefaultL2TunnelPolicy(id, cP1, cP1InnerVlan, cP1OuterVlan,
200 cP2, cP2InnerVlan, cP2OuterVlan);
201
202 return new DefaultL2TunnelDescription(l2Tunnel, l2Policy);
203
204 }
205}