OS Neutron Extension Router

This commit is contained in:
Kris Sterckx 2013-11-07 08:54:36 +01:00 committed by Zack Shoylev
parent 7f68dacaf2
commit 964b16c311
34 changed files with 1993 additions and 56 deletions

View File

@ -126,6 +126,7 @@
<test.openstack-neutron.credential>${test.openstack-neutron.credential}</test.openstack-neutron.credential>
<test.jclouds.keystone.credential-type>${test.jclouds.keystone.credential-type}</test.jclouds.keystone.credential-type>
</systemPropertyVariables>
<parallel>classes</parallel>
</configuration>
</execution>
</executions>

View File

@ -18,10 +18,12 @@
*/
package org.jclouds.openstack.neutron.v2_0;
import com.google.common.base.Optional;
import com.google.inject.Provides;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Zone;
import org.jclouds.location.functions.ZoneToEndpoint;
import org.jclouds.openstack.neutron.v2_0.extensions.RouterApi;
import org.jclouds.openstack.neutron.v2_0.features.NetworkApi;
import org.jclouds.openstack.neutron.v2_0.features.PortApi;
import org.jclouds.openstack.neutron.v2_0.features.SubnetApi;
@ -71,4 +73,10 @@ public interface NeutronApi extends Closeable {
*/
@Delegate
PortApi getPortApiForZone(@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/**
* Provides synchronous access to Router features.
*/
@Delegate
Optional<? extends RouterApi> getRouterExtensionForZone(@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
}

View File

@ -0,0 +1,105 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.neutron.v2_0.domain;
import com.google.common.base.Objects;
import java.beans.ConstructorProperties;
/**
* Information on external gateway for the router
*
* @author Nick Livens
*/
public class ExternalGatewayInfo {
private final String networkId;
@ConstructorProperties({"network_id"})
protected ExternalGatewayInfo(String networkId) {
this.networkId = networkId;
}
/**
* @return the id of the network which is used as external gateway for the router
*/
public String getNetworkId() {
return networkId;
}
@Override
public int hashCode() {
return Objects.hashCode(networkId);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
ExternalGatewayInfo that = ExternalGatewayInfo.class.cast(obj);
return Objects.equal(this.networkId, that.networkId);
}
protected Objects.ToStringHelper string() {
return Objects.toStringHelper(this).add("networkId", networkId);
}
@Override
public String toString() {
return string().toString();
}
public static Builder builder() {
return new ConcreteBuilder();
}
public Builder toBuilder() {
return new ConcreteBuilder().fromExternalGatewayInfo(this);
}
public static abstract class Builder {
protected abstract Builder self();
protected String networkId;
/**
* @see ExternalGatewayInfo#getNetworkId()
*/
public Builder networkId(String networkId) {
this.networkId = networkId;
return self();
}
public ExternalGatewayInfo build() {
return new ExternalGatewayInfo(networkId);
}
public Builder fromExternalGatewayInfo(ExternalGatewayInfo in) {
return this.networkId(in.getNetworkId());
}
}
private static class ConcreteBuilder extends Builder {
@Override
protected ConcreteBuilder self() {
return this;
}
}
}

View File

@ -54,7 +54,7 @@ public class Network extends ReferenceWithName {
this.adminStateUp = adminStateUp;
this.shared = shared;
this.external = external;
this.networkType = NetworkType.fromValue(networkType);
this.networkType = networkType != null ? NetworkType.fromValue(networkType) : null;
this.physicalNetworkName = physicalNetworkName;
this.segmentationId = segmentationId;
}

View File

@ -37,10 +37,6 @@ public enum NetworkType {
}
public static NetworkType fromValue(String value) {
for (NetworkType networkType : values()) {
if (networkType.getValue().equalsIgnoreCase(value))
return networkType;
}
return null;
return NetworkType.valueOf(value.toUpperCase());
}
}

View File

@ -23,6 +23,8 @@ import com.google.common.base.Objects;
import java.beans.ConstructorProperties;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A Neutron port
*
@ -47,7 +49,7 @@ public class Port extends ReferenceWithName {
super(id, tenantId, name);
this.adminStateUp = adminStateUp;
this.state = state;
this.networkId = networkId;
this.networkId = checkNotNull(networkId, "networkId");
this.deviceId = deviceId;
this.deviceOwner = deviceOwner;
this.fixedIps = fixedIps;

View File

@ -0,0 +1,151 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.neutron.v2_0.domain;
import com.google.common.base.Objects;
import java.beans.ConstructorProperties;
/**
* A Neutron Router
*
* @author Nick Livens
* @see <a href="http://docs.openstack.org/api/openstack-network/2.0/content/router_ext_concepts.html">api doc</a>
*/
public class Router extends ReferenceWithName {
private final Boolean adminStateUp;
private final State state;
private final ExternalGatewayInfo externalGatewayInfo;
@ConstructorProperties({
"id", "tenant_id", "name", "admin_state_up", "status", "external_gateway_info"
})
protected Router(String id, String tenantId, String name, Boolean adminStateUp, State state, ExternalGatewayInfo externalGatewayInfo) {
super(id, tenantId, name);
this.adminStateUp = adminStateUp;
this.state = state;
this.externalGatewayInfo = externalGatewayInfo;
}
/**
* @return the administrative state of the router
*/
public Boolean getAdminStateUp() {
return adminStateUp;
}
/**
* @return the current state of the router
*/
public State getState() {
return state;
}
/**
* @return the information on external gateway for the router
*/
public ExternalGatewayInfo getExternalGatewayInfo() {
return externalGatewayInfo;
}
@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(), adminStateUp, state, externalGatewayInfo);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Router that = Router.class.cast(obj);
return super.equals(obj)
&& Objects.equal(this.adminStateUp, that.adminStateUp)
&& Objects.equal(this.state, that.state)
&& Objects.equal(this.externalGatewayInfo, that.externalGatewayInfo);
}
protected Objects.ToStringHelper string() {
return super.string()
.add("adminStateUp", adminStateUp).add("state", state).add("externalGatewayInfo", externalGatewayInfo != null ? externalGatewayInfo.toString() : "");
}
@Override
public String toString() {
return string().toString();
}
public static Builder<?> builder() {
return new ConcreteBuilder();
}
public Builder<?> toBuilder() {
return new ConcreteBuilder().fromRouter(this);
}
public static abstract class Builder<T extends Builder<T>> extends ReferenceWithName.Builder<T> {
protected Boolean adminStateUp;
protected State state;
protected ExternalGatewayInfo externalGatewayInfo;
/**
* @see Router#getAdminStateUp()
*/
public T adminStateUp(Boolean adminStateUp) {
this.adminStateUp = adminStateUp;
return self();
}
/**
* @see Router#getState()
*/
public T state(State state) {
this.state = state;
return self();
}
/**
* @see Router#getExternalGatewayInfo()
*/
public T externalGatewayInfo(ExternalGatewayInfo externalGatewayInfo) {
this.externalGatewayInfo = externalGatewayInfo;
return self();
}
public Router build() {
return new Router(id, tenantId, name, adminStateUp, state, externalGatewayInfo);
}
public T fromRouter(Router in) {
return super.fromReference(in)
.adminStateUp(in.getAdminStateUp())
.state(in.getState())
.externalGatewayInfo(in.getExternalGatewayInfo());
}
}
private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
@Override
protected ConcreteBuilder self() {
return this;
}
}
}

View File

@ -0,0 +1,127 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.neutron.v2_0.domain;
import com.google.common.base.Objects;
import java.beans.ConstructorProperties;
/**
* A Neutron Router Interface
*
* @author Nick Livens
* @see <a href="http://docs.openstack.org/api/openstack-network/2.0/content/router_add_interface.html">api doc</a>
*/
public class RouterInterface {
private final String subnetId;
private final String portId;
@ConstructorProperties({
"subnet_id", "port_id"
})
protected RouterInterface(String subnetId, String portId) {
this.subnetId = subnetId;
this.portId = portId;
}
/**
* @return the id of the subnet this router interface is associated with
*/
public String getSubnetId() {
return subnetId;
}
/**
* @return the id of the port this router interface is associated with
*/
public String getPortId() {
return portId;
}
@Override
public int hashCode() {
return Objects.hashCode(subnetId, portId);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
RouterInterface that = RouterInterface.class.cast(obj);
return Objects.equal(this.subnetId, that.subnetId) && Objects.equal(this.portId, that.portId);
}
protected Objects.ToStringHelper string() {
return Objects.toStringHelper(this)
.add("subnetId", subnetId).add("portId", portId);
}
@Override
public String toString() {
return string().toString();
}
public static Builder builder() {
return new ConcreteBuilder();
}
public Builder toBuilder() {
return new ConcreteBuilder().fromRouterInterface(this);
}
public static abstract class Builder {
protected abstract Builder self();
protected String subnetId;
protected String portId;
/**
* @see RouterInterface#getSubnetId()
*/
public Builder subnetId(String subnetId) {
this.subnetId = subnetId;
return self();
}
/**
* @see RouterInterface#getPortId()
*/
public Builder portId(String portId) {
this.portId = portId;
return self();
}
public RouterInterface build() {
return new RouterInterface(subnetId, portId);
}
public Builder fromRouterInterface(RouterInterface in) {
return this.subnetId(in.getSubnetId()).portId(in.getPortId());
}
}
private static class ConcreteBuilder extends Builder {
@Override
protected ConcreteBuilder self() {
return this;
}
}
}

