blob: 1a713466fc8a8c127593ec8e071109b122cbedee [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 Pantelopoulosff691b72018-03-12 16:30:20 -070018import com.fasterxml.jackson.databind.JsonNode;
Andreas Pantelopouloscd339592018-02-23 14:18:00 -080019import com.fasterxml.jackson.databind.ObjectMapper;
Andreas Pantelopoulosff691b72018-03-12 16:30:20 -070020import com.fasterxml.jackson.databind.node.ArrayNode;
Andreas Pantelopouloscd339592018-02-23 14:18:00 -080021import com.fasterxml.jackson.databind.node.ObjectNode;
Andreas Pantelopoulosff691b72018-03-12 16:30:20 -070022import org.onlab.util.ItemNotFoundException;
Andreas Pantelopouloscd339592018-02-23 14:18:00 -080023import org.onosproject.rest.AbstractWebResource;
24import org.onosproject.segmentrouting.SegmentRoutingService;
25import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelDescription;
26import org.onosproject.segmentrouting.pwaas.L2TunnelPolicy;
27import org.onosproject.segmentrouting.pwaas.L2Tunnel;
28import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
29import org.slf4j.Logger;
30import org.slf4j.LoggerFactory;
31
32import javax.ws.rs.Consumes;
33import javax.ws.rs.DELETE;
34import javax.ws.rs.GET;
35import javax.ws.rs.POST;
36import javax.ws.rs.Path;
37import javax.ws.rs.Produces;
38import javax.ws.rs.core.MediaType;
39import javax.ws.rs.core.Response;
40import java.io.IOException;
41import java.io.InputStream;
Andreas Pantelopoulosff691b72018-03-12 16:30:20 -070042import java.util.ArrayList;
Andreas Pantelopouloscd339592018-02-23 14:18:00 -080043import java.util.List;
44import java.util.stream.Collectors;
45
Andreas Pantelopoulosff691b72018-03-12 16:30:20 -070046import static org.onlab.util.Tools.nullIsIllegal;
47
Andreas Pantelopouloscd339592018-02-23 14:18:00 -080048/**
49 * Query, create and remove pseudowires.
50 */
51@Path("pseudowire")
52public class PseudowireWebResource extends AbstractWebResource {
53
54 private static final PseudowireCodec PSEUDOWIRE_CODEC = new PseudowireCodec();
Andreas Pantelopoulosff691b72018-03-12 16:30:20 -070055 public static final String PWS = "pseudowires";
56 private static final String PWS_KEY_ERROR = "Pseudowires key must be present.";
Andreas Pantelopouloscd339592018-02-23 14:18:00 -080057
58 private static Logger log = LoggerFactory
59 .getLogger(PseudowireWebResource.class);
60
61 /**
62 * Get all pseudowires.
63 * Returns an array of pseudowires.
64 *
65 * @return status of OK
66 */
67 @GET
68 @Produces(MediaType.APPLICATION_JSON)
69 public Response getPseudowire() {
70 SegmentRoutingService srService = get(SegmentRoutingService.class);
71
72 log.debug("Fetching pseudowires form rest api!");
73
74 List<L2TunnelPolicy> policies = srService.getL2Policies();
75 List<L2Tunnel> tunnels = srService.getL2Tunnels();
76 List<DefaultL2TunnelDescription> pseudowires = tunnels.stream()
77 .map(l2Tunnel -> {
78 L2TunnelPolicy policy = null;
79 for (L2TunnelPolicy l2Policy : policies) {
80 if (l2Policy.tunnelId() == l2Tunnel.tunnelId()) {
81 policy = l2Policy;
82 break;
83 }
84 }
85
86 // return a copy
87 return new DefaultL2TunnelDescription(l2Tunnel, policy);
88 })
89 .collect(Collectors.toList());
90
91 ObjectNode result = new ObjectMapper().createObjectNode();
92 result.set("pseudowires", new PseudowireCodec().encode(pseudowires, this));
93
94 return ok(result.toString()).build();
95 }
96
97 /**
98 * Create a new pseudowire.
99 *
100 * @param input JSON stream for pseudowire to create
101 * @return Response with appropriate status
102 * @throws IOException Throws IO exception.
103 * @onos.rsModel PseudowireCreate
104 */
105 @POST
106 @Consumes(MediaType.APPLICATION_JSON)
107 public Response createPseudowire(InputStream input) throws IOException {
108
109 ObjectMapper mapper = new ObjectMapper();
110 ObjectNode pseudowireJson = (ObjectNode) mapper.readTree(input);
111 SegmentRoutingService srService = get(SegmentRoutingService.class);
112
113 DefaultL2TunnelDescription pseudowire = PSEUDOWIRE_CODEC.decode(pseudowireJson, this);
114 if (pseudowire == null) {
115 return Response.serverError().status(Response.Status.BAD_REQUEST).build();
116 }
117
Andreas Pantelopoulosff691b72018-03-12 16:30:20 -0700118 log.debug("Creating pseudowire {} from rest api!", pseudowire.l2Tunnel().tunnelId());
Andreas Pantelopouloscd339592018-02-23 14:18:00 -0800119
120 L2TunnelHandler.Result res = srService.addPseudowire(pseudowire);
121 switch (res) {
122 case ADDITION_ERROR:
123 log.error("Pseudowire {} could not be added, error in configuration," +
124 " please check logs for more details!",
125 pseudowire.l2Tunnel().tunnelId());
126 return Response.serverError().status(Response.Status.INTERNAL_SERVER_ERROR).build();
127
128 case SUCCESS:
Andreas Pantelopoulosff691b72018-03-12 16:30:20 -0700129 log.debug("Pseudowire {} succesfully deployed!", pseudowire.l2Tunnel().tunnelId());
130 return Response.ok().build();
131 default:
132 return Response.ok().build();
133 }
134 }
135
136 /**
137 * Create a bulk of pseudowires.
138 *
139 * @param input JSON stream for pseudowires to create
140 * @return Response with appropriate status
141 * @throws IOException Throws IO exception.
142 * @onos.rsModel PseudowireCreateBulk
143 */
144 @POST
145 @Path("/bulk")
146 @Consumes(MediaType.APPLICATION_JSON)
147 public Response createPseudowiresBulk(InputStream input) throws IOException {
148
149 ObjectMapper mapper = new ObjectMapper();
150 ObjectNode pseudowireJson = (ObjectNode) mapper.readTree(input);
151 SegmentRoutingService srService = get(SegmentRoutingService.class);
152 List<DefaultL2TunnelDescription> pseudowires;
153
154 try {
155 ArrayNode pseudowiresArray = nullIsIllegal((ArrayNode) pseudowireJson.get(PWS), PWS_KEY_ERROR);
156 pseudowires = PSEUDOWIRE_CODEC.decode(pseudowiresArray, this);
157 } catch (ItemNotFoundException e) {
158 return Response.serverError().status(Response.Status.BAD_REQUEST).build();
159 }
160
161 log.debug("Creating pseudowires {} from rest api!", pseudowires);
162
163 L2TunnelHandler.Result res = srService.addPseudowiresBulk(pseudowires);
164 switch (res) {
165 case ADDITION_ERROR:
166 log.error("Bulk of pseudowires {} could not be added, error in configuration," +
167 " please check logs for more details!",
168 pseudowires);
169 return Response.serverError().status(Response.Status.INTERNAL_SERVER_ERROR).build();
170
171 case SUCCESS:
172 log.debug("Bulk of pseudowires {} succesfully deployed!", pseudowires);
Andreas Pantelopouloscd339592018-02-23 14:18:00 -0800173 return Response.ok().build();
174 default:
175 return Response.ok().build();
176 }
177 }
178
179 /**
180 * Delete a pseudowire.
181 *
182 * @param input JSON stream for pseudowire to delete
183 * @return Response with appropriate status
184 * @throws IOException Throws IO exception.
185 * @onos.rsModel PseudowireDelete
186 */
187 @DELETE
188 @Consumes(MediaType.APPLICATION_JSON)
189 public Response removePseudowire(InputStream input) throws IOException {
190
191 ObjectMapper mapper = new ObjectMapper();
192 ObjectNode pseudowireJson = (ObjectNode) mapper.readTree(input);
193 SegmentRoutingService srService = get(SegmentRoutingService.class);
194
195 Integer pseudowireId = PSEUDOWIRE_CODEC.decodeId(pseudowireJson);
196 if (pseudowireId == null) {
197 return Response.serverError().status(Response.Status.BAD_REQUEST).build();
198 }
199
Andreas Pantelopoulosff691b72018-03-12 16:30:20 -0700200 log.debug("Deleting pseudowire {} from rest api!", pseudowireId);
Andreas Pantelopouloscd339592018-02-23 14:18:00 -0800201
202 L2TunnelHandler.Result res = srService.removePseudowire(pseudowireId);
203 switch (res) {
204 case REMOVAL_ERROR:
205 log.error("Pseudowire {} could not be removed, error in configuration," +
206 " please check logs for more details!",
207 pseudowireId);
208
209 return Response.noContent().build();
210 case SUCCESS:
Andreas Pantelopoulosff691b72018-03-12 16:30:20 -0700211 log.debug("Pseudowire {} was removed succesfully!", pseudowireId);
Andreas Pantelopouloscd339592018-02-23 14:18:00 -0800212 return Response.noContent().build();
213 default:
214 return Response.noContent().build();
215 }
216 }
Andreas Pantelopoulosff691b72018-03-12 16:30:20 -0700217
218 /**
219 * Delete a bulk of pseudowires.
220 *
221 * @param input JSON stream for pseudowires to delete
222 * @return Response with appropriate status
223 * @throws IOException Throws IO exception.
224 * @onos.rsModel PseudowireDeleteBulk
225 */
226 @DELETE
227 @Path("/bulk")
228 @Consumes(MediaType.APPLICATION_JSON)
229 public Response removePseudowiresBulk(InputStream input) throws IOException {
230
231 ObjectMapper mapper = new ObjectMapper();
232 ObjectNode pseudowireJson = (ObjectNode) mapper.readTree(input);
233 SegmentRoutingService srService = get(SegmentRoutingService.class);
234
235 List<Integer> ids = new ArrayList<>();
236
237 // try to parse all ids, if key is not present, or if an id is not an int
238 // throw an exception and stop process
239 try {
240 for (JsonNode node : pseudowireJson.withArray(PWS)) {
241 Integer idToDelete = PseudowireCodec.decodeId((ObjectNode) node);
242 if (idToDelete == null) {
243 log.error("Error when parsing pseudowire for deletion in REST API.");
244 throw new IllegalArgumentException("Id of pseudowire should be an integer!");
245 }
246 ids.add(idToDelete);
247 }
248 } catch (IllegalArgumentException e) {
249 log.error("Pseudowire ID should be an integer.");
250 return Response.serverError().status(Response.Status.BAD_REQUEST).build();
251 } catch (UnsupportedOperationException e) {
252 log.error("Pseudowires for deletion should be an array of pseudowire ids.");
253 return Response.serverError().status(Response.Status.BAD_REQUEST).build();
254 }
255
256 for (Integer pseudowireId : ids) {
257 L2TunnelHandler.Result res = srService.removePseudowire(pseudowireId);
258 switch (res) {
259 case REMOVAL_ERROR:
260 log.error("Pseudowire {} could not be removed, error in configuration," +
261 " please check logs for more details!",
262 pseudowireId);
263 case SUCCESS:
264 log.debug("Pseudowire {} was removed succesfully!", pseudowireId);
265 default:
266 }
267 }
268
269 return Response.noContent().build();
270 }
Andreas Pantelopouloscd339592018-02-23 14:18:00 -0800271}