From 6ad21cade82f6c488dff28fe298b3b5f552a7ba6 Mon Sep 17 00:00:00 2001 From: Dave Tucker Date: Tue, 1 Jul 2014 14:47:13 +0100 Subject: [PATCH] Refactor Neutron Pagination Code to support Network, Port and Subnet - Move pagination logic to PaginatedRequestFactory - Add INeutronObject interface to bound Generics - Add INeutronRequest interface to enable pagination to be generic Patchset 4: - Fix typos in @XMLElement annotation on the 'links' attributes Change-Id: I7fb6c800268847a36eccd2bc402580cb48c60c46 Signed-off-by: Dave Tucker --- .../networkconfig/neutron/INeutronObject.java | 19 +++ .../networkconfig/neutron/NeutronNetwork.java | 4 +- .../networkconfig/neutron/NeutronPort.java | 4 +- .../networkconfig/neutron/NeutronRouter.java | 4 +- .../networkconfig/neutron/NeutronSubnet.java | 4 +- .../neutron/northbound/INeutronRequest.java | 21 +++ .../northbound/NeutronNetworkRequest.java | 11 +- .../northbound/NeutronNetworksNorthbound.java | 93 +---------- .../northbound/NeutronPortRequest.java | 11 +- .../northbound/NeutronPortsNorthbound.java | 21 ++- .../northbound/NeutronSubnetRequest.java | 14 +- .../northbound/NeutronSubnetsNorthbound.java | 23 ++- .../PaginatedNeutronNetworkRequest.java | 55 ------- .../northbound/PaginatedRequestFactory.java | 154 ++++++++++++++++++ 14 files changed, 281 insertions(+), 157 deletions(-) create mode 100644 opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronObject.java create mode 100644 opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/INeutronRequest.java delete mode 100644 opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/PaginatedNeutronNetworkRequest.java create mode 100644 opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/PaginatedRequestFactory.java diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronObject.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronObject.java new file mode 100644 index 0000000000..bebac37c41 --- /dev/null +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronObject.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + * Authors : Dave Tucker + */ + +package org.opendaylight.controller.networkconfig.neutron; + +/** + * This class contains behaviour common to Neutron configuration objects + */ +public interface INeutronObject { + public String getID(); + public void setID(String id); +} diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronNetwork.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronNetwork.java index 5b35dc2b34..a3c38a9265 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronNetwork.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronNetwork.java @@ -23,7 +23,7 @@ import org.opendaylight.controller.configuration.ConfigurationObject; @XmlRootElement(name = "network") @XmlAccessorType(XmlAccessType.NONE) -public class NeutronNetwork extends ConfigurationObject implements Serializable { +public class NeutronNetwork extends ConfigurationObject implements Serializable, INeutronObject { // See OpenStack Network API v2.0 Reference for description of // annotated attributes @@ -93,6 +93,8 @@ public class NeutronNetwork extends ConfigurationObject implements Serializable public String getID() { return networkUUID; } + public void setID(String id) { this.networkUUID = id; } + public String getNetworkUUID() { return networkUUID; } diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java index 680a07453b..b32b01cb3f 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java @@ -25,7 +25,7 @@ import org.opendaylight.controller.configuration.ConfigurationObject; @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) -public class NeutronPort extends ConfigurationObject implements Serializable { +public class NeutronPort extends ConfigurationObject implements Serializable, INeutronObject { private static final long serialVersionUID = 1L; // See OpenStack Network API v2.0 Reference for description of @@ -76,6 +76,8 @@ public class NeutronPort extends ConfigurationObject implements Serializable { public String getID() { return portUUID; } + public void setID(String id) { this.portUUID = id; } + public String getPortUUID() { return portUUID; } diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter.java index fa35f71fd6..2c10cca0c0 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter.java @@ -23,7 +23,7 @@ import org.opendaylight.controller.configuration.ConfigurationObject; @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) -public class NeutronRouter extends ConfigurationObject implements Serializable { +public class NeutronRouter extends ConfigurationObject implements Serializable, INeutronObject { private static final long serialVersionUID = 1L; // See OpenStack Network API v2.0 Reference for description of @@ -57,6 +57,8 @@ public class NeutronRouter extends ConfigurationObject implements Serializable { public String getID() { return routerUUID; } + public void setID(String id) { this.routerUUID = id; } + public String getRouterUUID() { return routerUUID; } diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet.java index ae84a72bba..840029006b 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet.java @@ -25,7 +25,7 @@ import org.opendaylight.controller.configuration.ConfigurationObject; @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) -public class NeutronSubnet extends ConfigurationObject implements Serializable { +public class NeutronSubnet extends ConfigurationObject implements Serializable, INeutronObject { private static final long serialVersionUID = 1L; // See OpenStack Network API v2.0 Reference for description of @@ -83,6 +83,8 @@ public class NeutronSubnet extends ConfigurationObject implements Serializable { public String getID() { return subnetUUID; } + public void setID(String id) { this.subnetUUID = id; } + public String getSubnetUUID() { return subnetUUID; } diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/INeutronRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/INeutronRequest.java new file mode 100644 index 0000000000..8e0ff5c859 --- /dev/null +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/INeutronRequest.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + * Authors : Dave Tucker + */ + +package org.opendaylight.controller.networkconfig.neutron.northbound; + +import org.opendaylight.controller.networkconfig.neutron.INeutronObject; + +import java.util.List; + +public interface INeutronRequest { + public T getSingleton(); + public boolean isSingleton(); + public List getBulk(); +} diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworkRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworkRequest.java index cebd3c267d..a4c113c2c1 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworkRequest.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworkRequest.java @@ -19,7 +19,7 @@ import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork; @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) -public class NeutronNetworkRequest { +public class NeutronNetworkRequest implements INeutronRequest { // See OpenStack Network API v2.0 Reference for description of // annotated attributes @@ -29,9 +29,18 @@ public class NeutronNetworkRequest { @XmlElement(name="networks") List bulkRequest; + @XmlElement(name="networks_links") + List links; + NeutronNetworkRequest() { } + NeutronNetworkRequest(List bulkRequest, List links) { + this.bulkRequest = bulkRequest; + this.links = links; + this.singletonNetwork = null; + } + NeutronNetworkRequest(List bulk) { bulkRequest = bulk; singletonNetwork = null; diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworksNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworksNorthbound.java index 52c3337e40..9de5aef5f4 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworksNorthbound.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworksNorthbound.java @@ -9,8 +9,6 @@ package org.opendaylight.controller.networkconfig.neutron.northbound; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -33,6 +31,7 @@ import javax.ws.rs.core.Response; import org.codehaus.enunciate.jaxrs.ResponseCode; import org.codehaus.enunciate.jaxrs.StatusCodes; import org.codehaus.enunciate.jaxrs.TypeHint; + import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkAware; import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD; import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces; @@ -95,13 +94,13 @@ public class NeutronNetworksNorthbound { @QueryParam("provider_network_type") String queryProviderNetworkType, @QueryParam("provider_physical_network") String queryProviderPhysicalNetwork, @QueryParam("provider_segmentation_id") String queryProviderSegmentationID, - // pagination + // linkTitle @QueryParam("limit") Integer limit, @QueryParam("marker") String marker, @DefaultValue("false") @QueryParam("page_reverse") Boolean pageReverse // sorting not supported ) { - INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this); + INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this); if (networkInterface == null) { throw new ServiceUnavailableException("Network CRUD Interface " + RestMessages.SERVICEUNAVAILABLE.toString()); @@ -139,89 +138,11 @@ public class NeutronNetworksNorthbound { } } - Comparator neutronNetworkComparator = new Comparator() { - @Override - public int compare(NeutronNetwork o1, NeutronNetwork o2) { - return o1.getID().compareTo(o2.getID()); - } - }; - - Collections.sort(ans, neutronNetworkComparator); - if (limit != null && ans.size() > 1) { - List links = new ArrayList<>(); - Integer startPos = null; - String startMarker; - String endMarker; - Boolean firstPage = false; - Boolean lastPage = false; - - if (marker == null) { - startPos = 0; - } - - else { - - NeutronNetwork markerNetwork = new NeutronNetwork(); - markerNetwork.setNetworkUUID(marker); - - startPos = Collections.binarySearch(ans, markerNetwork, neutronNetworkComparator); - - if (!pageReverse){ - startPos = startPos + 1; - } - else { - startPos = startPos - limit; - } - - } - - if (startPos == null) { - throw new ResourceNotFoundException("UUID for marker:" + marker + " could not be found"); - } - - if (startPos == 0){ - firstPage = true; - } - - if (startPos + limit >= ans.size()) { - ans = ans.subList(startPos, ans.size()); - startMarker = ans.get(0).getID(); - endMarker = ans.get(ans.size() - 1).getID(); - lastPage = true; - } - else if (startPos < 0) { - if (startPos + limit > 0) { - ans = ans.subList(0, startPos + limit); - startMarker = ans.get(0).getID(); - endMarker = ans.get(ans.size() - 1).getID(); - firstPage = true; - } - else { - throw new BadRequestException("Requested page is out of bounds. Please check the supplied limit and marker"); - } - } - else { - ans = ans.subList(startPos, startPos + limit); - startMarker = ans.get(0).getID(); - endMarker = ans.get(limit-1).getID(); - } - - if (!lastPage) { - NeutronPageLink next = new NeutronPageLink(); - next.setRef("next"); - next.setHref(uriInfo.getAbsolutePath().toString() + "?limit=" + limit.toString() + "&marker=" + endMarker); - links.add(next); - } - - if (!firstPage) { - NeutronPageLink previous = new NeutronPageLink(); - previous.setRef("previous"); - previous.setHref(uriInfo.getAbsolutePath().toString() + "?limit=" + limit.toString() + "&marker=" + startMarker + "&page_reverse=True"); - links.add(previous); - } - - return Response.status(200).entity(new PaginatedNeutronNetworkRequest(ans, links)).build(); + // Return a paginated request + NeutronNetworkRequest request = (NeutronNetworkRequest) PaginatedRequestFactory.createRequest(limit, + marker, pageReverse, uriInfo, ans, NeutronNetwork.class); + return Response.status(200).entity(request).build(); } return Response.status(200).entity(new NeutronNetworkRequest(ans)).build(); diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortRequest.java index 9b3399d9a8..12b58aa2ab 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortRequest.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortRequest.java @@ -19,7 +19,7 @@ import org.opendaylight.controller.networkconfig.neutron.NeutronPort; @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) -public class NeutronPortRequest { +public class NeutronPortRequest implements INeutronRequest { // See OpenStack Network API v2.0 Reference for description of // annotated attributes @@ -29,9 +29,18 @@ public class NeutronPortRequest { @XmlElement(name="ports") List bulkRequest; + @XmlElement(name="ports_links") + List links; + NeutronPortRequest() { } + public NeutronPortRequest(List bulkRequest, List links) { + this.bulkRequest = bulkRequest; + this.links = links; + this.singletonPort = null; + } + NeutronPortRequest(List bulk) { bulkRequest = bulk; singletonPort = null; diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java index 1a2512fde3..5451fbf3e1 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java @@ -15,6 +15,7 @@ import java.util.List; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; @@ -22,8 +23,10 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; import org.codehaus.enunciate.jaxrs.ResponseCode; import org.codehaus.enunciate.jaxrs.StatusCodes; @@ -69,6 +72,9 @@ public class NeutronPortsNorthbound { return o.extractFields(fields); } + @Context + UriInfo uriInfo; + /** * Returns a list of all Ports */ @@ -92,10 +98,10 @@ public class NeutronPortsNorthbound { @QueryParam("device_id") String queryDeviceID, @QueryParam("device_owner") String queryDeviceOwner, @QueryParam("tenant_id") String queryTenantID, - // pagination - @QueryParam("limit") String limit, + // linkTitle + @QueryParam("limit") Integer limit, @QueryParam("marker") String marker, - @QueryParam("page_reverse") String pageReverse + @DefaultValue("false") @QueryParam("page_reverse") Boolean pageReverse // sorting not supported ) { INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this); @@ -124,7 +130,14 @@ public class NeutronPortsNorthbound { } } } - //TODO: apply pagination to results + + if (limit != null && ans.size() > 1) { + // Return a paginated request + NeutronPortRequest request = (NeutronPortRequest) PaginatedRequestFactory.createRequest(limit, + marker, pageReverse, uriInfo, ans, NeutronPort.class); + return Response.status(200).entity(request).build(); + } + return Response.status(200).entity( new NeutronPortRequest(ans)).build(); } diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetRequest.java index aed9db58bd..57a724c1cc 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetRequest.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetRequest.java @@ -20,7 +20,7 @@ import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet; @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) -public class NeutronSubnetRequest { +public class NeutronSubnetRequest implements INeutronRequest { // See OpenStack Network API v2.0 Reference for description of // annotated attributes @@ -30,16 +30,28 @@ public class NeutronSubnetRequest { @XmlElement(name="subnets") List bulkRequest; + @XmlElement(name="subnets_links") + List links; + NeutronSubnetRequest() { } + public NeutronSubnetRequest(List bulkRequest, List links) { + this.bulkRequest = bulkRequest; + this.links = links; + this.singletonSubnet = null; + } + NeutronSubnetRequest(List bulk) { bulkRequest = bulk; singletonSubnet = null; + links = null; } NeutronSubnetRequest(NeutronSubnet subnet) { singletonSubnet = subnet; + bulkRequest = null; + links = null; } public NeutronSubnet getSingleton() { diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetsNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetsNorthbound.java index f397eb3a97..8f20269603 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetsNorthbound.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetsNorthbound.java @@ -13,8 +13,10 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; + import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; @@ -22,8 +24,10 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; import org.codehaus.enunciate.jaxrs.ResponseCode; import org.codehaus.enunciate.jaxrs.StatusCodes; @@ -65,6 +69,8 @@ public class NeutronSubnetsNorthbound { return o.extractFields(fields); } + @Context + UriInfo uriInfo; /** * Returns a list of all Subnets */ @@ -89,13 +95,13 @@ public class NeutronSubnetsNorthbound { @QueryParam("tenant_id") String queryTenantID, @QueryParam("ipv6_address_mode") String queryIpV6AddressMode, @QueryParam("ipv6_ra_mode") String queryIpV6RaMode, - // pagination - @QueryParam("limit") String limit, + // linkTitle + @QueryParam("limit") Integer limit, @QueryParam("marker") String marker, - @QueryParam("page_reverse") String pageReverse + @DefaultValue("false") @QueryParam("page_reverse") Boolean pageReverse // sorting not supported ) { - INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this); + INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this); if (subnetInterface == null) { throw new ServiceUnavailableException("Subnet CRUD Interface " + RestMessages.SERVICEUNAVAILABLE.toString()); @@ -122,7 +128,14 @@ public class NeutronSubnetsNorthbound { } } } - //TODO: apply pagination to results + + if (limit != null && ans.size() > 1) { + // Return a paginated request + NeutronSubnetRequest request = (NeutronSubnetRequest) PaginatedRequestFactory.createRequest(limit, + marker, pageReverse, uriInfo, ans, NeutronSubnet.class); + return Response.status(200).entity(request).build(); + } + return Response.status(200).entity( new NeutronSubnetRequest(ans)).build(); } diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/PaginatedNeutronNetworkRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/PaginatedNeutronNetworkRequest.java deleted file mode 100644 index c050661329..0000000000 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/PaginatedNeutronNetworkRequest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2014 Hewlett-Packard Development Company L.P - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - * - * Authors : Dave Tucker - */ - -package org.opendaylight.controller.networkconfig.neutron.northbound; - -import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import java.util.List; - -@XmlRootElement -@XmlAccessorType(XmlAccessType.NONE) - -public class PaginatedNeutronNetworkRequest { - - @XmlElement (name="networks") - List networks; - - @XmlElement (name="network_links") - List networkLinks; - - public PaginatedNeutronNetworkRequest() { - } - - public PaginatedNeutronNetworkRequest(List networks, List networkLinks) { - this.networks = networks; - this.networkLinks = networkLinks; - } - - public List getNetworks() { - return networks; - } - - public void setNetworks(List networks) { - this.networks = networks; - } - - public List getNetworkLinks() { - return networkLinks; - } - - public void setNetworkLinks(List networkLinks) { - this.networkLinks = networkLinks; - } -} diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/PaginatedRequestFactory.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/PaginatedRequestFactory.java new file mode 100644 index 0000000000..8f05e76e18 --- /dev/null +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/PaginatedRequestFactory.java @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + * Authors : Dave Tucker + */ + +package org.opendaylight.controller.networkconfig.neutron.northbound; + +import org.opendaylight.controller.networkconfig.neutron.INeutronObject; +import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork; +import org.opendaylight.controller.networkconfig.neutron.NeutronPort; +import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet; +import org.opendaylight.controller.northbound.commons.exception.BadRequestException; +import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException; + +import javax.ws.rs.core.UriInfo; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public class PaginatedRequestFactory { + + public static class PaginationResults { + List collection; + List links; + + public PaginationResults(List collection, List links) { + this.collection = collection; + this.links = links; + } + } + + public static INeutronRequest createRequest(Integer limit, String marker, + Boolean pageReverse, + UriInfo uriInfo, + List collection, + Class clazz) { + PaginationResults results = _paginate(limit, marker, pageReverse, uriInfo, collection); + + if (clazz.equals(NeutronNetwork.class)){ + return new NeutronNetworkRequest(results.collection, results.links); + } + if (clazz.equals(NeutronSubnet.class)){ + return new NeutronSubnetRequest(results.collection, results.links); + } + if (clazz.equals(NeutronPort.class)){ + return new NeutronPortRequest(results.collection, results.links); + } + return null; + } + + private static PaginationResults _paginate(Integer limit, String marker, Boolean pageReverse, UriInfo uriInfo, List collection) { + List links = new ArrayList<>(); + Integer startPos = null; + String startMarker; + String endMarker; + Boolean firstPage = false; + Boolean lastPage = false; + + Comparator neutronObjectComparator = new Comparator() { + @Override + public int compare(INeutronObject o1, INeutronObject o2) { + return o1.getID().compareTo(o2.getID()); + } + }; + + Collections.sort(collection, neutronObjectComparator); + + if (marker == null) { + startPos = 0; + } + + else { + + class MarkerObject implements INeutronObject { + private String id; + + public String getID() { + return id; + } + + public void setID(String id) { + this.id = id; + } + } + + INeutronObject markerObject = new MarkerObject(); + + markerObject.setID(marker); + + startPos = Collections.binarySearch(collection, markerObject, neutronObjectComparator); + + if (!pageReverse){ + startPos = startPos + 1; + } + else { + startPos = startPos - limit; + } + + } + + if (startPos == null) { + throw new ResourceNotFoundException("UUID for marker:" + marker + " could not be found"); + } + + if (startPos == 0){ + firstPage = true; + } + + if (startPos + limit >= collection.size()) { + collection = collection.subList(startPos, collection.size()); + startMarker = collection.get(0).getID(); + endMarker = collection.get(collection.size() - 1).getID(); + lastPage = true; + } + else if (startPos < 0) { + if (startPos + limit > 0) { + collection = collection.subList(0, startPos + limit); + startMarker = collection.get(0).getID(); + endMarker = collection.get(collection.size() - 1).getID(); + firstPage = true; + } + else { + throw new BadRequestException("Requested page is out of bounds. Please check the supplied limit and marker"); + } + } + else { + collection = collection.subList(startPos, startPos + limit); + startMarker = collection.get(0).getID(); + endMarker = collection.get(limit-1).getID(); + } + + if (!lastPage) { + NeutronPageLink next = new NeutronPageLink(); + next.setRef("next"); + next.setHref(uriInfo.getAbsolutePath().toString() + "?limit=" + limit.toString() + "&marker=" + endMarker); + links.add(next); + } + + if (!firstPage) { + NeutronPageLink previous = new NeutronPageLink(); + previous.setRef("previous"); + previous.setHref(uriInfo.getAbsolutePath().toString() + "?limit=" + limit.toString() + "&marker=" + startMarker + "&page_reverse=True"); + links.add(previous); + } + + return new PaginationResults(collection, links); + } +} -- 2.36.6