View File

@ -26,8 +26,10 @@ import java.beans.ConstructorProperties;
import java.util.Collection;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A Neutron network
* A Neutron subnet
*
* @author Nick Livens
* @see <a href="http://docs.openstack.org/api/openstack-network/2.0/content/Subnets.html">api doc</a>
@ -50,10 +52,10 @@ public class Subnet extends ReferenceWithName {
String gatewayIp, Integer ipVersion, String cidr, Set<AllocationPool> allocationPools,
Boolean enableDhcp, Set<String> dnsNameServers, Set<HostRoute> hostRoutes) {
super(id, tenantId, name);
this.networkId = networkId;
this.networkId = checkNotNull(networkId, "networkId");
this.gatewayIp = gatewayIp;
this.ipVersion = ipVersion;
this.cidr = cidr;
this.ipVersion = checkNotNull(ipVersion, "ipVersion");
this.cidr = checkNotNull(cidr, "cidr");
this.allocationPools = allocationPools != null ? ImmutableSet.copyOf(allocationPools) : ImmutableSet.<AllocationPool>of();
this.enableDhcp = enableDhcp;
this.dnsNameServers = dnsNameServers != null ? ImmutableSet.copyOf(dnsNameServers) : ImmutableSet.<String>of();

View File

@ -0,0 +1,217 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.neutron.v2_0.extensions;
import org.jclouds.Fallbacks;
import org.jclouds.collect.PagedIterable;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.openstack.neutron.v2_0.domain.ReferenceWithName;
import org.jclouds.openstack.neutron.v2_0.domain.Router;
import org.jclouds.openstack.neutron.v2_0.domain.RouterInterface;
import org.jclouds.openstack.neutron.v2_0.functions.ParseRouterDetails;
import org.jclouds.openstack.neutron.v2_0.functions.ParseRouters;
import org.jclouds.openstack.neutron.v2_0.options.CreateRouterOptions;
import org.jclouds.openstack.neutron.v2_0.options.EmptyOptions;
import org.jclouds.openstack.neutron.v2_0.options.UpdateRouterOptions;
import org.jclouds.openstack.v2_0.options.PaginationOptions;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.Transform;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import static org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
/**
* Provides synchronous access to Router operations on the OpenStack Neutron API.
* <p/>
* A logical entity for forwarding packets across internal subnets and NATting them on external
* networks through an appropriate external gateway.
*
* @author Nick Livens
* @see <a href=
* "http://docs.openstack.org/api/openstack-network/2.0/content/router_ext.html">api doc</a>
*/
@Path("/v2.0/routers")
@RequestFilters(AuthenticateRequest.class)
@Consumes(MediaType.APPLICATION_JSON)
public interface RouterApi {
/**
* Returns the list of all routers currently defined in Neutron for the current tenant. The list provides the unique
* identifier of each router configured for the tenant
*
* @return the list of all router references configured for the tenant.
*/
@Named("router:list")
@GET
@ResponseParser(ParseRouters.class)
@Transform(ParseRouters.ToPagedIterable.class)
@Fallback(Fallbacks.EmptyPagedIterableOnNotFoundOr404.class)
@QueryParams(keys = {"fields", "fields", "fields"}, values = {"id", "tenant_id", "name"})
PagedIterable<? extends ReferenceWithName> list();
/**
* @see <a href="http://docs.openstack.org/api/openstack-network/2.0/content/pagination.html">api doc</a>
*/
@Named("router:list")
@GET
@ResponseParser(ParseRouters.class)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
@QueryParams(keys = {"fields", "fields", "fields"}, values = {"id", "tenant_id", "name"})
PagedIterable<? extends ReferenceWithName> list(PaginationOptions options);
/**
* Returns all routers currently defined in Neutron for the current tenant.
*
* @return the list of all routers configured for the tenant
*/
@Named("router:list")
@GET
@ResponseParser(ParseRouterDetails.class)
@Transform(ParseRouterDetails.ToPagedIterable.class)
@Fallback(Fallbacks.EmptyPagedIterableOnNotFoundOr404.class)
PagedIterable<? extends Router> listInDetail();
/**
* @see <a href="http://docs.openstack.org/api/openstack-network/2.0/content/pagination.html">api doc</a>
*/
@Named("router:list")
@GET
@ResponseParser(ParseRouterDetails.class)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
PagedIterable<? extends Router> listInDetail(PaginationOptions options);
/**
* Returns the specific router.
*
* @param id the id of the router to return
* @return Router or null if not found
*/
@Named("router:get")
@GET
@Path("/{id}")
@SelectJson("router")
@Fallback(Fallbacks.NullOnNotFoundOr404.class)
@Nullable
Router get(@PathParam("id") String id);
/**
* Create a new router
*
* @param options optional arguments
* @return the newly created router
*/
@Named("router:create")
@POST
@SelectJson("router")
@MapBinder(CreateRouterOptions.class)
Router create(CreateRouterOptions... options);
/**
* Update a router
*
* @param id the id of the router to update
* @param options the attributes to update
* @return true if update successful, false if not
*/
@Named("router:update")
@PUT
@Path("/{id}")
@MapBinder(UpdateRouterOptions.class)
@Fallback(Fallbacks.FalseOnNotFoundOr404.class)
boolean update(@PathParam("id") String id, UpdateRouterOptions... options);
/**
* Deletes the specified router
*
* @param id the id of the router to delete
* @return true if delete successful, false if not
*/
@Named("router:delete")
@DELETE
@Path("/{id}")
@Fallback(Fallbacks.FalseOnNotFoundOr404.class)
boolean delete(@PathParam("id") String id);
/**
* Add a interface to a router to connect to the specified subnet
*
* @param routerId the id of the router to create the interface at
* @param subnetId the id of the subnet to connect with the interface
* @return the newly-created router interface
*/
@Named("router:addInterfaceForSubnet")
@PUT
@Path("/{id}/add_router_interface")
@MapBinder(EmptyOptions.class)
RouterInterface addInterfaceForSubnet(@PathParam("id") String routerId, @PayloadParam("subnet_id") String subnetId);
/**
* Add a interface to a router to connect to the specified port
*
* @param routerId the id of the router to create the interface at
* @param portId the id of the port to connect with the interface
* @return the newly-created router interface
*/
@Named("router:addInterfaceForPort")
@PUT
@Path("{id}/add_router_interface")
@MapBinder(EmptyOptions.class)
RouterInterface addInterfaceForPort(@PathParam("id") String routerId, @PayloadParam("port_id") String portId);
/**
* Remove the interface where the specified subnet is connected to
*
* @param routerId the id of the router to remove the interface from
* @param subnetId the id of the subnet to disconnect from the interface
*/
@Named("router:removeInterfaceForSubnet")
@PUT
@Path("/{id}/remove_router_interface")
@MapBinder(EmptyOptions.class)
boolean removeInterfaceForSubnet(@PathParam("id") String routerId, @PayloadParam("subnet_id") String subnetId);
/**
* Remove the interface where the specified port is connected to
*
* @param routerId the id of the router to remove the interface from
* @param portId the id of the port to disconnect from the interface
*/
@Named("router:removeInterfaceForPort")
@PUT
@Path("{id}/remove_router_interface")
@MapBinder(EmptyOptions.class)
boolean removeInterfaceForPort(@PathParam("id") String routerId, @PayloadParam("port_id") String portId);
}

View File

@ -21,7 +21,7 @@ package org.jclouds.openstack.neutron.v2_0.features;
import com.google.common.collect.FluentIterable;
import org.jclouds.Fallbacks;
import org.jclouds.collect.PagedIterable;
import org.jclouds.openstack.v2_0.domain.PaginatedCollection;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.openstack.neutron.v2_0.domain.Network;
import org.jclouds.openstack.neutron.v2_0.domain.ReferenceWithName;
@ -82,12 +82,15 @@ public interface NetworkApi {
@QueryParams(keys = {"fields", "fields", "fields"}, values = {"id", "tenant_id", "name"})
PagedIterable<? extends ReferenceWithName> list();
/**
* @see <a href="http://docs.openstack.org/api/openstack-network/2.0/content/pagination.html">api doc</a>
*/
@Named("network:list")
@GET
@ResponseParser(ParseNetworks.class)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
@QueryParams(keys = {"fields", "fields", "fields"}, values = {"id", "tenant_id", "name"})
PaginatedCollection<? extends ReferenceWithName> list(PaginationOptions options);
PagedIterable<? extends ReferenceWithName> list(PaginationOptions options);
/**
* Returns all networks currently defined in Neutron for the current tenant.
@ -101,11 +104,14 @@ public interface NetworkApi {
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
PagedIterable<? extends Network> listInDetail();
/**
* @see <a href="http://docs.openstack.org/api/openstack-network/2.0/content/pagination.html">api doc</a>
*/
@Named("network:list")
@GET
@ResponseParser(ParseNetworkDetails.class)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
PaginatedCollection<? extends Network> listInDetail(PaginationOptions options);
PagedIterable<? extends Network> listInDetail(PaginationOptions options);
/**
* Return a specific network
@ -118,6 +124,7 @@ public interface NetworkApi {
@Path("/{id}")
@SelectJson("network")
@Fallback(Fallbacks.NullOnNotFoundOr404.class)
@Nullable
Network get(@PathParam("id") String id);
/**

View File

@ -21,7 +21,7 @@ package org.jclouds.openstack.neutron.v2_0.features;
import com.google.common.collect.FluentIterable;
import org.jclouds.Fallbacks;
import org.jclouds.collect.PagedIterable;
import org.jclouds.openstack.v2_0.domain.PaginatedCollection;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.openstack.neutron.v2_0.domain.Port;
import org.jclouds.openstack.neutron.v2_0.domain.ReferenceWithName;
@ -84,12 +84,15 @@ public interface PortApi {
@QueryParams(keys = {"fields", "fields", "fields"}, values = {"id", "tenant_id", "name"})
PagedIterable<? extends ReferenceWithName> list();
/**
* @see <a href="http://docs.openstack.org/api/openstack-network/2.0/content/pagination.html">api doc</a>
*/
@Named("port:list")
@GET
@ResponseParser(ParsePorts.class)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
@QueryParams(keys = {"fields", "fields", "fields"}, values = {"id", "tenant_id", "name"})
PaginatedCollection<? extends ReferenceWithName> list(PaginationOptions options);
PagedIterable<? extends ReferenceWithName> list(PaginationOptions options);
/**
* Returns the set of ports currently defined in Neutron for the requested network.
@ -103,11 +106,14 @@ public interface PortApi {
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
PagedIterable<? extends Port> listInDetail();
/**
* @see <a href="http://docs.openstack.org/api/openstack-network/2.0/content/pagination.html">api doc</a>
*/
@Named("port:list")
@GET
@ResponseParser(ParsePortDetails.class)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
PaginatedCollection<? extends Port> listInDetail(PaginationOptions options);
PagedIterable<? extends Port> listInDetail(PaginationOptions options);
/**
* Returns the specific port
@ -120,6 +126,7 @@ public interface PortApi {
@Path("/{id}")
@SelectJson("port")
@Fallback(Fallbacks.NullOnNotFoundOr404.class)
@Nullable
Port get(@PathParam("id") String id);
/**

View File

@ -21,7 +21,7 @@ package org.jclouds.openstack.neutron.v2_0.features;
import com.google.common.collect.FluentIterable;
import org.jclouds.Fallbacks;
import org.jclouds.collect.PagedIterable;
import org.jclouds.openstack.v2_0.domain.PaginatedCollection;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.openstack.neutron.v2_0.domain.ReferenceWithName;
import org.jclouds.openstack.neutron.v2_0.domain.Subnet;
@ -80,12 +80,15 @@ public interface SubnetApi {
@QueryParams(keys = {"fields", "fields", "fields"}, values = {"id", "tenant_id", "name"})
PagedIterable<? extends ReferenceWithName> list();
/**
* @see <a href="http://docs.openstack.org/api/openstack-network/2.0/content/pagination.html">api doc</a>
*/
@Named("subnet:list")
@GET
@ResponseParser(ParseSubnets.class)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
@QueryParams(keys = {"fields", "fields", "fields"}, values = {"id", "tenant_id", "name"})
PaginatedCollection<? extends ReferenceWithName> list(PaginationOptions options);
PagedIterable<? extends ReferenceWithName> list(PaginationOptions options);
/**
* Returns all subnets currently defined in Neutron for the current tenant.
@ -99,11 +102,14 @@ public interface SubnetApi {
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
PagedIterable<? extends Subnet> listInDetail();
/**
* @see <a href="http://docs.openstack.org/api/openstack-network/2.0/content/pagination.html">api doc</a>
*/
@Named("subnet:list")
@GET
@ResponseParser(ParseSubnetDetails.class)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
PaginatedCollection<? extends Subnet> listInDetail(PaginationOptions options);
PagedIterable<? extends Subnet> listInDetail(PaginationOptions options);
/**
* Returns the specific Subnet.
@ -116,6 +122,7 @@ public interface SubnetApi {
@Path("/{id}")
@SelectJson("subnet")
@Fallback(Fallbacks.NullOnNotFoundOr404.class)
@Nullable
Subnet get(@PathParam("id") String id);
/**

View File

@ -47,8 +47,8 @@ public class ParseNetworkDetails extends ParseJson<Networks> {
static class Networks extends PaginatedCollection<Network> {
@ConstructorProperties({ "networks", "networks_links" })
protected Networks(Iterable<Network> networks, Iterable<Link> networks_links) {
super(networks, networks_links);
protected Networks(Iterable<Network> networks, Iterable<Link> networksLinks) {
super(networks, networksLinks);
}
}
@ -82,7 +82,7 @@ public class ParseNetworkDetails extends ParseJson<Networks> {
@Override
public String toString() {
return "list()";
return "listNetworksInDetail()";
}
};
}

View File

@ -47,8 +47,8 @@ public class ParseNetworks extends ParseJson<Networks> {
static class Networks extends PaginatedCollection<ReferenceWithName> {
@ConstructorProperties({ "networks", "networks_links" })
protected Networks(Iterable<ReferenceWithName> networks, Iterable<Link> networks_links) {
super(networks, networks_links);
protected Networks(Iterable<ReferenceWithName> networks, Iterable<Link> networksLinks) {
super(networks, networksLinks);
}
}
@ -82,7 +82,7 @@ public class ParseNetworks extends ParseJson<Networks> {
@Override
public String toString() {
return "list()";
return "listNetworks()";
}
};
}

View File

@ -48,8 +48,8 @@ public class ParsePortDetails extends ParseJson<Ports> {
static class Ports extends PaginatedCollection<Port> {
@ConstructorProperties({ "ports", "ports_links" })
protected Ports(Iterable<Port> ports, Iterable<Link> ports_links) {
super(ports, ports_links);
protected Ports(Iterable<Port> ports, Iterable<Link> portsLinks) {
super(ports, portsLinks);
}
}
@ -83,7 +83,7 @@ public class ParsePortDetails extends ParseJson<Ports> {
@Override
public String toString() {
return "list()";
return "listPortsInDetail()";
}
};
}

View File

@ -47,8 +47,8 @@ public class ParsePorts extends ParseJson<Ports> {
static class Ports extends PaginatedCollection<ReferenceWithName> {
@ConstructorProperties({ "ports", "ports_links" })
protected Ports(Iterable<ReferenceWithName> ports, Iterable<Link> ports_links) {
super(ports, ports_links);
protected Ports(Iterable<ReferenceWithName> ports, Iterable<Link> portsLinks) {
super(ports, portsLinks);
}
}
@ -82,7 +82,7 @@ public class ParsePorts extends ParseJson<Ports> {
@Override
public String toString() {
return "list()";
return "listPorts()";
}
};
}

View File

@ -0,0 +1,93 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.neutron.v2_0.functions;
import com.google.common.annotations.Beta;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.inject.TypeLiteral;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.internal.Arg0ToPagedIterable;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.json.Json;
import org.jclouds.openstack.neutron.v2_0.NeutronApi;
import org.jclouds.openstack.neutron.v2_0.domain.Router;
import org.jclouds.openstack.neutron.v2_0.extensions.RouterApi;
import org.jclouds.openstack.neutron.v2_0.functions.ParseRouterDetails.Routers;
import org.jclouds.openstack.v2_0.domain.Link;
import org.jclouds.openstack.v2_0.domain.PaginatedCollection;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.beans.ConstructorProperties;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.openstack.v2_0.options.PaginationOptions.Builder.marker;
/**
* @author Nick Livens
*/
@Beta
@Singleton
public class ParseRouterDetails extends ParseJson<Routers> {
static class Routers extends PaginatedCollection<Router> {
@ConstructorProperties({ "routers", "routers_links" })
protected Routers(Iterable<Router> routers, Iterable<Link> routersLinks) {
super(routers, routersLinks);
}
}
@Inject
public ParseRouterDetails(Json json) {
super(json, TypeLiteral.get(Routers.class));
}
public static class ToPagedIterable extends Arg0ToPagedIterable.FromCaller<Router, ToPagedIterable> {
private final NeutronApi api;
@Inject
protected ToPagedIterable(NeutronApi api) {
this.api = checkNotNull(api, "api");
}
@Override
protected Function<Object, IterableWithMarker<Router>> markerToNextForArg0(Optional<Object> arg0) {
String zone = arg0.isPresent() ? arg0.get().toString() : null;
final RouterApi routerApi = api.getRouterExtensionForZone(zone).get();
return new Function<Object, IterableWithMarker<Router>>() {
@SuppressWarnings("unchecked")
@Override
public IterableWithMarker<Router> apply(Object input) {
return IterableWithMarker.class.cast(routerApi.listInDetail(marker(input.toString())));
}
@Override
public String toString() {
return "listRoutersInDetail()";
}
};
}
}
}

View File

@ -0,0 +1,93 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.neutron.v2_0.functions;
import com.google.common.annotations.Beta;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.inject.TypeLiteral;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.internal.Arg0ToPagedIterable;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.json.Json;
import org.jclouds.openstack.neutron.v2_0.NeutronApi;
import org.jclouds.openstack.neutron.v2_0.domain.ReferenceWithName;
import org.jclouds.openstack.neutron.v2_0.extensions.RouterApi;
import org.jclouds.openstack.neutron.v2_0.functions.ParseRouters.Routers;
import org.jclouds.openstack.v2_0.domain.Link;
import org.jclouds.openstack.v2_0.domain.PaginatedCollection;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.beans.ConstructorProperties;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.openstack.v2_0.options.PaginationOptions.Builder.marker;
/**
* @author Nick Livens
*/
@Beta
@Singleton
public class ParseRouters extends ParseJson<Routers> {
static class Routers extends PaginatedCollection<ReferenceWithName> {
@ConstructorProperties({ "routers", "routers_links" })
protected Routers(Iterable<ReferenceWithName> routers, Iterable<Link> routersLinks) {
super(routers, routersLinks);
}
}
@Inject
public ParseRouters(Json json) {
super(json, TypeLiteral.get(Routers.class));
}
public static class ToPagedIterable extends Arg0ToPagedIterable.FromCaller<ReferenceWithName, ToPagedIterable> {
private final NeutronApi api;
@Inject
protected ToPagedIterable(NeutronApi api) {
this.api = checkNotNull(api, "api");
}
@Override
protected Function<Object, IterableWithMarker<ReferenceWithName>> markerToNextForArg0(Optional<Object> arg0) {
String zone = arg0.isPresent() ? arg0.get().toString() : null;
final RouterApi routerApi = api.getRouterExtensionForZone(zone).get();
return new Function<Object, IterableWithMarker<ReferenceWithName>>() {
@SuppressWarnings("unchecked")
@Override
public IterableWithMarker<ReferenceWithName> apply(Object input) {
return IterableWithMarker.class.cast(routerApi.list(marker(input.toString())));
}
@Override
public String toString() {
return "listRouters()";
}
};
}
}
}

View File

@ -47,8 +47,8 @@ public class ParseSubnetDetails extends ParseJson<Subnets> {
static class Subnets extends PaginatedCollection<Subnet> {
@ConstructorProperties({ "subnets", "subnets_links" })
protected Subnets(Iterable<Subnet> subnets, Iterable<Link> subnets_links) {
super(subnets, subnets_links);
protected Subnets(Iterable<Subnet> subnets, Iterable<Link> subnetsLinks) {
super(subnets, subnetsLinks);
}
}
@ -82,7 +82,7 @@ public class ParseSubnetDetails extends ParseJson<Subnets> {
@Override
public String toString() {
return "list()";
return "listSubnetsInDetail()";
}
};
}

View File

@ -47,8 +47,8 @@ public class ParseSubnets extends ParseJson<Subnets> {
static class Subnets extends PaginatedCollection<ReferenceWithName> {
@ConstructorProperties({ "subnets", "subnets_links" })
protected Subnets(Iterable<ReferenceWithName> subnets, Iterable<Link> subnets_links) {
super(subnets, subnets_links);
protected Subnets(Iterable<ReferenceWithName> subnets, Iterable<Link> subnetsLinks) {
super(subnets, subnetsLinks);
}
}
@ -82,7 +82,7 @@ public class ParseSubnets extends ParseJson<Subnets> {
@Override
public String toString() {
return "list()";
return "listSubnets()";
}
};
}

View File

@ -0,0 +1,168 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.neutron.v2_0.options;
import com.google.common.collect.ImmutableMap;
import org.jclouds.http.HttpRequest;
import org.jclouds.openstack.neutron.v2_0.domain.ExternalGatewayInfo;
import org.jclouds.rest.MapBinder;
import org.jclouds.rest.binders.BindToJsonPayload;
import javax.inject.Inject;
import java.util.Map;
/**
* @author Nick Livens
*/
public class CreateRouterOptions implements MapBinder {
@Inject
private BindToJsonPayload jsonBinder;
public static Builder<?> builder() {
return new ConcreteBuilder();
}
public Builder<?> toBuilder() {
return new ConcreteBuilder().fromCreateRouterOptions(this);
}
public static abstract class Builder<T extends Builder<T>> {
protected abstract T self();
protected String name;
protected Boolean adminStateUp;
protected ExternalGatewayInfo externalGatewayInfo;
/**
* @see CreateRouterOptions#getName()
*/
public T name(String name) {
this.name = name;
return self();
}
/**
* @see CreateRouterOptions#getAdminStateUp()
*/
public T adminStateUp(Boolean adminStateUp) {
this.adminStateUp = adminStateUp;
return self();
}
/**
* @see CreateRouterOptions#getExternalGatewayInfo()
*/
public T externalGatewayInfo(ExternalGatewayInfo externalGatewayInfo) {
this.externalGatewayInfo = externalGatewayInfo;
return self();
}
public CreateRouterOptions build() {
return new CreateRouterOptions(name, adminStateUp, externalGatewayInfo);
}
public T fromCreateRouterOptions(CreateRouterOptions options) {
return this.name(options.getName())
.adminStateUp(options.getAdminStateUp())
.externalGatewayInfo(options.getExternalGatewayInfo());
}
}
private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
@Override
protected ConcreteBuilder self() {
return this;
}
}
protected static class CreateRouterRequest {
protected String name;
protected Boolean admin_state_up;
protected ExternalGatewayInfo external_gateway_info;
protected CreateRouterRequest() {
}
protected static final class ExternalGatewayInfo {
protected String network_id;
protected ExternalGatewayInfo(String network_id) {
this.network_id = network_id;
}
}
}
protected String name;
protected Boolean adminStateUp;
protected ExternalGatewayInfo externalGatewayInfo;
protected CreateRouterOptions() {
this.name = null;
this.adminStateUp = null;
this.externalGatewayInfo = null;
}
public CreateRouterOptions(String name, Boolean adminStateUp, ExternalGatewayInfo externalGatewayInfo) {
this.name = name;
this.adminStateUp = adminStateUp;
this.externalGatewayInfo = externalGatewayInfo;
}
/**
* @return the name for the router
*/
public String getName() {
return name;
}
/**
* @return the administrative state of the router
*/
public Boolean getAdminStateUp() {
return adminStateUp;
}
/**
* @return the external gateway info for the router
*/
public ExternalGatewayInfo getExternalGatewayInfo() {
return externalGatewayInfo;
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) {
CreateRouterRequest createRouterRequest = new CreateRouterRequest();
if (this.name != null)
createRouterRequest.name = this.name;
if (this.adminStateUp != null)
createRouterRequest.admin_state_up = this.adminStateUp;
if (this.externalGatewayInfo != null)
createRouterRequest.external_gateway_info = new CreateRouterRequest.ExternalGatewayInfo(this.externalGatewayInfo.getNetworkId());
return bindToRequest(request, ImmutableMap.of("router", createRouterRequest));
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
return jsonBinder.bindToRequest(request, input);
}
}

View File

@ -0,0 +1,48 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.neutron.v2_0.options;
import com.google.inject.Inject;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.MapBinder;
import org.jclouds.rest.binders.BindToJsonPayload;
import java.util.Map;
/**
* This class is used for methods who don't need a wrapper around their JSON body
*
* @author Nick Livens
*/
public class EmptyOptions implements MapBinder {
@Inject
private BindToJsonPayload jsonBinder;
@Override
public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) {
return bindToRequest(request, (Object) postParams);
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
return jsonBinder.bindToRequest(request, input);
}
}

View File

@ -0,0 +1,168 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.neutron.v2_0.options;
import com.google.common.collect.ImmutableMap;
import org.jclouds.http.HttpRequest;
import org.jclouds.openstack.neutron.v2_0.domain.ExternalGatewayInfo;
import org.jclouds.rest.MapBinder;
import org.jclouds.rest.binders.BindToJsonPayload;
import javax.inject.Inject;
import java.util.Map;
/**
* @author Nick Livens
*/
public class UpdateRouterOptions implements MapBinder {
@Inject
private BindToJsonPayload jsonBinder;
public static Builder<?> builder() {
return new ConcreteBuilder();
}
public Builder<?> toBuilder() {
return new ConcreteBuilder().fromUpdateRouterOptions(this);
}
public static abstract class Builder<T extends Builder<T>> {
protected abstract T self();
protected String name;
protected Boolean adminStateUp;
protected ExternalGatewayInfo externalGatewayInfo;
/**
* @see UpdateRouterOptions#getName()
*/
public T name(String name) {
this.name = name;
return self();
}
/**
* @see UpdateRouterOptions#getAdminStateUp()
*/
public T adminStateUp(Boolean adminStateUp) {
this.adminStateUp = adminStateUp;
return self();
}
/**
* @see UpdateRouterOptions#getExternalGatewayInfo()
*/
public T externalGatewayInfo(ExternalGatewayInfo externalGatewayInfo) {
this.externalGatewayInfo = externalGatewayInfo;
return self();
}
public UpdateRouterOptions build() {
return new UpdateRouterOptions(name, adminStateUp, externalGatewayInfo);
}
public T fromUpdateRouterOptions(UpdateRouterOptions options) {
return this.name(options.getName())
.adminStateUp(options.getAdminStateUp())
.externalGatewayInfo(options.getExternalGatewayInfo());
}
}
private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
@Override
protected ConcreteBuilder self() {
return this;
}
}
protected static class UpdateRouterRequest {
protected String name;
protected Boolean admin_state_up;
protected ExternalGatewayInfo external_gateway_info;
protected UpdateRouterRequest() {
}
protected static final class ExternalGatewayInfo {
protected String network_id;
protected ExternalGatewayInfo(String network_id) {
this.network_id = network_id;
}
}
}
protected String name;
protected Boolean adminStateUp;
protected ExternalGatewayInfo externalGatewayInfo;
protected UpdateRouterOptions() {
this.name = null;
this.adminStateUp = null;
this.externalGatewayInfo = null;
}
public UpdateRouterOptions(String name, Boolean adminStateUp, ExternalGatewayInfo externalGatewayInfo) {
this.name = name;
this.adminStateUp = adminStateUp;
this.externalGatewayInfo = externalGatewayInfo;
}
/**
* @return the new name for the router
*/
public String getName() {
return name;
}
/**
* @return the new administrative state for the router
*/
public Boolean getAdminStateUp() {
return adminStateUp;
}
/**
* @return the new information on external gateway for the router
*/
public ExternalGatewayInfo getExternalGatewayInfo() {
return externalGatewayInfo;
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) {
UpdateRouterRequest updateRouterRequest = new UpdateRouterRequest();
if (this.name != null)
updateRouterRequest.name = this.name;
if (this.adminStateUp != null)
updateRouterRequest.admin_state_up = this.adminStateUp;
if (this.externalGatewayInfo != null)
updateRouterRequest.external_gateway_info = new UpdateRouterRequest.ExternalGatewayInfo(this.externalGatewayInfo.getNetworkId());
return bindToRequest(request, ImmutableMap.of("router", updateRouterRequest));
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
return jsonBinder.bindToRequest(request, input);
}
}

View File

@ -0,0 +1,295 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.neutron.v2_0.extensions;
import com.google.common.collect.ImmutableSet;
import org.jclouds.http.HttpResponse;
import org.jclouds.openstack.neutron.v2_0.domain.ExternalGatewayInfo;
import org.jclouds.openstack.neutron.v2_0.domain.ReferenceWithName;
import org.jclouds.openstack.neutron.v2_0.domain.Router;
import org.jclouds.openstack.neutron.v2_0.domain.RouterInterface;
import org.jclouds.openstack.neutron.v2_0.domain.State;
import org.jclouds.openstack.neutron.v2_0.internal.BaseNeutronApiExpectTest;
import org.jclouds.openstack.neutron.v2_0.options.CreateRouterOptions;
import org.jclouds.openstack.neutron.v2_0.options.UpdateRouterOptions;
import org.jclouds.openstack.neutron.v2_0.parse.ParseRouterTest;
import org.jclouds.rest.AuthorizationException;
import org.testng.annotations.Test;
import javax.ws.rs.core.MediaType;
import java.util.Set;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
/**
* Tests parsing and Guice wiring of RouterApi
*
* @author Nick Livens
*/
@Test(groups = "unit", testName = "RouterApiExpectTest")
public class RouterApiExpectTest extends BaseNeutronApiExpectTest {
private static final String ZONE = "region-a.geo-1";
public void testListReferencesReturns2xx() {
RouterApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/routers").addQueryParam("fields", "id", "tenant_id", "name").build(),
HttpResponse.builder().statusCode(200).payload(payloadFromResourceWithContentType("/list_routers.json", APPLICATION_JSON)).build())
.getRouterExtensionForZone(ZONE).get();
Set<? extends ReferenceWithName> references = api.list().concat().toSet();
assertEquals(references, listOfReferencesWithNames());
}
public void testListReferencesReturns4xx() {
RouterApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/routers").addQueryParam("fields", "id", "tenant_id", "name").build(),
HttpResponse.builder().statusCode(404).build())
.getRouterExtensionForZone(ZONE).get();
assertTrue(api.list().concat().isEmpty());
}
public void testListReturns2xx() {
RouterApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/routers").build(),
HttpResponse.builder().statusCode(200).payload(payloadFromResourceWithContentType("/list_routers.json", APPLICATION_JSON)).build())
.getRouterExtensionForZone(ZONE).get();
Set<? extends Router> routers = api.listInDetail().concat().toSet();
assertEquals(routers, listOfRouters());
}
public void testListReturns4xx() {
RouterApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/routers").build(),
HttpResponse.builder().statusCode(404).build())
.getRouterExtensionForZone(ZONE).get();
assertTrue(api.listInDetail().concat().isEmpty());
}
public void testGetReturns2xx() {
RouterApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/routers/16dba3bc-f3fa-4775-afdc-237e12c72f6a").build(),
HttpResponse.builder().statusCode(200).payload(payloadFromResourceWithContentType("/router.json", APPLICATION_JSON)).build())
.getRouterExtensionForZone(ZONE).get();
Router router = api.get("16dba3bc-f3fa-4775-afdc-237e12c72f6a");
assertEquals(router, new ParseRouterTest().expected());
}
public void testGetReturns4xx() {
RouterApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/routers/16dba3bc-f3fa-4775-afdc-237e12c72f6a").build(),
HttpResponse.builder().statusCode(404).build())
.getRouterExtensionForZone(ZONE).get();
assertNull(api.get("16dba3bc-f3fa-4775-afdc-237e12c72f6a"));
}
public void testCreateReturns2xx() {
RouterApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/routers").method("POST")
.payload(payloadFromStringWithContentType("{\"router\":{\"name\":\"test\",\"external_gateway_info\":{\"network_id\":\"1234567890\"}}}", MediaType.APPLICATION_JSON)).build(),
HttpResponse.builder().statusCode(200).payload(payloadFromStringWithContentType("{\"router\":{\"id\":\"12345\",\"tenant_id\":\"6789\",\"external_gateway_info\":{\"network_id\":\"1234567890\"}}}", APPLICATION_JSON)).build())
.getRouterExtensionForZone(ZONE).get();
Router router = api.create(CreateRouterOptions.builder().name("test").externalGatewayInfo(ExternalGatewayInfo.builder().networkId("1234567890").build()).build());
assertEquals(router, Router.builder().id("12345").tenantId("6789").externalGatewayInfo(ExternalGatewayInfo.builder().networkId("1234567890").build()).build());
}
@Test(expectedExceptions = AuthorizationException.class)
public void testCreateReturns4xx() {
RouterApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/routers").method("POST")
.payload(payloadFromStringWithContentType("{\"router\":{\"name\":\"another-test\",\"external_gateway_info\":{\"network_id\":\"1234567890\"}}}", MediaType.APPLICATION_JSON)).build(),
HttpResponse.builder().statusCode(401).build())
.getRouterExtensionForZone(ZONE).get();
api.create(CreateRouterOptions.builder().name("another-test").externalGatewayInfo(ExternalGatewayInfo.builder().networkId("1234567890").build()).build());
}
public void testUpdateReturns2xx() {
RouterApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/routers/12345").method("PUT")
.payload(payloadFromStringWithContentType("{\"router\":{\"name\":\"another-test\",\"admin_state_up\":true}}", MediaType.APPLICATION_JSON)).build(),
HttpResponse.builder().statusCode(200).build())
.getRouterExtensionForZone(ZONE).get();
assertTrue(api.update("12345", UpdateRouterOptions.builder().name("another-test").adminStateUp(true).build()));
}
public void testUpdateReturns4xx() {
RouterApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/routers/12345").method("PUT")
.payload(payloadFromStringWithContentType("{\"router\":{\"name\":\"another-test\",\"admin_state_up\":true}}", MediaType.APPLICATION_JSON)).build(),
HttpResponse.builder().statusCode(404).build())
.getRouterExtensionForZone(ZONE).get();
assertFalse(api.update("12345", UpdateRouterOptions.builder().name("another-test").adminStateUp(true).build()));
}
public void testDeleteReturns2xx() {
RouterApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/routers/12345").method("DELETE").build(),
HttpResponse.builder().statusCode(200).build())
.getRouterExtensionForZone(ZONE).get();
assertTrue(api.delete("12345"));
}
@Test(expectedExceptions = AuthorizationException.class)
public void testDeleteReturns4xx() {
RouterApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/routers/12345").method("DELETE").build(),
HttpResponse.builder().statusCode(403).build())
.getRouterExtensionForZone(ZONE).get();
api.delete("12345");
}
public void testAddInterfaceForSubnetReturns2xx() {
RouterApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/routers/12345/add_router_interface").method("PUT")
.payload(payloadFromStringWithContentType("{\"subnet_id\":\"1234567890\"}", MediaType.APPLICATION_JSON)).build(),
HttpResponse.builder().statusCode(200).payload(payloadFromStringWithContentType("{\"subnet_id\":\"1234567890\",\"port_id\":\"987654321\"}", MediaType.APPLICATION_JSON)).build())
.getRouterExtensionForZone(ZONE).get();
RouterInterface routerInterface = api.addInterfaceForSubnet("12345", "1234567890");
assertEquals(routerInterface, RouterInterface.builder().subnetId("1234567890").portId("987654321").build());
}
@Test(expectedExceptions = AuthorizationException.class)
public void testAddInterfaceForSubnetReturns4xx() {
RouterApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/routers/12345/add_router_interface").method("PUT")
.payload(payloadFromStringWithContentType("{\"subnet_id\":\"1234567890\"}", MediaType.APPLICATION_JSON)).build(),
HttpResponse.builder().statusCode(403).build())
.getRouterExtensionForZone(ZONE).get();
api.addInterfaceForSubnet("12345", "1234567890");
}
public void testAddInterfaceForPortReturns2xx() {
RouterApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/routers/12345/add_router_interface").method("PUT")
.payload(payloadFromStringWithContentType("{\"port_id\":\"987654321\"}", MediaType.APPLICATION_JSON)).build(),
HttpResponse.builder().statusCode(200).payload(payloadFromStringWithContentType("{\"subnet_id\":\"1234567890\",\"port_id\":\"987654321\"}", MediaType.APPLICATION_JSON)).build())
.getRouterExtensionForZone(ZONE).get();
RouterInterface routerInterface = api.addInterfaceForPort("12345", "987654321");
assertEquals(routerInterface, RouterInterface.builder().subnetId("1234567890").portId("987654321").build());
}
@Test(expectedExceptions = AuthorizationException.class)
public void testAddInterfaceForPortReturns4xx() {
RouterApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/routers/12345/add_router_interface").method("PUT")
.payload(payloadFromStringWithContentType("{\"port_id\":\"1234567890\"}", MediaType.APPLICATION_JSON)).build(),
HttpResponse.builder().statusCode(403).build())
.getRouterExtensionForZone(ZONE).get();
api.addInterfaceForPort("12345", "1234567890");
}
public void testRemoveInterfaceForSubnetReturns2xx() {
RouterApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/routers/12345/remove_router_interface").method("PUT")
.payload(payloadFromStringWithContentType("{\"subnet_id\":\"1234567890\"}", MediaType.APPLICATION_JSON)).build(),
HttpResponse.builder().statusCode(200).build())
.getRouterExtensionForZone(ZONE).get();
api.removeInterfaceForSubnet("12345", "1234567890");
}
@Test(expectedExceptions = AuthorizationException.class)
public void testRemoveInterfaceForSubnetReturns4xx() {
RouterApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/routers/12345/remove_router_interface").method("PUT")
.payload(payloadFromStringWithContentType("{\"subnet_id\":\"1234567890\"}", MediaType.APPLICATION_JSON)).build(),
HttpResponse.builder().statusCode(403).build())
.getRouterExtensionForZone(ZONE).get();
api.removeInterfaceForSubnet("12345", "1234567890");
}
public void testRemoveInterfaceForPortReturns2xx() {
RouterApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/routers/12345/remove_router_interface").method("PUT")
.payload(payloadFromStringWithContentType("{\"port_id\":\"1234567890\"}", MediaType.APPLICATION_JSON)).build(),
HttpResponse.builder().statusCode(200).build())
.getRouterExtensionForZone(ZONE).get();
api.removeInterfaceForPort("12345", "1234567890");
}
@Test(expectedExceptions = AuthorizationException.class)
public void testRemoveInterfaceForPortReturns4xx() {
RouterApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess,
authenticatedGET().endpoint(endpoint + "/routers/12345/remove_router_interface").method("PUT")
.payload(payloadFromStringWithContentType("{\"port_id\":\"1234567890\"}", MediaType.APPLICATION_JSON)).build(),
HttpResponse.builder().statusCode(403).build())
.getRouterExtensionForZone(ZONE).get();
api.removeInterfaceForPort("12345", "1234567890");
}
protected Set<Router> listOfRouters() {
return ImmutableSet.of(
Router.builder().state(State.ACTIVE).name("jclouds-test").tenantId("1234567890").id("16dba3bc-f3fa-4775-afdc-237e12c72f6a").build(),
Router.builder().state(State.ACTIVE).name("wibble").tenantId("1234567890").id("1a104cf5-cb18-4d35-9407-2fd2646d9d0b").build(),
Router.builder().state(State.ACTIVE).name("jclouds-test").tenantId("1234567890").id("31083ae2-420d-48b2-ac98-9f7a4fd8dbdc").build(),
Router.builder().state(State.ACTIVE).name("jclouds-test").tenantId("1234567890").id("49c6d6fa-ff2a-459d-b975-75a8d31c9a89").build(),
Router.builder().state(State.ACTIVE).name("wibble").tenantId("1234567890").id("5cb3d6f4-62cb-41c9-b964-ba7d9df79e4e").build(),
Router.builder().state(State.ACTIVE).name("jclouds-test").tenantId("1234567890").id("5d51d012-3491-4db7-b1b5-6f254015015d").build(),
Router.builder().state(State.ACTIVE).name("wibble").tenantId("1234567890").id("5f9cf7dc-22ca-4097-8e49-1cc8b23faf17").build(),
Router.builder().state(State.ACTIVE).name("jclouds-test").tenantId("1234567890").id("6319ecad-6bff-48b2-9b53-02ede8cb7588").build(),
Router.builder().state(State.ACTIVE).name("jclouds-test").tenantId("1234567890").id("6ba4c788-661f-49ab-9bf8-5f10cbbb2f57").build(),
Router.builder().state(State.ACTIVE).name("jclouds-test").tenantId("1234567890").id("74ed170b-5069-4353-ab38-9719766dc57e").build(),
Router.builder().state(State.ACTIVE).name("wibble").tenantId("1234567890").id("b71fcac1-e864-4031-8c5b-edbecd9ece36").build(),
Router.builder().state(State.ACTIVE).name("jclouds-test").tenantId("1234567890").id("c7681895-d84d-4650-9ca0-82c72036b855").build()
);
}
}

