A great update on the alto-commons implementation.
[alto.git] / alto-northbound / src / main / java / org / opendaylight / alto / northbound / AltoNorthbound.java
1 /*
2  * Copyright (c) 2015 Yale University and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.alto.northbound;
9
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;
18
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;
28
29 import org.opendaylight.alto.services.api.rfc7285.AltoService;
30
31 import org.opendaylight.alto.ext.fake.FakeAltoService;
32
33 import org.opendaylight.alto.northbound.exception.AltoBasicException;
34 import org.opendaylight.alto.northbound.exception.AltoBadFormatException;
35
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 @Path("/")
40 public class AltoNorthbound {
41
42     private static final Logger logger = LoggerFactory.getLogger(AltoNorthbound.class);
43
44     private AltoService altoService = new FakeAltoService();
45     private RFC7285JSONMapper mapper = new RFC7285JSONMapper();
46
47     private void checkAltoService() throws Exception {
48         if (altoService == null)
49             throw new AltoBasicException(Status.SERVICE_UNAVAILABLE, null);
50     }
51
52     private void checkResourceId(String rid) throws AltoBadFormatException {
53         if (!FormatValidator.validResourceId(rid))
54             throw new AltoBadFormatException("resource-id", rid);
55     }
56
57     private void checkTag(String tag) throws AltoBadFormatException {
58         if (!FormatValidator.validTag(tag))
59             throw new AltoBadFormatException("tag", tag);
60     }
61
62     private Response fail(Response.Status status, Object data) {
63         try {
64             String output = (data == null ? "" : mapper.asJSON(data));
65             return Response.status(status)
66                         .entity(output)
67                         .type(MediaType.ALTO_ERROR).build();
68         } catch (Exception e) {
69             logger.error("Failed to parse object to json: {}", data.toString());
70             return Response.status(status)
71                         .type(MediaType.ALTO_ERROR).build();
72         }
73     }
74
75     private Response success(Object data, String mediaType) {
76         try {
77             String output = mapper.asJSON(data);
78             return Response.ok(output, mediaType).build();
79         } catch (Exception e) {
80             logger.error("Failed to parse object to json: {}", data.toString());
81             return fail(Status.INTERNAL_SERVER_ERROR, null);
82         }
83     }
84
85     @GET
86     @Produces({ MediaType.ALTO_DIRECTORY, MediaType.ALTO_ERROR })
87     public Response retrieveIRD() throws Exception {
88         checkAltoService();
89
90         RFC7285IRD ird = altoService.getDefaultIRD();
91         if (ird == null)
92             return fail(Status.NOT_FOUND, null);
93         return success(ird, MediaType.ALTO_DIRECTORY);
94     }
95
96     @Path("/ird/{id}")
97     @GET
98     @Produces({ MediaType.ALTO_DIRECTORY, MediaType.ALTO_ERROR })
99     public Response retrieveIRD(
100             @PathParam("id") String id) throws Exception {
101         checkAltoService();
102         checkResourceId(id);
103
104         RFC7285IRD ird = altoService.getIRD(id);
105         if (ird == null)
106             return fail(Status.NOT_FOUND, id);
107         return success(ird, MediaType.ALTO_DIRECTORY);
108     }
109
110     @Path("/networkmap")
111     @GET
112     @Produces({ MediaType.ALTO_NETWORKMAP, MediaType.ALTO_ERROR })
113     public Response retrieveDefaultNetworkMap() throws Exception {
114         checkAltoService();
115
116         RFC7285NetworkMap map = altoService.getDefaultNetworkMap();
117         if (map == null)
118             return fail(Status.NOT_FOUND, null);
119         return success(map, MediaType.ALTO_NETWORKMAP);
120     }
121
122     @Path("/networkmap/{id}")
123     @GET
124     @Produces({ MediaType.ALTO_NETWORKMAP, MediaType.ALTO_ERROR })
125     public Response retrieveNetworkMap(
126             @PathParam("id") String id) throws Exception {
127         checkAltoService();
128         checkResourceId(id);
129
130         RFC7285NetworkMap map = altoService.getNetworkMap(id);
131         if (map == null)
132             return fail(Status.NOT_FOUND, id);
133         return success(map, MediaType.ALTO_NETWORKMAP);
134     }
135
136     @Path("/networkmap/{id}/{tag}")
137     @GET
138     @Produces({ MediaType.ALTO_NETWORKMAP, MediaType.ALTO_ERROR })
139     public Response retrieveNetworkMap(
140             @PathParam("id") String id,
141             @PathParam("tag") String tag) throws Exception {
142         checkAltoService();
143         checkResourceId(id);
144         checkTag(tag);
145
146        RFC7285VersionTag vtag = new RFC7285VersionTag(id, tag);
147         RFC7285NetworkMap map = altoService.getNetworkMap(vtag);
148         if (map == null)
149             return fail(Status.NOT_FOUND, vtag);
150         return success(map, MediaType.ALTO_NETWORKMAP);
151     }
152
153     @Path("/costmap/{id}")
154     @GET
155     @Produces({ MediaType.ALTO_COSTMAP, MediaType.ALTO_ERROR})
156     public Response retrieveCostMap(@PathParam("id") String id) throws Exception {
157         checkAltoService();
158         checkResourceId(id);
159
160         RFC7285CostMap map = altoService.getCostMap(id);
161         if (map == null)
162             return fail(Status.NOT_FOUND, id);
163         return success(map, MediaType.ALTO_COSTMAP);
164     }
165
166     @Path("/costmap/{id}/{tag}")
167     @GET
168     @Produces({ MediaType.ALTO_COSTMAP, MediaType.ALTO_ERROR})
169     public Response retrieveCostMap(
170             @PathParam("id") String id,
171             @PathParam("tag") String tag) throws Exception {
172         checkAltoService();
173         checkResourceId(id);
174         checkTag(tag);
175
176        RFC7285VersionTag vtag = new RFC7285VersionTag(id, tag);
177         RFC7285CostMap map = altoService.getCostMap(vtag);
178         if (map == null)
179             return fail(Status.NOT_FOUND, vtag);
180         return success(map, MediaType.ALTO_COSTMAP);
181     }
182
183     @Path("/costmap/{id}/{mode}/{metric}")
184     @GET
185     @Produces({ MediaType.ALTO_COSTMAP, MediaType.ALTO_ERROR})
186     public Response retrieveCostMap(
187             @PathParam("id") String id,
188             @PathParam("mode") String mode,
189             @PathParam("metric") String metric) throws Exception {
190         checkAltoService();
191         checkResourceId(id);
192
193         RFC7285CostType costType = new RFC7285CostType(mode, metric);
194         if (!altoService.supportCostType(id, costType))
195             return fail(Status.NOT_FOUND, costType);
196         RFC7285CostMap map = altoService.getCostMap(id, costType);
197         if (map == null)
198             return fail(Status.NOT_FOUND, id);
199         return success(map, MediaType.ALTO_COSTMAP);
200     }
201
202     @Path("/costmap/{id}/{tag}/{mode}/{metric}")
203     @GET
204     @Produces({ MediaType.ALTO_COSTMAP, MediaType.ALTO_ERROR})
205     public Response retrieveCostMap(
206             @PathParam("id") String id,
207             @PathParam("tag") String tag,
208             @PathParam("mode") String mode,
209             @PathParam("metric") String metric) throws Exception {
210         checkAltoService();
211         checkResourceId(id);
212         checkTag(tag);
213
214        RFC7285VersionTag vtag = new RFC7285VersionTag(id, tag);
215         RFC7285CostType costType = new RFC7285CostType(mode, metric);
216         if (!altoService.supportCostType(vtag, costType))
217             return fail(Status.NOT_FOUND, costType);
218         RFC7285CostMap map = altoService.getCostMap(vtag, costType);
219         if (map == null)
220             return fail(Status.NOT_FOUND, vtag);
221         return success(map, MediaType.ALTO_COSTMAP);
222     }
223
224     @Path("/filtered/networkmap/{id}")
225     @POST
226     @Consumes({ MediaType.ALTO_NETWORKMAP_FILTER})
227     @Produces({ MediaType.ALTO_NETWORKMAP, MediaType.ALTO_ERROR})
228     public Response retrieveFilteredNetworkMap(
229             @PathParam("id") String id, String filterJSON) throws Exception {
230         checkAltoService();
231         checkResourceId(id);
232
233         RFC7285NetworkMap.Filter filter = mapper.asNetworkMapFilter(filterJSON);
234
235         if (!altoService.validateNetworkMapFilter(id, filter))
236             return fail(Status.BAD_REQUEST, filter);
237         RFC7285NetworkMap map = altoService.getNetworkMap(id, filter);
238         if (map == null)
239             return fail(Status.NOT_FOUND, id);
240         return success(map, MediaType.ALTO_NETWORKMAP);
241     }
242
243     @Path("/filtered/networkmap/{id}/{tag}")
244     @POST
245     @Consumes({ MediaType.ALTO_NETWORKMAP_FILTER})
246     @Produces({ MediaType.ALTO_NETWORKMAP, MediaType.ALTO_ERROR})
247     public Response retrieveFilteredNetworkMap(
248             @PathParam("id") String id,
249             @PathParam("tag") String tag,
250             String filterJSON) throws Exception {
251         checkAltoService();
252         checkResourceId(id);
253         checkTag(tag);
254
255        RFC7285VersionTag vtag = new RFC7285VersionTag(id, tag);
256         RFC7285NetworkMap.Filter filter = mapper.asNetworkMapFilter(filterJSON);
257         if (!altoService.validateNetworkMapFilter(vtag, filter))
258             return fail(Status.BAD_REQUEST, filter);
259
260         RFC7285NetworkMap map = altoService.getNetworkMap(vtag, filter);
261         if (map == null)
262             return fail(Status.NOT_FOUND, vtag);
263         return success(map, MediaType.ALTO_NETWORKMAP);
264     }
265
266     @Path("/filtered/costmap/{id}")
267     @POST
268     @Consumes({ MediaType.ALTO_COSTMAP_FILTER })
269     @Produces({ MediaType.ALTO_COSTMAP, MediaType.ALTO_ERROR})
270     public Response retrieveFilteredCostMap(
271             @PathParam("id") String id, String filterJSON) throws Exception {
272         checkAltoService();
273         checkResourceId(id);
274
275         RFC7285CostMap.Filter filter = mapper.asCostMapFilter(filterJSON);
276         if (!altoService.validateCostMapFilter(id, filter))
277             return fail(Status.BAD_REQUEST, filter);
278
279         RFC7285CostMap map = altoService.getCostMap(id, filter);
280         if (map == null)
281             return fail(Status.NOT_FOUND, id);
282         return success(map, MediaType.ALTO_COSTMAP);
283     }
284
285     @Path("/filtered/costmap/{id}/{tag}")
286     @POST
287     @Consumes({ MediaType.ALTO_COSTMAP_FILTER })
288     @Produces({ MediaType.ALTO_COSTMAP, MediaType.ALTO_ERROR})
289     public Response retrieveFilteredCostMap(
290             @PathParam("id") String id,
291             @PathParam("tag") String tag, String filterJSON) throws Exception {
292         checkAltoService();
293         checkResourceId(id);
294         checkTag(tag);
295
296        RFC7285VersionTag vtag = new RFC7285VersionTag(id, tag);
297         RFC7285CostMap.Filter filter = mapper.asCostMapFilter(filterJSON);
298         if (!altoService.validateCostMapFilter(vtag, filter))
299             return fail(Status.BAD_REQUEST, filter);
300
301         RFC7285CostMap map = altoService.getCostMap(vtag, filter);
302         if (map == null)
303             return fail(Status.NOT_FOUND, vtag);
304         return success(map, MediaType.ALTO_COSTMAP);
305     }
306
307     @Path("/endpointprop/lookup/{id}")
308     @POST
309     @Consumes({ MediaType.ALTO_ENDPOINT_PROPPARAMS })
310     @Produces({ MediaType.ALTO_ENDPOINT_PROP, MediaType.ALTO_ERROR })
311     public Response retrieveEndpointPropMap(
312             @PathParam("id") String id,
313             String params) throws Exception {
314         checkAltoService();
315         checkResourceId(id);
316
317         RFC7285Endpoint.PropertyRequest request = mapper.asPropertyRequest(params);
318         RFC7285Endpoint.PropertyResponse response = altoService.getEndpointProperty(id, request);
319         if (response == null)
320             return fail(Status.NOT_FOUND, request);
321         return success(response, MediaType.ALTO_ENDPOINT_PROP);
322     }
323
324     @Path("/endpointprop/lookup/{id}/{tag}")
325     @POST
326     @Consumes({ MediaType.ALTO_ENDPOINT_PROPPARAMS })
327     @Produces({ MediaType.ALTO_ENDPOINT_PROP, MediaType.ALTO_ERROR })
328     public Response retrieveEndpointPropMap(
329             @PathParam("id") String id,
330             @PathParam("tag") String tag,
331             String params) throws Exception {
332         checkAltoService();
333         checkResourceId(id);
334         checkTag(tag);
335
336        RFC7285VersionTag vtag = new RFC7285VersionTag(id, tag);
337         RFC7285Endpoint.PropertyRequest request = mapper.asPropertyRequest(params);
338         RFC7285Endpoint.PropertyResponse response = altoService.getEndpointProperty(vtag, request);
339         if (response == null)
340             return fail(Status.NOT_FOUND, request);
341         return success(response, MediaType.ALTO_ENDPOINT_PROP);
342     }
343
344     @Path("/endpointcost/lookup/{id}")
345     @POST
346     @Consumes({ MediaType.ALTO_ENDPOINT_COSTPARAMS })
347     @Produces({ MediaType.ALTO_ENDPOINT_COST, MediaType.ALTO_ERROR })
348     public Response retrieveEndpointCostMap(
349             @PathParam("id") String id,
350             String params) throws Exception {
351         checkAltoService();
352         checkResourceId(id);
353
354         RFC7285Endpoint.CostRequest request = mapper.asCostRequest(params);
355         RFC7285Endpoint.CostResponse response = altoService.getEndpointCost(id, request);
356         if (response == null)
357             return fail(Status.NOT_FOUND, request);
358         return success(response, MediaType.ALTO_ENDPOINT_COST);
359     }
360
361     @Path("/endpointcost/lookup/{id}/{tag}")
362     @POST
363     @Consumes({ MediaType.ALTO_ENDPOINT_COSTPARAMS })
364     @Produces({ MediaType.ALTO_ENDPOINT_COST, MediaType.ALTO_ERROR })
365     public Response retrieveEndpointCostMap(
366             @PathParam("id") String id,
367             @PathParam("tag") String tag,
368             String params) throws Exception {
369         checkAltoService();
370         checkResourceId(id);
371         checkTag(tag);
372
373         RFC7285VersionTag vtag = new RFC7285VersionTag(id, tag);
374         RFC7285Endpoint.CostRequest request = mapper.asCostRequest(params);
375         RFC7285Endpoint.CostResponse response = altoService.getEndpointCost(vtag, request);
376         if (response == null)
377             return fail(Status.NOT_FOUND, request);
378         return success(response, MediaType.ALTO_ENDPOINT_COST);
379     }
380 }