2 * Copyright (c) 2015 Yale University and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.alto.northbound;
10 import javax.ws.rs.GET;
11 import javax.ws.rs.POST;
12 import javax.ws.rs.Path;
13 import javax.ws.rs.PathParam;
14 import javax.ws.rs.Consumes;
15 import javax.ws.rs.Produces;
16 import javax.ws.rs.core.Response;
17 import javax.ws.rs.core.Response.Status;
19 import org.opendaylight.alto.commons.types.rfc7285.RFC7285JSONMapper;
20 import org.opendaylight.alto.commons.types.rfc7285.FormatValidator;
21 import org.opendaylight.alto.commons.types.rfc7285.MediaType;
22 import org.opendaylight.alto.commons.types.rfc7285.RFC7285NetworkMap;
23 import org.opendaylight.alto.commons.types.rfc7285.RFC7285CostType;
24 import org.opendaylight.alto.commons.types.rfc7285.RFC7285IRD;
25 import org.opendaylight.alto.commons.types.rfc7285.RFC7285VersionTag;
26 import org.opendaylight.alto.commons.types.rfc7285.RFC7285CostMap;
27 import org.opendaylight.alto.commons.types.rfc7285.RFC7285Endpoint;
29 import org.opendaylight.alto.services.api.rfc7285.AltoService;
30 import org.opendaylight.alto.services.api.rfc7285.IRDService;
31 import org.opendaylight.alto.services.api.rfc7285.NetworkMapService;
32 import org.opendaylight.alto.services.api.rfc7285.CostMapService;
33 import org.opendaylight.alto.services.api.rfc7285.EndpointCostService;
34 import org.opendaylight.alto.services.api.rfc7285.EndpointPropertyService;
37 import org.opendaylight.alto.northbound.exception.AltoBasicException;
38 import org.opendaylight.alto.northbound.exception.AltoBadFormatException;
40 import org.opendaylight.controller.sal.utils.ServiceHelper;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
46 public class AltoNorthbound {
48 private static final Logger logger = LoggerFactory.getLogger(AltoNorthbound.class);
50 private RFC7285JSONMapper mapper = new RFC7285JSONMapper();
52 private <E> E getService(Class<E> clazz) {
53 E service = (E)ServiceHelper.getGlobalInstance(clazz, this);
54 if (service == null) {
55 service = (E)ServiceHelper.getGlobalInstance(AltoService.class, this);
60 private void checkService(Object service) throws Exception {
62 throw new AltoBasicException(Status.SERVICE_UNAVAILABLE, null);
65 private void checkResourceId(String rid) throws AltoBadFormatException {
66 if (!FormatValidator.validResourceId(rid))
67 throw new AltoBadFormatException("resource-id", rid);
70 private void checkTag(String tag) throws AltoBadFormatException {
71 if (!FormatValidator.validTag(tag))
72 throw new AltoBadFormatException("tag", tag);
75 private Response fail(Response.Status status, Object data) {
77 String output = (data == null ? "" : mapper.asJSON(data));
78 return Response.status(status)
80 .type(MediaType.ALTO_ERROR).build();
81 } catch (Exception e) {
82 logger.error("Failed to parse object to json: {}", data.toString());
83 return Response.status(status)
84 .type(MediaType.ALTO_ERROR).build();
88 private Response success(Object data, String mediaType) {
90 String output = mapper.asJSON(data);
91 return Response.ok(output, mediaType).build();
92 } catch (Exception e) {
93 logger.error("Failed to parse object to json: {}", data.toString());
94 return fail(Status.INTERNAL_SERVER_ERROR, null);
99 @Produces({ MediaType.ALTO_DIRECTORY, MediaType.ALTO_ERROR })
100 public Response retrieveIRD() throws Exception {
101 IRDService service = getService(IRDService.class);
102 checkService(service);
104 RFC7285IRD ird = service.getDefaultIRD();
106 return fail(Status.NOT_FOUND, null);
107 return success(ird, MediaType.ALTO_DIRECTORY);
112 @Produces({ MediaType.ALTO_DIRECTORY, MediaType.ALTO_ERROR })
113 public Response retrieveIRD(
114 @PathParam("id") String id) throws Exception {
115 IRDService service = getService(IRDService.class);
116 checkService(service);
119 RFC7285IRD ird = service.getIRD(id);
121 return fail(Status.NOT_FOUND, id);
122 return success(ird, MediaType.ALTO_DIRECTORY);
127 @Produces({ MediaType.ALTO_NETWORKMAP, MediaType.ALTO_ERROR })
128 public Response retrieveDefaultNetworkMap() throws Exception {
129 NetworkMapService service = getService(NetworkMapService.class);
130 checkService(service);
132 RFC7285NetworkMap map = service.getDefaultNetworkMap();
134 return fail(Status.NOT_FOUND, null);
135 return success(map, MediaType.ALTO_NETWORKMAP);
138 @Path("/networkmap/{id}")
140 @Produces({ MediaType.ALTO_NETWORKMAP, MediaType.ALTO_ERROR })
141 public Response retrieveNetworkMap(
142 @PathParam("id") String id) throws Exception {
143 NetworkMapService service = getService(NetworkMapService.class);
144 checkService(service);
147 RFC7285NetworkMap map = service.getNetworkMap(id);
149 return fail(Status.NOT_FOUND, id);
150 return success(map, MediaType.ALTO_NETWORKMAP);
153 @Path("/networkmap/{id}/{tag}")
155 @Produces({ MediaType.ALTO_NETWORKMAP, MediaType.ALTO_ERROR })
156 public Response retrieveNetworkMap(
157 @PathParam("id") String id,
158 @PathParam("tag") String tag) throws Exception {
159 NetworkMapService service = getService(NetworkMapService.class);
160 checkService(service);
164 RFC7285VersionTag vtag = new RFC7285VersionTag(id, tag);
165 RFC7285NetworkMap map = service.getNetworkMap(vtag);
167 return fail(Status.NOT_FOUND, vtag);
168 return success(map, MediaType.ALTO_NETWORKMAP);
171 @Path("/costmap/{id}")
173 @Produces({ MediaType.ALTO_COSTMAP, MediaType.ALTO_ERROR})
174 public Response retrieveCostMap(@PathParam("id") String id) throws Exception {
175 CostMapService service = getService(CostMapService.class);
176 checkService(service);
179 RFC7285CostMap map = service.getCostMap(id);
181 return fail(Status.NOT_FOUND, id);
182 return success(map, MediaType.ALTO_COSTMAP);
185 @Path("/costmap/{id}/{tag}")
187 @Produces({ MediaType.ALTO_COSTMAP, MediaType.ALTO_ERROR})
188 public Response retrieveCostMap(
189 @PathParam("id") String id,
190 @PathParam("tag") String tag) throws Exception {
191 CostMapService service = getService(CostMapService.class);
192 checkService(service);
196 RFC7285VersionTag vtag = new RFC7285VersionTag(id, tag);
197 RFC7285CostMap map = service.getCostMap(vtag);
199 return fail(Status.NOT_FOUND, vtag);
200 return success(map, MediaType.ALTO_COSTMAP);
203 @Path("/costmap/{id}/{mode}/{metric}")
205 @Produces({ MediaType.ALTO_COSTMAP, MediaType.ALTO_ERROR})
206 public Response retrieveCostMap(
207 @PathParam("id") String id,
208 @PathParam("mode") String mode,
209 @PathParam("metric") String metric) throws Exception {
210 CostMapService service = getService(CostMapService.class);
211 checkService(service);
214 RFC7285CostType costType = new RFC7285CostType(mode, metric);
215 if (!service.supportCostType(id, costType))
216 return fail(Status.NOT_FOUND, costType);
217 RFC7285CostMap map = service.getCostMap(id, costType);
219 return fail(Status.NOT_FOUND, id);
220 return success(map, MediaType.ALTO_COSTMAP);
223 @Path("/costmap/{id}/{tag}/{mode}/{metric}")
225 @Produces({ MediaType.ALTO_COSTMAP, MediaType.ALTO_ERROR})
226 public Response retrieveCostMap(
227 @PathParam("id") String id,
228 @PathParam("tag") String tag,
229 @PathParam("mode") String mode,
230 @PathParam("metric") String metric) throws Exception {
231 CostMapService service = getService(CostMapService.class);
232 checkService(service);
236 RFC7285VersionTag vtag = new RFC7285VersionTag(id, tag);
237 RFC7285CostType costType = new RFC7285CostType(mode, metric);
238 if (!service.supportCostType(vtag, costType))
239 return fail(Status.NOT_FOUND, costType);
240 RFC7285CostMap map = service.getCostMap(vtag, costType);
242 return fail(Status.NOT_FOUND, vtag);
243 return success(map, MediaType.ALTO_COSTMAP);
246 @Path("/filtered/networkmap/{id}")
248 @Consumes({ MediaType.ALTO_NETWORKMAP_FILTER})
249 @Produces({ MediaType.ALTO_NETWORKMAP, MediaType.ALTO_ERROR})
250 public Response retrieveFilteredNetworkMap(
251 @PathParam("id") String id, String filterJSON) throws Exception {
252 NetworkMapService service = getService(NetworkMapService.class);
253 checkService(service);
256 RFC7285NetworkMap.Filter filter = mapper.asNetworkMapFilter(filterJSON);
258 if (!service.validateNetworkMapFilter(id, filter))
259 return fail(Status.BAD_REQUEST, filter);
260 RFC7285NetworkMap map = service.getNetworkMap(id, filter);
262 return fail(Status.NOT_FOUND, id);
263 return success(map, MediaType.ALTO_NETWORKMAP);
266 @Path("/filtered/networkmap/{id}/{tag}")
268 @Consumes({ MediaType.ALTO_NETWORKMAP_FILTER})
269 @Produces({ MediaType.ALTO_NETWORKMAP, MediaType.ALTO_ERROR})
270 public Response retrieveFilteredNetworkMap(
271 @PathParam("id") String id,
272 @PathParam("tag") String tag,
273 String filterJSON) throws Exception {
274 NetworkMapService service = getService(NetworkMapService.class);
275 checkService(service);
279 RFC7285VersionTag vtag = new RFC7285VersionTag(id, tag);
280 RFC7285NetworkMap.Filter filter = mapper.asNetworkMapFilter(filterJSON);
281 if (!service.validateNetworkMapFilter(vtag, filter))
282 return fail(Status.BAD_REQUEST, filter);
284 RFC7285NetworkMap map = service.getNetworkMap(vtag, filter);
286 return fail(Status.NOT_FOUND, vtag);
287 return success(map, MediaType.ALTO_NETWORKMAP);
290 @Path("/filtered/costmap/{id}")
292 @Consumes({ MediaType.ALTO_COSTMAP_FILTER })
293 @Produces({ MediaType.ALTO_COSTMAP, MediaType.ALTO_ERROR})
294 public Response retrieveFilteredCostMap(
295 @PathParam("id") String id, String filterJSON) throws Exception {
296 CostMapService service = getService(CostMapService.class);
297 checkService(service);
300 RFC7285CostMap.Filter filter = mapper.asCostMapFilter(filterJSON);
301 if (!service.validateCostMapFilter(id, filter))
302 return fail(Status.BAD_REQUEST, filter);
304 RFC7285CostMap map = service.getCostMap(id, filter);
306 return fail(Status.NOT_FOUND, id);
307 return success(map, MediaType.ALTO_COSTMAP);
310 @Path("/filtered/costmap/{id}/{tag}")
312 @Consumes({ MediaType.ALTO_COSTMAP_FILTER })
313 @Produces({ MediaType.ALTO_COSTMAP, MediaType.ALTO_ERROR})
314 public Response retrieveFilteredCostMap(
315 @PathParam("id") String id,
316 @PathParam("tag") String tag, String filterJSON) throws Exception {
317 CostMapService service = getService(CostMapService.class);
318 checkService(service);
322 RFC7285VersionTag vtag = new RFC7285VersionTag(id, tag);
323 RFC7285CostMap.Filter filter = mapper.asCostMapFilter(filterJSON);
324 if (!service.validateCostMapFilter(vtag, filter))
325 return fail(Status.BAD_REQUEST, filter);
327 RFC7285CostMap map = service.getCostMap(vtag, filter);
329 return fail(Status.NOT_FOUND, vtag);
330 return success(map, MediaType.ALTO_COSTMAP);
333 @Path("/endpointprop/lookup/{id}")
335 @Consumes({ MediaType.ALTO_ENDPOINT_PROPPARAMS })
336 @Produces({ MediaType.ALTO_ENDPOINT_PROP, MediaType.ALTO_ERROR })
337 public Response retrieveEndpointPropMap(
338 @PathParam("id") String id,
339 String params) throws Exception {
340 EndpointPropertyService service = getService(EndpointPropertyService.class);
341 checkService(service);
344 RFC7285Endpoint.PropertyRequest request = mapper.asPropertyRequest(params);
345 RFC7285Endpoint.PropertyResponse response = service.getEndpointProperty(id, request);
346 if (response == null)
347 return fail(Status.NOT_FOUND, request);
348 return success(response, MediaType.ALTO_ENDPOINT_PROP);
351 @Path("/endpointprop/lookup/{id}/{tag}")
353 @Consumes({ MediaType.ALTO_ENDPOINT_PROPPARAMS })
354 @Produces({ MediaType.ALTO_ENDPOINT_PROP, MediaType.ALTO_ERROR })
355 public Response retrieveEndpointPropMap(
356 @PathParam("id") String id,
357 @PathParam("tag") String tag,
358 String params) throws Exception {
359 EndpointPropertyService service = getService(EndpointPropertyService.class);
360 checkService(service);
364 RFC7285VersionTag vtag = new RFC7285VersionTag(id, tag);
365 RFC7285Endpoint.PropertyRequest request = mapper.asPropertyRequest(params);
366 RFC7285Endpoint.PropertyResponse response = service.getEndpointProperty(vtag, request);
367 if (response == null)
368 return fail(Status.NOT_FOUND, request);
369 return success(response, MediaType.ALTO_ENDPOINT_PROP);
372 @Path("/endpointcost/lookup/{id}")
374 @Consumes({ MediaType.ALTO_ENDPOINT_COSTPARAMS })
375 @Produces({ MediaType.ALTO_ENDPOINT_COST, MediaType.ALTO_ERROR })
376 public Response retrieveEndpointCostMap(
377 @PathParam("id") String id,
378 String params) throws Exception {
379 EndpointCostService service = getService(EndpointCostService.class);
380 checkService(service);
383 RFC7285Endpoint.CostRequest request = mapper.asCostRequest(params);
384 RFC7285Endpoint.CostResponse response = service.getEndpointCost(id, request);
385 if (response == null)
386 return fail(Status.NOT_FOUND, request);
387 return success(response, MediaType.ALTO_ENDPOINT_COST);
390 @Path("/endpointcost/lookup/{id}/{tag}")
392 @Consumes({ MediaType.ALTO_ENDPOINT_COSTPARAMS })
393 @Produces({ MediaType.ALTO_ENDPOINT_COST, MediaType.ALTO_ERROR })
394 public Response retrieveEndpointCostMap(
395 @PathParam("id") String id,
396 @PathParam("tag") String tag,
397 String params) throws Exception {
398 EndpointCostService service = getService(EndpointCostService.class);
399 checkService(service);
403 RFC7285VersionTag vtag = new RFC7285VersionTag(id, tag);
404 RFC7285Endpoint.CostRequest request = mapper.asCostRequest(params);
405 RFC7285Endpoint.CostResponse response = service.getEndpointCost(vtag, request);
406 if (response == null)
407 return fail(Status.NOT_FOUND, request);
408 return success(response, MediaType.ALTO_ENDPOINT_COST);