View File

@ -0,0 +1,192 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.neutron.v2_0.extensions;
import org.jclouds.openstack.neutron.v2_0.domain.ExternalGatewayInfo;
import org.jclouds.openstack.neutron.v2_0.domain.Network;
import org.jclouds.openstack.neutron.v2_0.domain.NetworkType;
import org.jclouds.openstack.neutron.v2_0.domain.Port;
import org.jclouds.openstack.neutron.v2_0.domain.ReferenceWithName;
import org.jclouds.openstack.neutron.v2_0.domain.Router;
import org.jclouds.openstack.neutron.v2_0.domain.RouterInterface;
import org.jclouds.openstack.neutron.v2_0.domain.Subnet;
import org.jclouds.openstack.neutron.v2_0.features.NetworkApi;
import org.jclouds.openstack.neutron.v2_0.features.PortApi;
import org.jclouds.openstack.neutron.v2_0.features.SubnetApi;
import org.jclouds.openstack.neutron.v2_0.internal.BaseNeutronApiLiveTest;
import org.jclouds.openstack.neutron.v2_0.options.CreateNetworkOptions;
import org.jclouds.openstack.neutron.v2_0.options.CreateRouterOptions;
import org.jclouds.openstack.neutron.v2_0.options.UpdateRouterOptions;
import org.testng.annotations.Test;
import java.util.Set;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
/**
* Tests parsing and Guice wiring of RouterApi
*
* @author Nick Livens
*/
@Test(groups = "live", testName = "RouterApiLiveTest")
public class RouterApiLiveTest extends BaseNeutronApiLiveTest {
public void testGetAndListRouters() {
for (String zone : api.getConfiguredZones()) {
Set<? extends ReferenceWithName> references = api.getRouterExtensionForZone(zone).get().list().concat().toSet();
Set<? extends Router> routers = api.getRouterExtensionForZone(zone).get().listInDetail().concat().toSet();
assertNotNull(references);
assertNotNull(routers);
assertEquals(references.size(), routers.size());
for (Router router : routers) {
assertNotNull(router.getName());
assertTrue(references.contains(ReferenceWithName.builder().id(router.getId()).tenantId(router.getTenantId()).name(router.getName()).build()));
Router retrievedRouter = api.getRouterExtensionForZone(zone).get().get(router.getId());
assertEquals(router, retrievedRouter);
}
}
}
public void testCreateUpdateAndDeleteRouter() {
for (String zone : api.getConfiguredZones()) {
RouterApi routerApi = api.getRouterExtensionForZone(zone).get();
NetworkApi networkApi = api.getNetworkApiForZone(zone);
SubnetApi subnetApi = api.getSubnetApiForZone(zone);
Network network = networkApi.create(CreateNetworkOptions.builder().name("jclouds-network-test").external(true).networkType(NetworkType.LOCAL).build());
assertNotNull(network);
Subnet subnet = subnetApi.create(network.getId(), 4, "192.168.0.0/16");
assertNotNull(subnet);
Router ref = routerApi.create(CreateRouterOptions.builder().name("jclouds-router-test")
.externalGatewayInfo(ExternalGatewayInfo.builder().networkId(network.getId()).build()).build());
assertNotNull(ref);
Router router = routerApi.get(ref.getId());
assertEquals(router.getId(), ref.getId());
assertEquals(router.getName(), "jclouds-router-test");
assertEquals(router.getExternalGatewayInfo().getNetworkId(), network.getId());
assertTrue(routerApi.update(router.getId(), UpdateRouterOptions.builder().name("jclouds-router-test-rename").build()));
router = routerApi.get(ref.getId());
assertEquals(router.getId(), ref.getId());
assertEquals(router.getName(), "jclouds-router-test-rename");
ReferenceWithName ref2 = routerApi.create(CreateRouterOptions.builder().name("jclouds-router-test2")
.externalGatewayInfo(ExternalGatewayInfo.builder().networkId(network.getId()).build()).build());
assertNotNull(ref2);
assertTrue(routerApi.delete(ref.getId()));
assertTrue(routerApi.delete(ref2.getId()));
assertTrue(subnetApi.delete(subnet.getId()));
assertTrue(networkApi.delete(network.getId()));
}
}
public void testCreateAndDeleteRouterInterfaceForSubnet() {
for (String zone : api.getConfiguredZones()) {
RouterApi routerApi = api.getRouterExtensionForZone(zone).get();
NetworkApi networkApi = api.getNetworkApiForZone(zone);
SubnetApi subnetApi = api.getSubnetApiForZone(zone);
Network network = networkApi.create(CreateNetworkOptions.builder().name("jclouds-network-test").external(true).networkType(NetworkType.LOCAL).build());
assertNotNull(network);
Subnet subnet = subnetApi.create(network.getId(), 4, "192.168.0.0/16");
assertNotNull(subnet);
Network network2 = networkApi.create(CreateNetworkOptions.builder().name("jclouds-network-test2").external(true).networkType(NetworkType.LOCAL).build());
assertNotNull(network2);
Subnet subnet2 = subnetApi.create(network2.getId(), 4, "192.169.0.0/16");
assertNotNull(subnet2);
Router router = routerApi.create(CreateRouterOptions.builder().name("jclouds-router-test").build());
assertNotNull(router);
RouterInterface routerInterface = routerApi.addInterfaceForSubnet(router.getId(), subnet.getId());
assertNotNull(routerInterface);
RouterInterface routerInterface2 = routerApi.addInterfaceForSubnet(router.getId(), subnet2.getId());
assertNotNull(routerInterface2);
assertTrue(routerApi.removeInterfaceForSubnet(router.getId(), subnet.getId()));
assertTrue(routerApi.removeInterfaceForSubnet(router.getId(), subnet2.getId()));
assertTrue(routerApi.delete(router.getId()));
assertTrue(subnetApi.delete(subnet.getId()));
assertTrue(networkApi.delete(network.getId()));
assertTrue(subnetApi.delete(subnet2.getId()));
assertTrue(networkApi.delete(network2.getId()));
}
}
public void testCreateAndDeleteRouterInterfaceForPort() {
for (String zone : api.getConfiguredZones()) {
RouterApi routerApi = api.getRouterExtensionForZone(zone).get();
NetworkApi networkApi = api.getNetworkApiForZone(zone);
SubnetApi subnetApi = api.getSubnetApiForZone(zone);
PortApi portApi = api.getPortApiForZone(zone);
Network network = networkApi.create(CreateNetworkOptions.builder().name("jclouds-network-test").external(true).networkType(NetworkType.LOCAL).build());
assertNotNull(network);
Subnet subnet = subnetApi.create(network.getId(), 4, "192.168.0.0/16");
assertNotNull(subnet);
Network network2 = networkApi.create(CreateNetworkOptions.builder().name("jclouds-network-test2").external(true).networkType(NetworkType.LOCAL).build());
assertNotNull(network2);
Subnet subnet2 = subnetApi.create(network2.getId(), 4, "192.169.0.0/16");
assertNotNull(subnet2);
Port port = portApi.create(network.getId());
assertNotNull(port);
Port port2 = portApi.create(network2.getId());
assertNotNull(port2);
Router router = routerApi.create(CreateRouterOptions.builder().name("jclouds-router-test").build());
assertNotNull(router);
RouterInterface routerInterface = routerApi.addInterfaceForPort(router.getId(), port.getId());
assertNotNull(routerInterface);
RouterInterface routerInterface2 = routerApi.addInterfaceForPort(router.getId(), port2.getId());
assertNotNull(routerInterface2);
assertTrue(routerApi.removeInterfaceForPort(router.getId(), port.getId()));
assertTrue(routerApi.removeInterfaceForPort(router.getId(), port2.getId()));
assertTrue(routerApi.delete(router.getId()));
assertTrue(subnetApi.delete(subnet.getId()));
assertTrue(networkApi.delete(network.getId()));
assertTrue(subnetApi.delete(subnet2.getId()));
assertTrue(networkApi.delete(network2.getId()));
}
}
}

