JCLOUDS-1255 Dimension Data Network API implementation.
Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/2495dd9a Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/2495dd9a Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/2495dd9a Branch: refs/heads/master Commit: 2495dd9a6453450c7341b66043b8ed82bc377600 Parents: 4febcfa Author: Trevor Flanagan <[email protected]> Authored: Wed Jun 28 13:44:47 2017 +0100 Committer: Ignasi Barrera <[email protected]> Committed: Thu Jul 6 16:14:10 2017 +0200 ---------------------------------------------------------------------- .../DimensionDataCloudControlApi.java | 4 + .../cloudcontrol/domain/NetworkDomain.java | 6 +- .../cloudcontrol/domain/Server.java | 24 - .../cloudcontrol/domain/State.java | 43 ++ .../dimensiondata/cloudcontrol/domain/Vlan.java | 6 +- .../cloudcontrol/features/NetworkApi.java | 487 +++++++++++++++++++ .../predicates/NetworkDomainStatus.java | 50 ++ .../cloudcontrol/predicates/VlanStatus.java | 52 ++ .../DimensionDataCloudControlResponseUtils.java | 52 ++ .../cloudcontrol/utils/ParseResponse.java | 86 ++++ .../features/NetworkApiLiveTest.java | 126 +++++ .../features/NetworkApiMockTest.java | 392 +++++++++++++++ .../BaseDimensionDataCloudControlMockTest.java | 9 + .../parse/FirewallRulesParseTest.java | 52 ++ .../cloudcontrol/parse/NatRulesParseTest.java | 49 ++ .../parse/NetworkDomainsParseTest.java | 49 ++ .../parse/PublicIpBlocksParseTest.java | 46 ++ .../cloudcontrol/parse/VlansParseTest.java | 52 ++ .../cloudcontrol/utils/ResponseParseTest.java | 56 +++ .../src/test/resources/firewallRules-page1.json | 283 +++++++++++ .../src/test/resources/firewallRules-page2.json | 108 ++++ .../src/test/resources/firewallRules.json | 33 ++ dimensiondata/src/test/resources/natRule.json | 9 + .../src/test/resources/natRules-page1.json | 98 ++++ .../src/test/resources/natRules-page2.json | 98 ++++ dimensiondata/src/test/resources/natRules.json | 26 + .../src/test/resources/networkDomain.json | 10 + .../test/resources/networkDomains-page1.json | 108 ++++ .../test/resources/networkDomains-page2.json | 108 ++++ .../src/test/resources/networkDomains.json | 18 + dimensiondata/src/test/resources/portList.json | 16 + dimensiondata/src/test/resources/portLists.json | 32 ++ .../src/test/resources/publicIpBlock.json | 9 + .../test/resources/publicIpBlocks-page1.json | 98 ++++ .../test/resources/publicIpBlocks-page2.json | 98 ++++ .../src/test/resources/publicIpBlocks.json | 17 + dimensiondata/src/test/resources/response.json | 30 ++ dimensiondata/src/test/resources/vlan.json | 22 + .../src/test/resources/vlans-page1.json | 228 +++++++++ .../src/test/resources/vlans-page2.json | 228 +++++++++ dimensiondata/src/test/resources/vlans.json | 30 ++ 41 files changed, 3318 insertions(+), 30 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2495dd9a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApi.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApi.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApi.java index 7e21571..5967453 100644 --- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApi.java +++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApi.java @@ -18,6 +18,7 @@ package org.jclouds.dimensiondata.cloudcontrol; import org.jclouds.dimensiondata.cloudcontrol.features.AccountApi; import org.jclouds.dimensiondata.cloudcontrol.features.InfrastructureApi; +import org.jclouds.dimensiondata.cloudcontrol.features.NetworkApi; import org.jclouds.dimensiondata.cloudcontrol.features.ServerImageApi; import org.jclouds.rest.annotations.Delegate; @@ -33,4 +34,7 @@ public interface DimensionDataCloudControlApi extends Closeable { @Delegate ServerImageApi getServerImageApi(); + + @Delegate + NetworkApi getNetworkApi(); } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2495dd9a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/NetworkDomain.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/NetworkDomain.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/NetworkDomain.java index eb6c291..acdaf75 100644 --- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/NetworkDomain.java +++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/NetworkDomain.java @@ -47,7 +47,7 @@ public abstract class NetworkDomain { public abstract String description(); @Nullable - public abstract String state(); + public abstract State state(); @Nullable public abstract Type type(); @@ -59,7 +59,7 @@ public abstract class NetworkDomain { public abstract Date createTime(); @SerializedNames({ "id", "datacenterId", "name", "description", "state", "type", "snatIpv4Address", "createTime" }) - public static NetworkDomain create(String id, String datacenterId, String name, String description, String state, + public static NetworkDomain create(String id, String datacenterId, String name, String description, State state, Type type, String snatIpv4Address, Date createTime) { return builder().id(id).datacenterId(datacenterId).name(name).description(description).state(state).type(type) .snatIpv4Address(snatIpv4Address).createTime(createTime).build(); @@ -77,7 +77,7 @@ public abstract class NetworkDomain { public abstract Builder description(String description); - public abstract Builder state(String state); + public abstract Builder state(State state); public abstract Builder type(Type type); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2495dd9a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/Server.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/Server.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/Server.java index 9be5f33..79de501 100644 --- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/Server.java +++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/Server.java @@ -17,7 +17,6 @@ package org.jclouds.dimensiondata.cloudcontrol.domain; import com.google.auto.value.AutoValue; -import com.google.common.base.CaseFormat; import com.google.common.collect.ImmutableList; import org.jclouds.javax.annotation.Nullable; import org.jclouds.json.SerializedNames; @@ -25,32 +24,9 @@ import org.jclouds.json.SerializedNames; import java.util.Date; import java.util.List; -import static com.google.common.base.Preconditions.checkNotNull; - @AutoValue public abstract class Server { - public enum State { - NORMAL, FAILED_ADD, FAILED_CHANGE, FAILED_DELETE, PENDING_DELETE, DELETED, UNRECOGNIZED; - - @Override - public String toString() { - return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name()); - } - - public static State fromValue(String state) { - try { - return valueOf(CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(state, "state"))); - } catch (IllegalArgumentException e) { - return UNRECOGNIZED; - } - } - - public boolean isFailed() { - return this == FAILED_ADD || this == FAILED_CHANGE || this == FAILED_DELETE; - } - } - Server() { } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2495dd9a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/State.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/State.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/State.java new file mode 100644 index 0000000..e832264 --- /dev/null +++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/State.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.dimensiondata.cloudcontrol.domain; + +import com.google.common.base.CaseFormat; + +import static com.google.common.base.Preconditions.checkNotNull; + +public enum State { + + NORMAL, FAILED_ADD, FAILED_CHANGE, FAILED_DELETE, PENDING_DELETE, DELETED, UNRECOGNIZED; + + @Override + public String toString() { + return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name()); + } + + public static State fromValue(String state) { + try { + return valueOf(CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(state, "state"))); + } catch (IllegalArgumentException e) { + return UNRECOGNIZED; + } + } + + public boolean isFailed() { + return this == FAILED_ADD || this == FAILED_CHANGE || this == FAILED_DELETE; + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2495dd9a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/Vlan.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/Vlan.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/Vlan.java index 7a62543..4e40beb 100644 --- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/Vlan.java +++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/Vlan.java @@ -39,7 +39,7 @@ public abstract class Vlan { public abstract String datacenterId(); - public abstract String state(); + public abstract State state(); public abstract Date createTime(); @@ -55,7 +55,7 @@ public abstract class Vlan { @SerializedNames({ "id", "name", "description", "datacenterId", "state", "createTime", "ipv4GatewayAddress", "ipv6GatewayAddress", "networkDomain", "privateIpv4Range", "ipv6Range" }) - public static Vlan create(String id, String name, String description, String datacenterId, String state, + public static Vlan create(String id, String name, String description, String datacenterId, State state, Date createTime, String ipv4GatewayAddress, String ipv6GatewayAddress, NetworkDomain networkDomain, IpRange privateIpv4Range, IpRange ipv6Range) { return builder().id(id).name(name).description(description).datacenterId(datacenterId).state(state) @@ -75,7 +75,7 @@ public abstract class Vlan { public abstract Builder datacenterId(String datacenterId); - public abstract Builder state(String state); + public abstract Builder state(State state); public abstract Builder createTime(Date createTime); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2495dd9a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApi.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApi.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApi.java new file mode 100644 index 0000000..129fa99 --- /dev/null +++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApi.java @@ -0,0 +1,487 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.dimensiondata.cloudcontrol.features; + +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.inject.TypeLiteral; +import org.jclouds.Fallbacks; +import org.jclouds.Fallbacks.NullOnNotFoundOr404; +import org.jclouds.collect.IterableWithMarker; +import org.jclouds.collect.PagedIterable; +import org.jclouds.collect.internal.Arg0ToPagedIterable; +import org.jclouds.dimensiondata.cloudcontrol.DimensionDataCloudControlApi; +import org.jclouds.dimensiondata.cloudcontrol.domain.FirewallRule; +import org.jclouds.dimensiondata.cloudcontrol.domain.FirewallRuleTarget; +import org.jclouds.dimensiondata.cloudcontrol.domain.FirewallRuleTarget.Port; +import org.jclouds.dimensiondata.cloudcontrol.domain.FirewallRules; +import org.jclouds.dimensiondata.cloudcontrol.domain.NatRule; +import org.jclouds.dimensiondata.cloudcontrol.domain.NatRules; +import org.jclouds.dimensiondata.cloudcontrol.domain.NetworkDomain; +import org.jclouds.dimensiondata.cloudcontrol.domain.NetworkDomains; +import org.jclouds.dimensiondata.cloudcontrol.domain.PaginatedCollection; +import org.jclouds.dimensiondata.cloudcontrol.domain.Placement; +import org.jclouds.dimensiondata.cloudcontrol.domain.PublicIpBlock; +import org.jclouds.dimensiondata.cloudcontrol.domain.PublicIpBlocks; +import org.jclouds.dimensiondata.cloudcontrol.domain.Response; +import org.jclouds.dimensiondata.cloudcontrol.domain.Vlan; +import org.jclouds.dimensiondata.cloudcontrol.domain.Vlans; +import org.jclouds.dimensiondata.cloudcontrol.filters.OrganisationIdFilter; +import org.jclouds.dimensiondata.cloudcontrol.options.PaginationOptions; +import org.jclouds.dimensiondata.cloudcontrol.utils.ParseResponse; +import org.jclouds.http.filters.BasicAuthentication; +import org.jclouds.http.functions.ParseJson; +import org.jclouds.json.Json; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.MapBinder; +import org.jclouds.rest.annotations.PayloadParam; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.Transform; +import org.jclouds.rest.binders.BindToJsonPayload; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +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.MediaType; +import java.util.List; + +@RequestFilters({ BasicAuthentication.class, OrganisationIdFilter.class }) +@Consumes(MediaType.APPLICATION_JSON) +@Path("/{jclouds.api-version}/network") +public interface NetworkApi { + + @Named("network:deployNetworkDomain") + @POST + @Path("/deployNetworkDomain") + @Produces(MediaType.APPLICATION_JSON) + @MapBinder(BindToJsonPayload.class) + @ResponseParser(ParseNetworkDomainId.class) + String deployNetworkDomain(@PayloadParam("datacenterId") String datacenterId, @PayloadParam("name") String name, + @PayloadParam("description") String description, @PayloadParam("type") String type); + + @Named("networkDomain:get") + @GET + @Path("/networkDomain/{id}") + @Fallback(NullOnNotFoundOr404.class) + NetworkDomain getNetworkDomain(@PathParam("id") String networkDomainId); + + @Named("networkDomain:listWithDatacenterIdAndName") + @GET + @Path("/networkDomain") + @Transform(ParseNetworkDomains.ToPagedIterable.class) + @ResponseParser(ParseNetworkDomains.class) + @Fallback(Fallbacks.EmptyPagedIterableOnNotFoundOr404.class) + PagedIterable<NetworkDomain> listNetworkDomainsWithDatacenterIdAndName( + @QueryParam("datacenterId") String datacenterId, @QueryParam("name") String name); + + @Named("networkDomain:list") + @GET + @Path("/networkDomain") + @ResponseParser(ParseNetworkDomains.class) + @Fallback(Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404.class) + PaginatedCollection<NetworkDomain> listNetworkDomains(PaginationOptions options); + + @Named("networkDomain:list") + @GET + @Path("/networkDomain") + @Transform(ParseNetworkDomains.ToPagedIterable.class) + @ResponseParser(ParseNetworkDomains.class) + @Fallback(Fallbacks.EmptyPagedIterableOnNotFoundOr404.class) + PagedIterable<NetworkDomain> listNetworkDomains(); + + @Named("networkDomain:delete") + @POST + @Path("/deleteNetworkDomain") + @Produces(MediaType.APPLICATION_JSON) + @MapBinder(BindToJsonPayload.class) + @Fallback(Fallbacks.VoidOnNotFoundOr404.class) + void deleteNetworkDomain(@PayloadParam("id") String networkDomainId); + + @Named("vlan:deploy") + @POST + @Path("/deployVlan") + @Produces(MediaType.APPLICATION_JSON) + @MapBinder(BindToJsonPayload.class) + @ResponseParser(ParseVlanId.class) + String deployVlan(@PayloadParam("networkDomainId") String networkDomainId, @PayloadParam("name") String name, + @PayloadParam("description") String description, + @PayloadParam("privateIpv4BaseAddress") String privateIpv4BaseAddress, + @PayloadParam("privateIpv4PrefixSize") Integer privateIpv4PrefixSize); + + @Named("vlan:get") + @GET + @Path("/vlan/{id}") + @Fallback(NullOnNotFoundOr404.class) + Vlan getVlan(@PathParam("id") String vlanId); + + @Named("vlan:list") + @GET + @Path("/vlan") + @ResponseParser(ParseVlans.class) + @Fallback(Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404.class) + PaginatedCollection<Vlan> listVlans(@QueryParam("networkDomainId") String networkDomainId, + PaginationOptions options); + + @Named("vlan:list") + @GET + @Path("/vlan") + @Transform(ParseVlans.ToPagedIterable.class) + @ResponseParser(ParseVlans.class) + @Fallback(Fallbacks.EmptyPagedIterableOnNotFoundOr404.class) + PagedIterable<Vlan> listVlans(@QueryParam("networkDomainId") String networkDomainId); + + @Named("vlan:delete") + @POST + @Path("/deleteVlan") + @Produces(MediaType.APPLICATION_JSON) + @MapBinder(BindToJsonPayload.class) + @Fallback(Fallbacks.VoidOnNotFoundOr404.class) + void deleteVlan(@PayloadParam("id") String vlanId); + + @Named("networkDomain:addPublicIpBlock") + @POST + @Path("/addPublicIpBlock") + @Produces(MediaType.APPLICATION_JSON) + @MapBinder(BindToJsonPayload.class) + Response addPublicIpBlock(@PayloadParam("networkDomainId") String networkDomainId); + + @Named("networkDomain:listPublicIPv4AddressBlocks") + @GET + @Path("/publicIpBlock") + @ResponseParser(ParsePublicIpBlocks.class) + @Fallback(Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404.class) + PaginatedCollection<PublicIpBlock> listPublicIPv4AddressBlocks(@QueryParam("networkDomainId") String networkDomainId, + PaginationOptions options); + + @Named("networkDomain:listPublicIPv4AddressBlock") + @GET + @Path("/publicIpBlock") + @Transform(ParsePublicIpBlocks.ToPagedIterable.class) + @ResponseParser(ParsePublicIpBlocks.class) + @Fallback(Fallbacks.EmptyPagedIterableOnNotFoundOr404.class) + PagedIterable<PublicIpBlock> listPublicIPv4AddressBlocks(@QueryParam("networkDomainId") String networkDomainId); + + @Named("networkDomain:removePublicIpBlock") + @POST + @Path("/removePublicIpBlock") + @Produces(MediaType.APPLICATION_JSON) + @MapBinder(BindToJsonPayload.class) + @Fallback(Fallbacks.VoidOnNotFoundOr404.class) + void removePublicIpBlock(@PayloadParam("id") String publicIpBlockId); + + @Named("networkDomain:getPublicIPv4AddressBlock") + @GET + @Path("/publicIpBlock/{id}") + @Fallback(NullOnNotFoundOr404.class) + PublicIpBlock getPublicIPv4AddressBlock(@PathParam("id") String publicIPv4AddressBlockId); + + @Named("network:createNatRule") + @POST + @Path("/createNatRule") + @Produces(MediaType.APPLICATION_JSON) + @MapBinder(BindToJsonPayload.class) + @Fallback(Fallbacks.VoidOnNotFoundOr404.class) + Response createNatRule(@PayloadParam("networkDomainId") String networkDomainId, + @PayloadParam("internalIp") String internalIp, @PayloadParam("externalIp") String externalIp); + + @Named("networkDomain:listNatRules") + @GET + @Path("/natRule") + @ResponseParser(ParseNatRules.class) + @Fallback(Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404.class) + PaginatedCollection<NatRule> listNatRules(@QueryParam("networkDomainId") String networkDomainId, + PaginationOptions options); + + @Named("networkDomain:listNatRules") + @GET + @Path("/natRule") + @Transform(ParseNatRules.ToPagedIterable.class) + @ResponseParser(ParseNatRules.class) + @Fallback(Fallbacks.EmptyPagedIterableOnNotFoundOr404.class) + PagedIterable<NatRule> listNatRules(@QueryParam("networkDomainId") String networkDomainId); + + @Named("network:getNatRule") + @GET + @Path("/natRule/{id}") + @Fallback(NullOnNotFoundOr404.class) + NatRule getNatRule(@PathParam("id") String natRuleId); + + @Named("network:deleteNatRule") + @POST + @Path("/deleteNatRule") + @Produces(MediaType.APPLICATION_JSON) + @MapBinder(BindToJsonPayload.class) + @Fallback(Fallbacks.VoidOnNotFoundOr404.class) + void deleteNatRule(@PayloadParam("id") String natRuleId); + + @Named("networkDomain:createFirewallRule") + @POST + @Path("/createFirewallRule") + @Produces(MediaType.APPLICATION_JSON) + @MapBinder(BindToJsonPayload.class) + @ResponseParser(FirewallRuleId.class) + String createFirewallRule(@PayloadParam("networkDomainId") String networkDomainId, @PayloadParam("name") String name, + @PayloadParam("action") String action, @PayloadParam("ipVersion") String ipVersion, + @PayloadParam("protocol") String protocol, @PayloadParam("source") FirewallRuleTarget source, + @PayloadParam("destination") FirewallRuleTarget destination, @PayloadParam("enabled") Boolean enabled, + @PayloadParam("placement") Placement placement); + + @Named("networkDomain:listFirewallRules") + @GET + @Path("/firewallRule") + @ResponseParser(ParseFirewallRules.class) + @Fallback(Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404.class) + PaginatedCollection<FirewallRule> listFirewallRules(@QueryParam("networkDomainId") String networkDomainId, + PaginationOptions options); + + @Named("networkDomain:listFirewallRules") + @GET + @Path("/firewallRule") + @Transform(ParseFirewallRules.ToPagedIterable.class) + @ResponseParser(ParseFirewallRules.class) + @Fallback(Fallbacks.EmptyPagedIterableOnNotFoundOr404.class) + PagedIterable<FirewallRule> listFirewallRules(@QueryParam("networkDomainId") String networkDomainId); + + @Named("networkDomain:deleteFirewallRule") + @POST + @Path("/deleteFirewallRule") + @Produces(MediaType.APPLICATION_JSON) + @MapBinder(BindToJsonPayload.class) + @Fallback(Fallbacks.VoidOnNotFoundOr404.class) + void deleteFirewallRule(@PayloadParam("id") String firewallRuleId); + + @Named("networkDomain:createPortList") + @POST + @Path("/createPortList") + @Produces(MediaType.APPLICATION_JSON) + @MapBinder(BindToJsonPayload.class) + @ResponseParser(PortListId.class) + String createPortList(@PayloadParam("networkDomainId") String networkDomainId, @PayloadParam("name") String name, + @PayloadParam("description") String description, @PayloadParam("port") List<Port> port, + @PayloadParam("childPortListId") List<String> childPortListId); + + @Named("networkDomain:getPortList") + @GET + @Path("/portList/{id}") + @Fallback(NullOnNotFoundOr404.class) + FirewallRuleTarget.PortList getPortList(@PathParam("id") String portListId); + + @Named("networkDomain:deletePortList") + @POST + @Path("/deletePortList") + @Produces(MediaType.APPLICATION_JSON) + @MapBinder(BindToJsonPayload.class) + @Fallback(Fallbacks.VoidOnNotFoundOr404.class) + void deletePortList(@PayloadParam("id") String portListId); + + @Singleton + final class ParseFirewallRules extends ParseJson<FirewallRules> { + + @Inject + ParseFirewallRules(Json json) { + super(json, TypeLiteral.get(FirewallRules.class)); + } + + private static class ToPagedIterable + extends Arg0ToPagedIterable<FirewallRule, ParseFirewallRules.ToPagedIterable> { + + private DimensionDataCloudControlApi api; + + @Inject + ToPagedIterable(DimensionDataCloudControlApi api) { + this.api = api; + } + + @Override + protected Function<Object, IterableWithMarker<FirewallRule>> markerToNextForArg0(Optional<Object> optional) { + return new Function<Object, IterableWithMarker<FirewallRule>>() { + @Override + public IterableWithMarker<FirewallRule> apply(Object input) { + PaginationOptions paginationOptions = PaginationOptions.class.cast(input); + return api.getNetworkApi().listFirewallRules(getArgs(request).get(0).toString(), paginationOptions); + } + }; + } + } + } + + @Singleton + final class ParseNatRules extends ParseJson<NatRules> { + + @Inject + ParseNatRules(Json json) { + super(json, TypeLiteral.get(NatRules.class)); + } + + private static class ToPagedIterable extends Arg0ToPagedIterable<NatRule, ToPagedIterable> { + + private DimensionDataCloudControlApi api; + + @Inject + ToPagedIterable(DimensionDataCloudControlApi api) { + this.api = api; + } + + @Override + protected Function<Object, IterableWithMarker<NatRule>> markerToNextForArg0(Optional<Object> optional) { + return new Function<Object, IterableWithMarker<NatRule>>() { + @Override + public IterableWithMarker<NatRule> apply(Object input) { + PaginationOptions paginationOptions = PaginationOptions.class.cast(input); + return api.getNetworkApi().listNatRules(getArgs(request).get(0).toString(), paginationOptions); + } + }; + } + } + } + + @Singleton + final class ParseNetworkDomains extends ParseJson<NetworkDomains> { + + @Inject + ParseNetworkDomains(Json json) { + super(json, TypeLiteral.get(NetworkDomains.class)); + } + + private static class ToPagedIterable extends Arg0ToPagedIterable<NetworkDomain, ToPagedIterable> { + + private DimensionDataCloudControlApi api; + + @Inject + ToPagedIterable(DimensionDataCloudControlApi api) { + this.api = api; + } + + @Override + protected Function<Object, IterableWithMarker<NetworkDomain>> markerToNextForArg0(Optional<Object> optional) { + return new Function<Object, IterableWithMarker<NetworkDomain>>() { + @Override + public IterableWithMarker<NetworkDomain> apply(Object input) { + PaginationOptions paginationOptions = PaginationOptions.class.cast(input); + return api.getNetworkApi().listNetworkDomains(paginationOptions); + } + }; + } + } + } + + @Singleton + final class ParsePublicIpBlocks extends ParseJson<PublicIpBlocks> { + + @Inject + ParsePublicIpBlocks(Json json) { + super(json, TypeLiteral.get(PublicIpBlocks.class)); + } + + private static class ToPagedIterable extends Arg0ToPagedIterable<PublicIpBlock, ToPagedIterable> { + + private DimensionDataCloudControlApi api; + + @Inject + ToPagedIterable(DimensionDataCloudControlApi api) { + this.api = api; + } + + @Override + protected Function<Object, IterableWithMarker<PublicIpBlock>> markerToNextForArg0(Optional<Object> optional) { + return new Function<Object, IterableWithMarker<PublicIpBlock>>() { + @Override + public IterableWithMarker<PublicIpBlock> apply(Object input) { + PaginationOptions paginationOptions = PaginationOptions.class.cast(input); + return api.getNetworkApi() + .listPublicIPv4AddressBlocks(getArgs(request).get(0).toString(), paginationOptions); + } + }; + } + } + } + + @Singleton + final class ParseVlans extends ParseJson<Vlans> { + + @Inject + ParseVlans(Json json) { + super(json, TypeLiteral.get(Vlans.class)); + } + + static class ToPagedIterable extends Arg0ToPagedIterable<Vlan, ToPagedIterable> { + + private DimensionDataCloudControlApi api; + + @Inject + ToPagedIterable(DimensionDataCloudControlApi api) { + this.api = api; + } + + @Override + protected Function<Object, IterableWithMarker<Vlan>> markerToNextForArg0(Optional<Object> optional) { + return new Function<Object, IterableWithMarker<Vlan>>() { + @Override + public IterableWithMarker<Vlan> apply(Object input) { + PaginationOptions paginationOptions = PaginationOptions.class.cast(input); + return api.getNetworkApi().listVlans(getArgs(request).get(0).toString(), paginationOptions); + } + }; + } + } + } + + @Singleton + final class ParseNetworkDomainId extends ParseResponse { + + @Inject + ParseNetworkDomainId(Json json) { + super(json, "networkDomainId"); + } + } + + @Singleton + final class ParseVlanId extends ParseResponse { + + @Inject + ParseVlanId(Json json) { + super(json, "vlanId"); + } + } + + @Singleton + final class PortListId extends ParseResponse { + + @Inject + PortListId(Json json) { + super(json, "portListId"); + } + } + + @Singleton + final class FirewallRuleId extends ParseResponse { + + @Inject + FirewallRuleId(Json json) { + super(json, "firewallRuleId"); + } + } +} + http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2495dd9a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/predicates/NetworkDomainStatus.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/predicates/NetworkDomainStatus.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/predicates/NetworkDomainStatus.java new file mode 100644 index 0000000..94882d1 --- /dev/null +++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/predicates/NetworkDomainStatus.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.dimensiondata.cloudcontrol.predicates; + +import com.google.common.base.Predicate; +import org.jclouds.dimensiondata.cloudcontrol.domain.NetworkDomain; +import org.jclouds.dimensiondata.cloudcontrol.domain.State; +import org.jclouds.dimensiondata.cloudcontrol.features.NetworkApi; +import org.jclouds.logging.Logger; + +import javax.annotation.Resource; + +import static com.google.common.base.Preconditions.checkNotNull; + +public class NetworkDomainStatus implements Predicate<String> { + + @Resource + protected Logger logger = Logger.NULL; + + private final State state; + private final NetworkApi networkApi; + + public NetworkDomainStatus(NetworkApi networkApi, State state) { + this.networkApi = networkApi; + this.state = state; + } + + @Override + public boolean apply(String networkDomainId) { + checkNotNull(networkDomainId, "networkDomainId"); + logger.trace("looking for state on network domain %s", networkDomainId); + final NetworkDomain networkDomain = networkApi.getNetworkDomain(networkDomainId); + final boolean isDeleted = networkDomain == null && state == State.DELETED; + return isDeleted || (networkDomain != null && networkDomain.state() == state); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2495dd9a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/predicates/VlanStatus.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/predicates/VlanStatus.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/predicates/VlanStatus.java new file mode 100644 index 0000000..79aa75a --- /dev/null +++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/predicates/VlanStatus.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.dimensiondata.cloudcontrol.predicates; + +import com.google.common.base.Predicate; +import org.jclouds.dimensiondata.cloudcontrol.domain.State; +import org.jclouds.dimensiondata.cloudcontrol.domain.Vlan; +import org.jclouds.dimensiondata.cloudcontrol.features.NetworkApi; +import org.jclouds.logging.Logger; + +import javax.annotation.Resource; + +import static com.google.common.base.Preconditions.checkNotNull; + +public class VlanStatus implements Predicate<String> { + + @Resource + protected Logger logger = Logger.NULL; + + private final State state; + private final NetworkApi networkApi; + + public VlanStatus(NetworkApi networkApi, State state) { + this.networkApi = networkApi; + this.state = state; + } + + @Override + public boolean apply(String vlanId) { + checkNotNull(vlanId, "vlanId"); + logger.trace("looking for state on vlan %s", vlanId); + final Vlan vlan = networkApi.getVlan(vlanId); + final boolean isDeleted = (vlan == null) && (state == State.DELETED); + return isDeleted || ((vlan != null) && vlan.state() == state); + + } +} + http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2495dd9a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/utils/DimensionDataCloudControlResponseUtils.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/utils/DimensionDataCloudControlResponseUtils.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/utils/DimensionDataCloudControlResponseUtils.java new file mode 100644 index 0000000..2c80d7c --- /dev/null +++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/utils/DimensionDataCloudControlResponseUtils.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.dimensiondata.cloudcontrol.utils; + +import org.jclouds.dimensiondata.cloudcontrol.domain.State; +import org.jclouds.dimensiondata.cloudcontrol.features.NetworkApi; +import org.jclouds.dimensiondata.cloudcontrol.predicates.NetworkDomainStatus; +import org.jclouds.dimensiondata.cloudcontrol.predicates.VlanStatus; + +import static org.jclouds.util.Predicates2.retry; + +public class DimensionDataCloudControlResponseUtils { + + private static String convertServerId(String serverId) { + return serverId.replaceAll("-", "_"); + } + + public static String generateFirewallRuleName(String serverId) { + return String.format("fw.%s", convertServerId(serverId)); + } + + public static void waitForNetworkDomainStatus(NetworkApi api, String networkDomainId, State state, + long timeoutMillis, String message) { + boolean isNetworkDomainInState = retry(new NetworkDomainStatus(api, state), timeoutMillis).apply(networkDomainId); + if (!isNetworkDomainInState) { + throw new IllegalStateException(message); + } + } + + public static void waitForVlanStatus(NetworkApi api, String vlanId, State state, long timeoutMillis, + String message) { + boolean isVlanInstate = retry(new VlanStatus(api, state), timeoutMillis).apply(vlanId); + if (!isVlanInstate) { + throw new IllegalStateException(message); + } + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2495dd9a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/utils/ParseResponse.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/utils/ParseResponse.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/utils/ParseResponse.java new file mode 100644 index 0000000..6f8b5de --- /dev/null +++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/utils/ParseResponse.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.dimensiondata.cloudcontrol.utils; + +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.collect.FluentIterable; +import com.google.inject.TypeLiteral; +import org.jclouds.dimensiondata.cloudcontrol.domain.Property; +import org.jclouds.dimensiondata.cloudcontrol.domain.Response; +import org.jclouds.http.HttpResponse; +import org.jclouds.http.HttpResponseException; +import org.jclouds.json.Json; +import org.jclouds.logging.Logger; + +import javax.annotation.Resource; +import java.io.InputStream; + +import static org.jclouds.http.HttpUtils.releasePayload; + +public class ParseResponse implements Function<HttpResponse, String> { + + @Resource + protected Logger logger = Logger.NULL; + protected final Json json; + protected final String propertyName; + + protected ParseResponse(Json json, String propertyName) { + this.json = json; + this.propertyName = propertyName; + } + + public String apply(HttpResponse from) { + try { + InputStream gson = from.getPayload().openStream(); + + final Response response = json.fromJson(gson, TypeLiteral.get(Response.class).getType()); + return tryFindInfoPropertyValue(response); + } catch (Exception e) { + StringBuilder message = new StringBuilder(); + message.append("Error parsing input: "); + message.append(e.getMessage()); + logger.error(e, message.toString()); + throw new HttpResponseException(message.toString() + "\n" + from, null, from, e); + } finally { + releasePayload(from); + } + } + + String tryFindInfoPropertyValue(Response response) { + if (!response.info().isEmpty()) { + Optional<String> optionalPropertyName = FluentIterable.from(response.info()) + .firstMatch(new Predicate<Property>() { + @Override + public boolean apply(Property input) { + return input.name().equals(propertyName); + } + }).transform(new Function<Property, String>() { + @Override + public String apply(Property input) { + return input.value(); + } + }); + if (!optionalPropertyName.isPresent()) { + throw new IllegalStateException("Could not find expected property name: " + propertyName); + } + return optionalPropertyName.get(); + } + return ""; + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2495dd9a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiLiveTest.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiLiveTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiLiveTest.java new file mode 100644 index 0000000..424eecc --- /dev/null +++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiLiveTest.java @@ -0,0 +1,126 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.dimensiondata.cloudcontrol.features; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import org.jclouds.dimensiondata.cloudcontrol.domain.FirewallRuleTarget; +import org.jclouds.dimensiondata.cloudcontrol.domain.IpRange; +import org.jclouds.dimensiondata.cloudcontrol.domain.Placement; +import org.jclouds.dimensiondata.cloudcontrol.domain.State; +import org.jclouds.dimensiondata.cloudcontrol.internal.BaseDimensionDataCloudControlApiLiveTest; +import org.jclouds.rest.ResourceAlreadyExistsException; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import java.util.List; + +import static org.jclouds.dimensiondata.cloudcontrol.features.NetworkApiMockTest.DEFAULT_ACTION; +import static org.jclouds.dimensiondata.cloudcontrol.features.NetworkApiMockTest.DEFAULT_IP_VERSION; +import static org.jclouds.dimensiondata.cloudcontrol.utils.DimensionDataCloudControlResponseUtils.generateFirewallRuleName; +import static org.jclouds.dimensiondata.cloudcontrol.utils.DimensionDataCloudControlResponseUtils.waitForNetworkDomainStatus; +import static org.jclouds.dimensiondata.cloudcontrol.utils.DimensionDataCloudControlResponseUtils.waitForVlanStatus; +import static org.testng.Assert.assertNotNull; + +@Test(groups = "live", testName = "NetworkApiLiveTest", singleThreaded = true) +public class NetworkApiLiveTest extends BaseDimensionDataCloudControlApiLiveTest { + + private static final String DATACENTER = "NW20-EPC-LAB04"; + + private static final String DEFAULT_PRIVATE_IPV4_BASE_ADDRESS = "10.0.0.0"; + private static final Integer DEFAULT_PRIVATE_IPV4_PREFIX_SIZE = 24; + private static final String DEFAULT_PROTOCOL = "TCP"; + + private String networkDomainId; + private String vlanId; + private String portListId; + private List<String> firewallRuleIds; + + @BeforeClass + public void init() { + firewallRuleIds = Lists.newArrayList(); + } + + @Test(dependsOnMethods = "testDeployVlan") + public void testCreatePortList() { + portListId = api() + .createPortList(networkDomainId, this.getClass().getCanonicalName(), this.getClass().getCanonicalName(), + ImmutableList.of(FirewallRuleTarget.Port.create(22, null)), Lists.<String>newArrayList()); + assertNotNull(portListId); + } + + @Test(dependsOnMethods = "testCreatePortList") + public void testCreateFirewallRuleWithPortList() { + String id = api().createFirewallRule(networkDomainId, generateFirewallRuleName("server-id"), DEFAULT_ACTION, + DEFAULT_IP_VERSION, DEFAULT_PROTOCOL, FirewallRuleTarget.builder().ip(IpRange.create("ANY", null)).build(), + FirewallRuleTarget.builder().ip(IpRange.create("ANY", null)).portListId(portListId).build(), Boolean.TRUE, + Placement.builder().position("LAST").build()); + firewallRuleIds.add(id); + } + + @Test(dependsOnMethods = "testDeployNetworkDomain") + public void testDeployVlan() { + vlanId = api().deployVlan(networkDomainId, NetworkApiLiveTest.class.getSimpleName(), + NetworkApiLiveTest.class.getSimpleName(), DEFAULT_PRIVATE_IPV4_BASE_ADDRESS, + DEFAULT_PRIVATE_IPV4_PREFIX_SIZE); + assertNotNull(vlanId); + waitForVlanStatus(api(), vlanId, State.NORMAL, 30 * 60 * 1000, "Error - unable to deploy vlan"); + } + + @Test + public void testDeployNetworkDomain() { + String networkDomainName = NetworkApiLiveTest.class.getSimpleName(); + networkDomainId = api() + .deployNetworkDomain(DATACENTER, networkDomainName, NetworkApiLiveTest.class.getSimpleName(), "ESSENTIALS"); + assertNotNull(networkDomainId); + waitForNetworkDomainStatus(api(), networkDomainId, State.NORMAL, 30 * 60 * 1000, + "Error - unable to deploy network domain"); + } + + @Test(expectedExceptions = ResourceAlreadyExistsException.class) + public void testDeploySameNetworkDomain() { + api().deployNetworkDomain(DATACENTER, NetworkApiLiveTest.class.getSimpleName(), + NetworkApiLiveTest.class.getSimpleName(), "ESSENTIALS"); + } + + @AfterClass + public void tearDown() { + if (!firewallRuleIds.isEmpty()) { + for (String firewallRuleId : firewallRuleIds) { + api().deleteFirewallRule(firewallRuleId); + } + } + if (portListId != null) { + api().deletePortList(portListId); + } + if (vlanId != null) { + api().deleteVlan(vlanId); + waitForVlanStatus(api(), vlanId, State.DELETED, 30 * 60 * 1000, "Error deleting vlan"); + } + if (networkDomainId != null) { + api().deleteNetworkDomain(networkDomainId); + waitForNetworkDomainStatus(api(), networkDomainId, State.DELETED, 30 * 60 * 1000, + "Error deleting network domain"); + } + } + + private NetworkApi api() { + return api.getNetworkApi(); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2495dd9a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiMockTest.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiMockTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiMockTest.java new file mode 100644 index 0000000..6e4fc86 --- /dev/null +++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiMockTest.java @@ -0,0 +1,392 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.dimensiondata.cloudcontrol.features; + +import com.squareup.okhttp.mockwebserver.MockResponse; +import org.jclouds.dimensiondata.cloudcontrol.domain.FirewallRule; +import org.jclouds.dimensiondata.cloudcontrol.domain.FirewallRuleTarget; +import org.jclouds.dimensiondata.cloudcontrol.domain.IpRange; +import org.jclouds.dimensiondata.cloudcontrol.domain.NatRule; +import org.jclouds.dimensiondata.cloudcontrol.domain.NetworkDomain; +import org.jclouds.dimensiondata.cloudcontrol.domain.Placement; +import org.jclouds.dimensiondata.cloudcontrol.domain.PublicIpBlock; +import org.jclouds.dimensiondata.cloudcontrol.domain.Vlan; +import org.jclouds.dimensiondata.cloudcontrol.internal.BaseAccountAwareCloudControlMockTest; +import org.jclouds.dimensiondata.cloudcontrol.parse.PublicIpBlocksParseTest; +import org.jclouds.dimensiondata.cloudcontrol.parse.VlansParseTest; +import org.jclouds.http.Uris; +import org.testng.annotations.Test; + +import javax.ws.rs.HttpMethod; + +import static ch.qos.logback.core.net.ssl.SSL.DEFAULT_PROTOCOL; +import static com.google.common.collect.Iterables.size; +import static javax.ws.rs.HttpMethod.GET; +import static javax.ws.rs.HttpMethod.POST; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +/** + * Mock tests for the {@link org.jclouds.dimensiondata.cloudcontrol.features.NetworkApi} class. + */ +@Test(groups = "unit", testName = "NetworkApiMockTest", singleThreaded = true) +public class NetworkApiMockTest extends BaseAccountAwareCloudControlMockTest { + + public static final String DEFAULT_ACTION = "ACCEPT_DECISIVELY"; + public static final String DEFAULT_IP_VERSION = "IPV4"; + + public void testListNetworkDomains() throws Exception { + server.enqueue(jsonResponse("/networkDomains.json")); + Iterable<NetworkDomain> networkDomains = api.getNetworkApi().listNetworkDomains().concat(); + assertEquals(size(networkDomains), 1); // Force the PagedIterable to advance + assertEquals(server.getRequestCount(), 2); + + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/networkDomain"); + } + + public void testListNetworkDomainsWithPagination() throws Exception { + server.enqueue(jsonResponse("/networkDomains-page1.json")); + server.enqueue(jsonResponse("/networkDomains-page2.json")); + Iterable<NetworkDomain> networkDomains = api.getNetworkApi().listNetworkDomains().concat().toList(); + + consumeIterableAndAssertAdditionalPagesRequested(networkDomains, 20, 0); + + assertSent(HttpMethod.GET, expectedListNetworkDomainsUriBuilder().toString()); + assertSent(HttpMethod.GET, addPageNumberToUriBuilder(expectedListNetworkDomainsUriBuilder(), 2).toString()); + } + + public void testGetNetworkDomain() throws Exception { + server.enqueue(jsonResponse("/networkDomain.json")); + api.getNetworkApi().getNetworkDomain("networkDomainId"); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/networkDomain/networkDomainId"); + } + + public void testGetNetworkDomain_404() throws Exception { + server.enqueue(response404()); + api.getNetworkApi().listNetworkDomainsWithDatacenterIdAndName("testDatacenterId", "testName").concat(); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/networkDomain" + + "?datacenterId=testDatacenterId&name=testName"); + } + + public void testListNetworkDomainsWithName() throws Exception { + server.enqueue(jsonResponse("/networkDomains.json")); + api.getNetworkApi().listNetworkDomainsWithDatacenterIdAndName("testDatacenterId", "testName").concat(); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/networkDomain" + + "?datacenterId=testDatacenterId&name=testName"); + } + + public void testListNetworkDomainsWithNameWithPagination() throws Exception { + server.enqueue(jsonResponse("/networkDomains-page1.json")); + server.enqueue(jsonResponse("/networkDomains-page2.json")); + Iterable<NetworkDomain> networkDomains = api.getNetworkApi() + .listNetworkDomainsWithDatacenterIdAndName("testDatacenterId", "testName").concat(); + + consumeIterableAndAssertAdditionalPagesRequested(networkDomains, 20, 1); + + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/networkDomain" + + "?datacenterId=testDatacenterId&name=testName"); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/networkDomain" + "?pageNumber=2"); + } + + public void testListNetworkDomainsWithName_404() throws Exception { + server.enqueue(response404()); + api.getNetworkApi().listNetworkDomainsWithDatacenterIdAndName("testDatacenterId", "testName").concat(); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/networkDomain" + + "?datacenterId=testDatacenterId&name=testName"); + } + + public void testListVlansWithNetworkDomainId() throws Exception { + server.enqueue(jsonResponse("/vlans.json")); + api.getNetworkApi().listVlans("testNetworkDomainId"); + assertSent(GET, + "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/vlan?networkDomainId=testNetworkDomainId"); + } + + public void testListVlansWithNetworkDomainId_404() throws Exception { + server.enqueue(response404()); + api.getNetworkApi().listVlans("testNetworkDomainId"); + assertSent(GET, + "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/vlan?networkDomainId=testNetworkDomainId"); + } + + public void testListVlanssWithPagination() throws Exception { + server.enqueue(jsonResponse("/vlans-page1.json")); + server.enqueue(jsonResponse("/vlans-page2.json")); + Iterable<Vlan> vlans = api.getNetworkApi().listVlans("12345").concat().toList(); + + consumeIterableAndAssertAdditionalPagesRequested(vlans, 20, 0); + + assertSent(HttpMethod.GET, expectedListVlansRulesUriBuilder().toString()); + assertSent(HttpMethod.GET, addPageNumberToUriBuilder(expectedListVlansRulesUriBuilder(), 2).toString()); + } + + public void testListVlans() throws Exception { + server.enqueue(new MockResponse().setBody(payloadFromResource("/vlans.json"))); + assertEquals(api.getNetworkApi().listVlans("12345").concat().toList(), new VlansParseTest().expected().toList()); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/vlan?networkDomainId=12345"); + } + + public void testListVlans_404() throws Exception { + server.enqueue(response404()); + assertTrue(api.getNetworkApi().listVlans("12345").concat().isEmpty()); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/vlan?networkDomainId=12345"); + } + + public void testGetVlan() throws Exception { + server.enqueue(new MockResponse().setBody(payloadFromResource("/vlan.json"))); + api.getNetworkApi().getVlan("12345"); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/vlan/12345"); + } + + public void testGetVlan_404() throws Exception { + server.enqueue(response404()); + api.getNetworkApi().getVlan("12345"); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/vlan/12345"); + } + + public void testListPublicIPv4AddressBlock() throws Exception { + server.enqueue(new MockResponse().setBody(payloadFromResource("/publicIpBlocks.json"))); + assertEquals(api.getNetworkApi().listPublicIPv4AddressBlocks("12345").concat().toList(), + new PublicIpBlocksParseTest().expected().toList()); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/publicIpBlock?networkDomainId=12345"); + } + + public void testListPublicIPv4AddressBlock_404() throws Exception { + server.enqueue(response404()); + assertTrue(api.getNetworkApi().listPublicIPv4AddressBlocks("12345").concat().isEmpty()); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/publicIpBlock?networkDomainId=12345"); + } + + public void testListPublicIPv4AddressBlockWithPagination() throws Exception { + server.enqueue(jsonResponse("/publicIpBlocks-page1.json")); + server.enqueue(jsonResponse("/publicIpBlocks-page2.json")); + Iterable<PublicIpBlock> ipBlocks = api.getNetworkApi().listPublicIPv4AddressBlocks("12345").concat().toList(); + + consumeIterableAndAssertAdditionalPagesRequested(ipBlocks, 20, 0); + + assertSent(HttpMethod.GET, expectedListPublicIpBlockUriBuilder().toString()); + assertSent(HttpMethod.GET, addPageNumberToUriBuilder(expectedListPublicIpBlockUriBuilder(), 2).toString()); + } + + public void testCreateFirewallRule() throws Exception { + server.enqueue(new MockResponse().setResponseCode(200).setBody( + "{\n" + "\"operation\": \"CREATE_FIREWALL_RULE\",\n" + "\"responseCode\": \"OK\",\n" + + "\"message\": \"Request create Firewall Rule 'My.Rule' successful\", \"info\": [\n" + "{\n" + + "\"name\": \"firewallRuleId\",\n" + "\"value\": \"dc545f3e-823c-4500-93c9-8d7f576311de\"\n" + + "} ],\n" + "\"warning\": [],\n" + "\"error\": [],\n" + + "\"requestId\": \"NA9/2015-03-05T13:46:34.848-05:00/f8fdef24-8a12-45ea-a831-\n" + + "d5463212ef6a\" }")); + api.getNetworkApi().createFirewallRule("123456", "test", DEFAULT_ACTION, DEFAULT_IP_VERSION, DEFAULT_PROTOCOL, + FirewallRuleTarget.builder().ip(IpRange.create("ANY", null)).build(), + FirewallRuleTarget.builder().ip(IpRange.create("ANY", null)).build(), true, + Placement.builder().position("LAST").build()); + assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/createFirewallRule"); + } + + public void testDeleteNetworkDomain() throws Exception { + server.enqueue(new MockResponse().setResponseCode(200).setBody( + "{\n" + "\"operation\": \"DELETE_NETWORK_DOMAIN\",\n" + "\"responseCode\": \"IN_PROGRESS\",\n" + + "\"message\": \"Request to Delete Network Domain (Id:12623a68-ebdb-11e3-9153-001b21cfdbe0)" + + " has been accepted and is being processed\", \"info\": [],\n" + "\"warning\": [],\n" + + "\"error\": [],\n" + "\"requestId\": \"NA9/2015-03-05T13:46:34.848-05:00/f8fdef24-8a12-45ea-a831-\n" + + "d5463212ef6a\" }")); + api.getNetworkApi().deleteNetworkDomain("networkDomainId"); + assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/deleteNetworkDomain"); + } + + public void testDeleteNetworkDomain_404() throws Exception { + server.enqueue(response404()); + api.getNetworkApi().deleteNetworkDomain("networkDomainId"); + assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/deleteNetworkDomain"); + } + + public void testRemovePublicIpBlock() throws Exception { + server.enqueue(new MockResponse().setResponseCode(200).setBody( + "{\n" + "\"operation\": \"REMOVE_PUBLIC_IP_BLOCK\",\n" + "\"responseCode\": \"OK\",\n" + + "\"message\": \"Public Ip Block (Id:12623a68-ebdb-11e3-9153-001b21cfdbe0) has been removed successfully\"," + + " \"info\": [],\n" + "\"warning\": [],\n" + "\"error\": [],\n" + + "\"requestId\": \"NA9/2015-03-05T13:46:34.848-05:00/f8fdef24-8a12-45ea-a831-\n" + + "d5463212ef6a\" }")); + api.getNetworkApi().removePublicIpBlock("publicIpBlockId"); + assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/removePublicIpBlock"); + } + + public void testRemovePublicIpBlock_404() throws Exception { + server.enqueue(response404()); + api.getNetworkApi().removePublicIpBlock("publicIpBlockId"); + assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/removePublicIpBlock"); + } + + public void testGetPublicIpBlock() throws Exception { + server.enqueue(jsonResponse("/publicIpBlock.json")); + api.getNetworkApi().getPublicIPv4AddressBlock("publicIpBlockId"); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/publicIpBlock/publicIpBlockId"); + } + + public void testGetPublicIpBlock_404() throws Exception { + server.enqueue(response404()); + api.getNetworkApi().getPublicIPv4AddressBlock("publicIpBlockId"); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/publicIpBlock/publicIpBlockId"); + } + + public void testCreateNatRule() throws Exception { + server.enqueue(new MockResponse().setResponseCode(200).setBody( + "{\n" + "\"operation\": \"CREATE_NAT_RULE\",\n" + "\"responseCode\": \"OK\",\n" + + "\"message\": \"Create Nat Rule Complete\", \"info\": [\n" + "{\n" + "\"name\": \"natRuleId\",\n" + + "\"value\": \"dc545f3e-823c-4500-93c9-8d7f576311de\"\n" + "} ],\n" + "\"warning\": [],\n" + + "\"error\": [],\n" + "\"requestId\": \"NA9/2015-03-05T13:46:34.848-05:00/f8fdef24-8a12-45ea-a831-\n" + + "d5463212ef6a\" }")); + api.getNetworkApi().createNatRule("networkDomainId", "10.0.0.5", "155.143.0.54"); + assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/createNatRule"); + } + + public void testListNatRules() throws Exception { + server.enqueue(new MockResponse().setBody(payloadFromResource("/natRules.json"))); + api.getNetworkApi().listNatRules("12345").concat().toList(); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/natRule?networkDomainId=12345"); + } + + public void testListNatRulesWithPagination() throws Exception { + server.enqueue(jsonResponse("/natRules-page1.json")); + server.enqueue(jsonResponse("/natRules-page2.json")); + Iterable<NatRule> natRules = api.getNetworkApi().listNatRules("12345").concat().toList(); + + consumeIterableAndAssertAdditionalPagesRequested(natRules, 20, 0); + + assertSent(HttpMethod.GET, expectedListNatRulesUriBuilder().toString()); + assertSent(HttpMethod.GET, addPageNumberToUriBuilder(expectedListNatRulesUriBuilder(), 2).toString()); + } + + public void testListNatRules_404() throws Exception { + server.enqueue(response404()); + assertTrue(api.getNetworkApi().listNatRules("12345").concat().isEmpty()); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/natRule?networkDomainId=12345"); + } + + public void testGetNatRule() throws Exception { + server.enqueue(jsonResponse("/natRule.json")); + api.getNetworkApi().getNatRule("natRuleId"); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/natRule/natRuleId"); + } + + public void testGetNatRule_404() throws Exception { + server.enqueue(response404()); + api.getNetworkApi().getNatRule("natRuleId"); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/natRule/natRuleId"); + } + + public void testListFirewallRules() throws Exception { + server.enqueue(new MockResponse().setBody(payloadFromResource("/firewallRules.json"))); + api.getNetworkApi().listFirewallRules("12345").concat().toList(); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/firewallRule?networkDomainId=12345"); + } + + public void testListFirewallRules_404() throws Exception { + server.enqueue(response404()); + api.getNetworkApi().listFirewallRules("12345").concat().toList(); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/firewallRule?networkDomainId=12345"); + } + + public void testListFirewallRulesWithPagination() throws Exception { + server.enqueue(jsonResponse("/firewallRules-page1.json")); + server.enqueue(jsonResponse("/firewallRules-page2.json")); + Iterable<FirewallRule> firewallRules = api.getNetworkApi().listFirewallRules("12345").concat().toList(); + + consumeIterableAndAssertAdditionalPagesRequested(firewallRules, 15, 0); + + assertSent(HttpMethod.GET, expectedListFirewallRulesUriBuilder().toString()); + assertSent(HttpMethod.GET, addPageNumberToUriBuilder(expectedListFirewallRulesUriBuilder(), 2).toString()); + } + + public void testDeleteFirewallRule() throws Exception { + server.enqueue(new MockResponse().setResponseCode(200).setBody( + "{\n" + "\"operation\": \"DELETE_FIREWALL_RULE\",\n" + "\"responseCode\": \"IN_PROGRESS\",\n" + + "\"message\": \"Delete Firewall Rule (Id:12623a68-ebdb-11e3-9153-001b21cfdbe0) complete\", " + + "\"info\": [],\n" + "\"warning\": [],\n" + "\"error\": [],\n" + + "\"requestId\": \"NA9/2015-03-05T13:46:34.848-05:00/f8fdef24-8a12-45ea-a831-\n" + + "d5463212ef6a\" }")); + api.getNetworkApi().deleteFirewallRule("firewallRuleId"); + assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/deleteFirewallRule"); + } + + public void testDeleteFirewallRule_404() throws Exception { + server.enqueue(response404()); + api.getNetworkApi().deleteFirewallRule("firewallRuleId"); + assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/deleteFirewallRule"); + } + + public void testGetPortList() throws Exception { + server.enqueue(new MockResponse().setBody(payloadFromResource("/portList.json"))); + api.getNetworkApi().getPortList("portListId"); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/portList/portListId"); + } + + public void testGetPortList_404() throws Exception { + server.enqueue(response404()); + api.getNetworkApi().getPortList("portListId"); + assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/portList/portListId"); + } + + public void testDeletePortList() throws Exception { + server.enqueue(new MockResponse().setResponseCode(200).setBody( + "{\n" + "\"operation\": \"DELETE_PORT_LIST\",\n" + "\"responseCode\": \"IN_PROGRESS\",\n" + + "\"message\": \"Port List with id portListId has been deleted.\", " + "\"info\": [],\n" + + "\"warning\": [],\n" + "\"error\": [],\n" + + "\"requestId\": \"NA9/2015-03-05T13:46:34.848-05:00/f8fdef24-8a12-45ea-a831-\n" + + "d5463212ef6a\" }")); + api.getNetworkApi().deletePortList("portListId"); + assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/deletePortList"); + } + + public void testDeletePortList_404() throws Exception { + server.enqueue(response404()); + api.getNetworkApi().deletePortList("portListId"); + assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/deletePortList"); + } + + private Uris.UriBuilder expectedListFirewallRulesUriBuilder() { + Uris.UriBuilder uriBuilder = Uris + .uriBuilder("/caas/" + VERSION + "/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/firewallRule"); + uriBuilder.addQuery("networkDomainId", "12345"); + return uriBuilder; + } + + private Uris.UriBuilder expectedListNatRulesUriBuilder() { + Uris.UriBuilder uriBuilder = Uris + .uriBuilder("/caas/" + VERSION + "/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/natRule"); + uriBuilder.addQuery("networkDomainId", "12345"); + return uriBuilder; + } + + private Uris.UriBuilder expectedListNetworkDomainsUriBuilder() { + return Uris.uriBuilder("/caas/" + VERSION + "/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/networkDomain"); + } + + private Uris.UriBuilder expectedListVlansRulesUriBuilder() { + Uris.UriBuilder uriBuilder = Uris + .uriBuilder("/caas/" + VERSION + "/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/vlan"); + uriBuilder.addQuery("networkDomainId", "12345"); + return uriBuilder; + } + + private Uris.UriBuilder expectedListPublicIpBlockUriBuilder() { + Uris.UriBuilder uriBuilder = Uris + .uriBuilder("/caas/" + VERSION + "/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/publicIpBlock"); + uriBuilder.addQuery("networkDomainId", "12345"); + return uriBuilder; + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2495dd9a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlMockTest.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlMockTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlMockTest.java index 92079a0..7856524 100644 --- a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlMockTest.java +++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlMockTest.java @@ -47,6 +47,7 @@ import java.util.Set; import static com.google.common.collect.Iterables.size; import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor; import static org.assertj.core.api.Assertions.assertThat; +import static org.jclouds.util.Strings2.toStringAndClose; import static org.testng.Assert.assertEquals; import static org.testng.Assert.fail; @@ -208,4 +209,12 @@ public class BaseDimensionDataCloudControlMockTest implements IHookable { uriBuilder.addQuery("pageNumber", Integer.toString(pageNumber)); return uriBuilder; } + + public byte[] payloadFromResource(String resource) { + try { + return toStringAndClose(getClass().getResourceAsStream(resource)).getBytes(Charsets.UTF_8); + } catch (IOException e) { + throw Throwables.propagate(e); + } + } } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2495dd9a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/FirewallRulesParseTest.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/FirewallRulesParseTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/FirewallRulesParseTest.java new file mode 100644 index 0000000..2fe920c --- /dev/null +++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/FirewallRulesParseTest.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.dimensiondata.cloudcontrol.parse; + +import com.google.common.collect.ImmutableList; +import org.jclouds.dimensiondata.cloudcontrol.domain.FirewallRule; +import org.jclouds.dimensiondata.cloudcontrol.domain.FirewallRuleTarget; +import org.jclouds.dimensiondata.cloudcontrol.domain.FirewallRules; +import org.jclouds.dimensiondata.cloudcontrol.domain.IpRange; +import org.jclouds.dimensiondata.cloudcontrol.internal.BaseDimensionDataCloudControlParseTest; +import org.testng.annotations.Test; + +import javax.ws.rs.Consumes; +import javax.ws.rs.core.MediaType; +import java.util.List; + +@Test(groups = "unit") +public class FirewallRulesParseTest extends BaseDimensionDataCloudControlParseTest<FirewallRules> { + + @Override + public String resource() { + return "/firewallRules.json"; + } + + @Override + @Consumes(MediaType.APPLICATION_JSON) + public FirewallRules expected() { + List<FirewallRule> firewallRules = ImmutableList + .of(FirewallRule.builder().id("1aa3d0ce-d95d-4296-8338-9717e0d37ff9") + .name("CCDEFAULT.BlockOutboundMailIPv6Secure").state("NORMAL").action("DROP").ipVersion("IPV6") + .protocol("TCP").source(FirewallRuleTarget.builder().ip(IpRange.create("ANY", null)).build()) + .destination(FirewallRuleTarget.builder().ip(IpRange.create("ANY", null)) + .port(FirewallRuleTarget.Port.create(587, null)).build()).ruleType("DEFAULT_RULE") + .networkDomainId("484174a2-ae74-4658-9e56-50fc90e086cf").enabled(Boolean.TRUE).datacenterId("NA9") + .build()); + return new FirewallRules(firewallRules, 1, 2, 2, 250); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2495dd9a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/NatRulesParseTest.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/NatRulesParseTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/NatRulesParseTest.java new file mode 100644 index 0000000..7858a0e --- /dev/null +++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/NatRulesParseTest.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.dimensiondata.cloudcontrol.parse; + +import com.google.common.collect.ImmutableList; +import org.jclouds.dimensiondata.cloudcontrol.domain.NatRule; +import org.jclouds.dimensiondata.cloudcontrol.domain.NatRules; +import org.jclouds.dimensiondata.cloudcontrol.internal.BaseDimensionDataCloudControlParseTest; +import org.testng.annotations.Test; + +import javax.ws.rs.Consumes; +import javax.ws.rs.core.MediaType; +import java.util.List; + +@Test(groups = "unit") +public class NatRulesParseTest extends BaseDimensionDataCloudControlParseTest<NatRules> { + + @Override + public String resource() { + return "/natRules.json"; + } + + @Override + @Consumes(MediaType.APPLICATION_JSON) + public NatRules expected() { + List<NatRule> natRules = ImmutableList.of(NatRule.builder().id("2187a636-7ebb-49a1-a2ff-5d617f496dce") + .createTime(parseDate("2015-03-06T13:43:45.000Z")).state("NORMAL").externalIp("165.180.12.18") + .internalIp("10.0.0.15").networkDomainId("484174a2-ae74-4658-9e56-50fc90e086cf").datacenterId("NA9") + .build(), NatRule.builder().id("2169a38e-5692-497e-a22a-701a838a6539") + .createTime(parseDate("2015-03-06T13:45:10.000Z")).state("NORMAL").externalIp("165.180.12.19") + .internalIp("10.0.0.16").networkDomainId("484174a2-ae74-4658-9e56-50fc90e086cf").datacenterId("NA9") + .build()); + return new NatRules(natRules, 1, 2, 2, 250); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2495dd9a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/NetworkDomainsParseTest.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/NetworkDomainsParseTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/NetworkDomainsParseTest.java new file mode 100644 index 0000000..c1eec7f --- /dev/null +++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/NetworkDomainsParseTest.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.dimensiondata.cloudcontrol.parse; + +import com.google.common.collect.ImmutableList; +import org.jclouds.dimensiondata.cloudcontrol.domain.NetworkDomain; +import org.jclouds.dimensiondata.cloudcontrol.domain.NetworkDomains; +import org.jclouds.dimensiondata.cloudcontrol.domain.State; +import org.jclouds.dimensiondata.cloudcontrol.internal.BaseDimensionDataCloudControlParseTest; +import org.testng.annotations.Test; + +import javax.ws.rs.Consumes; +import javax.ws.rs.core.MediaType; +import java.util.List; + +import static org.jclouds.dimensiondata.cloudcontrol.domain.NetworkDomain.Type.ESSENTIALS; + +@Test(groups = "unit") +public class NetworkDomainsParseTest extends BaseDimensionDataCloudControlParseTest<NetworkDomains> { + + @Override + public String resource() { + return "/networkDomains.json"; + } + + @Override + @Consumes(MediaType.APPLICATION_JSON) + public NetworkDomains expected() { + List<NetworkDomain> networkDomains = ImmutableList + .of(NetworkDomain.builder().id("8e082ed6-c198-4eff-97cb-aeac6f9685d8").datacenterId("NA9").name("test") + .description("").state(State.NORMAL).type(ESSENTIALS).snatIpv4Address("168.128.3.44") + .createTime(parseDate("2016-03-08T14:39:47.000Z")).build()); + return new NetworkDomains(networkDomains, 1, 5, 5, 250); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2495dd9a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/PublicIpBlocksParseTest.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/PublicIpBlocksParseTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/PublicIpBlocksParseTest.java new file mode 100644 index 0000000..97c9512 --- /dev/null +++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/PublicIpBlocksParseTest.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.dimensiondata.cloudcontrol.parse; + +import com.google.common.collect.ImmutableList; +import org.jclouds.dimensiondata.cloudcontrol.domain.PublicIpBlock; +import org.jclouds.dimensiondata.cloudcontrol.domain.PublicIpBlocks; +import org.jclouds.dimensiondata.cloudcontrol.internal.BaseDimensionDataCloudControlParseTest; +import org.testng.annotations.Test; + +import javax.ws.rs.Consumes; +import javax.ws.rs.core.MediaType; +import java.util.List; + +@Test(groups = "unit") +public class PublicIpBlocksParseTest extends BaseDimensionDataCloudControlParseTest<PublicIpBlocks> { + + @Override + public String resource() { + return "/publicIpBlocks.json"; + } + + @Override + @Consumes(MediaType.APPLICATION_JSON) + public PublicIpBlocks expected() { + List<PublicIpBlock> publicIpBlocks = ImmutableList + .of(PublicIpBlock.builder().networkDomainId("690de302-bb80-49c6-b401-8c02bbefb945") + .id("9993e5fc-bdce-11e4-8c14-b8ca3a5d9ef8").createTime(parseDate("2016-03-14T11:49:33.000Z")) + .state("NORMAL").datacenterId("NA9").size(2).baseIp("168.128.6.216").build()); + return new PublicIpBlocks(publicIpBlocks, 1, 5, 5, 250); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2495dd9a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/VlansParseTest.java ---------------------------------------------------------------------- diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/VlansParseTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/VlansParseTest.java new file mode 100644 index 0000000..cb74939 --- /dev/null +++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/VlansParseTest.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.dimensiondata.cloudcontrol.parse; + +import com.google.common.collect.ImmutableList; +import org.jclouds.dimensiondata.cloudcontrol.domain.IpRange; +import org.jclouds.dimensiondata.cloudcontrol.domain.NetworkDomain; +import org.jclouds.dimensiondata.cloudcontrol.domain.State; +import org.jclouds.dimensiondata.cloudcontrol.domain.Vlan; +import org.jclouds.dimensiondata.cloudcontrol.domain.Vlans; +import org.jclouds.dimensiondata.cloudcontrol.internal.BaseDimensionDataCloudControlParseTest; +import org.testng.annotations.Test; + +import javax.ws.rs.Consumes; +import javax.ws.rs.core.MediaType; +import java.util.List; + +@Test(groups = "unit") +public class VlansParseTest extends BaseDimensionDataCloudControlParseTest<Vlans> { + + @Override + public String resource() { + return "/vlans.json"; + } + + @Override + @Consumes(MediaType.APPLICATION_JSON) + public Vlans expected() { + List<Vlan> vlans = ImmutableList.of(Vlan.builder() + .networkDomain(NetworkDomain.builder().id("690de302-bb80-49c6-b401-8c02bbefb945").name("test").build()) + .id("6b25b02e-d3a2-4e69-8ca7-9bab605deebd").name("vlan1").description("") + .privateIpv4Range(IpRange.create("10.0.0.0", 24)) + .ipv6Range(IpRange.create("2607:f480:111:1575:0:0:0:0", 64)).ipv4GatewayAddress("10.0.0.1") + .ipv6GatewayAddress("2607:f480:111:1575:0:0:0:1").createTime(parseDate("2016-03-11T10:41:19.000Z")) + .state(State.NORMAL).datacenterId("NA9").build()); + return new Vlans(vlans, 1, 5, 5, 250); + } +}
