2 * Copyright (c) 2013 Plexxi, Inc. 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
9 package org.opendaylight.affinity.affinity.northbound;
11 import java.util.ArrayList;
12 import java.util.HashSet;
13 import java.util.List;
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;
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;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
53 * The class provides Northbound REST APIs to access affinity configuration.
58 public class AffinityNorthbound {
60 private String username;
61 private static final Logger log = LoggerFactory.getLogger(AffinityNorthbound.class);
64 public void setSecurityContext(SecurityContext context) {
65 username = context.getUserPrincipal().getName();
68 protected String getUserName() {
72 private IAffinityManager getIfAffinityManagerService(String containerName) {
73 log.debug("In getIfAffinityManager");
75 IContainerManager containerManager = (IContainerManager) ServiceHelper
76 .getGlobalInstance(IContainerManager.class, this);
77 if (containerManager == null) {
78 throw new ServiceUnavailableException("Container "
79 + RestMessages.SERVICEUNAVAILABLE.toString());
82 boolean found = false;
83 List<String> containerNames = containerManager.getContainerNames();
84 for (String cName : containerNames) {
85 if (cName.trim().equalsIgnoreCase(containerName.trim())) {
92 throw new ResourceNotFoundException(containerName + " "
93 + RestMessages.SERVICEUNAVAILABLE.toString());
96 IAffinityManager affinityManager = (IAffinityManager) ServiceHelper
97 .getInstance(IAffinityManager.class, containerName, this);
99 if (affinityManager == null) {
100 throw new ServiceUnavailableException("Affinity Manager "
101 + RestMessages.SERVICEUNAVAILABLE.toString());
104 return affinityManager;
108 * Add an affinity to the configuration database
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
117 @Path("/{containerName}/create/group/{affinityGroupName}")
119 @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
120 @TypeHint(Response.class)
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) {
129 if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
130 throw new UnauthorizedException("User is not authorized to perform this operation on container "
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());
140 AffinityGroup ag1 = new AffinityGroup(affinityGroupName);
141 Status ret = affinityManager.addAffinityGroup(ag1);
143 return Response.status(Response.Status.CREATED).build();
147 * Returns details of an affinity group.
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.
156 @Path("/{containerName}/group/{affinityGroupName}")
158 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
159 @TypeHint(AffinityGroup.class)
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 "
174 IAffinityManager affinityManager = getIfAffinityManagerService(containerName);
175 if (affinityManager == null) {
176 throw new ServiceUnavailableException("Affinity "
177 + RestMessages.SERVICEUNAVAILABLE.toString());
180 log.info("Get affinity group details" + affinityGroupName);
181 AffinityGroup ag = affinityManager.getAffinityGroup(affinityGroupName);
183 throw new ResourceNotFoundException(RestMessages.SERVICEUNAVAILABLE.toString());
190 * Add an affinity link with one "from" and one "to" affinity group.
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
199 @Path("/{containerName}/create/link/{affinityLinkName}/from/{fromAffinityGroup}/to/{toAffinityGroup}")
201 @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
202 @TypeHint(Response.class)
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) {
213 if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
214 throw new UnauthorizedException("User is not authorized to perform this operation on container "
218 IAffinityManager affinityManager = getIfAffinityManagerService(containerName);
219 if (affinityManager == null) {
220 throw new ServiceUnavailableException("Affinity Manager "
221 + RestMessages.SERVICEUNAVAILABLE.toString());
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);
230 Status ret = affinityManager.addAffinityLink(al1);
231 if (!ret.isSuccess()) {
232 throw new InternalServerErrorException(ret.getDescription());
234 return Response.status(Response.Status.CREATED).build();
239 * Add path redirect details to an affinity link.
241 * @param containerName
242 * Name of the Container
243 * @param affinityLinkName
244 * Name of the new affinity link being added
246 * IP address string of a waypoint server or VM
247 * @return Response as dictated by the HTTP Response Status code
250 @Path("/{containerName}/link/{affinityLinkName}/setwaypoint/{waypointIP}")
252 @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
253 @TypeHint(Response.class)
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) {
263 if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
264 throw new UnauthorizedException("User is not authorized to perform this operation on container "
268 IAffinityManager affinityManager = getIfAffinityManagerService(containerName);
269 if (affinityManager == null) {
270 throw new ServiceUnavailableException("Affinity Manager "
271 + RestMessages.SERVICEUNAVAILABLE.toString());
273 log.info("Set waypoint address (link)" + affinityLinkName + " (waypoint ip) " + waypointIP);
275 AffinityLink al1 = affinityManager.getAffinityLink(affinityLinkName);
276 al1.setWaypoint(waypointIP);
278 affinityManager.addNfchain(al1);
279 affinityManager.enableRedirect(al1);
280 } catch (Exception e) {
281 String message = "An error occurred during flow programming.";
282 log.error(message, e);
284 return Response.status(Response.Status.CREATED).build();
289 * Add IP addresses to a group.
291 * @param containerName
292 * Name of the Container
293 * @param affinityGroupName
294 * Name of the affinity group to add to.
296 * IP address of the new affinity member.
297 * @return Response as dictated by the HTTP Response Status code
299 @Path("/{containerName}/group/{affinityGroupName}/add/ip/{ipaddress}")
301 @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
302 @TypeHint(Response.class)
304 @ResponseCode(code = 200, condition = "Operation successful"),
305 @ResponseCode(code = 404, condition = "The Container Name or nodeId or configuration name is not found"),
306 @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
307 public Response addInetAddress(
308 @PathParam("containerName") String containerName,
309 @PathParam("affinityGroupName") String affinityGroupName,
310 @PathParam("ipaddress") String ipaddress) {
311 if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
312 throw new UnauthorizedException("User is not authorized to perform this operation on container "
316 IAffinityManager affinityManager = getIfAffinityManagerService(containerName);
317 if (affinityManager == null) {
318 throw new ServiceUnavailableException("Affinity Manager "
319 + RestMessages.SERVICEUNAVAILABLE.toString());
322 log.info("add Inet address " + affinityGroupName + " (ipaddress) " + ipaddress);
323 AffinityGroup ag1 = affinityManager.getAffinityGroup(affinityGroupName);
326 return Response.status(Response.Status.CREATED).build();
330 * Add prefix/mask subnet as a member of the affinity group.
332 * @param containerName
333 * Name of the Container
334 * @param affinityGroupName
335 * Name of the affinity group to add to.
337 * a.b.c.d/mm format of a set of IP addresses to add.
338 * @return Response as dictated by the HTTP Response Status code
340 @Path("/{containerName}/group/{affinityGroupName}/addsubnet/ipprefix/{ipprefix}/mask/{mask}")
342 @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
343 @TypeHint(Response.class)
345 @ResponseCode(code = 200, condition = "Operation successful"),
346 @ResponseCode(code = 404, condition = "The Container Name or nodeId or configuration name is not found"),
347 @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
348 public Response addSubnet(
349 @PathParam("containerName") String containerName,
350 @PathParam("affinityGroupName") String affinityGroupName,
351 @PathParam("ipprefix") String ipprefix,
352 @PathParam("mask") String mask) {
353 if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
354 throw new UnauthorizedException("User is not authorized to perform this operation on container "
358 IAffinityManager affinityManager = getIfAffinityManagerService(containerName);
359 if (affinityManager == null) {
360 throw new ServiceUnavailableException("Affinity Manager "
361 + RestMessages.SERVICEUNAVAILABLE.toString());
364 log.info("addSubnet to affinitygroup" + affinityGroupName);
365 AffinityGroup ag1 = affinityManager.getAffinityGroup(affinityGroupName);
366 String ipmask = ipprefix + "/" + mask;
367 ag1.addInetMask(ipmask);
369 return Response.status(Response.Status.CREATED).build();
373 @Path("/{containerName}/affinity-groups")
375 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
376 @TypeHint(AffinityGroupList.class)
377 @StatusCodes({ @ResponseCode(code = 200, condition = "Operation successful"),
378 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
379 @ResponseCode(code = 404, condition = "The containerName is not found"),
380 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
381 public AffinityGroupList getAllAffinityGroups(@PathParam("containerName") String containerName) {
383 // if (!isValidContainer(containerName)) {
384 // throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
387 if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) {
388 throw new UnauthorizedException("User is not authorized to perform this operation on container "
392 IAffinityManager affinityManager = getIfAffinityManagerService(containerName);
393 if (affinityManager == null) {
394 throw new ServiceUnavailableException("Affinity Manager "
395 + RestMessages.SERVICEUNAVAILABLE.toString());
397 log.info("getallgroups");
398 return new AffinityGroupList(affinityManager.getAllAffinityGroups());