blob: e4ff608e8885f61e02050c4cde2b0765b24b4ca1 [file] [log] [blame]
Andrea Campanella545edb42018-03-20 16:37:29 -07001/*
2 * Copyright 2017-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 */
16
17package org.onosproject.mcast.web;
18
Andrea Campanella644a8a62018-03-21 19:08:21 -070019import com.fasterxml.jackson.databind.node.ArrayNode;
20import com.fasterxml.jackson.databind.node.ObjectNode;
Andrea Campanella545edb42018-03-20 16:37:29 -070021import com.google.common.annotations.Beta;
Andrea Campanella644a8a62018-03-21 19:08:21 -070022import org.onlab.packet.IpAddress;
23import org.onosproject.mcast.api.McastRoute;
24import org.onosproject.mcast.api.MulticastRouteService;
25import org.onosproject.net.ConnectPoint;
26import org.onosproject.net.HostId;
Andrea Campanella545edb42018-03-20 16:37:29 -070027import org.onosproject.rest.AbstractWebResource;
28
Andrea Campanella644a8a62018-03-21 19:08:21 -070029import javax.ws.rs.Consumes;
30import javax.ws.rs.DELETE;
Andrea Campanella545edb42018-03-20 16:37:29 -070031import javax.ws.rs.GET;
Andrea Campanella644a8a62018-03-21 19:08:21 -070032import javax.ws.rs.POST;
Andrea Campanella545edb42018-03-20 16:37:29 -070033import javax.ws.rs.Path;
Andrea Campanella644a8a62018-03-21 19:08:21 -070034import javax.ws.rs.PathParam;
Andrea Campanella545edb42018-03-20 16:37:29 -070035import javax.ws.rs.Produces;
36import javax.ws.rs.core.MediaType;
37import javax.ws.rs.core.Response;
Andrea Campanella644a8a62018-03-21 19:08:21 -070038import java.io.IOException;
39import java.io.InputStream;
40import java.net.URI;
41import java.util.HashSet;
42import java.util.List;
43import java.util.Optional;
44import java.util.Set;
45
46import static org.onlab.util.Tools.nullIsIllegal;
Andrea Campanella545edb42018-03-20 16:37:29 -070047
48/**
49 * Manage the multicast routing information.
50 */
51@Beta
52@Path("mcast")
53public class McastRouteWebResource extends AbstractWebResource {
54
Andrea Campanella644a8a62018-03-21 19:08:21 -070055 //TODO return error messages
56
57 private static final String SOURCES = "sources";
58 private static final String SINKS = "sinks";
59 private static final String ROUTES = "routes";
60 private static final String ROUTES_KEY_ERROR = "No routes";
61 private static final String ASM = "*";
62
63 private Optional<McastRoute> getStaticRoute(Set<McastRoute> mcastRoutes) {
64 return mcastRoutes.stream()
65 .filter(mcastRoute -> mcastRoute.type() == McastRoute.Type.STATIC)
66 .findAny();
67 }
68
Andrea Campanella545edb42018-03-20 16:37:29 -070069 /**
70 * Get all multicast routes.
71 * Returns array of all known multicast routes.
72 *
73 * @return 200 OK with array of all known multicast routes
74 */
75 @GET
76 @Produces(MediaType.APPLICATION_JSON)
77 public Response getRoutes() {
Andrea Campanella644a8a62018-03-21 19:08:21 -070078 Set<McastRoute> routes = get(MulticastRouteService.class).getRoutes();
79 ObjectNode root = encodeArray(McastRoute.class, ROUTES, routes);
80 return ok(root).build();
81 }
82
83 /**
84 * Gets a multicast route.
85 *
86 * @param group group IP address
87 * @param srcIp source IP address
88 * @return 200 OK with a multicast routes
89 */
90 @GET
91 @Produces(MediaType.APPLICATION_JSON)
92 @Path("{group}/{srcIp}")
93 public Response getRoute(@PathParam("group") String group,
94 @PathParam("srcIp") String srcIp) {
95 Optional<McastRoute> route = getMcastRoute(group, srcIp);
96 if (route.isPresent()) {
97 ObjectNode root = encode(route.get(), McastRoute.class);
98 return ok(root).build();
99 }
Andrea Campanella545edb42018-03-20 16:37:29 -0700100 return Response.noContent().build();
101 }
102
Andrea Campanella644a8a62018-03-21 19:08:21 -0700103 /**
104 * Get all sources connect points for a multicast route.
105 *
106 * @param group group IP address
107 * @param srcIp source IP address
108 * @return 200 OK with array of all sources for multicast route
109 */
110 @GET
111 @Produces(MediaType.APPLICATION_JSON)
112 @Path("sources/{group}/{srcIp}")
113 public Response getSources(@PathParam("group") String group,
114 @PathParam("srcIp") String srcIp) {
115 Optional<McastRoute> route = getMcastRoute(group, srcIp);
116 if (route.isPresent()) {
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200117 ObjectNode sources = this.mapper().createObjectNode();
118 get(MulticastRouteService.class).routeData(route.get()).sources().forEach((k, v) -> {
119 ArrayNode node = this.mapper().createArrayNode();
120 v.forEach(source -> {
121 node.add(source.toString());
122 });
123 sources.putPOJO(k.toString(), node);
Andrea Campanella644a8a62018-03-21 19:08:21 -0700124 });
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200125 ObjectNode root = this.mapper().createObjectNode().putPOJO(SOURCES, sources);
Andrea Campanella644a8a62018-03-21 19:08:21 -0700126 return ok(root).build();
127 }
128 return Response.noContent().build();
129 }
130
131 /**
Andrea Campanella663b14c2018-04-05 20:52:03 +0200132 * Get all HostId sinks and their connect points for a multicast route.
Andrea Campanella644a8a62018-03-21 19:08:21 -0700133 *
134 * @param group group IP address
135 * @param srcIp source IP address
136 * @return 200 OK with array of all sinks for multicast route
137 */
138 @GET
139 @Produces(MediaType.APPLICATION_JSON)
140 @Path("sinks/{group}/{srcIp}")
141 public Response getSinks(@PathParam("group") String group,
142 @PathParam("srcIp") String srcIp) {
143 Optional<McastRoute> route = getMcastRoute(group, srcIp);
144 if (route.isPresent()) {
Andrea Campanella644a8a62018-03-21 19:08:21 -0700145 ObjectNode sinks = this.mapper().createObjectNode();
146 get(MulticastRouteService.class).routeData(route.get()).sinks().forEach((k, v) -> {
147 ArrayNode node = this.mapper().createArrayNode();
148 v.forEach(sink -> {
149 node.add(sink.toString());
150 });
151 sinks.putPOJO(k.toString(), node);
152 });
153 ObjectNode root = this.mapper().createObjectNode().putPOJO(SINKS, sinks);
154 return ok(root).build();
155 }
156 return Response.noContent().build();
157 }
158
159 /**
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200160 * Get all source connect points for a given sink host in a multicast route.
161 *
162 * @param group group IP address
163 * @param srcIp source IP address
164 * @param hostId host Id
165 * @return 200 OK with array of all sources for multicast route
166 */
167 @GET
168 @Produces(MediaType.APPLICATION_JSON)
169 @Path("sources/{group}/{srcIp}/{hostId}")
170 public Response getHostSources(@PathParam("group") String group,
171 @PathParam("srcIp") String srcIp,
172 @PathParam("hostId") String hostId) {
173 Optional<McastRoute> route = getMcastRoute(group, srcIp);
174 if (route.isPresent()) {
175 ArrayNode node = this.mapper().createArrayNode();
176 get(MulticastRouteService.class).sources(route.get(), HostId.hostId(hostId))
177 .forEach(source -> {
178 node.add(source.toString());
179 });
180 ObjectNode root = this.mapper().createObjectNode().putPOJO(SOURCES, node);
181 return ok(root).build();
182 }
183 return Response.noContent().build();
184 }
185
186 /**
Andrea Campanella644a8a62018-03-21 19:08:21 -0700187 * Get all sink connect points for a given sink host in a multicast route.
188 *
189 * @param group group IP address
190 * @param srcIp source IP address
191 * @param hostId host Id
192 * @return 200 OK with array of all sinks for multicast route
193 */
194 @GET
195 @Produces(MediaType.APPLICATION_JSON)
196 @Path("sinks/{group}/{srcIp}/{hostId}")
197 public Response getHostSinks(@PathParam("group") String group,
198 @PathParam("srcIp") String srcIp,
199 @PathParam("hostId") String hostId) {
200 Optional<McastRoute> route = getMcastRoute(group, srcIp);
201 if (route.isPresent()) {
Andrea Campanella644a8a62018-03-21 19:08:21 -0700202 ArrayNode node = this.mapper().createArrayNode();
203 get(MulticastRouteService.class).sinks(route.get(), HostId.hostId(hostId))
204 .forEach(source -> {
205 node.add(source.toString());
206 });
207 ObjectNode root = this.mapper().createObjectNode().putPOJO(SINKS, node);
208 return ok(root).build();
209 }
210 return Response.noContent().build();
211 }
212
213 /**
214 * Creates a set of new multicast routes.
215 *
216 * @param stream multicast routes JSON
217 * @return status of the request - CREATED if the JSON is correct,
218 * BAD_REQUEST if the JSON is invalid
219 * @onos.rsModel McastRouteBulk
220 */
221 @POST
222 @Consumes(MediaType.APPLICATION_JSON)
223 @Path("bulk/")
224 public Response createRoutes(InputStream stream) {
225 MulticastRouteService service = get(MulticastRouteService.class);
226 try {
227 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
228 ArrayNode routesArray = nullIsIllegal((ArrayNode) jsonTree.get(ROUTES),
229 ROUTES_KEY_ERROR);
230 routesArray.forEach(routeJson -> {
231 McastRoute route = codec(McastRoute.class).decode((ObjectNode) routeJson, this);
232 service.add(route);
233
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200234 Set<HostId> sources = new HashSet<>();
Andrea Campanella644a8a62018-03-21 19:08:21 -0700235 routeJson.path(SOURCES).elements().forEachRemaining(src -> {
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200236 sources.add(HostId.hostId(src.asText()));
Andrea Campanella644a8a62018-03-21 19:08:21 -0700237 });
238 Set<HostId> sinks = new HashSet<>();
239 routeJson.path(SINKS).elements().forEachRemaining(sink -> {
240 sinks.add(HostId.hostId(sink.asText()));
241 });
242
243 if (!sources.isEmpty()) {
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200244 sources.forEach(source -> {
245 service.addSource(route, source);
246 });
Andrea Campanella644a8a62018-03-21 19:08:21 -0700247 }
248 if (!sinks.isEmpty()) {
249 sinks.forEach(sink -> {
250 service.addSink(route, sink);
251 });
252 }
253 });
254 } catch (IOException ex) {
255 throw new IllegalArgumentException(ex);
256 }
257
258 return Response
259 .created(URI.create(""))
260 .build();
261 }
262
263 /**
264 * Create new multicast route.
265 *
266 * @param stream multicast route JSON
267 * @return status of the request - CREATED if the JSON is correct,
268 * BAD_REQUEST if the JSON is invalid
269 * @onos.rsModel McastRoute
270 */
271 @POST
272 @Consumes(MediaType.APPLICATION_JSON)
273 public Response createRoute(InputStream stream) {
274 MulticastRouteService service = get(MulticastRouteService.class);
275 try {
276 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
277 McastRoute route = codec(McastRoute.class).decode(jsonTree, this);
278 service.add(route);
279
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200280 Set<HostId> sources = new HashSet<>();
Andrea Campanella644a8a62018-03-21 19:08:21 -0700281 jsonTree.path(SOURCES).elements().forEachRemaining(src -> {
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200282 sources.add(HostId.hostId(src.asText()));
Andrea Campanella644a8a62018-03-21 19:08:21 -0700283 });
284 Set<HostId> sinks = new HashSet<>();
285 jsonTree.path(SINKS).elements().forEachRemaining(sink -> {
286 sinks.add(HostId.hostId(sink.asText()));
287 });
288
289 if (!sources.isEmpty()) {
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200290 sources.forEach(source -> {
291 service.addSource(route, source);
292 });
Andrea Campanella644a8a62018-03-21 19:08:21 -0700293 }
294 if (!sinks.isEmpty()) {
295 sinks.forEach(sink -> {
296 service.addSink(route, sink);
297 });
298 }
299
300 } catch (IOException ex) {
301 throw new IllegalArgumentException(ex);
302 }
303
304 return Response
305 .created(URI.create(""))
306 .build();
307 }
308
309 /**
310 * Adds sources for a given existing multicast route.
311 *
312 * @param group group IP address
313 * @param srcIp source IP address
314 * @param stream host sinks JSON
315 * @return status of the request - CREATED if the JSON is correct,
316 * BAD_REQUEST if the JSON is invalid
317 * @onos.rsModel McastSourcesAdd
318 */
319 @POST
320 @Consumes(MediaType.APPLICATION_JSON)
321 @Produces(MediaType.APPLICATION_JSON)
322 @Path("sources/{group}/{srcIp}")
323 public Response addSources(@PathParam("group") String group,
324 @PathParam("srcIp") String srcIp,
325 InputStream stream) {
326 MulticastRouteService service = get(MulticastRouteService.class);
327 Optional<McastRoute> route = getMcastRoute(group, srcIp);
328 if (route.isPresent()) {
329 ArrayNode jsonTree;
330 try {
331 jsonTree = (ArrayNode) mapper().readTree(stream).get(SOURCES);
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200332 Set<HostId> sources = new HashSet<>();
Andrea Campanella644a8a62018-03-21 19:08:21 -0700333 jsonTree.elements().forEachRemaining(src -> {
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200334 sources.add(HostId.hostId(src.asText()));
Andrea Campanella644a8a62018-03-21 19:08:21 -0700335 });
336 if (!sources.isEmpty()) {
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200337 sources.forEach(src -> {
338 service.addSource(route.get(), src);
339 });
Andrea Campanella644a8a62018-03-21 19:08:21 -0700340 }
341 } catch (IOException e) {
342 throw new IllegalArgumentException(e);
343 }
344 return Response.ok().build();
345 }
346 return Response.noContent().build();
347
348 }
349
350 /**
351 * Adds sinks for a given existing multicast route.
352 *
353 * @param group group IP address
354 * @param srcIp source IP address
355 * @param stream host sinks JSON
356 * @return status of the request - CREATED if the JSON is correct,
357 * BAD_REQUEST if the JSON is invalid
358 * @onos.rsModel McastSinksAdd
359 */
360 @POST
361 @Consumes(MediaType.APPLICATION_JSON)
362 @Produces(MediaType.APPLICATION_JSON)
363 @Path("sinks/{group}/{srcIp}")
364 public Response addSinks(@PathParam("group") String group,
365 @PathParam("srcIp") String srcIp,
366 InputStream stream) {
367 MulticastRouteService service = get(MulticastRouteService.class);
368 Optional<McastRoute> route = getMcastRoute(group, srcIp);
369 if (route.isPresent()) {
370 ArrayNode jsonTree;
371 try {
372 jsonTree = (ArrayNode) mapper().readTree(stream).get(SINKS);
373 Set<HostId> sinks = new HashSet<>();
374 jsonTree.elements().forEachRemaining(sink -> {
375 sinks.add(HostId.hostId(sink.asText()));
376 });
377 if (!sinks.isEmpty()) {
378 sinks.forEach(sink -> {
379 service.addSink(route.get(), sink);
380 });
381 }
382 } catch (IOException e) {
383 throw new IllegalArgumentException(e);
384 }
385 return Response.ok().build();
386 }
387 return Response.noContent().build();
388 }
389
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200390 /**
391 * Adds a new set of connect points for an existing host source in a given multicast route.
392 *
393 * @param group group IP address
394 * @param srcIp source IP address
395 * @param hostId the host Id
396 * @param stream source connect points JSON
397 * @return status of the request - CREATED if the JSON is correct,
398 * BAD_REQUEST if the JSON is invalid
399 * @onos.rsModel McastHostSourcesAdd
400 */
401 @POST
402 @Consumes(MediaType.APPLICATION_JSON)
403 @Produces(MediaType.APPLICATION_JSON)
404 @Path("source/{group}/{srcIp}/{hostId}")
405 public Response addHostSource(@PathParam("group") String group,
406 @PathParam("srcIp") String srcIp,
407 @PathParam("hostId") String hostId,
408 InputStream stream) {
409 MulticastRouteService service = get(MulticastRouteService.class);
410 Optional<McastRoute> route = getMcastRoute(group, srcIp);
411 if (route.isPresent()) {
412 ArrayNode jsonTree;
413 try {
414 jsonTree = (ArrayNode) mapper().readTree(stream).get(SOURCES);
415 Set<ConnectPoint> sources = new HashSet<>();
416 jsonTree.elements().forEachRemaining(src -> {
417 sources.add(ConnectPoint.deviceConnectPoint(src.asText()));
418 });
419 if (!sources.isEmpty()) {
420 service.addSources(route.get(), HostId.hostId(hostId), sources);
421 }
422 } catch (IOException e) {
423 throw new IllegalArgumentException(e);
424 }
425 return Response.ok().build();
426 }
427 return Response.noContent().build();
428 }
Andrea Campanella644a8a62018-03-21 19:08:21 -0700429
430 /**
431 * Adds a new sink for an existing host in a given multicast route.
432 *
433 * @param group group IP address
434 * @param srcIp source IP address
435 * @param hostId the host Id
436 * @param stream sink connect points JSON
437 * @return status of the request - CREATED if the JSON is correct,
438 * BAD_REQUEST if the JSON is invalid
439 * @onos.rsModel McastHostSinksAdd
440 */
441 @POST
442 @Consumes(MediaType.APPLICATION_JSON)
443 @Produces(MediaType.APPLICATION_JSON)
444 @Path("sinks/{group}/{srcIp}/{hostId}")
445 public Response addHostSinks(@PathParam("group") String group,
446 @PathParam("srcIp") String srcIp,
447 @PathParam("hostId") String hostId,
448 InputStream stream) {
449 MulticastRouteService service = get(MulticastRouteService.class);
450 Optional<McastRoute> route = getMcastRoute(group, srcIp);
451 if (route.isPresent()) {
452 ArrayNode jsonTree;
453 try {
454 jsonTree = (ArrayNode) mapper().readTree(stream).get(SINKS);
455 Set<ConnectPoint> sinks = new HashSet<>();
456 jsonTree.elements().forEachRemaining(src -> {
457 sinks.add(ConnectPoint.deviceConnectPoint(src.asText()));
458 });
459 if (!sinks.isEmpty()) {
460 service.addSinks(route.get(), HostId.hostId(hostId), sinks);
461 }
462 } catch (IOException e) {
463 throw new IllegalArgumentException(e);
464 }
465 return Response.ok().build();
466 }
467 return Response.noContent().build();
468 }
469
470 /**
471 * Removes all the multicast routes.
472 *
473 * @return 204 NO CONTENT
474 */
475 @DELETE
476 public Response deleteRoutes() {
477 MulticastRouteService service = get(MulticastRouteService.class);
478 service.getRoutes().forEach(service::remove);
479 return Response.noContent().build();
480 }
481
482 /**
483 * Removes all the given multicast routes.
484 *
485 * @param stream the set of multicast routes
486 * @return 204 NO CONTENT
487 */
488 @DELETE
489 @Consumes(MediaType.APPLICATION_JSON)
490 @Path("bulk/")
491 public Response deleteRoutes(InputStream stream) {
492 MulticastRouteService service = get(MulticastRouteService.class);
493 try {
494 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
495 ArrayNode routesArray = nullIsIllegal((ArrayNode) jsonTree.get(ROUTES),
496 ROUTES_KEY_ERROR);
497 List<McastRoute> routes = codec(McastRoute.class).decode(routesArray, this);
498 routes.forEach(service::remove);
499 } catch (IOException ex) {
500 throw new IllegalArgumentException(ex);
501 }
502 return Response.noContent().build();
503 }
504
505 /**
506 * Deletes a specific route.
507 *
508 * @param group group IP address
509 * @param srcIp source IP address
510 * @return 204 NO CONTENT
511 */
512 @DELETE
513 @Path("{group}/{srcIp}")
514 public Response deleteRoute(@PathParam("group") String group,
515 @PathParam("srcIp") String srcIp) {
516 Optional<McastRoute> route = getMcastRoute(group, srcIp);
517 route.ifPresent(mcastRoute -> {
518 get(MulticastRouteService.class).remove(mcastRoute);
519 });
520 return Response.noContent().build();
521 }
522
523 /**
524 * Deletes all the source connect points for a specific route.
525 * If the sources are empty the entire route is removed.
526 *
527 * @param group group IP address
528 * @param srcIp source IP address
529 * @return 204 NO CONTENT
530 */
531 @DELETE
532 @Consumes(MediaType.APPLICATION_JSON)
533 @Path("sources/{group}/{srcIp}")
534 public Response deleteSources(@PathParam("group") String group,
535 @PathParam("srcIp") String srcIp) {
536 Optional<McastRoute> route = getMcastRoute(group, srcIp);
537 route.ifPresent(mcastRoute -> get(MulticastRouteService.class).removeSources(mcastRoute));
538 return Response.noContent().build();
539 }
540
541 /**
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200542 * Deletes a source hostId for a specific route.
Andrea Campanella644a8a62018-03-21 19:08:21 -0700543 * If the sources are empty the entire route is removed.
544 *
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200545 * @param group group IP address
546 * @param srcIp source IP address
547 * @param hostId source host id
Andrea Campanella644a8a62018-03-21 19:08:21 -0700548 * @return 204 NO CONTENT
549 */
550 @DELETE
551 @Consumes(MediaType.APPLICATION_JSON)
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200552 @Path("sources/{group}/{srcIp}/{hostId}")
Andrea Campanella644a8a62018-03-21 19:08:21 -0700553 public Response deleteSource(@PathParam("group") String group,
554 @PathParam("srcIp") String srcIp,
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200555 @PathParam("hostId") String hostId) {
Andrea Campanella644a8a62018-03-21 19:08:21 -0700556 Optional<McastRoute> route = getMcastRoute(group, srcIp);
557 route.ifPresent(mcastRoute -> get(MulticastRouteService.class)
Andrea Campanella0ddf9b82018-04-27 15:54:42 +0200558 .removeSource(mcastRoute, HostId.hostId(hostId)));
Andrea Campanella644a8a62018-03-21 19:08:21 -0700559 return Response.noContent().build();
560 }
561
562 /**
563 * Deletes all the sinks for a specific route.
564 *
565 * @param group group IP address
566 * @param srcIp source IP address
567 * @return 204 NO CONTENT
568 */
569 @DELETE
570 @Consumes(MediaType.APPLICATION_JSON)
571 @Path("sinks/{group}/{srcIp}")
572 public Response deleteHostsSinks(@PathParam("group") String group,
573 @PathParam("srcIp") String srcIp) {
574 Optional<McastRoute> route = getMcastRoute(group, srcIp);
575 route.ifPresent(mcastRoute -> get(MulticastRouteService.class)
576 .removeSinks(mcastRoute));
577 return Response.noContent().build();
578 }
579
580 /**
581 * Deletes a sink connect points for a given host for a specific route.
582 *
583 * @param group group IP address
584 * @param srcIp source IP address
585 * @param hostId sink host
586 * @return 204 NO CONTENT
587 */
588 @DELETE
589 @Consumes(MediaType.APPLICATION_JSON)
590 @Path("sinks/{group}/{srcIp}/{hostId}")
591 public Response deleteHostSinks(@PathParam("group") String group,
592 @PathParam("srcIp") String srcIp,
593 @PathParam("hostId") String hostId) {
594 Optional<McastRoute> route = getMcastRoute(group, srcIp);
595 route.ifPresent(mcastRoute -> get(MulticastRouteService.class)
596 .removeSink(mcastRoute, HostId.hostId(hostId)));
597 return Response.noContent().build();
598 }
599
600 private Optional<McastRoute> getMcastRoute(String group, String srcIp) {
601 IpAddress ipAddress = null;
602 if (!srcIp.equals(ASM)) {
603 ipAddress = IpAddress.valueOf(srcIp);
604 }
605 return getStaticRoute(get(MulticastRouteService.class)
606 .getRoute(IpAddress.valueOf(group), ipAddress));
607 }
608
Andrea Campanella545edb42018-03-20 16:37:29 -0700609}