Merge changes I69928220,Ia0704c89
authorChi-Vien Ly <chivly@cisco.com>
Thu, 18 Jul 2013 16:40:27 +0000 (16:40 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 18 Jul 2013 16:40:27 +0000 (16:40 +0000)
* changes:
  Change default timeout to 30 sec.
  REST APIs to add/delete ports to/from a subnet.

opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini
opendaylight/northbound/subnets/src/main/java/org/opendaylight/controller/subnets/northbound/SubnetsNorthboundJAXRS.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/DiscoveryService.java

index 6e8a3555234ef8cd668a048fd299eddac823656e..6bf09bb368678b3be59a652bb192da49df5367e4 100644 (file)
@@ -64,8 +64,8 @@ org.eclipse.gemini.web.tomcat.config.path=configuration/tomcat-server.xml
 # of.discoveryInterval=300
 # The timeout multiple of discovery interval
 # of.discoveryTimeoutMultiple=2
-# For newly added ports, allow one more retry if the elapsed time exceeds this threshold (default 10 sec)
-# of.discoveryThreshold=10
+# For newly added ports, allow one more retry if the elapsed time exceeds this threshold (default 30 sec)
+# of.discoveryThreshold=30
 # The maximum number of ports handled in one discovery batch (default 1024)
 # of.discoveryBatchMaxPorts=1024
 
index 6869fd5fbea37595c33eec0d2f04c950db5e754a..e3c2189bf91550bd7c8d35526ec0d75413a88a6a 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.controller.subnets.northbound;
 
 import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 import javax.ws.rs.Consumes;
@@ -31,7 +32,6 @@ import org.codehaus.enunciate.jaxrs.TypeHint;
 import org.opendaylight.controller.northbound.commons.RestMessages;
 import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
-import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
 import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
 import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
 import org.opendaylight.controller.sal.authorization.Privilege;
@@ -44,8 +44,7 @@ import org.slf4j.LoggerFactory;
 
 @Path("/")
 public class SubnetsNorthboundJAXRS {
-    protected static final Logger logger = LoggerFactory
-            .getLogger(SubnetsNorthboundJAXRS.class);
+    protected static final Logger logger = LoggerFactory.getLogger(SubnetsNorthboundJAXRS.class);
 
     private String username;
 
@@ -71,20 +70,15 @@ public class SubnetsNorthboundJAXRS {
     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
     @StatusCodes({ @ResponseCode(code = 404, condition = "The containerName passed was not found") })
     @TypeHint(SubnetConfigs.class)
-    public SubnetConfigs listSubnets(
-            @PathParam("containerName") String containerName) {
-        if (!NorthboundUtils.isAuthorized(
-                getUserName(), containerName, Privilege.READ, this)) {
-            throw new UnauthorizedException(
-                    "User is not authorized to perform this operation on container "
-                            + containerName);
+    public SubnetConfigs listSubnets(@PathParam("containerName") String containerName) {
+        if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) {
+            throw new UnauthorizedException("User is not authorized to perform this operation on container "
+                    + containerName);
         }
         ISwitchManager switchManager = null;
-        switchManager = (ISwitchManager) ServiceHelper.getInstance(
-                ISwitchManager.class, containerName, this);
+        switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName, this);
         if (switchManager == null) {
-            throw new ResourceNotFoundException(
-                    RestMessages.NOCONTAINER.toString());
+            throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
         }
         return new SubnetConfigs(switchManager.getSubnetsConfigList());
     }
@@ -103,30 +97,25 @@ public class SubnetsNorthboundJAXRS {
     @GET
     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
     @StatusCodes({
-            @ResponseCode(code = 404, condition = "The containerName passed was not found"),
-            @ResponseCode(code = 404, condition = "Subnet does not exist") })
-    @TypeHint(SubnetConfig.class)
+        @ResponseCode(code = 404, condition = "The containerName passed was not found"),
+        @ResponseCode(code = 404, condition = "Subnet does not exist") })
+        @TypeHint(SubnetConfig.class)
     public SubnetConfig listSubnet(
-            @PathParam("containerName") String containerName,
-            @PathParam("subnetName") String subnetName) {
+        @PathParam("containerName") String containerName,
+        @PathParam("subnetName") String subnetName) {
 
-        if (!NorthboundUtils.isAuthorized(
-                getUserName(), containerName, Privilege.READ, this)) {
-            throw new UnauthorizedException(
-                    "User is not authorized to perform this operation on container "
-                            + containerName);
+        if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) {
+            throw new UnauthorizedException("User is not authorized to perform this operation on container "
+                    + containerName);
         }
         ISwitchManager switchManager = null;
-        switchManager = (ISwitchManager) ServiceHelper.getInstance(
-                ISwitchManager.class, containerName, this);
+        switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName, this);
         if (switchManager == null) {
-            throw new ResourceNotFoundException(
-                    RestMessages.NOCONTAINER.toString());
+            throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
         }
         SubnetConfig res = switchManager.getSubnetConfig(subnetName);
         if (res == null) {
-            throw new ResourceNotFoundException(
-                    RestMessages.NOSUBNET.toString());
+            throw new ResourceNotFoundException(RestMessages.NOSUBNET.toString());
         } else {
             return res;
         }
@@ -147,37 +136,30 @@ public class SubnetsNorthboundJAXRS {
     @Path("/{containerName}/{subnetName}")
     @POST
     @StatusCodes({
-            @ResponseCode(code = 404, condition = "Invalid Data passed"),
-            @ResponseCode(code = 201, condition = "Subnet added"),
-            @ResponseCode(code = 500, condition = "Addition of subnet failed") })
-    public Response addSubnet(@PathParam("containerName") String containerName,
-            @PathParam("subnetName") String subnetName,
-            @QueryParam("subnet") String subnet) {
-
-        if (!NorthboundUtils.isAuthorized(
-                getUserName(), containerName, Privilege.WRITE, this)) {
-            throw new UnauthorizedException(
-                    "User is not authorized to perform this operation on container "
-                            + containerName);
+        @ResponseCode(code = 404, condition = "Invalid Data passed"),
+        @ResponseCode(code = 201, condition = "Subnet added"),
+        @ResponseCode(code = 500, condition = "Addition of subnet failed") })
+    public Response addSubnet(
+        @PathParam("containerName") String containerName,
+        @PathParam("subnetName") String subnetName, @QueryParam("subnet") String subnet) {
+
+        if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
+            throw new UnauthorizedException("User is not authorized to perform this operation on container "
+                    + containerName);
         }
         if (subnetName == null) {
-            throw new ResourceNotFoundException(
-                    RestMessages.INVALIDDATA.toString());
+            throw new ResourceNotFoundException(RestMessages.INVALIDDATA.toString());
         }
         if (subnet == null) {
-            throw new ResourceNotFoundException(
-                    RestMessages.INVALIDDATA.toString());
+            throw new ResourceNotFoundException(RestMessages.INVALIDDATA.toString());
         }
         ISwitchManager switchManager = null;
-        switchManager = (ISwitchManager) ServiceHelper.getInstance(
-                ISwitchManager.class, containerName, this);
+        switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName, this);
         if (switchManager == null) {
-            throw new ResourceNotFoundException(
-                    RestMessages.NOCONTAINER.toString());
+            throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
         }
 
-        SubnetConfig cfgObject = new SubnetConfig(subnetName, subnet,
-                new ArrayList<String>(0));
+        SubnetConfig cfgObject = new SubnetConfig(subnetName, subnet, new ArrayList<String>(0));
         Status status = switchManager.addSubnet(cfgObject);
         if (status.isSuccess()) {
             return Response.status(Response.Status.CREATED).build();
@@ -197,29 +179,24 @@ public class SubnetsNorthboundJAXRS {
     @Path("/{containerName}/{subnetName}")
     @DELETE
     @StatusCodes({
-            @ResponseCode(code = 404, condition = "The containerName passed was not found"),
-            @ResponseCode(code = 500, condition = "Removal of subnet failed") })
+        @ResponseCode(code = 404, condition = "The containerName passed was not found"),
+        @ResponseCode(code = 500, condition = "Removal of subnet failed") })
     public Response removeSubnet(
-            @PathParam("containerName") String containerName,
-            @PathParam("subnetName") String subnetName) {
+        @PathParam("containerName") String containerName,
+        @PathParam("subnetName") String subnetName) {
         if (subnetName == null) {
-            throw new ResourceNotFoundException(
-                    RestMessages.INVALIDDATA.toString());
+            throw new ResourceNotFoundException(RestMessages.INVALIDDATA.toString());
         }
 
-        if (!NorthboundUtils.isAuthorized(
-                getUserName(), containerName, Privilege.WRITE, this)) {
-            throw new UnauthorizedException(
-                    "User is not authorized to perform this operation on container "
-                            + containerName);
+        if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
+            throw new UnauthorizedException("User is not authorized to perform this operation on container "
+                    + containerName);
         }
 
         ISwitchManager switchManager = null;
-        switchManager = (ISwitchManager) ServiceHelper.getInstance(
-                ISwitchManager.class, containerName, this);
+        switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName, this);
         if (switchManager == null) {
-            throw new ResourceNotFoundException(
-                    RestMessages.NOCONTAINER.toString());
+            throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
         }
         Status status = switchManager.removeSubnet(subnetName);
         if (status.isSuccess()) {
@@ -244,22 +221,21 @@ public class SubnetsNorthboundJAXRS {
     @POST
     @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
     @StatusCodes({
-            @ResponseCode(code = 202, condition = "Operation successful"),
-            @ResponseCode(code = 400, condition = "Invalid request, i.e., requested changing the subnet name"),
-            @ResponseCode(code = 404, condition = "The containerName or subnetName is not found"),
-            @ResponseCode(code = 500, condition = "Internal server error")})
+        @ResponseCode(code = 202, condition = "Operation successful"),
+        @ResponseCode(code = 400, condition = "Invalid request, i.e., requested changing the subnet name"),
+        @ResponseCode(code = 404, condition = "The containerName or subnetName is not found"),
+        @ResponseCode(code = 500, condition = "Internal server error") })
     public Response modifySubnet(@PathParam("containerName") String containerName,
-                                 @PathParam("subnetName") String name,
-                                 @TypeHint(SubnetConfig.class) JAXBElement<SubnetConfig> subnetConfigData) {
+        @PathParam("subnetName") String name,
+        @TypeHint(SubnetConfig.class) JAXBElement<SubnetConfig> subnetConfigData) {
 
-        if (!NorthboundUtils.isAuthorized(getUserName(), containerName,
-                                          Privilege.WRITE, this)) {
-            throw new UnauthorizedException(
-                "User is not authorized to perform this operation on container " + containerName);
+        if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
+            throw new UnauthorizedException("User is not authorized to perform this operation on container "
+                    + containerName);
         }
 
-        ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class,
-                                                                                  containerName, this);
+        ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName,
+                this);
         if (switchManager == null) {
             throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
         }
@@ -271,96 +247,171 @@ public class SubnetsNorthboundJAXRS {
 
         // make sure that the name matches an existing subnet and we're not
         // changing the name or subnet IP/mask
-        if (existingConf == null){
+        if (existingConf == null) {
             // don't have a subnet by that name
             return Response.status(Response.Status.NOT_FOUND).build();
 
-        }else if( !existingConf.getName().equals(subnetConf.getName())
-            || !existingConf.getSubnet().equals(subnetConf.getSubnet())) {
+        } else if (!existingConf.getName().equals(subnetConf.getName())
+                || !existingConf.getSubnet().equals(subnetConf.getSubnet())) {
             // can't change the name of a subnet
             return Response.status(Response.Status.BAD_REQUEST).build();
 
-        }else{
+        } else {
             // create a set for fast lookups
             Set<String> newPorts = new HashSet<String>(subnetConf.getNodePorts());
 
             // go through the current ports and (1) remove ports that aren't
             // there anymore and (2) remove ports that are still there from the
             // set of ports to add
-            for(String s : existingConf.getNodePorts()){
-                if(newPorts.contains(s)){
+            for (String s : existingConf.getNodePorts()) {
+                if (newPorts.contains(s)) {
                     newPorts.remove(s);
-                }else{
+                } else {
                     Status st = switchManager.removePortsFromSubnet(name, s);
                     successful = successful && st.isSuccess();
                 }
             }
 
             // add any remaining ports
-            for(String s : newPorts){
+            for (String s : newPorts) {
                 Status st = switchManager.addPortsToSubnet(name, s);
                 successful = successful && st.isSuccess();
             }
         }
 
-        if(successful){
+        if (successful) {
             return Response.status(Response.Status.ACCEPTED).build();
-        }else{
+        } else {
             return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
         }
     }
 
-    /*
-     *
-     * Add or remove switch ports to a subnet POST subnets/green/sw
+    /**
      *
-     * @param model
+     * Add ports to a subnet
      *
      * @param containerName
-     *
+     *            Name of the Container
      * @param name
+     *            Name of the SubnetConfig to be modified
+     * @param subnetConfigData
+     *            the {@link SubnetConfig} structure in JSON passed as a POST
+     *            parameter
+     * @return If the operation is successful or not
+     */
+    @Path("/{containerName}/{subnetName}/add")
+    @POST
+    @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+    @StatusCodes({
+        @ResponseCode(code = 202, condition = "Operation successful"),
+        @ResponseCode(code = 400, condition = "Invalid request"),
+        @ResponseCode(code = 404, condition = "The containerName or subnetName is not found"),
+        @ResponseCode(code = 500, condition = "Internal server error") })
+    public Response addNodePorts(
+            @PathParam("containerName") String containerName,
+            @PathParam("subnetName") String name,
+            @TypeHint(SubnetConfig.class) JAXBElement<SubnetConfig> subnetConfigData) {
+
+        SubnetConfig subnetConf = subnetConfigData.getValue();
+        return addOrDeletePorts(containerName, name, subnetConf, "add");
+    }
+
+    /**
      *
-     * @param subnet: the subnet name name
-     *
-     * @param switchports: datapath ID/port list =>
-     * xx:xx:xx:xx:xx:xx:xx:xx/a,b,c-m,r-t,y
-     *
-     * @return
-     *
-     * @RequestMapping(value = "/{containerName}/{name}", method =
-     * RequestMethod.POST)
-     *
-     * public View addSwitchports(Map<String, Object> model,
-     *
-     * @PathVariable(value = "containerName") String containerName,
-     *
-     * @PathVariable(value = "name") String name,
-     *
-     * @RequestParam(value = "nodeports") String nodePorts,
-     *
-     * @RequestParam(value = "action") String action) {
-     *
-     * checkDefaultDisabled(containerName); ISwitchManager switchManager = null;
-     * try { BundleContext bCtx = FrameworkUtil.getBundle(this.getClass())
-     * .getBundleContext();
-     *
-     * ServiceReference[] services = bCtx.getServiceReferences(
-     * ISwitchManager.class.getName(), "(containerName=" + containerName + ")");
-     *
-     * if (services != null) { switchManager = (ISwitchManager)
-     * bCtx.getService(services[0]); logger.debug("Switch manager reference is:"
-     * + switchManager); } } catch (Exception e) {
-     * logger.error("Switch Manager reference is NULL"); }
-     *
-     * checkContainerExists(switchManager);
-     *
-     * String ret; if (action.equals("add")) { ret =
-     * switchManager.addPortsToSubnet(name, nodePorts); } else if
-     * (action.equals("remove")) { ret =
-     * switchManager.removePortsFromSubnet(name, nodePorts); } else { throw new
-     * UnsupportedMediaTypeException(RestMessages.UNKNOWNACTION .toString() +
-     * ": " + action); }
+     * Delete ports from a subnet
      *
-     * return returnViewOrThrowConflicEx(model, ret); }
+     * @param containerName
+     *            Name of the Container
+     * @param name
+     *            Name of the SubnetConfig to be modified
+     * @param subnetConfigData
+     *            the {@link SubnetConfig} structure in JSON passed as a POST
+     *            parameter
+     * @return If the operation is successful or not
      */
+    @Path("/{containerName}/{subnetName}/delete")
+    @POST
+    @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+    @StatusCodes({
+        @ResponseCode(code = 202, condition = "Operation successful"),
+        @ResponseCode(code = 400, condition = "Invalid request"),
+        @ResponseCode(code = 404, condition = "The containerName or subnetName is not found"),
+        @ResponseCode(code = 500, condition = "Internal server error") })
+    public Response deleteNodePorts(
+            @PathParam("containerName") String containerName,
+            @PathParam("subnetName") String name,
+            @TypeHint(SubnetConfig.class) JAXBElement<SubnetConfig> subnetConfigData) {
+
+        SubnetConfig subnetConf = subnetConfigData.getValue();
+        return addOrDeletePorts(containerName, name, subnetConf, "delete");
+    }
+
+    /**
+    *
+    * Add/Delete ports to/from a subnet
+    *
+    * @param containerName
+    *            Name of the Container
+    * @param name
+    *            Name of the SubnetConfig to be modified
+    * @param subnetConfig
+    *            the {@link SubnetConfig} structure
+    * @param action
+    *            add or delete
+    * @return If the operation is successful or not
+    */
+    private Response addOrDeletePorts(String containerName, String name, SubnetConfig subnetConf, String action) {
+
+        if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
+            throw new UnauthorizedException("User is not authorized to perform this operation on container "
+                    + containerName);
+        }
+
+        ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName,
+                this);
+        if (switchManager == null) {
+            throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
+        }
+
+        SubnetConfig existingConf = switchManager.getSubnetConfig(name);
+
+        // make sure that the name matches an existing subnet and we're not
+        // changing the name or subnet IP/mask
+        if (existingConf == null) {
+            // don't have a subnet by that name
+            return Response.status(Response.Status.NOT_FOUND).build();
+        } else if (!existingConf.getName().equals(subnetConf.getName())
+                || !existingConf.getSubnet().equals(subnetConf.getSubnet())) {
+            // can't change the name of a subnet
+            return Response.status(Response.Status.BAD_REQUEST).build();
+        } else {
+            Status st;
+            boolean successful = true;
+            List<String> ports = subnetConf.getNodePorts();
+
+            if (action.equals("add")) {
+                // add new ports
+                ports.removeAll(existingConf.getNodePorts());
+                for (String port : ports) {
+                    st = switchManager.addPortsToSubnet(name, port);
+                    successful = successful && st.isSuccess();
+                }
+            } else if (action.equals("delete")) {
+                // delete existing ports
+                ports.retainAll(existingConf.getNodePorts());
+                for (String port : ports) {
+                    st = switchManager.removePortsFromSubnet(name, port);
+                    successful = successful && st.isSuccess();
+                }
+            } else {
+                return Response.status(Response.Status.BAD_REQUEST).build();
+            }
+
+            if (successful) {
+                return Response.status(Response.Status.ACCEPTED).build();
+            } else {
+                return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
+            }
+        }
+    }
 }
index ebd5a68341b9caa5cc3166f415c3d0ed212d8bf4..b3cfde9c146983b4ac44f115178d5af16da606a6 100644 (file)
@@ -167,7 +167,7 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
     public enum DiscoveryPeriod {
         INTERVAL        (300),
         AGEOUT          (120),
-        THRESHOLD       (10);
+        THRESHOLD       (30);
 
         private int time;   // sec
         private int tick;   // tick