Working northbound rest api calls for affinity objects.
[affinity.git] / affinity / northbound / src / main / java / org / opendaylight / affinity / affinity / northbound / AffinityNorthbound.java
1 /*
2  * Copyright (c) 2013 Plexxi, 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
9 package org.opendaylight.affinity.affinity.northbound;
10
11 import java.util.ArrayList;
12 import java.util.HashSet;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Set;
16
17 import javax.ws.rs.Consumes;
18 import javax.ws.rs.DELETE;
19 import javax.ws.rs.GET;
20 import javax.ws.rs.POST;
21 import javax.ws.rs.PUT;
22 import javax.ws.rs.Path;
23 import javax.ws.rs.PathParam;
24 import javax.ws.rs.Produces;
25 import javax.ws.rs.core.Context;
26 import javax.ws.rs.core.MediaType;
27 import javax.ws.rs.core.Response;
28 import javax.ws.rs.core.SecurityContext;
29
30 import org.codehaus.enunciate.jaxrs.ResponseCode;
31 import org.codehaus.enunciate.jaxrs.StatusCodes;
32 import org.codehaus.enunciate.jaxrs.TypeHint;
33 import org.opendaylight.controller.containermanager.IContainerManager;
34 import org.opendaylight.controller.northbound.commons.RestMessages;
35 import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
36 import org.opendaylight.controller.northbound.commons.exception.ResourceConflictException;
37 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
38 import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
39 import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
40 import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
41 import org.opendaylight.controller.sal.authorization.Privilege;
42 import org.opendaylight.controller.sal.utils.GlobalConstants;
43 import org.opendaylight.controller.sal.utils.ServiceHelper;
44 import org.opendaylight.controller.sal.utils.Status;
45 import org.opendaylight.affinity.affinity.IAffinityManager;
46 import org.opendaylight.affinity.affinity.AffinityLink;
47 import org.opendaylight.affinity.affinity.AffinityGroup;
48
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52 /**
53  * The class provides Northbound REST APIs to access affinity configuration.
54  *
55  */
56
57 @Path("/")
58 public class AffinityNorthbound {
59
60     private String username;
61     private static final Logger log = LoggerFactory.getLogger(AffinityNorthbound.class);
62
63     @Context
64     public void setSecurityContext(SecurityContext context) {
65         username = context.getUserPrincipal().getName();
66     }
67
68     protected String getUserName() {
69         return username;
70     }
71
72     private IAffinityManager getIfAffinityManagerService(String containerName) {
73         log.debug("In getIfAffinityManager");
74
75         IContainerManager containerManager = (IContainerManager) ServiceHelper
76                 .getGlobalInstance(IContainerManager.class, this);
77         if (containerManager == null) {
78             throw new ServiceUnavailableException("Container "
79                     + RestMessages.SERVICEUNAVAILABLE.toString());
80         }
81
82         boolean found = false;
83         List<String> containerNames = containerManager.getContainerNames();
84         for (String cName : containerNames) {
85             if (cName.trim().equalsIgnoreCase(containerName.trim())) {
86                 found = true;
87                 break;
88             }
89         }
90
91         if (found == false) {
92             throw new ResourceNotFoundException(containerName + " "
93                     + RestMessages.SERVICEUNAVAILABLE.toString());
94         }
95
96         IAffinityManager affinityManager = (IAffinityManager) ServiceHelper
97                 .getInstance(IAffinityManager.class, containerName, this);
98
99         if (affinityManager == null) {
100             throw new ServiceUnavailableException("Affinity Manager "
101                     + RestMessages.SERVICEUNAVAILABLE.toString());
102         }
103
104         return affinityManager;
105     }
106
107     /**
108      * Add an affinity to the configuration database
109      *
110      * @param containerName
111      *            Name of the Container
112      * @param affinityGroupName
113      *            Name of the new affinity group being added
114      * @return Response as dictated by the HTTP Response Status code
115      */
116
117     @Path("/{containerName}/create/group/{affinityGroupName}")
118     @PUT
119     @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
120     @TypeHint(Response.class)
121     @StatusCodes({
122             @ResponseCode(code = 200, condition = "Operation successful"),
123             @ResponseCode(code = 404, condition = "The Container Name or nodeId or configuration name is not found"),
124             @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
125     public Response createAffinityGroup(
126             @PathParam("containerName") String containerName,
127             @PathParam("affinityGroupName") String affinityGroupName) {
128
129         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
130             throw new UnauthorizedException("User is not authorized to perform this operation on container "
131                                             + containerName);
132         }
133         log.info("add a new affinitygroup = {}, containerName = {}",  affinityGroupName, containerName);
134         IAffinityManager affinityManager = getIfAffinityManagerService(containerName);
135         if (affinityManager == null) {
136             throw new ServiceUnavailableException("Affinity Manager "
137                                                   + RestMessages.SERVICEUNAVAILABLE.toString());
138         }
139
140         AffinityGroup ag1 = new AffinityGroup(affinityGroupName);
141         Status ret = affinityManager.addAffinityGroup(ag1);
142         
143         return Response.status(Response.Status.CREATED).build();
144     }
145
146     /**
147      * Returns details of an affinity group.
148      *
149      * @param containerName
150      *            Name of the Container. The Container name for the base
151      *            controller is "default".
152      * @param affinityGroupName
153      *            Name of the affinity group being retrieved.
154      * @return affinity configuration that matches the affinity name.
155      */
156     @Path("/{containerName}/group/{affinityGroupName}")
157     @GET
158     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
159     @TypeHint(AffinityGroup.class)
160     @StatusCodes({
161             @ResponseCode(code = 200, condition = "Operation successful"),
162             @ResponseCode(code = 404, condition = "The containerName is not found"),
163             @ResponseCode(code = 415, condition = "Affinity name is not found"),
164             @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
165     public AffinityGroup getAffinityGroupDetails(
166             @PathParam("containerName") String containerName,
167             @PathParam("affinityGroupName") String affinityGroupName) {
168         if (!NorthboundUtils.isAuthorized(
169                 getUserName(), containerName, Privilege.READ, this)) {
170             throw new UnauthorizedException(
171                     "User is not authorized to perform this operation on container "
172                             + containerName);
173         }
174         IAffinityManager affinityManager = getIfAffinityManagerService(containerName);
175         if (affinityManager == null) {
176             throw new ServiceUnavailableException("Affinity "
177                                                   + RestMessages.SERVICEUNAVAILABLE.toString());
178         }
179
180         log.info("Get affinity group details" + affinityGroupName);
181         AffinityGroup ag = affinityManager.getAffinityGroup(affinityGroupName);
182         if (ag == null) {
183             throw new ResourceNotFoundException(RestMessages.SERVICEUNAVAILABLE.toString());
184         } else {
185             return ag;
186         }
187     }
188
189     /**
190      * Add an affinity link with one "from" and one "to" affinity group. 
191      *
192      * @param containerName
193      *            Name of the Container
194      * @param affinityLinkName
195      *            Name of the new affinity link being added
196      * @return Response as dictated by the HTTP Response Status code
197      */
198
199     @Path("/{containerName}/create/link/{affinityLinkName}/from/{fromAffinityGroup}/to/{toAffinityGroup}")
200     @PUT
201     @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
202     @TypeHint(Response.class)
203     @StatusCodes({
204             @ResponseCode(code = 200, condition = "Operation successful"),
205             @ResponseCode(code = 404, condition = "The Container Name or nodeId or configuration name is not found"),
206             @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
207     public Response createAffinityLink(
208             @PathParam("containerName") String containerName,
209             @PathParam("affinityLinkName") String affinityLinkName,
210             @PathParam("fromAffinityGroup") String fromAffinityGroup,
211             @PathParam("toAffinityGroup") String toAffinityGroup) {
212
213         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
214             throw new UnauthorizedException("User is not authorized to perform this operation on container "
215                                             + containerName);
216         }
217
218         IAffinityManager affinityManager = getIfAffinityManagerService(containerName);
219         if (affinityManager == null) {
220             throw new ServiceUnavailableException("Affinity Manager "
221                                                   + RestMessages.SERVICEUNAVAILABLE.toString());
222         }
223
224         
225         log.info("Create affinity link" + affinityLinkName + "fromGroup" + fromAffinityGroup + "toGroup" + toAffinityGroup);
226         AffinityGroup from = affinityManager.getAffinityGroup(fromAffinityGroup);
227         AffinityGroup to = affinityManager.getAffinityGroup(toAffinityGroup);
228         AffinityLink al1 = new AffinityLink(affinityLinkName, from, to);
229
230         Status ret = affinityManager.addAffinityLink(al1);
231         if (!ret.isSuccess()) {
232             throw new InternalServerErrorException(ret.getDescription());
233         }
234         return Response.status(Response.Status.CREATED).build();
235     }
236
237
238     /**
239      * Add path redirect details to an affinity link. 
240      *
241      * @param containerName
242      *            Name of the Container
243      * @param affinityLinkName
244      *            Name of the new affinity link being added
245      * @param wayPoint
246      *            IP address string of a waypoint server or VM
247      * @return Response as dictated by the HTTP Response Status code
248      */
249
250     @Path("/{containerName}/link/{affinityLinkName}/setwaypoint/{waypointIP}")
251     @PUT
252     @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
253     @TypeHint(Response.class)
254     @StatusCodes({
255             @ResponseCode(code = 200, condition = "Operation successful"),
256             @ResponseCode(code = 404, condition = "The Container Name or nodeId or configuration name is not found"),
257             @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
258     public Response setLinkWaypoint(
259             @PathParam("containerName") String containerName,
260             @PathParam("affinityLinkName") String affinityLinkName,
261             @PathParam("waypointIP") String waypointIP) {
262
263         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
264             throw new UnauthorizedException("User is not authorized to perform this operation on container "
265                                             + containerName);
266         }
267
268         IAffinityManager affinityManager = getIfAffinityManagerService(containerName);
269         if (affinityManager == null) {
270             throw new ServiceUnavailableException("Affinity Manager "
271                                                   + RestMessages.SERVICEUNAVAILABLE.toString());
272         }
273         log.info("Set waypoint address (link)" + affinityLinkName + " (waypoint ip) " + waypointIP);
274
275         AffinityLink al1 = affinityManager.getAffinityLink(affinityLinkName);
276         al1.setWaypoint(waypointIP);
277         return Response.status(Response.Status.CREATED).build();
278     }
279
280
281     /**
282      * Add IP addresses to a group. 
283      *
284      * @param containerName
285      *            Name of the Container
286      * @param affinityGroupName
287      *            Name of the affinity group to add to. 
288      * @param ipaddress
289      *            IP address of the new affinity member. 
290      * @return Response as dictated by the HTTP Response Status code
291      */
292     @Path("/{containerName}/group/{affinityGroupName}/add/ip/{ipaddress}")
293     @PUT
294     @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
295     @TypeHint(Response.class)
296     @StatusCodes({
297             @ResponseCode(code = 200, condition = "Operation successful"),
298             @ResponseCode(code = 404, condition = "The Container Name or nodeId or configuration name is not found"),
299             @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
300     public Response addInetAddress(
301             @PathParam("containerName") String containerName,
302             @PathParam("affinityGroupName") String affinityGroupName,
303             @PathParam("ipaddress") String ipaddress) {
304         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
305             throw new UnauthorizedException("User is not authorized to perform this operation on container "
306                                             + containerName);
307         }
308         
309         IAffinityManager affinityManager = getIfAffinityManagerService(containerName);
310         if (affinityManager == null) {
311             throw new ServiceUnavailableException("Affinity Manager "
312                                                   + RestMessages.SERVICEUNAVAILABLE.toString());
313         }
314         
315         log.info("add Inet address " + affinityGroupName + " (ipaddress) " + ipaddress);
316         AffinityGroup ag1 = affinityManager.getAffinityGroup(affinityGroupName);
317         ag1.add(ipaddress);
318         
319         return Response.status(Response.Status.CREATED).build();
320     }
321     
322     /**
323      * Add prefix/mask subnet as a member of the affinity group.
324      *
325      * @param containerName
326      *            Name of the Container
327      * @param affinityGroupName
328      *            Name of the affinity group to add to. 
329      * @param ipmask
330      *            a.b.c.d/mm format of a set of IP addresses to add.
331      * @return Response as dictated by the HTTP Response Status code
332      */
333     @Path("/{containerName}/group/{affinityGroupName}/addsubnet/ipprefix/{ipprefix}/mask/{mask}")
334     @PUT
335     @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
336     @TypeHint(Response.class)
337     @StatusCodes({
338             @ResponseCode(code = 200, condition = "Operation successful"),
339             @ResponseCode(code = 404, condition = "The Container Name or nodeId or configuration name is not found"),
340             @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
341     public Response addSubnet(
342             @PathParam("containerName") String containerName,
343             @PathParam("affinityGroupName") String affinityGroupName,
344             @PathParam("ipprefix") String ipprefix,
345             @PathParam("mask") String mask) {
346         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
347             throw new UnauthorizedException("User is not authorized to perform this operation on container "
348                                             + containerName);
349         }
350         
351         IAffinityManager affinityManager = getIfAffinityManagerService(containerName);
352         if (affinityManager == null) {
353             throw new ServiceUnavailableException("Affinity Manager "
354                                                   + RestMessages.SERVICEUNAVAILABLE.toString());
355         }
356         
357         log.info("addSubnet to affinitygroup" + affinityGroupName);
358         AffinityGroup ag1 = affinityManager.getAffinityGroup(affinityGroupName);
359         String ipmask = ipprefix + "/" + mask;
360         ag1.addInetMask(ipmask);
361         
362         return Response.status(Response.Status.CREATED).build();
363     }
364
365
366     @Path("/{containerName}/affinity-groups")
367     @GET
368     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
369     @TypeHint(AffinityGroupList.class)
370     @StatusCodes({ @ResponseCode(code = 200, condition = "Operation successful"),
371         @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
372         @ResponseCode(code = 404, condition = "The containerName is not found"),
373         @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
374     public AffinityGroupList getAllAffinityGroups(@PathParam("containerName") String containerName) {
375
376         //        if (!isValidContainer(containerName)) {
377         //            throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
378         //}
379
380         if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) {
381             throw new UnauthorizedException("User is not authorized to perform this operation on container "
382                     + containerName);
383         }
384
385         IAffinityManager affinityManager = getIfAffinityManagerService(containerName);
386         if (affinityManager == null) {
387             throw new ServiceUnavailableException("Affinity Manager "
388                                                   + RestMessages.SERVICEUNAVAILABLE.toString());
389         }
390         log.info("getallgroups");
391         return new AffinityGroupList(affinityManager.getAllAffinityGroups());
392     }
393
394 }