View File

@ -16,7 +16,9 @@
*/
package org.jclouds.openstack.neutron.v2_0.features;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
import org.jclouds.openstack.neutron.v2_0.domain.BulkNetwork;
import org.jclouds.openstack.neutron.v2_0.domain.Network;
import org.jclouds.openstack.neutron.v2_0.domain.NetworkType;
@ -25,6 +27,8 @@ import org.jclouds.openstack.neutron.v2_0.internal.BaseNeutronApiLiveTest;
import org.jclouds.openstack.neutron.v2_0.options.CreateNetworkBulkOptions;
import org.jclouds.openstack.neutron.v2_0.options.CreateNetworkOptions;
import org.jclouds.openstack.neutron.v2_0.options.UpdateNetworkOptions;
import org.jclouds.openstack.neutron.v2_0.util.PredicateUtil;
import org.testng.annotations.Test;
import java.util.Set;
@ -37,6 +41,7 @@ import static org.testng.Assert.assertTrue;
*
* @author Nick Livens
*/
@Test(groups = "live", testName = "NetworkApiLiveTest")
public class NetworkApiLiveTest extends BaseNeutronApiLiveTest {
public void testGetAndListNetworks() {
@ -107,7 +112,8 @@ public class NetworkApiLiveTest extends BaseNeutronApiLiveTest {
assertEquals(nets.size(), 3);
for (Network net : nets) {
assertTrue(existingNets.contains(net));
Predicate<Network> idEqualsPredicate = PredicateUtil.createIdEqualsPredicate(net.getId());
assertEquals(1, Sets.filter(existingNets, idEqualsPredicate).size());
assertTrue(networkApi.delete(net.getId()));
}
}

View File

@ -16,31 +16,37 @@
*/
package org.jclouds.openstack.neutron.v2_0.features;
import com.google.common.collect.ImmutableSet;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import java.util.Set;
import org.jclouds.openstack.neutron.v2_0.domain.BulkPort;
import org.jclouds.openstack.neutron.v2_0.domain.IP;
import org.jclouds.openstack.neutron.v2_0.domain.NetworkType;
import org.jclouds.openstack.neutron.v2_0.domain.ReferenceWithName;
import org.jclouds.openstack.neutron.v2_0.domain.Port;
import org.jclouds.openstack.neutron.v2_0.domain.ReferenceWithName;
import org.jclouds.openstack.neutron.v2_0.internal.BaseNeutronApiLiveTest;
import org.jclouds.openstack.neutron.v2_0.options.CreateNetworkOptions;
import org.jclouds.openstack.neutron.v2_0.options.CreatePortBulkOptions;
import org.jclouds.openstack.neutron.v2_0.options.CreatePortOptions;
import org.jclouds.openstack.neutron.v2_0.options.CreateSubnetOptions;
import org.jclouds.openstack.neutron.v2_0.options.UpdatePortOptions;
import org.jclouds.openstack.neutron.v2_0.util.PredicateUtil;
import org.testng.annotations.Test;
import java.util.Set;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
/**
* Tests PortApi in combination with the Network & SubnetApi
*
* @author Nick Livens
*/
@Test(groups = "live", testName = "PortApiLiveTest")
public class PortApiLiveTest extends BaseNeutronApiLiveTest {
public void testGetAndListPorts() {
@ -134,7 +140,8 @@ public class PortApiLiveTest extends BaseNeutronApiLiveTest {
assertEquals(ports.size(), 4);
for (Port port : ports) {
assertTrue(existingPorts.contains(port));
Predicate<Port> idEqualsPredicate = PredicateUtil.createIdEqualsPredicate(port.getId());
assertEquals(1, Sets.filter(existingPorts, idEqualsPredicate).size());
assertTrue(portApi.delete(port.getId()));
}
assertTrue(subnetApi.delete(ipv4SubnetId));

View File

@ -16,8 +16,12 @@
*/
package org.jclouds.openstack.neutron.v2_0.features;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import java.util.Set;
import org.jclouds.openstack.neutron.v2_0.domain.AllocationPool;
import org.jclouds.openstack.neutron.v2_0.domain.BulkSubnet;
import org.jclouds.openstack.neutron.v2_0.domain.HostRoute;
@ -29,18 +33,20 @@ import org.jclouds.openstack.neutron.v2_0.options.CreateNetworkOptions;
import org.jclouds.openstack.neutron.v2_0.options.CreateSubnetBulkOptions;
import org.jclouds.openstack.neutron.v2_0.options.CreateSubnetOptions;
import org.jclouds.openstack.neutron.v2_0.options.UpdateSubnetOptions;
import org.jclouds.openstack.neutron.v2_0.util.PredicateUtil;
import org.testng.annotations.Test;
import java.util.Set;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
/**
* Tests subnet api in combination with the network api
*
* @author Nick Livens
*/
@Test(groups = "live", testName = "SubnetApiLiveTest")
public class SubnetApiLiveTest extends BaseNeutronApiLiveTest {
public void testGetAndListSubnets() {
@ -124,7 +130,8 @@ public class SubnetApiLiveTest extends BaseNeutronApiLiveTest {
assertEquals(subnets.size(), 3);
for (Subnet net : subnets) {
assertTrue(existingSubnets.contains(net));
Predicate<Subnet> idEqualsPredicate = PredicateUtil.createIdEqualsPredicate(net.getId());
assertEquals(1, Sets.filter(existingSubnets, idEqualsPredicate).size());
assertTrue(subnetApi.delete(net.getId()));
}
assertTrue(networkApi.delete(networkId));

View File

@ -0,0 +1,55 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.neutron.v2_0.parse;
import org.jclouds.json.BaseItemParserTest;
import org.jclouds.openstack.neutron.v2_0.domain.ExternalGatewayInfo;
import org.jclouds.openstack.neutron.v2_0.domain.Router;
import org.jclouds.openstack.neutron.v2_0.domain.State;
import org.jclouds.rest.annotations.SelectJson;
import org.testng.annotations.Test;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
/**
* @author Nick Livens
*/
@Test(groups = "unit", testName = "ParseRouterTest")
public class ParseRouterTest extends BaseItemParserTest<Router> {
@Override
public String resource() {
return "/router.json";
}
@Override
@SelectJson("router")
@Consumes(MediaType.APPLICATION_JSON)
public Router expected() {
return Router.builder()
.externalGatewayInfo(ExternalGatewayInfo.builder().networkId("624312ff-d14b-4ba3-9834-1c78d23d574d").build())
.state(State.ACTIVE)
.name("jclouds-wibble")
.tenantId("1234567890")
.id("16dba3bc-f3fa-4775-afdc-237e12c72f6a")
.build();
}
}

View File

@ -0,0 +1,43 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.neutron.v2_0.util;
import java.lang.reflect.Field;
/**
* @author Nick Livens
*/
public class ClassUtil {
public static Field findField(Class clazz, String fieldName) {
Field fieldToFind = null;
if (clazz.getSuperclass() != null)
fieldToFind = findField(clazz.getSuperclass(), fieldName);
if (fieldToFind != null)
return fieldToFind;
for (Field field : clazz.getDeclaredFields()) {
if (field.getName().equals(fieldName))
return field;
}
return null;
}
}

View File

@ -0,0 +1,51 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.neutron.v2_0.util;
import com.google.common.base.Predicate;
import org.jclouds.javax.annotation.Nullable;
import java.lang.reflect.Field;
/**
* @author Nick Livens
*/
public class PredicateUtil {
public static <T> Predicate<T> createIdEqualsPredicate(final String id) {
return new Predicate<T>() {
@Override
public boolean apply(@Nullable T input) {
if (input == null) return false;
try {
Class clazz = input.getClass();
Field field = ClassUtil.findField(clazz, "id");
field.setAccessible(true);
String value = (String) field.get(input);
field.setAccessible(false);
return value != null && value.equals(id);
} catch (IllegalAccessException iae) {
return false;
}
}
};
}
}

View File

@ -0,0 +1,74 @@
{"routers":[
{
"status":"ACTIVE",
"name":"jclouds-test",
"tenant_id":"1234567890",
"id":"16dba3bc-f3fa-4775-afdc-237e12c72f6a"
},
{
"status":"ACTIVE",
"name":"wibble",
"tenant_id":"1234567890",
"id":"1a104cf5-cb18-4d35-9407-2fd2646d9d0b"
},
{
"status":"ACTIVE",
"name":"jclouds-test",
"tenant_id":"1234567890",
"id":"31083ae2-420d-48b2-ac98-9f7a4fd8dbdc"
},
{
"status":"ACTIVE",
"name":"jclouds-test",
"tenant_id":"1234567890",
"id":"49c6d6fa-ff2a-459d-b975-75a8d31c9a89"
},
{
"status":"ACTIVE",
"name":"wibble",
"tenant_id":"1234567890",
"id":"5cb3d6f4-62cb-41c9-b964-ba7d9df79e4e"
},
{
"status":"ACTIVE",
"name":"jclouds-test",
"tenant_id":"1234567890",
"id":"5d51d012-3491-4db7-b1b5-6f254015015d"
},
{
"status":"ACTIVE",
"name":"wibble",
"tenant_id":"1234567890",
"id":"5f9cf7dc-22ca-4097-8e49-1cc8b23faf17"
},
{
"status":"ACTIVE",
"name":"jclouds-test",
"tenant_id":"1234567890",
"id":"6319ecad-6bff-48b2-9b53-02ede8cb7588"
},
{
"status":"ACTIVE",
"name":"jclouds-test",
"tenant_id":"1234567890",
"id":"6ba4c788-661f-49ab-9bf8-5f10cbbb2f57"
},
{
"status":"ACTIVE",
"name":"jclouds-test",
"tenant_id":"1234567890",
"id":"74ed170b-5069-4353-ab38-9719766dc57e"
},
{
"status":"ACTIVE",
"name":"wibble",
"tenant_id":"1234567890",
"id":"b71fcac1-e864-4031-8c5b-edbecd9ece36"
},
{
"status":"ACTIVE",
"name":"jclouds-test",
"tenant_id":"1234567890",
"id":"c7681895-d84d-4650-9ca0-82c72036b855"
}
]}

View File

@ -0,0 +1,7 @@
{"router":{
"status":"ACTIVE",
"external_gateway_info":{"network_id":"624312ff-d14b-4ba3-9834-1c78d23d574d"},
"name":"jclouds-wibble",
"tenant_id":"1234567890",
"id":"16dba3bc-f3fa-4775-afdc-237e12c72f6a"
}}