7ed7dfea98587da76c82a8fbd82115c4582e1cea
[lispflowmapping.git] / mappingservice / northbound / src / main / java / org / opendaylight / lispflowmapping / northbound / LispMappingNorthbound.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. 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.lispflowmapping.northbound;
9
10 import java.util.List;
11
12 import javax.ws.rs.Consumes;
13 import javax.ws.rs.DELETE;
14 import javax.ws.rs.GET;
15 import javax.ws.rs.PUT;
16 import javax.ws.rs.Path;
17 import javax.ws.rs.PathParam;
18 import javax.ws.rs.Produces;
19 import javax.ws.rs.core.Context;
20 import javax.ws.rs.core.MediaType;
21 import javax.ws.rs.core.Response;
22 import javax.ws.rs.core.SecurityContext;
23
24 import org.codehaus.enunciate.jaxrs.ResponseCode;
25 import org.codehaus.enunciate.jaxrs.StatusCodes;
26 import org.codehaus.enunciate.jaxrs.TypeHint;
27 import org.opendaylight.controller.containermanager.IContainerManager;
28 import org.opendaylight.controller.northbound.commons.RestMessages;
29 import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
30 import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
31 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
32 import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
33 import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
34 import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
35 import org.opendaylight.controller.sal.authorization.Privilege;
36 import org.opendaylight.controller.sal.utils.ServiceHelper;
37 import org.opendaylight.lispflowmapping.interfaces.lisp.IFlowMapping;
38 import org.opendaylight.lispflowmapping.type.AddressFamilyNumberEnum;
39 import org.opendaylight.lispflowmapping.type.LispCanonicalAddressFormatEnum;
40 import org.opendaylight.lispflowmapping.type.lisp.EidRecord;
41 import org.opendaylight.lispflowmapping.type.lisp.MapRequest;
42 import org.opendaylight.lispflowmapping.type.lisp.address.LispAddress;
43 import org.opendaylight.lispflowmapping.type.lisp.address.LispAddressGeneric;
44 import org.opendaylight.lispflowmapping.type.lisp.address.LispIpv4Address;
45 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapNotify;
46 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapReply;
47 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.eidtolocatorrecords.EidToLocatorRecord;
48 import org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.lispaddress.LispAddressContainer;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52 @Path("/")
53 public class LispMappingNorthbound implements ILispmappingNorthbound {
54     protected static final Logger LOG = LoggerFactory.getLogger(LispMappingNorthbound.class);
55     private IFlowMapping mappingService;
56
57     private String userName;
58
59     // Based on code from controller project
60     @Context
61     public void setSecurityContext(SecurityContext context) {
62         if (context != null && context.getUserPrincipal() != null) {
63             userName = context.getUserPrincipal().getName();
64         }
65     }
66
67     protected String getUserName() {
68         return userName;
69     }
70
71     public IFlowMapping getMappingService() {
72         return this.mappingService;
73     }
74
75     void setFlowMappingService(IFlowMapping mappingService) {
76         LOG.trace("FlowMapping set in LispNorthbound");
77         this.mappingService = mappingService;
78     }
79
80     void unsetFlowMappingService(IFlowMapping mappingService) {
81         LOG.trace("LispDAO was unset in LISP Northbound");
82         this.mappingService = null;
83     }
84
85     public void init() {
86         LOG.trace("LISP Northbound Service is initialized!");
87     }
88
89     public void start() {
90         LOG.info("LISP Northbound Service is up!");
91     }
92
93     public void stop() {
94         LOG.info("LISP Northbound Service is down!");
95     }
96
97     public void destroy() {
98         LOG.trace("LISP Northbound Service is destroyed!");
99         mappingService = null;
100     }
101
102     // Based on code from controller project
103     private void handleContainerDoesNotExist(String containerName) {
104         IContainerManager containerManager = (IContainerManager) ServiceHelper.getGlobalInstance(IContainerManager.class, this);
105         if (containerManager == null) {
106             throw new ServiceUnavailableException("Container " + containerName + RestMessages.NOCONTAINER.toString());
107         }
108
109         List<String> containerNames = containerManager.getContainerNames();
110         for (String cName : containerNames) {
111             if (cName.trim().equalsIgnoreCase(containerName.trim())) {
112                 return;
113             }
114         }
115
116         throw new ResourceNotFoundException("Container " + containerName + " " + RestMessages.NOCONTAINER.toString());
117     }
118
119     private void authorizationCheck(String containerName, Privilege privilege) {
120
121         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, privilege, this)) {
122             throw new UnauthorizedException("User is not authorized to perform this operation on container " + containerName);
123         }
124     }
125
126     private EidToLocatorRecord lookupEID(String containerName, int mask, LispAddress EID) {
127
128         ILispmappingNorthbound nbService = (ILispmappingNorthbound) ServiceHelper.getInstance(ILispmappingNorthbound.class, containerName, this);
129
130         MapRequest mapRequest = new MapRequest();
131         EidRecord EIDRecord = new EidRecord((byte) mask, EID);
132         mapRequest.addEidRecord(EIDRecord);
133         mapRequest.setSourceEid(new LispIpv4Address("127.0.0.1"));
134
135         org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapRequest mr = YangTransformerNB.transformMapRequest(mapRequest);
136         MapReply mapReply;
137         try {
138             mapReply = nbService.getMappingService().handleMapRequest(mr);
139         } catch (Exception e) {
140             throw new InternalServerErrorException(RestMessages.INTERNALERROR.toString() + " : There was an error looking up the EID");
141         }
142
143         if (mapReply == null) {
144             throw new InternalServerErrorException(RestMessages.INTERNALERROR.toString() + " : There was an error looking up the EID");
145         }
146
147         return mapReply.getEidToLocatorRecord().get(0);
148     }
149
150     private void keyCheck(IFlowMapping mappingService, MapRegisterNB mapRegisterNB) {
151
152         String usedKey = mapRegisterNB.getKey();
153
154         LispAddressGeneric lispAddressGeneric;
155         LispAddress lispAddress;
156         int mask;
157         String storedKey;
158
159         int numEidRecords = mapRegisterNB.getMapRegister().getEidToLocatorRecords().size();
160
161         for (int i = 0; i < numEidRecords; i++) {
162
163             lispAddressGeneric = mapRegisterNB.getMapRegister().getEidToLocatorRecords().get(i).getPrefixGeneric();
164
165             try {
166                 lispAddress = LispAddressConvertorNB.convertToLispAddress(lispAddressGeneric);
167             } catch (Exception e) {
168                 throw new BadRequestException(RestMessages.INVALIDDATA.toString() + " : Address is not valid");
169             }
170             mask = mapRegisterNB.getMapRegister().getEidToLocatorRecords().get(i).getMaskLength();
171             try {
172                 storedKey = mappingService.getAuthenticationKey(YangTransformerNB.transformLispAddress(lispAddress), mask);
173             } catch (Exception e) {
174                 throw new InternalServerErrorException(RestMessages.INTERNALERROR.toString() + " : There was an error while retrieving the key");
175             }
176
177             if (!usedKey.equals(storedKey)) {
178                 throw new UnauthorizedException("The key used to register the mapping " + "does not match with the stored key for that mapping");
179             }
180         }
181     }
182
183     /**
184      * Add a mapping to the LISP mapping system
185      *
186      * @param containerName
187      *            name of the container context in which the mapping needs to be
188      *            added
189      * @param mapRegisterNB
190      *            JSON object that contains the mapping information
191      *
192      * @return Text plain confirming reception
193      *
194      *         <pre>
195      * Example:
196      *
197      * Request URL:
198      * http://localhost:8080/lispflowmapping/nb/v2/default/mapping
199      *
200      * Request body in JSON:
201      *
202      * {
203      * "key" : "asdf",
204      * "mapregister" :
205      *   {
206      *   "wantMapNotify" : true,
207      *   "proxyMapReply" : false,
208      *   "eidToLocatorRecords" :
209      *     [
210      *       {
211      *       "authoritative" : true,
212      *       "prefixGeneric" :
213      *         {
214      *         "ipAddress" : "10.0.0.1",
215      *         "afi" : 1
216      *         },
217      *       "mapVersion" : 3,
218      *       "maskLength" : 32,
219      *       "action" : "NoAction",
220      *       "locators" :
221      *         [
222      *           {
223      *           "multicastPriority" : 3,
224      *           "locatorGeneric" :
225      *             {
226      *             "ipAddress" : "3.3.3.3",
227      *             "afi" : 1
228      *             },
229      *           "routed" : true,
230      *           "multicastWeight" : 3,
231      *           "rlocProbed" : false,
232      *           "localLocator" : false,
233      *           "priority" : 3,
234      *           "weight" : 3
235      *           }
236      *         ],
237      *       "recordTtl" : 3
238      *       }
239      *     ],
240      *   "nonce" : 3,
241      *   "keyId" : 0
242      *   }
243      * }
244      * </pre>
245      */
246
247     @Path("/{containerName}/mapping")
248     @PUT
249     @Consumes(MediaType.APPLICATION_JSON)
250     @StatusCodes({ @ResponseCode(code = 400, condition = "Invalid data passed"),
251             @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
252             @ResponseCode(code = 404, condition = "The containerName passed was not found"),
253             @ResponseCode(code = 500, condition = "Internal Server Error: Addition of mapping failed"),
254             @ResponseCode(code = 503, condition = "Service unavailable") })
255     public Response addMapping(@PathParam("containerName") String containerName, @TypeHint(MapRegisterNB.class) MapRegisterNB mapRegisterNB) {
256
257         handleContainerDoesNotExist(containerName);
258
259         authorizationCheck(containerName, Privilege.WRITE);
260
261         ILispmappingNorthbound nbService = (ILispmappingNorthbound) ServiceHelper.getInstance(ILispmappingNorthbound.class, containerName, this);
262
263         try {
264             keyCheck(nbService.getMappingService(), mapRegisterNB);
265
266             LispAddressConvertorNB.convertGenericToLispAddresses(mapRegisterNB.getMapRegister());
267         } catch (Exception e) {
268             throw new BadRequestException(RestMessages.INVALIDDATA.toString() + " : Address is not valid");
269         }
270         // Always request MapNotify
271         mapRegisterNB.getMapRegister().setWantMapNotify(true);
272
273         org.opendaylight.yang.gen.v1.lispflowmapping.rev131031.MapRegister mr = null;
274         try {
275             mr = YangTransformerNB.transformMapRegister(mapRegisterNB.getMapRegister());
276         } catch (Exception e) {
277             throw new InternalServerErrorException(RestMessages.INTERNALERROR.toString() + " : There was an error while converting the map register");
278
279         }
280         MapNotify mapNotify;
281         try {
282             mapNotify = nbService.getMappingService().handleMapRegister(mr);
283         } catch (Exception e) {
284             throw new InternalServerErrorException(RestMessages.INTERNALERROR.toString() + " : There was an error while registering the mapping");
285         }
286
287         if (mapNotify == null) {
288             throw new InternalServerErrorException(RestMessages.INTERNALERROR.toString() + " : There was an error while registering the mapping");
289         }
290         return Response.status(Response.Status.OK).build();
291     }
292
293     /**
294      * Delete a mapping from the LISP Map-Server database
295      *
296      * @param containerName
297      *            name of the container context from which the key is going to
298      *            be deleted
299      *
300      * @param afi
301      *            Address Family of the address (IPv4, IPv6 or MAC)
302      *
303      * @param address
304      *            Address of type defined by afi
305      *
306      * @param mask
307      *            Network mask length
308      *
309      * @return Text plain confirming deletion
310      *
311      *         <pre>
312      * Example:
313      *
314      * Request URL:
315      * http://localhost:8080/lispflowmapping/nb/v2/default/mapping/0/1/10.0.0.1/32
316      *
317      * </pre>
318      */
319
320     @Path("/{containerName}/mapping/{iid}/{afi}/{address}/{mask}")
321     @DELETE
322     @Consumes(MediaType.APPLICATION_JSON)
323     @StatusCodes({ @ResponseCode(code = 400, condition = "Invalid data passed"),
324             @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
325             @ResponseCode(code = 404, condition = "The containerName passed was not found"),
326             @ResponseCode(code = 500, condition = "Internal Server Error: Addition of mapping failed"),
327             @ResponseCode(code = 503, condition = "Service unavailable") })
328     public Response deleteMapping(@PathParam("containerName") String containerName, @PathParam("iid") int iid,
329             @PathParam("afi") int afi, @PathParam("address") String address, @PathParam("mask") int mask) {
330
331         handleContainerDoesNotExist(containerName);
332         authorizationCheck(containerName, Privilege.WRITE);
333
334         LispAddressGeneric eidGeneric = parseAddressURL(iid, afi, address, mask);
335         LispAddress eid;
336         try {
337             eid = LispAddressConvertorNB.convertToLispAddress(eidGeneric);
338         } catch (Exception e) {
339             throw new BadRequestException(RestMessages.INVALIDDATA.toString() + " : Address is not valid");
340         }
341
342         ILispmappingNorthbound nbService = (ILispmappingNorthbound) ServiceHelper.getInstance(ILispmappingNorthbound.class, containerName, this);
343
344         try {
345             nbService.getMappingService().removeMapping(YangTransformerNB.transformLispAddress(eid), mask);
346         } catch (Exception e) {
347             throw new InternalServerErrorException(RestMessages.INTERNALERROR.toString() + " : There was an error while deleting the key");
348         }
349
350         return Response.status(Response.Status.OK).build();
351     }
352
353
354     /**
355      * Retrieve a mapping from the LISP mapping system
356      *
357      * @param containerName
358      *            name of the container context from which the mapping is going
359      *            to be retrieved
360      * @param iid
361      *            Instance-ID of the address (0 if none)
362      *
363      * @param afi
364      *            Address Family of the address (IPv4, IPv6 or MAC)
365      *
366      * @param address
367      *            Address of type defined by afi
368      *
369      * @param mask
370      *            Network mask length
371      *
372      * @return EidToLocatorRecord as a JSON object
373      *
374      *         <pre>
375      * Example:
376      *
377      * Request URL:
378      * http://localhost:8080/lispflowmapping/nb/v2/default/mapping/0/1/10.0.0.1/32
379      *
380      * </pre>
381      */
382
383     private LispAddressGeneric parseAddressURL(int iid, int afi, String address, int mask) {
384         LispAddressGeneric eidGeneric = new LispAddressGeneric(afi, address);
385
386         if (iid != 0) {
387             eidGeneric = new LispAddressGeneric(AddressFamilyNumberEnum.LCAF.getIanaCode(), eidGeneric);
388             eidGeneric.setLcafType(LispCanonicalAddressFormatEnum.SEGMENT.getLispCode());
389             eidGeneric.setInstanceId(iid);
390         }
391
392         return eidGeneric;
393     }
394
395     private LispAddressGeneric parseSrcDstAddressURL(int iid, int afi, String srcAdd, int srcML, String dstAdd, int dstML) {
396         LispAddressGeneric srcGeneric = new LispAddressGeneric(afi, srcAdd);
397         LispAddressGeneric dstGeneric = new LispAddressGeneric(afi, dstAdd);
398
399         if (iid != 0) {
400             srcGeneric = new LispAddressGeneric(AddressFamilyNumberEnum.LCAF.getIanaCode(), srcGeneric);
401             srcGeneric.setLcafType(LispCanonicalAddressFormatEnum.SEGMENT.getLispCode());
402             srcGeneric.setInstanceId(iid);
403
404             dstGeneric = new LispAddressGeneric(AddressFamilyNumberEnum.LCAF.getIanaCode(), dstGeneric);
405             dstGeneric.setLcafType(LispCanonicalAddressFormatEnum.SEGMENT.getLispCode());
406             dstGeneric.setInstanceId(iid);
407         }
408
409         LispAddressGeneric address = new LispAddressGeneric(AddressFamilyNumberEnum.LCAF.getIanaCode());
410
411         address.setLcafType(LispCanonicalAddressFormatEnum.SOURCE_DEST.getLispCode());
412         address.setSrcAddress(srcGeneric);
413         address.setSrcMaskLength((byte) srcML);
414         address.setDstAddress(dstGeneric);
415         address.setDstMaskLength((byte) dstML);
416
417         return address;
418     }
419
420     @Path("/{containerName}/mapping/{iid}/{afi}/{address}/{mask}")
421     @GET
422     @Produces(MediaType.APPLICATION_JSON)
423     @StatusCodes({ @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
424             @ResponseCode(code = 400, condition = "Invalid data passed"),
425             @ResponseCode(code = 404, condition = "The containerName passed was not found"),
426             @ResponseCode(code = 500, condition = "Internal Server Error: Get mapping failed"),
427             @ResponseCode(code = 503, condition = "Service unavailable") })
428     public org.opendaylight.lispflowmapping.type.lisp.EidToLocatorRecord getMapping(@PathParam("containerName") String containerName,
429             @PathParam("iid") int iid, @PathParam("afi") int afi, @PathParam("address") String address, @PathParam("mask") int mask) {
430
431         handleContainerDoesNotExist(containerName);
432
433         authorizationCheck(containerName, Privilege.READ);
434
435         LispAddressGeneric eidGeneric = parseAddressURL(iid, afi, address, mask);
436
437         LispAddress eid;
438         try {
439             eid = LispAddressConvertorNB.convertToLispAddress(eidGeneric);
440         } catch (Exception e) {
441             throw new BadRequestException(RestMessages.INVALIDDATA.toString() + " : Address is not valid");
442         }
443
444         EidToLocatorRecord record = lookupEID(containerName, mask, eid);
445
446         org.opendaylight.lispflowmapping.type.lisp.EidToLocatorRecord legacyRecord = YangTransformerNB.reTransformEidToLocatorRecord(record);
447         LispAddressConvertorNB.convertRecordToGenericAddress(legacyRecord);
448
449         return legacyRecord;
450     }
451
452     /**
453      * Retrieve a mapping from the LISP mapping system, using Source-Destination
454      * LCAF as EID
455      *
456      * @param containerName
457      *            name of the container context from which the mapping is going
458      *            to be retrieved
459      * @param iid
460      *            Instance-ID of the addresses (0 if none)
461      *
462      * @param afi
463      *            Address Family of the addresses (IPv4, IPv6 or MAC)
464      *
465      * @param srcAdd
466      *            Source address of type defined by afi
467      *
468      * @param srcML
469      *            Network mask length of the source address
470      *
471      * @param dstAdd
472      *            Destination address of type defined by afi
473      *
474      * @param dstML
475      *            Network mask length of the destination address
476      *
477      * @return EidToLocatorRecord as a JSON object
478      *
479      *         <pre>
480      * Example:
481      *
482      * Request URL:
483      *
484      *      http://localhost:8080/lispflowmapping/nb/v2/default/mapping/0/1/10.0.0.1/32/20.0.0.2/32
485      *
486      * </pre>
487      */
488
489     @Path("/{containerName}/mapping/{iid}/{afi}/{srcAdd}/{srcML}/{dstAdd}/{dstML}")
490     @GET
491     @Produces(MediaType.APPLICATION_JSON)
492     @StatusCodes({ @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
493             @ResponseCode(code = 404, condition = "The containerName passed was not found"),
494             @ResponseCode(code = 503, condition = "Service unavailable") })
495     public org.opendaylight.lispflowmapping.type.lisp.EidToLocatorRecord getMapping(@PathParam("containerName") String containerName,
496             @PathParam("iid") int iid, @PathParam("afi") int afi, @PathParam("srcAdd") String srcAdd, @PathParam("srcML") int srcML,
497             @PathParam("dstAdd") String dstAdd, @PathParam("dstML") int dstML) {
498
499         handleContainerDoesNotExist(containerName);
500
501         authorizationCheck(containerName, Privilege.READ);
502
503         LispAddressGeneric eidGeneric = parseSrcDstAddressURL(iid, afi, srcAdd, srcML, dstAdd, dstML);
504
505         int mask = 0; // Not used here
506
507         EidToLocatorRecord record = lookupEID(containerName, mask, LispAddressConvertorNB.convertToLispAddress(eidGeneric));
508
509         org.opendaylight.lispflowmapping.type.lisp.EidToLocatorRecord legacyRecord = YangTransformerNB.reTransformEidToLocatorRecord(record);
510         LispAddressConvertorNB.convertRecordToGenericAddress(legacyRecord);
511
512         return legacyRecord;
513     }
514
515     /**
516      * Set the authentication key for an EID prefix
517      *
518      * @param containerName
519      *            name of the container context in which the key needs to be set
520      * @param authKeyNB
521      *            JSON object that contains the key information
522      *
523      * @return Text plain confirming reception
524      *
525      *         <pre>
526      * Example:
527      *
528      * Request URL:
529      * http://localhost:8080/lispflowmapping/nb/v2/default/key
530      *
531      * Request body in JSON:
532      *
533      * {
534      * "key" : "asdf",
535      * "maskLength" : 24,
536      * "address" :
537      * {
538      * "ipAddress" : "10.0.0.1",
539      * "afi" : 1
540      * }
541      * }
542      *
543      * </pre>
544      */
545
546     @Path("/{containerName}/key")
547     @PUT
548     @Consumes(MediaType.APPLICATION_JSON)
549     @StatusCodes({ @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
550             @ResponseCode(code = 400, condition = "Invalid data passed"),
551             @ResponseCode(code = 404, condition = "The containerName passed was not found"),
552             @ResponseCode(code = 500, condition = "Internal Server Error: Addition of key failed"),
553             @ResponseCode(code = 503, condition = "Service unavailable") })
554     public Response addAuthKey(@PathParam("containerName") String containerName, @TypeHint(AuthKeyNB.class) AuthKeyNB authKeyNB) {
555
556         handleContainerDoesNotExist(containerName);
557
558         authorizationCheck(containerName, Privilege.WRITE);
559
560         LispAddress lispAddress;
561         try {
562             lispAddress = LispAddressConvertorNB.convertToLispAddress(authKeyNB.getAddress());
563         } catch (Exception e) {
564             throw new BadRequestException(RestMessages.INVALIDDATA.toString() + " : Address is not valid");
565         }
566         ILispmappingNorthbound nbService = (ILispmappingNorthbound) ServiceHelper.getInstance(ILispmappingNorthbound.class, containerName, this);
567
568         try {
569
570             nbService.getMappingService().addAuthenticationKey(YangTransformerNB.transformLispAddress(lispAddress), authKeyNB.getMaskLength(),
571                     authKeyNB.getKey());
572         } catch (Exception e) {
573             throw new InternalServerErrorException(RestMessages.INTERNALERROR.toString() + " : There was an error while adding the key");
574         }
575
576         return Response.status(Response.Status.OK).build();
577     }
578
579     /**
580      * Retrieve the key used to register an EID prefix
581      *
582      * @param containerName
583      *            name of the container context from which the key is going to
584      *            be retrieved
585      *
586      * @param afi
587      *            Address Family of the address (IPv4, IPv6 or MAC)
588      *
589      * @param address
590      *            Address of type defined by afi
591      *
592      * @param mask
593      *            Network mask length
594      *
595      * @return AuthKeyNB as a JSON object
596      *
597      *         <pre>
598      * Example:
599      *
600      * Request URL:
601      * http://localhost:8080/lispflowmapping/nb/v2/default/key/0/1/10.0.0.1/32
602      *
603      * </pre>
604      */
605
606     @Path("/{containerName}/key/{iid}/{afi}/{address}/{mask}")
607     @GET
608     @Produces(MediaType.APPLICATION_JSON)
609     @StatusCodes({ @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
610             @ResponseCode(code = 400, condition = "Invalid data passed"),
611             @ResponseCode(code = 404, condition = "The containerName passed was not found"),
612             @ResponseCode(code = 500, condition = "Internal Server Error: Get key failed"),
613             @ResponseCode(code = 503, condition = "Service unavailable") })
614     public AuthKeyNB getAuthKey(@PathParam("containerName") String containerName, @PathParam("iid") int iid, @PathParam("afi") int afi,
615             @PathParam("address") String address, @PathParam("mask") int mask) {
616
617         handleContainerDoesNotExist(containerName);
618
619         authorizationCheck(containerName, Privilege.READ);
620
621         LispAddressGeneric lispAddressGeneric = parseAddressURL(iid, afi, address, mask);
622
623         LispAddress lispAddress;
624
625         try {
626             lispAddress = LispAddressConvertorNB.convertToLispAddress(lispAddressGeneric);
627         } catch (Exception e) {
628             throw new BadRequestException(RestMessages.INVALIDDATA.toString() + " : Address is not valid");
629         }
630         ILispmappingNorthbound nbService = (ILispmappingNorthbound) ServiceHelper.getInstance(ILispmappingNorthbound.class, containerName, this);
631
632         String key;
633         try {
634             key = nbService.getMappingService().getAuthenticationKey(YangTransformerNB.transformLispAddress(lispAddress), mask);
635         } catch (Exception e) {
636             throw new InternalServerErrorException(RestMessages.INTERNALERROR.toString() + " : There was an error while retrieving the key");
637         }
638
639         if (key == null) {
640             throw new ResourceNotFoundException(RestMessages.NORESOURCE.toString() + " : The requested key was not found");
641         }
642
643         AuthKeyNB authKeyNB = new AuthKeyNB();
644
645         authKeyNB.setKey(key);
646         authKeyNB.setAddress(lispAddressGeneric);
647         authKeyNB.setMaskLength(mask);
648
649         return authKeyNB;
650     }
651
652     /**
653      * Retrieve a key used to register a Source-Destination LCAF EID prefix
654      *
655      * @param containerName
656      *            name of the container context from which the key is going to
657      *            be retrieved
658      *
659      * @param afi
660      *            Address Family of the addresses (IPv4, IPv6 or MAC)
661      *
662      * @param srcAdd
663      *            Source address of type defined by afi
664      *
665      * @param srcML
666      *            Network mask length of the source address
667      *
668      * @param dstAdd
669      *            Destination address of type defined by afi
670      *
671      * @param dstML
672      *            Network mask length of the destination address
673      *
674      * @return AuthKeyNB as a JSON object
675      *
676      *         <pre>
677      * Example:
678      *
679      * Request URL:
680      *
681      * http://localhost:8080/lispflowmapping/nb/v2/default/key/0/1/10.0.0.1/32/20.0.0.2/32
682      *
683      * </pre>
684      */
685
686     @Path("/{containerName}/key/{iid}/{afi}/{srcAdd}/{srcML}/{dstAdd}/{dstML}")
687     @GET
688     @Produces(MediaType.APPLICATION_JSON)
689     @StatusCodes({ @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
690             @ResponseCode(code = 404, condition = "The containerName passed was not found"),
691             @ResponseCode(code = 503, condition = "Service unavailable") })
692     public AuthKeyNB getAuthKey(@PathParam("containerName") String containerName, @PathParam("iid") int iid, @PathParam("afi") int afi,
693             @PathParam("srcAdd") String srcAdd, @PathParam("srcML") int srcML, @PathParam("dstAdd") String dstAdd, @PathParam("dstML") int dstML) {
694
695         handleContainerDoesNotExist(containerName);
696
697         authorizationCheck(containerName, Privilege.READ);
698
699         LispAddressGeneric lispAddressGeneric = parseSrcDstAddressURL(iid, afi, srcAdd, srcML, dstAdd, dstML);
700
701         LispAddress lispAddress = LispAddressConvertorNB.convertToLispAddress(lispAddressGeneric);
702
703         ILispmappingNorthbound nbService = (ILispmappingNorthbound) ServiceHelper.getInstance(ILispmappingNorthbound.class, containerName, this);
704
705         int mask = 0; // Not used here
706
707         LispAddressContainer yangAddress = YangTransformerNB.transformLispAddress(lispAddress);
708
709         String key = nbService.getMappingService().getAuthenticationKey(yangAddress, mask);
710
711         if (key == null) {
712             throw new ResourceNotFoundException(RestMessages.NORESOURCE.toString() + " : The requested key was not found");
713         }
714
715         AuthKeyNB authKeyNB = new AuthKeyNB();
716
717         authKeyNB.setKey(key);
718         authKeyNB.setAddress(lispAddressGeneric);
719         authKeyNB.setMaskLength(mask);
720
721         return authKeyNB;
722     }
723
724     /**
725      * Delete the key used to register an EID prefix
726      *
727      * @param containerName
728      *            name of the container context from which the key is going to
729      *            be deleted
730      *
731      * @param afi
732      *            Address Family of the address (IPv4, IPv6 or MAC)
733      *
734      * @param address
735      *            Address of type defined by afi
736      *
737      * @param mask
738      *            Network mask length
739      *
740      * @return Text plain confirming deletion
741      *
742      *         <pre>
743      * Example:
744      *
745      * Request URL:
746      * http://localhost:8080/lispflowmapping/nb/v2/default/key/0/1/10.0.0.1/32
747      *
748      * </pre>
749      */
750
751     @Path("/{containerName}/key/{iid}/{afi}/{address}/{mask}")
752     @DELETE
753     @StatusCodes({ @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
754             @ResponseCode(code = 400, condition = "Invalid data passed"),
755             @ResponseCode(code = 404, condition = "The containerName passed was not found"),
756             @ResponseCode(code = 500, condition = "Internal Server Error: Delete key failed"),
757             @ResponseCode(code = 503, condition = "Service unavailable") })
758     public Response delAuthKey(@PathParam("containerName") String containerName, @PathParam("afi") int afi, @PathParam("iid") int iid,
759             @PathParam("address") String address, @PathParam("mask") int mask) {
760
761         handleContainerDoesNotExist(containerName);
762
763         authorizationCheck(containerName, Privilege.WRITE);
764
765         LispAddressGeneric lispAddressGeneric = parseAddressURL(iid, afi, address, mask);
766
767         LispAddress lispAddress;
768         try {
769             lispAddress = LispAddressConvertorNB.convertToLispAddress(lispAddressGeneric);
770         } catch (Exception e) {
771             throw new BadRequestException(RestMessages.INVALIDDATA.toString() + " : Address is not valid");
772         }
773
774         ILispmappingNorthbound nbService = (ILispmappingNorthbound) ServiceHelper.getInstance(ILispmappingNorthbound.class, containerName, this);
775
776         try {
777             nbService.getMappingService().removeAuthenticationKey(YangTransformerNB.transformLispAddress(lispAddress), mask);
778         } catch (Exception e) {
779             throw new InternalServerErrorException(RestMessages.INTERNALERROR.toString() + " : There was an error while deleting the key");
780         }
781
782         return Response.status(Response.Status.OK).build();
783     }
784
785     /**
786      * Delete the key used to register an EID prefix
787      *
788      * @param containerName
789      *            name of the container context from which the key is going to
790      *            be retrieved
791      *
792      * @param afi
793      *            Address Family of the addresses (IPv4, IPv6 or MAC)
794      *
795      * @param srcAdd
796      *            Source address of type defined by afi
797      *
798      * @param srcML
799      *            Network mask length of the source address
800      *
801      * @param dstAdd
802      *            Destination address of type defined by afi
803      *
804      * @param dstML
805      *            Network mask length of the destination address
806      *
807      * @return AuthKeyNB as a JSON object
808      *
809      *         <pre>
810      * Example:
811      *
812      * Request URL:
813      * http://localhost:8080/lispflowmapping/nb/v2/default/key/0/1/10.0.0.1/32/20.0.0.2/32
814      *
815      * </pre>
816      */
817
818     @Path("/{containerName}/key/{iid}/{afi}/{srcAdd}/{srcML}/{dstAdd}/{dstML}")
819     @DELETE
820     @StatusCodes({ @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
821             @ResponseCode(code = 400, condition = "Invalid data passed"),
822             @ResponseCode(code = 404, condition = "The containerName passed was not found"),
823             @ResponseCode(code = 500, condition = "Internal Server Error: Delete key failed"),
824             @ResponseCode(code = 503, condition = "Service unavailable") })
825     public Response delAuthKey(@PathParam("containerName") String containerName, @PathParam("iid") int iid, @PathParam("afi") int afi,
826             @PathParam("srcAdd") String srcAdd, @PathParam("srcML") int srcML, @PathParam("dstAdd") String dstAdd, @PathParam("dstML") int dstML) {
827
828         handleContainerDoesNotExist(containerName);
829
830         authorizationCheck(containerName, Privilege.WRITE);
831
832         LispAddressGeneric lispAddressGeneric = parseSrcDstAddressURL(iid, afi, srcAdd, srcML, dstAdd, dstML);
833
834         LispAddress lispAddress;
835         try {
836             lispAddress = LispAddressConvertorNB.convertToLispAddress(lispAddressGeneric);
837         } catch (Exception e) {
838             throw new BadRequestException(RestMessages.INVALIDDATA.toString() + " : Address is not valid");
839         }
840
841         ILispmappingNorthbound nbService = (ILispmappingNorthbound) ServiceHelper.getInstance(ILispmappingNorthbound.class, containerName, this);
842
843         int mask = 0; // Not used here
844
845         try {
846             nbService.getMappingService().removeAuthenticationKey(YangTransformerNB.transformLispAddress(lispAddress), mask);
847         } catch (Exception e) {
848             throw new InternalServerErrorException(RestMessages.INTERNALERROR.toString() + " : There was an error while deleting the key");
849         }
850
851         return Response.status(Response.Status.OK).build();
852     }
853
854 }