Add remaining features to support the abstraction - add DeviceApi with Mock and Live Test - add FacilityApi with Mock and Live Test - add OperatingSystemApi with Mock and Live Test - add SshKeyApi with Mock and Live Test - fix Device domain object - refactor deviceApi.create and sshKeyApi.create as they actually return an object instead of a URI now - add mock and live tests for device api actions
Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/49f1d076 Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/49f1d076 Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/49f1d076 Branch: refs/heads/master Commit: 49f1d0760e06415143688bd7ac2ec2f2efcb2170 Parents: a7f97ac Author: Andrea Turli <[email protected]> Authored: Wed Jan 18 19:13:28 2017 +0100 Committer: Andrea Turli <[email protected]> Committed: Tue Jan 24 10:36:57 2017 +0100 ---------------------------------------------------------------------- .../main/java/org/jclouds/packet/PacketApi.java | 46 + .../packet/config/PacketHttpApiModule.java | 4 +- .../java/org/jclouds/packet/domain/Device.java | 82 +- .../packet/domain/ProvisioningEvent.java | 52 ++ .../org/jclouds/packet/features/DeviceApi.java | 148 +++ .../jclouds/packet/features/FacilityApi.java | 94 ++ .../packet/features/OperatingSystemApi.java | 94 ++ .../org/jclouds/packet/features/PlanApi.java | 94 ++ .../org/jclouds/packet/features/ProjectApi.java | 6 +- .../org/jclouds/packet/features/SshKeyApi.java | 122 +++ .../packet/functions/BaseToPagedIterable.java | 8 +- .../packet/functions/HrefToListOptions.java | 63 ++ .../packet/functions/LinkToListOptions.java | 63 -- .../packet/features/DeviceApiLiveTest.java | 138 +++ .../packet/features/DeviceApiMockTest.java | 184 ++++ .../packet/features/FacilityApiLiveTest.java | 62 ++ .../packet/features/FacilityApiMockTest.java | 78 ++ .../features/OperatingSystemApiLiveTest.java | 62 ++ .../features/OperatingSystemApiMockTest.java | 78 ++ .../packet/features/PlanApiLiveTest.java | 62 ++ .../packet/features/PlanApiMockTest.java | 78 ++ .../packet/features/ProjectApiLiveTest.java | 7 +- .../packet/features/ProjectApiMockTest.java | 1 - .../packet/features/SshKeyApiLiveTest.java | 83 ++ .../packet/features/SshKeyApiMockTest.java | 134 +++ .../packet/functions/HrefToListOptionsTest.java | 57 ++ .../packet/functions/LinkToListOptionsTest.java | 57 -- .../src/test/resources/device-create-req.json | 11 + .../src/test/resources/device-create-res.json | 211 +++++ providers/packet/src/test/resources/device.json | 278 ++++++ .../src/test/resources/devices-first.json | 910 +++++++++++++++++++ .../packet/src/test/resources/devices-last.json | 376 ++++++++ .../packet/src/test/resources/devices.json | 282 ++++++ .../src/test/resources/facilities-first.json | 39 + .../src/test/resources/facilities-last.json | 27 + .../packet/src/test/resources/facilities.json | 30 + .../test/resources/operatingSystems-first.json | 96 ++ .../test/resources/operatingSystems-last.json | 106 +++ .../src/test/resources/operatingSystems.json | 166 ++++ .../packet/src/test/resources/plans-first.json | 222 +++++ .../packet/src/test/resources/plans-last.json | 98 ++ providers/packet/src/test/resources/plans.json | 284 ++++++ .../packet/src/test/resources/power-off.json | 3 + .../packet/src/test/resources/power-on.json | 3 + .../packet/src/test/resources/projects.json | 78 +- providers/packet/src/test/resources/reboot.json | 3 + providers/packet/src/test/resources/rescue.json | 3 + .../src/test/resources/ssh-key-create-req.json | 4 + .../src/test/resources/ssh-key-create-res.json | 12 + .../packet/src/test/resources/ssh-key.json | 12 + .../src/test/resources/sshKeys-first.json | 80 ++ .../packet/src/test/resources/sshKeys-last.json | 56 ++ .../packet/src/test/resources/sshKeys.json | 16 + providers/packet/src/test/resources/user.json | 19 + 54 files changed, 5244 insertions(+), 138 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/main/java/org/jclouds/packet/PacketApi.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/main/java/org/jclouds/packet/PacketApi.java b/providers/packet/src/main/java/org/jclouds/packet/PacketApi.java index 1cb8e9b..e5f84e3 100644 --- a/providers/packet/src/main/java/org/jclouds/packet/PacketApi.java +++ b/providers/packet/src/main/java/org/jclouds/packet/PacketApi.java @@ -18,7 +18,14 @@ package org.jclouds.packet; import java.io.Closeable; +import javax.ws.rs.PathParam; + +import org.jclouds.packet.features.DeviceApi; +import org.jclouds.packet.features.FacilityApi; +import org.jclouds.packet.features.OperatingSystemApi; +import org.jclouds.packet.features.PlanApi; import org.jclouds.packet.features.ProjectApi; +import org.jclouds.packet.features.SshKeyApi; import org.jclouds.rest.annotations.Delegate; /** @@ -37,4 +44,43 @@ public interface PacketApi extends Closeable { @Delegate ProjectApi projectApi(); + /** + * This Packet API provides all of the devices + * + * @see <a href="https://www.packet.net/help/api/#page:devices">docs</a> + */ + @Delegate + DeviceApi deviceApi(@PathParam("projectId") String projectId); + + /** + * This Packet API provides all of the facilities + * + * @see <a href="https://www.packet.net/help/api/#page:devices,header:devices-operating-systems">docs</a> + */ + @Delegate + FacilityApi facilityApi(); + + /** + * This Packet API provides all of the plans + * + * @see <a href="https://www.packet.net/help/api/#page:devices,header:devices-plans">docs</a> + */ + @Delegate + PlanApi planApi(); + + /** + * This Packet API provides all of the operating systems + * + * @see <a href="https://www.packet.net/help/api/#page:devices,header:devices-operating-systems">docs</a> + */ + @Delegate + OperatingSystemApi operatingSystemApi(); + + /** + * This Packet API provides all of the operating systems + * + * @see <a href="https://www.packet.net/help/api/#page:ssh-keys">docs</a> + */ + @Delegate + SshKeyApi sshKeyApi(); } http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/main/java/org/jclouds/packet/config/PacketHttpApiModule.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/main/java/org/jclouds/packet/config/PacketHttpApiModule.java b/providers/packet/src/main/java/org/jclouds/packet/config/PacketHttpApiModule.java index e74bb19..6edeebd 100644 --- a/providers/packet/src/main/java/org/jclouds/packet/config/PacketHttpApiModule.java +++ b/providers/packet/src/main/java/org/jclouds/packet/config/PacketHttpApiModule.java @@ -25,7 +25,7 @@ import org.jclouds.location.suppliers.implicit.FirstRegion; import org.jclouds.packet.PacketApi; import org.jclouds.packet.domain.Href; import org.jclouds.packet.domain.options.ListOptions; -import org.jclouds.packet.functions.LinkToListOptions; +import org.jclouds.packet.functions.HrefToListOptions; import org.jclouds.packet.handlers.PacketErrorHandler; import org.jclouds.rest.ConfiguresHttpApi; import org.jclouds.rest.config.HttpApiModule; @@ -42,7 +42,7 @@ public class PacketHttpApiModule extends HttpApiModule<PacketApi> { super.configure(); bind(ImplicitLocationSupplier.class).to(FirstRegion.class).in(Scopes.SINGLETON); bind(new TypeLiteral<Function<Href, ListOptions>>() { - }).to(LinkToListOptions.class); + }).to(HrefToListOptions.class); } @Override http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/main/java/org/jclouds/packet/domain/Device.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/main/java/org/jclouds/packet/domain/Device.java b/providers/packet/src/main/java/org/jclouds/packet/domain/Device.java index af59970..96e0b53 100644 --- a/providers/packet/src/main/java/org/jclouds/packet/domain/Device.java +++ b/providers/packet/src/main/java/org/jclouds/packet/domain/Device.java @@ -18,6 +18,8 @@ package org.jclouds.packet.domain; import java.util.Date; import java.util.List; +import java.util.Map; +import java.util.Set; import org.jclouds.javax.annotation.Nullable; import org.jclouds.json.SerializedNames; @@ -27,6 +29,8 @@ import com.google.common.base.Enums; import com.google.common.base.Joiner; import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import static com.google.common.base.Preconditions.checkArgument; @@ -60,15 +64,19 @@ public abstract class Device { public abstract OperatingSystem operatingSystem(); public abstract Facility facility(); public abstract Href project(); + public abstract List<Href> sshKeys(); public abstract Href projectLite(); public abstract List<Object> volumes(); public abstract List<IpAddress> ipAddresses(); + public abstract List<ProvisioningEvent> provisioningEvents(); public abstract Plan plan(); public abstract String rootPassword(); public abstract String userdata(); public abstract String href(); - @SerializedNames({"id", "short_id", "hostname", "description", "state", "tags", "billing_cycle", "user", "iqn", "locked", "bonding_mode", "created_at", "updated_at", "operating_system", "facility", "project", "project_lite", "volumes", "ip_addresses", "plan", "root_password", "userdata", "href"}) + @SerializedNames({"id", "short_id", "hostname", "description", "state", "tags", "billing_cycle", "user", "iqn", + "locked", "bonding_mode", "created_at", "updated_at", "operating_system", "facility", "project", "ssh_keys", + "project_lite", "volumes", "ip_addresses", "provisioning_events", "plan", "root_password", "userdata", "href"}) public static Device create(String id, String shortId, String hostname, @@ -85,9 +93,11 @@ public abstract class Device { OperatingSystem operatingSystem, Facility facility, Href project, + List<Href> sshKeys, Href projectLite, List<Object> volumes, List<IpAddress> ipAddresses, + List<ProvisioningEvent> provisioningEvents, Plan plan, String rootPassword, String userdata, @@ -95,14 +105,80 @@ public abstract class Device { ) { return new AutoValue_Device(id, shortId, hostname, description, state, tags == null ? ImmutableList.<String> of() : ImmutableList.copyOf(tags), - billingCycle, user, iqn, locked, bondingMode, createdAt, updatedAt, operatingSystem, facility, project, projectLite, + billingCycle, user, iqn, locked, bondingMode, createdAt, updatedAt, operatingSystem, facility, project, + sshKeys == null ? ImmutableList.<Href> of() : ImmutableList.copyOf(sshKeys), + projectLite, volumes == null ? ImmutableList.of() : ImmutableList.copyOf(volumes), ipAddresses == null ? ImmutableList.<IpAddress>of() : ImmutableList.copyOf(ipAddresses), - plan, rootPassword, userdata, href + provisioningEvents == null ? ImmutableList.<ProvisioningEvent> of() : ImmutableList.copyOf(provisioningEvents), + plan, + rootPassword, userdata, href ); } Device() { } + @AutoValue + public abstract static class CreateDevice { + + public abstract String hostname(); + public abstract String plan(); + public abstract String billingCycle(); + public abstract String facility(); + public abstract Map<String, String> features(); + public abstract String operatingSystem(); + public abstract Boolean locked(); + public abstract String userdata(); + public abstract Set<String> tags(); + + @SerializedNames({"hostname", "plan", "billing_cycle", "facility", "features", "operating_system", + "locked", "userdata", "tags" }) + private static CreateDevice create(final String hostname, final String plan, final String billingCycle, + final String facility, final Map<String, String> features, final String operatingSystem, + final Boolean locked, final String userdata, + final Set<String> tags) { + return builder() + .hostname(hostname) + .plan(plan) + .billingCycle(billingCycle) + .facility(facility) + .features(features) + .operatingSystem(operatingSystem) + .locked(locked) + .userdata(userdata) + .tags(tags) + .build(); + } + + public static Builder builder() { + return new AutoValue_Device_CreateDevice.Builder(); + } + + @AutoValue.Builder + public abstract static class Builder { + + public abstract Builder hostname(String hostname); + public abstract Builder plan(String plan); + public abstract Builder billingCycle(String billingCycle); + public abstract Builder facility(String facility); + public abstract Builder features(Map<String, String> features); + public abstract Builder operatingSystem(String operatingSystem); + public abstract Builder locked(Boolean locked); + public abstract Builder userdata(String userdata); + public abstract Builder tags(Set<String> tags); + + abstract Map<String, String> features(); + abstract Set<String> tags(); + + abstract CreateDevice autoBuild(); + + public CreateDevice build() { + return tags(tags() != null ? ImmutableSet.copyOf(tags()) : ImmutableSet.<String> of()) + .features(features() != null ? ImmutableMap.copyOf(features()) : ImmutableMap.<String, String> of()) + .autoBuild(); + } + } + } + } http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/main/java/org/jclouds/packet/domain/ProvisioningEvent.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/main/java/org/jclouds/packet/domain/ProvisioningEvent.java b/providers/packet/src/main/java/org/jclouds/packet/domain/ProvisioningEvent.java new file mode 100644 index 0000000..3df979f --- /dev/null +++ b/providers/packet/src/main/java/org/jclouds/packet/domain/ProvisioningEvent.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.packet.domain; + +import java.util.Date; +import java.util.List; + +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.json.SerializedNames; + +import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableList; + +@AutoValue +public abstract class ProvisioningEvent { + + @Nullable + public abstract String id(); + public abstract String type(); + public abstract String body(); + @Nullable + public abstract Date createdAt(); + public abstract List<Href> relationships(); + public abstract String interpolated(); + @Nullable + public abstract String href(); + + @SerializedNames({"id", "type", "body", "created_at", "relationships", "interpolated", "href"}) + public static ProvisioningEvent create(String id, String type, String body, Date createdAt, + List<Href> relationships, String interpolated, String href) { + return new AutoValue_ProvisioningEvent(id, type, body, createdAt, + relationships == null ? ImmutableList.<Href> of() : ImmutableList.copyOf(relationships), + interpolated, + href); + } + + ProvisioningEvent() {} +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/main/java/org/jclouds/packet/features/DeviceApi.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/main/java/org/jclouds/packet/features/DeviceApi.java b/providers/packet/src/main/java/org/jclouds/packet/features/DeviceApi.java new file mode 100644 index 0000000..9f4c672 --- /dev/null +++ b/providers/packet/src/main/java/org/jclouds/packet/features/DeviceApi.java @@ -0,0 +1,148 @@ +/* + * 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.packet.features; + +import java.beans.ConstructorProperties; +import java.util.List; + +import javax.inject.Inject; +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.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.jclouds.Fallbacks; +import org.jclouds.Fallbacks.NullOnNotFoundOr404; +import org.jclouds.Fallbacks.VoidOnNotFoundOr404; +import org.jclouds.collect.IterableWithMarker; +import org.jclouds.collect.PagedIterable; +import org.jclouds.collect.internal.Arg0ToPagedIterable; +import org.jclouds.http.functions.ParseJson; +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.json.Json; +import org.jclouds.packet.PacketApi; +import org.jclouds.packet.domain.ActionType; +import org.jclouds.packet.domain.Device; +import org.jclouds.packet.domain.Href; +import org.jclouds.packet.domain.internal.PaginatedCollection; +import org.jclouds.packet.domain.options.ListOptions; +import org.jclouds.packet.filters.AddApiVersionToRequest; +import org.jclouds.packet.filters.AddXAuthTokenToRequest; +import org.jclouds.rest.annotations.BinderParam; +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 com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.inject.TypeLiteral; + +@Path("/projects/{projectId}/devices") +@Consumes(MediaType.APPLICATION_JSON) +@RequestFilters({AddXAuthTokenToRequest.class, AddApiVersionToRequest.class}) +public interface DeviceApi { + + @Named("device:list") + @GET + @ResponseParser(ParseDevices.class) + @Transform(ParseDevices.ToPagedIterable.class) + @Fallback(Fallbacks.EmptyPagedIterableOnNotFoundOr404.class) + PagedIterable<Device> list(); + + @Named("device:list") + @GET + @ResponseParser(ParseDevices.class) + @Fallback(Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404.class) + IterableWithMarker<Device> list(ListOptions options); + + final class ParseDevices extends ParseJson<ParseDevices.Devices> { + @Inject + ParseDevices(Json json) { + super(json, TypeLiteral.get(Devices.class)); + } + + private static class Devices extends PaginatedCollection<Device> { + @ConstructorProperties({"devices", "meta"}) + public Devices(List<Device> items, Meta meta) { + super(items, meta); + } + } + + public static class ToPagedIterable extends Arg0ToPagedIterable.FromCaller<Device, ToPagedIterable> { + + private final PacketApi api; + private final Function<Href, ListOptions> hrefToOptions; + + @Inject + ToPagedIterable(PacketApi api, Function<Href, ListOptions> hrefToOptions) { + this.api = api; + this.hrefToOptions = hrefToOptions; + } + + @Override + protected Function<Object, IterableWithMarker<Device>> markerToNextForArg0(Optional<Object> arg0) { + String projectId = arg0.get().toString(); + final DeviceApi deviceApi = api.deviceApi(projectId); + return new Function<Object, IterableWithMarker<Device>>() { + + @SuppressWarnings("unchecked") + @Override + public IterableWithMarker<Device> apply(Object input) { + ListOptions listOptions = hrefToOptions.apply(Href.class.cast(input)); + return IterableWithMarker.class.cast(deviceApi.list(listOptions)); + } + + }; + } + } + } + + @Named("device:create") + @POST + @Produces(MediaType.APPLICATION_JSON) + Device create(@BinderParam(BindToJsonPayload.class) Device.CreateDevice device); + + + @Named("device:get") + @GET + @Path("/{id}") + @Fallback(NullOnNotFoundOr404.class) + @Nullable + Device get(@PathParam("id") String id); + + @Named("device:delete") + @DELETE + @Path("/{id}") + @Fallback(VoidOnNotFoundOr404.class) + void delete(@PathParam("id") String id); + + @Named("device:actions") + @POST + @Path("/{id}/actions") + @MapBinder(BindToJsonPayload.class) + void actions(@PathParam("id") String id, @PayloadParam("type") ActionType type); + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/main/java/org/jclouds/packet/features/FacilityApi.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/main/java/org/jclouds/packet/features/FacilityApi.java b/providers/packet/src/main/java/org/jclouds/packet/features/FacilityApi.java new file mode 100644 index 0000000..bde9898 --- /dev/null +++ b/providers/packet/src/main/java/org/jclouds/packet/features/FacilityApi.java @@ -0,0 +1,94 @@ +/* + * 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.packet.features; + +import java.beans.ConstructorProperties; +import java.util.List; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.core.MediaType; + +import org.jclouds.Fallbacks; +import org.jclouds.collect.IterableWithMarker; +import org.jclouds.collect.PagedIterable; +import org.jclouds.http.functions.ParseJson; +import org.jclouds.json.Json; +import org.jclouds.packet.PacketApi; +import org.jclouds.packet.domain.Facility; +import org.jclouds.packet.domain.Href; +import org.jclouds.packet.domain.internal.PaginatedCollection; +import org.jclouds.packet.domain.options.ListOptions; +import org.jclouds.packet.filters.AddApiVersionToRequest; +import org.jclouds.packet.filters.AddXAuthTokenToRequest; +import org.jclouds.packet.functions.BaseToPagedIterable; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.Transform; + +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.inject.TypeLiteral; + +@Path("/facilities") +@Consumes(MediaType.APPLICATION_JSON) +@RequestFilters({ AddXAuthTokenToRequest.class, AddApiVersionToRequest.class} ) +public interface FacilityApi { + + @Named("facility:list") + @GET + @ResponseParser(ParseFacilities.class) + @Transform(ParseFacilities.ToPagedIterable.class) + @Fallback(Fallbacks.EmptyPagedIterableOnNotFoundOr404.class) + PagedIterable<Facility> list(); + + @Named("facility:list") + @GET + @ResponseParser(ParseFacilities.class) + @Fallback(Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404.class) + IterableWithMarker<Facility> list(ListOptions options); + + final class ParseFacilities extends ParseJson<ParseFacilities.Facilities> { + @Inject + ParseFacilities(Json json) { + super(json, TypeLiteral.get(Facilities.class)); + } + + private static class Facilities extends PaginatedCollection<Facility> { + @ConstructorProperties({ "facilities", "meta" }) + public Facilities(List<Facility> items, Meta meta) { + super(items, meta); + } + } + + private static class ToPagedIterable extends BaseToPagedIterable<Facility, ListOptions> { + @Inject ToPagedIterable(PacketApi api, Function<Href, ListOptions> hrefToOptions) { + super(api, hrefToOptions); + } + + @Override + protected IterableWithMarker<Facility> fetchPageUsingOptions(ListOptions options, Optional<Object> arg0) { + return api.facilityApi().list(options); + } + } + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/main/java/org/jclouds/packet/features/OperatingSystemApi.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/main/java/org/jclouds/packet/features/OperatingSystemApi.java b/providers/packet/src/main/java/org/jclouds/packet/features/OperatingSystemApi.java new file mode 100644 index 0000000..401b1e9 --- /dev/null +++ b/providers/packet/src/main/java/org/jclouds/packet/features/OperatingSystemApi.java @@ -0,0 +1,94 @@ +/* + * 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.packet.features; + +import java.beans.ConstructorProperties; +import java.util.List; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.core.MediaType; + +import org.jclouds.Fallbacks; +import org.jclouds.collect.IterableWithMarker; +import org.jclouds.collect.PagedIterable; +import org.jclouds.http.functions.ParseJson; +import org.jclouds.json.Json; +import org.jclouds.packet.PacketApi; +import org.jclouds.packet.domain.Href; +import org.jclouds.packet.domain.OperatingSystem; +import org.jclouds.packet.domain.internal.PaginatedCollection; +import org.jclouds.packet.domain.options.ListOptions; +import org.jclouds.packet.filters.AddApiVersionToRequest; +import org.jclouds.packet.filters.AddXAuthTokenToRequest; +import org.jclouds.packet.functions.BaseToPagedIterable; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.Transform; + +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.inject.TypeLiteral; + +@Path("/operating-systems") +@Consumes(MediaType.APPLICATION_JSON) +@RequestFilters({ AddXAuthTokenToRequest.class, AddApiVersionToRequest.class} ) +public interface OperatingSystemApi { + + @Named("operatingsystem:list") + @GET + @ResponseParser(ParseOperatingSystems.class) + @Transform(ParseOperatingSystems.ToPagedIterable.class) + @Fallback(Fallbacks.EmptyPagedIterableOnNotFoundOr404.class) + PagedIterable<OperatingSystem> list(); + + @Named("operatingsystem:list") + @GET + @ResponseParser(ParseOperatingSystems.class) + @Fallback(Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404.class) + IterableWithMarker<OperatingSystem> list(ListOptions options); + + final class ParseOperatingSystems extends ParseJson<ParseOperatingSystems.OperatingSystems> { + @Inject + ParseOperatingSystems(Json json) { + super(json, TypeLiteral.get(ParseOperatingSystems.OperatingSystems.class)); + } + + private static class OperatingSystems extends PaginatedCollection<OperatingSystem> { + @ConstructorProperties({ "operating_systems", "meta" }) + public OperatingSystems(List<OperatingSystem> items, Meta meta) { + super(items, meta); + } + } + + private static class ToPagedIterable extends BaseToPagedIterable<OperatingSystem, ListOptions> { + @Inject ToPagedIterable(PacketApi api, Function<Href, ListOptions> hrefToOptions) { + super(api, hrefToOptions); + } + + @Override + protected IterableWithMarker<OperatingSystem> fetchPageUsingOptions(ListOptions options, Optional<Object> arg0) { + return api.operatingSystemApi().list(options); + } + } + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/main/java/org/jclouds/packet/features/PlanApi.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/main/java/org/jclouds/packet/features/PlanApi.java b/providers/packet/src/main/java/org/jclouds/packet/features/PlanApi.java new file mode 100644 index 0000000..7ed5c3a --- /dev/null +++ b/providers/packet/src/main/java/org/jclouds/packet/features/PlanApi.java @@ -0,0 +1,94 @@ +/* + * 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.packet.features; + +import java.beans.ConstructorProperties; +import java.util.List; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.core.MediaType; + +import org.jclouds.Fallbacks; +import org.jclouds.collect.IterableWithMarker; +import org.jclouds.collect.PagedIterable; +import org.jclouds.http.functions.ParseJson; +import org.jclouds.json.Json; +import org.jclouds.packet.PacketApi; +import org.jclouds.packet.domain.Href; +import org.jclouds.packet.domain.Plan; +import org.jclouds.packet.domain.internal.PaginatedCollection; +import org.jclouds.packet.domain.options.ListOptions; +import org.jclouds.packet.filters.AddApiVersionToRequest; +import org.jclouds.packet.filters.AddXAuthTokenToRequest; +import org.jclouds.packet.functions.BaseToPagedIterable; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.Transform; + +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.inject.TypeLiteral; + +@Path("/plans") +@Consumes(MediaType.APPLICATION_JSON) +@RequestFilters({ AddXAuthTokenToRequest.class, AddApiVersionToRequest.class} ) +public interface PlanApi { + + @Named("plan:list") + @GET + @ResponseParser(ParsePlans.class) + @Transform(ParsePlans.ToPagedIterable.class) + @Fallback(Fallbacks.EmptyPagedIterableOnNotFoundOr404.class) + PagedIterable<Plan> list(); + + @Named("plan:list") + @GET + @ResponseParser(ParsePlans.class) + @Fallback(Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404.class) + IterableWithMarker<Plan> list(ListOptions options); + + final class ParsePlans extends ParseJson<ParsePlans.Plans> { + @Inject + ParsePlans(Json json) { + super(json, TypeLiteral.get(ParsePlans.Plans.class)); + } + + private static class Plans extends PaginatedCollection<Plan> { + @ConstructorProperties({ "plans", "meta" }) + public Plans(List<Plan> items, Meta meta) { + super(items, meta); + } + } + + private static class ToPagedIterable extends BaseToPagedIterable<Plan, ListOptions> { + @Inject ToPagedIterable(PacketApi api, Function<Href, ListOptions> hrefToOptions) { + super(api, hrefToOptions); + } + + @Override + protected IterableWithMarker<Plan> fetchPageUsingOptions(ListOptions options, Optional<Object> arg0) { + return api.planApi().list(options); + } + } + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/main/java/org/jclouds/packet/features/ProjectApi.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/main/java/org/jclouds/packet/features/ProjectApi.java b/providers/packet/src/main/java/org/jclouds/packet/features/ProjectApi.java index afdf1ef..9da50d0 100644 --- a/providers/packet/src/main/java/org/jclouds/packet/features/ProjectApi.java +++ b/providers/packet/src/main/java/org/jclouds/packet/features/ProjectApi.java @@ -53,7 +53,6 @@ import com.google.inject.TypeLiteral; @RequestFilters({ AddXAuthTokenToRequest.class, AddApiVersionToRequest.class} ) public interface ProjectApi { - @Named("project:list") @GET @ResponseParser(ParseProjects.class) @@ -81,8 +80,8 @@ public interface ProjectApi { } private static class ToPagedIterable extends BaseToPagedIterable<Project, ListOptions> { - @Inject ToPagedIterable(PacketApi api, Function<Href, ListOptions> linkToOptions) { - super(api, linkToOptions); + @Inject ToPagedIterable(PacketApi api, Function<Href, ListOptions> hrefToOptions) { + super(api, hrefToOptions); } @Override @@ -91,4 +90,5 @@ public interface ProjectApi { } } } + } http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/main/java/org/jclouds/packet/features/SshKeyApi.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/main/java/org/jclouds/packet/features/SshKeyApi.java b/providers/packet/src/main/java/org/jclouds/packet/features/SshKeyApi.java new file mode 100644 index 0000000..cd22107 --- /dev/null +++ b/providers/packet/src/main/java/org/jclouds/packet/features/SshKeyApi.java @@ -0,0 +1,122 @@ +/* + * 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.packet.features; + +import java.beans.ConstructorProperties; +import java.util.List; + +import javax.inject.Inject; +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.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.jclouds.Fallbacks; +import org.jclouds.Fallbacks.NullOnNotFoundOr404; +import org.jclouds.Fallbacks.VoidOnNotFoundOr404; +import org.jclouds.collect.IterableWithMarker; +import org.jclouds.collect.PagedIterable; +import org.jclouds.http.functions.ParseJson; +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.json.Json; +import org.jclouds.packet.PacketApi; +import org.jclouds.packet.domain.Href; +import org.jclouds.packet.domain.SshKey; +import org.jclouds.packet.domain.internal.PaginatedCollection; +import org.jclouds.packet.domain.options.ListOptions; +import org.jclouds.packet.filters.AddApiVersionToRequest; +import org.jclouds.packet.filters.AddXAuthTokenToRequest; +import org.jclouds.packet.functions.BaseToPagedIterable; +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 com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.inject.TypeLiteral; + +@Path("/ssh-keys") +@Consumes(MediaType.APPLICATION_JSON) +@RequestFilters({ AddXAuthTokenToRequest.class, AddApiVersionToRequest.class} ) +public interface SshKeyApi { + + @Named("sshkey:list") + @GET + @ResponseParser(ParseSshKeys.class) + @Transform(ParseSshKeys.ToPagedIterable.class) + @Fallback(Fallbacks.EmptyPagedIterableOnNotFoundOr404.class) + PagedIterable<SshKey> list(); + + @Named("sshkey:list") + @GET + @ResponseParser(ParseSshKeys.class) + @Fallback(Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404.class) + IterableWithMarker<SshKey> list(ListOptions options); + + final class ParseSshKeys extends ParseJson<ParseSshKeys.SshKeys> { + @Inject + ParseSshKeys(Json json) { + super(json, TypeLiteral.get(ParseSshKeys.SshKeys.class)); + } + + private static class SshKeys extends PaginatedCollection<SshKey> { + @ConstructorProperties({ "ssh_keys", "meta" }) + public SshKeys(List<SshKey> items, Meta meta) { + super(items, meta); + } + } + + private static class ToPagedIterable extends BaseToPagedIterable<SshKey, ListOptions> { + @Inject ToPagedIterable(PacketApi api, Function<Href, ListOptions> hrefToOptions) { + super(api, hrefToOptions); + } + + @Override + protected IterableWithMarker<SshKey> fetchPageUsingOptions(ListOptions options, Optional<Object> arg0) { + return api.sshKeyApi().list(options); + } + } + } + + @Named("sshkey:create") + @POST + @Produces(MediaType.APPLICATION_JSON) + @MapBinder(BindToJsonPayload.class) + SshKey create(@PayloadParam("label") String label, @PayloadParam("key") String key); + + @Named("sshkey:get") + @GET + @Path("/{id}") + @Fallback(NullOnNotFoundOr404.class) + @Nullable + SshKey get(@PathParam("id") String id); + + @Named("sshkey:delete") + @DELETE + @Path("/{id}") + @Fallback(VoidOnNotFoundOr404.class) + void delete(@PathParam("id") String id); +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/main/java/org/jclouds/packet/functions/BaseToPagedIterable.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/main/java/org/jclouds/packet/functions/BaseToPagedIterable.java b/providers/packet/src/main/java/org/jclouds/packet/functions/BaseToPagedIterable.java index c5c275b..abc59a2 100644 --- a/providers/packet/src/main/java/org/jclouds/packet/functions/BaseToPagedIterable.java +++ b/providers/packet/src/main/java/org/jclouds/packet/functions/BaseToPagedIterable.java @@ -35,12 +35,12 @@ import com.google.common.base.Optional; */ public abstract class BaseToPagedIterable<T, O extends ListOptions> extends Arg0ToPagedIterable<T, BaseToPagedIterable<T, O>> { - private final Function<Href, O> linkToOptions; + private final Function<Href, O> hrefToOptions; protected final PacketApi api; - @Inject protected BaseToPagedIterable(PacketApi api, Function<Href, O> linkToOptions) { + @Inject protected BaseToPagedIterable(PacketApi api, Function<Href, O> hrefToOptions) { this.api = api; - this.linkToOptions = linkToOptions; + this.hrefToOptions = hrefToOptions; } protected abstract IterableWithMarker<T> fetchPageUsingOptions(O options, Optional<Object> arg0); @@ -50,7 +50,7 @@ public abstract class BaseToPagedIterable<T, O extends ListOptions> extends return new Function<Object, IterableWithMarker<T>>() { @Override public IterableWithMarker<T> apply(Object input) { - O nextOptions = linkToOptions.apply(Href.class.cast(input)); + O nextOptions = hrefToOptions.apply(Href.class.cast(input)); return fetchPageUsingOptions(nextOptions, arg0); } }; http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/main/java/org/jclouds/packet/functions/HrefToListOptions.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/main/java/org/jclouds/packet/functions/HrefToListOptions.java b/providers/packet/src/main/java/org/jclouds/packet/functions/HrefToListOptions.java new file mode 100644 index 0000000..d380b26 --- /dev/null +++ b/providers/packet/src/main/java/org/jclouds/packet/functions/HrefToListOptions.java @@ -0,0 +1,63 @@ +/* + * 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.packet.functions; + +import java.net.URI; + +import org.jclouds.packet.domain.Href; +import org.jclouds.packet.domain.options.ListOptions; + +import com.google.common.base.Function; +import com.google.common.collect.Multimap; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Strings.emptyToNull; +import static com.google.common.collect.Iterables.getFirst; +import static org.jclouds.http.utils.Queries.queryParser; +import static org.jclouds.packet.domain.options.ListOptions.PAGE_PARAM; +import static org.jclouds.packet.domain.options.ListOptions.PER_PAGE_PARAM; + +/** + * Transforms an href returned by the API into a {@link ListOptions} that can be + * used to perform a request to get another page of a paginated list. + */ +public class HrefToListOptions implements Function<Href, ListOptions> { + + @Override + public ListOptions apply(Href input) { + checkNotNull(input, "input cannot be null"); + + Multimap<String, String> queryParams = queryParser().apply(URI.create(input.href()).getQuery()); + String nextPage = getFirstOrNull(PAGE_PARAM, queryParams); + String nextPerPage = getFirstOrNull(PER_PAGE_PARAM, queryParams); + + ListOptions options = new ListOptions(); + if (nextPage != null) { + options.page(Integer.parseInt(nextPage)); + } + if (nextPerPage != null) { + options.perPage(Integer.parseInt(nextPerPage)); + } + + return options; + } + + public static String getFirstOrNull(String key, Multimap<String, String> params) { + return params.containsKey(key) ? emptyToNull(getFirst(params.get(key), null)) : null; + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/main/java/org/jclouds/packet/functions/LinkToListOptions.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/main/java/org/jclouds/packet/functions/LinkToListOptions.java b/providers/packet/src/main/java/org/jclouds/packet/functions/LinkToListOptions.java deleted file mode 100644 index 4aef811..0000000 --- a/providers/packet/src/main/java/org/jclouds/packet/functions/LinkToListOptions.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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.packet.functions; - -import java.net.URI; - -import org.jclouds.packet.domain.Href; -import org.jclouds.packet.domain.options.ListOptions; - -import com.google.common.base.Function; -import com.google.common.collect.Multimap; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Strings.emptyToNull; -import static com.google.common.collect.Iterables.getFirst; -import static org.jclouds.http.utils.Queries.queryParser; -import static org.jclouds.packet.domain.options.ListOptions.PAGE_PARAM; -import static org.jclouds.packet.domain.options.ListOptions.PER_PAGE_PARAM; - -/** - * Transforms an href returned by the API into a {@link ListOptions} that can be - * used to perform a request to get another page of a paginated list. - */ -public class LinkToListOptions implements Function<Href, ListOptions> { - - @Override - public ListOptions apply(Href input) { - checkNotNull(input, "input cannot be null"); - - Multimap<String, String> queryParams = queryParser().apply(URI.create(input.href()).getQuery()); - String nextPage = getFirstOrNull(PAGE_PARAM, queryParams); - String nextPerPage = getFirstOrNull(PER_PAGE_PARAM, queryParams); - - ListOptions options = new ListOptions(); - if (nextPage != null) { - options.page(Integer.parseInt(nextPage)); - } - if (nextPerPage != null) { - options.perPage(Integer.parseInt(nextPerPage)); - } - - return options; - } - - public static String getFirstOrNull(String key, Multimap<String, String> params) { - return params.containsKey(key) ? emptyToNull(getFirst(params.get(key), null)) : null; - } - -} http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/test/java/org/jclouds/packet/features/DeviceApiLiveTest.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/test/java/org/jclouds/packet/features/DeviceApiLiveTest.java b/providers/packet/src/test/java/org/jclouds/packet/features/DeviceApiLiveTest.java new file mode 100644 index 0000000..36c08f1 --- /dev/null +++ b/providers/packet/src/test/java/org/jclouds/packet/features/DeviceApiLiveTest.java @@ -0,0 +1,138 @@ +/* + * 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.packet.features; + +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +import org.jclouds.packet.compute.internal.BasePacketApiLiveTest; +import org.jclouds.packet.domain.ActionType; +import org.jclouds.packet.domain.BillingCycle; +import org.jclouds.packet.domain.Device; +import org.jclouds.packet.domain.SshKey; +import org.jclouds.ssh.SshKeys; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; + +import static org.jclouds.packet.domain.options.ListOptions.Builder.page; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; +import static org.testng.util.Strings.isNullOrEmpty; + +@Test(groups = "live", testName = "DeviceApiLiveTest") +public class DeviceApiLiveTest extends BasePacketApiLiveTest { + + private SshKey sshKey; + private String deviceId; + + @BeforeClass + public void setupDevice() { + Map<String, String> keyPair = SshKeys.generate(); + sshKey = api.sshKeyApi().create(prefix + "-device-livetest", keyPair.get("public")); + } + + @AfterClass(alwaysRun = true) + public void tearDown() { + if (sshKey != null) { + api.sshKeyApi().delete(sshKey.id()); + } + } + + public void testCreate() { + Device deviceCreated = api().create( + Device.CreateDevice.builder() + .hostname(prefix + "-device-livetest") + .plan("baremetal_0") + .billingCycle(BillingCycle.HOURLY.value()) + .facility("ewr1") + .features(ImmutableMap.<String, String>of()) + .operatingSystem("ubuntu_16_04") + .locked(false) + .userdata("") + .tags(ImmutableSet.<String> of()) + .build() + ); + deviceId = deviceCreated.id(); + assertNodeRunning(deviceId); + Device device = api().get(deviceId); + assertNotNull(device, "Device must not be null"); + } + + @Test(groups = "live", dependsOnMethods = "testCreate") + public void testReboot() { + api().actions(deviceId, ActionType.REBOOT); + assertNodeRunning(deviceId); + } + + @Test(groups = "live", dependsOnMethods = "testReboot") + public void testPowerOff() { + api().actions(deviceId, ActionType.POWER_OFF); + assertNodeTerminated(deviceId); + } + + @Test(groups = "live", dependsOnMethods = "testPowerOff") + public void testPowerOn() { + api().actions(deviceId, ActionType.POWER_ON); + assertNodeRunning(deviceId); + } + + @Test(dependsOnMethods = "testCreate") + public void testList() { + final AtomicInteger found = new AtomicInteger(0); + assertTrue(Iterables.all(api().list().concat(), new Predicate<Device>() { + @Override + public boolean apply(Device input) { + found.incrementAndGet(); + return !isNullOrEmpty(input.id()); + } + }), "All devices must have the 'id' field populated"); + assertTrue(found.get() > 0, "Expected some devices to be returned"); + } + + @Test(dependsOnMethods = "testCreate") + public void testListOnePage() { + final AtomicInteger found = new AtomicInteger(0); + assertTrue(api().list(page(1).perPage(5)).allMatch(new Predicate<Device>() { + @Override + public boolean apply(Device input) { + found.incrementAndGet(); + return !isNullOrEmpty(input.id()); + } + }), "All devices must have the 'id' field populated"); + assertTrue(found.get() > 0, "Expected some devices to be returned"); + } + + @Test(dependsOnMethods = "testList", alwaysRun = true) + public void testDelete() throws InterruptedException { + if (deviceId != null) { + api().delete(deviceId); + assertNodeTerminated(deviceId); + assertNull(api().get(deviceId)); + } + } + + private DeviceApi api() { + return api.deviceApi(identity); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/test/java/org/jclouds/packet/features/DeviceApiMockTest.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/test/java/org/jclouds/packet/features/DeviceApiMockTest.java b/providers/packet/src/test/java/org/jclouds/packet/features/DeviceApiMockTest.java new file mode 100644 index 0000000..705955c --- /dev/null +++ b/providers/packet/src/test/java/org/jclouds/packet/features/DeviceApiMockTest.java @@ -0,0 +1,184 @@ +/* + * 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.packet.features; + +import org.jclouds.packet.compute.internal.BasePacketApiMockTest; +import org.jclouds.packet.domain.ActionType; +import org.jclouds.packet.domain.BillingCycle; +import org.jclouds.packet.domain.Device; +import org.jclouds.packet.domain.Device.CreateDevice; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +import static com.google.common.collect.Iterables.isEmpty; +import static com.google.common.collect.Iterables.size; +import static org.jclouds.packet.domain.options.ListOptions.Builder.page; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; + +@Test(groups = "unit", testName = "DeviceApiMockTest", singleThreaded = true) +public class DeviceApiMockTest extends BasePacketApiMockTest { + + public void testListDevices() throws InterruptedException { + server.enqueue(jsonResponse("/devices-first.json")); + server.enqueue(jsonResponse("/devices-last.json")); + + Iterable<Device> devices = api.deviceApi("93907f48-adfe-43ed-ad89-0e6e83721a54").list().concat(); + + assertEquals(size(devices), 7); // Force the PagedIterable to advance + assertEquals(server.getRequestCount(), 2); + + assertSent(server, "GET", "/projects/93907f48-adfe-43ed-ad89-0e6e83721a54/devices"); + assertSent(server, "GET", "/projects/93907f48-adfe-43ed-ad89-0e6e83721a54/devices?page=2"); + } + + public void testListDevicesReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Device> devices = api.deviceApi("93907f48-adfe-43ed-ad89-0e6e83721a54").list().concat(); + + assertTrue(isEmpty(devices)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/projects/93907f48-adfe-43ed-ad89-0e6e83721a54/devices"); + } + + public void testListDevicesWithOptions() throws InterruptedException { + server.enqueue(jsonResponse("/devices-first.json")); + + Iterable<Device> devices = api.deviceApi("93907f48-adfe-43ed-ad89-0e6e83721a54").list(page(1).perPage(5)); + + assertEquals(size(devices), 5); + assertEquals(server.getRequestCount(), 1); + + assertSent(server, "GET", "/projects/93907f48-adfe-43ed-ad89-0e6e83721a54/devices?page=1&per_page=5"); + } + + public void testListDevicesWithOptionsReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Device> actions = api.deviceApi("93907f48-adfe-43ed-ad89-0e6e83721a54").list(page(1).perPage(5)); + + assertTrue(isEmpty(actions)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/projects/93907f48-adfe-43ed-ad89-0e6e83721a54/devices?page=1&per_page=5"); + } + + public void testGetDevice() throws InterruptedException { + server.enqueue(jsonResponse("/device.json")); + + Device device = api.deviceApi("93907f48-adfe-43ed-ad89-0e6e83721a54").get("1"); + + assertEquals(device, objectFromResource("/device.json", Device.class)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/projects/93907f48-adfe-43ed-ad89-0e6e83721a54/devices/1"); + } + + public void testGetDeviceReturns404() throws InterruptedException { + server.enqueue(response404()); + + Device device = api.deviceApi("93907f48-adfe-43ed-ad89-0e6e83721a54").get("1"); + + assertNull(device); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/projects/93907f48-adfe-43ed-ad89-0e6e83721a54/devices/1"); + } + + public void testCreateDevice() throws InterruptedException { + server.enqueue(jsonResponse("/device-create-res.json")); + + Device device = api.deviceApi("93907f48-adfe-43ed-ad89-0e6e83721a54").create( + CreateDevice.builder() + .hostname("jclouds-device-livetest") + .plan("baremetal_0") + .billingCycle(BillingCycle.HOURLY.value()) + .facility("ewr1") + .features(ImmutableMap.<String, String>of()) + .operatingSystem("ubuntu_16_04") + .locked(false) + .userdata("") + .tags(ImmutableSet.<String> of()) + .build() + ); + + assertEquals(device, objectFromResource("/device-create-res.json", Device.class)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "POST", "/projects/93907f48-adfe-43ed-ad89-0e6e83721a54/devices", stringFromResource("/device-create-req.json")); + } + + public void testDeleteDevice() throws InterruptedException { + server.enqueue(response204()); + + api.deviceApi("93907f48-adfe-43ed-ad89-0e6e83721a54").delete("1"); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "DELETE", "/projects/93907f48-adfe-43ed-ad89-0e6e83721a54/devices/1"); + } + + public void testDeleteDeviceReturns404() throws InterruptedException { + server.enqueue(response404()); + + api.deviceApi("93907f48-adfe-43ed-ad89-0e6e83721a54").delete("1"); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "DELETE", "/projects/93907f48-adfe-43ed-ad89-0e6e83721a54/devices/1"); + } + + public void testActionPowerOn() throws InterruptedException { + server.enqueue(jsonResponse("/power-on.json")); + + api.deviceApi("93907f48-adfe-43ed-ad89-0e6e83721a54").actions("deviceId", ActionType.POWER_ON); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "POST", "/projects/93907f48-adfe-43ed-ad89-0e6e83721a54/devices/deviceId/actions"); + } + + public void testActionPowerOff() throws InterruptedException { + server.enqueue(jsonResponse("/power-off.json")); + + api.deviceApi("93907f48-adfe-43ed-ad89-0e6e83721a54").actions("deviceId", ActionType.POWER_OFF); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "POST", "/projects/93907f48-adfe-43ed-ad89-0e6e83721a54/devices/deviceId/actions"); + } + + public void testActionReboot() throws InterruptedException { + server.enqueue(jsonResponse("/reboot.json")); + + api.deviceApi("93907f48-adfe-43ed-ad89-0e6e83721a54").actions("deviceId", ActionType.REBOOT); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "POST", "/projects/93907f48-adfe-43ed-ad89-0e6e83721a54/devices/deviceId/actions"); + } + + public void testActionRescue() throws InterruptedException { + server.enqueue(jsonResponse("/rescue.json")); + + api.deviceApi("93907f48-adfe-43ed-ad89-0e6e83721a54").actions("deviceId", ActionType.RESCUE); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "POST", "/projects/93907f48-adfe-43ed-ad89-0e6e83721a54/devices/deviceId/actions"); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/test/java/org/jclouds/packet/features/FacilityApiLiveTest.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/test/java/org/jclouds/packet/features/FacilityApiLiveTest.java b/providers/packet/src/test/java/org/jclouds/packet/features/FacilityApiLiveTest.java new file mode 100644 index 0000000..95fc857 --- /dev/null +++ b/providers/packet/src/test/java/org/jclouds/packet/features/FacilityApiLiveTest.java @@ -0,0 +1,62 @@ +/* + * 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.packet.features; + +import java.util.concurrent.atomic.AtomicInteger; + +import org.jclouds.packet.compute.internal.BasePacketApiMockTest; +import org.jclouds.packet.domain.Facility; +import org.testng.annotations.Test; + +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; + +import static org.jclouds.packet.domain.options.ListOptions.Builder.page; +import static org.testng.Assert.assertTrue; +import static org.testng.util.Strings.isNullOrEmpty; + +@Test(groups = "live", testName = "FacilityApiLiveTest") +public class FacilityApiLiveTest extends BasePacketApiMockTest { + + public void testList() { + final AtomicInteger found = new AtomicInteger(0); + assertTrue(Iterables.all(api().list().concat(), new Predicate<Facility>() { + @Override + public boolean apply(Facility input) { + found.incrementAndGet(); + return !isNullOrEmpty(input.id()); + } + }), "All facilities must have the 'id' field populated"); + assertTrue(found.get() > 0, "Expected some facilities to be returned"); + } + + public void testListOnePage() { + final AtomicInteger found = new AtomicInteger(0); + assertTrue(api().list(page(1).perPage(5)).allMatch(new Predicate<Facility>() { + @Override + public boolean apply(Facility input) { + found.incrementAndGet(); + return !isNullOrEmpty(input.id()); + } + }), "All facilities must have the 'id' field populated"); + assertTrue(found.get() > 0, "Expected some facilities to be returned"); + } + + private FacilityApi api() { + return api.facilityApi(); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/test/java/org/jclouds/packet/features/FacilityApiMockTest.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/test/java/org/jclouds/packet/features/FacilityApiMockTest.java b/providers/packet/src/test/java/org/jclouds/packet/features/FacilityApiMockTest.java new file mode 100644 index 0000000..764fa7b --- /dev/null +++ b/providers/packet/src/test/java/org/jclouds/packet/features/FacilityApiMockTest.java @@ -0,0 +1,78 @@ +/* + * 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.packet.features; + +import org.jclouds.packet.compute.internal.BasePacketApiMockTest; +import org.jclouds.packet.domain.Facility; +import org.testng.annotations.Test; + +import static com.google.common.collect.Iterables.isEmpty; +import static com.google.common.collect.Iterables.size; +import static org.jclouds.packet.domain.options.ListOptions.Builder.page; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +@Test(groups = "unit", testName = "FacilityApiMockTest", singleThreaded = true) +public class FacilityApiMockTest extends BasePacketApiMockTest { + + public void testListFacilities() throws InterruptedException { + server.enqueue(jsonResponse("/facilities-first.json")); + server.enqueue(jsonResponse("/facilities-last.json")); + + Iterable<Facility> facilities = api.facilityApi().list().concat(); + + assertEquals(size(facilities), 3); // Force the PagedIterable to advance + assertEquals(server.getRequestCount(), 2); + + assertSent(server, "GET", "/facilities"); + assertSent(server, "GET", "/facilities?page=2"); + } + + public void testListFacilitiesReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Facility> facilities = api.facilityApi().list().concat(); + + assertTrue(isEmpty(facilities)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/facilities"); + } + + public void testListFacilitiesWithOptions() throws InterruptedException { + server.enqueue(jsonResponse("/facilities-first.json")); + + Iterable<Facility> actions = api.facilityApi().list(page(1).perPage(2)); + + assertEquals(size(actions), 2); + assertEquals(server.getRequestCount(), 1); + + assertSent(server, "GET", "/facilities?page=1&per_page=2"); + } + + public void testListFacilitiesWithOptionsReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Facility> actions = api.facilityApi().list(page(1).perPage(2)); + + assertTrue(isEmpty(actions)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/facilities?page=1&per_page=2"); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/test/java/org/jclouds/packet/features/OperatingSystemApiLiveTest.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/test/java/org/jclouds/packet/features/OperatingSystemApiLiveTest.java b/providers/packet/src/test/java/org/jclouds/packet/features/OperatingSystemApiLiveTest.java new file mode 100644 index 0000000..fd96a7e --- /dev/null +++ b/providers/packet/src/test/java/org/jclouds/packet/features/OperatingSystemApiLiveTest.java @@ -0,0 +1,62 @@ +/* + * 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.packet.features; + +import java.util.concurrent.atomic.AtomicInteger; + +import org.jclouds.packet.compute.internal.BasePacketApiLiveTest; +import org.jclouds.packet.domain.OperatingSystem; +import org.testng.annotations.Test; + +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; + +import static org.jclouds.packet.domain.options.ListOptions.Builder.page; +import static org.testng.Assert.assertTrue; +import static org.testng.util.Strings.isNullOrEmpty; + +@Test(groups = "live", testName = "OperatingSystemApiLiveTest") +public class OperatingSystemApiLiveTest extends BasePacketApiLiveTest { + + public void testList() { + final AtomicInteger found = new AtomicInteger(0); + assertTrue(Iterables.all(api().list().concat(), new Predicate<OperatingSystem>() { + @Override + public boolean apply(OperatingSystem input) { + found.incrementAndGet(); + return !isNullOrEmpty(input.id()); + } + }), "All operating systems must have the 'id' field populated"); + assertTrue(found.get() > 0, "Expected some operating systems to be returned"); + } + + public void testListOnePage() { + final AtomicInteger found = new AtomicInteger(0); + assertTrue(api().list(page(1).perPage(5)).allMatch(new Predicate<OperatingSystem>() { + @Override + public boolean apply(OperatingSystem input) { + found.incrementAndGet(); + return !isNullOrEmpty(input.id()); + } + }), "All operating systems must have the 'id' field populated"); + assertTrue(found.get() > 0, "Expected some operating systems to be returned"); + } + + private OperatingSystemApi api() { + return api.operatingSystemApi(); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/test/java/org/jclouds/packet/features/OperatingSystemApiMockTest.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/test/java/org/jclouds/packet/features/OperatingSystemApiMockTest.java b/providers/packet/src/test/java/org/jclouds/packet/features/OperatingSystemApiMockTest.java new file mode 100644 index 0000000..c0c332b --- /dev/null +++ b/providers/packet/src/test/java/org/jclouds/packet/features/OperatingSystemApiMockTest.java @@ -0,0 +1,78 @@ +/* + * 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.packet.features; + +import org.jclouds.packet.compute.internal.BasePacketApiMockTest; +import org.jclouds.packet.domain.OperatingSystem; +import org.testng.annotations.Test; + +import static com.google.common.collect.Iterables.isEmpty; +import static com.google.common.collect.Iterables.size; +import static org.jclouds.packet.domain.options.ListOptions.Builder.page; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +@Test(groups = "unit", testName = "OperatingSystemApiMockTest", singleThreaded = true) +public class OperatingSystemApiMockTest extends BasePacketApiMockTest { + + public void testListOperatingSystems() throws InterruptedException { + + server.enqueue(jsonResponse("/operatingSystems-first.json")); + server.enqueue(jsonResponse("/operatingSystems-last.json")); + + Iterable<OperatingSystem> operatingSystems = api.operatingSystemApi().list().concat(); + assertEquals(size(operatingSystems), 14); // Force the PagedIterable to advance + assertEquals(server.getRequestCount(), 2); + + assertSent(server, "GET", "/operating-systems"); + assertSent(server, "GET", "/operating-systems?page=2"); + } + + public void testListOperatingSystemsReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<OperatingSystem> operatingSystems = api.operatingSystemApi().list().concat(); + + assertTrue(isEmpty(operatingSystems)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/operating-systems"); + } + + public void testListOperatingSystemsWithOptions() throws InterruptedException { + server.enqueue(jsonResponse("/operatingSystems-first.json")); + + Iterable<OperatingSystem> operatingSystems = api.operatingSystemApi().list(page(1).perPage(5)); + + assertEquals(size(operatingSystems), 7); + assertEquals(server.getRequestCount(), 1); + + assertSent(server, "GET", "/operating-systems?page=1&per_page=5"); + } + + public void testListOperatingSystemsWithOptionsReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<OperatingSystem> operatingSystems = api.operatingSystemApi().list(page(1).perPage(5)); + + assertTrue(isEmpty(operatingSystems)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/operating-systems?page=1&per_page=5"); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/test/java/org/jclouds/packet/features/PlanApiLiveTest.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/test/java/org/jclouds/packet/features/PlanApiLiveTest.java b/providers/packet/src/test/java/org/jclouds/packet/features/PlanApiLiveTest.java new file mode 100644 index 0000000..1b66e04 --- /dev/null +++ b/providers/packet/src/test/java/org/jclouds/packet/features/PlanApiLiveTest.java @@ -0,0 +1,62 @@ +/* + * 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.packet.features; + +import java.util.concurrent.atomic.AtomicInteger; + +import org.jclouds.packet.compute.internal.BasePacketApiLiveTest; +import org.jclouds.packet.domain.Plan; +import org.testng.annotations.Test; + +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; + +import static org.jclouds.packet.domain.options.ListOptions.Builder.page; +import static org.testng.Assert.assertTrue; +import static org.testng.util.Strings.isNullOrEmpty; + +@Test(groups = "live", testName = "PlanApiLiveTest") +public class PlanApiLiveTest extends BasePacketApiLiveTest { + + public void testList() { + final AtomicInteger found = new AtomicInteger(0); + assertTrue(Iterables.all(api().list().concat(), new Predicate<Plan>() { + @Override + public boolean apply(Plan input) { + found.incrementAndGet(); + return !isNullOrEmpty(input.id()); + } + }), "All plans must have the 'id' field populated"); + assertTrue(found.get() > 0, "Expected some plans to be returned"); + } + + public void testListOnePage() { + final AtomicInteger found = new AtomicInteger(0); + assertTrue(api().list(page(1).perPage(5)).allMatch(new Predicate<Plan>() { + @Override + public boolean apply(Plan input) { + found.incrementAndGet(); + return !isNullOrEmpty(input.id()); + } + }), "All plans must have the 'id' field populated"); + assertTrue(found.get() > 0, "Expected some plans to be returned"); + } + + private PlanApi api() { + return api.planApi(); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/test/java/org/jclouds/packet/features/PlanApiMockTest.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/test/java/org/jclouds/packet/features/PlanApiMockTest.java b/providers/packet/src/test/java/org/jclouds/packet/features/PlanApiMockTest.java new file mode 100644 index 0000000..82683c8 --- /dev/null +++ b/providers/packet/src/test/java/org/jclouds/packet/features/PlanApiMockTest.java @@ -0,0 +1,78 @@ +/* + * 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.packet.features; + +import org.jclouds.packet.compute.internal.BasePacketApiMockTest; +import org.jclouds.packet.domain.Plan; +import org.testng.annotations.Test; + +import static com.google.common.collect.Iterables.isEmpty; +import static com.google.common.collect.Iterables.size; +import static org.jclouds.packet.domain.options.ListOptions.Builder.page; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +@Test(groups = "unit", testName = "PlanApiMockTest", singleThreaded = true) +public class PlanApiMockTest extends BasePacketApiMockTest { + + public void testListPlans() throws InterruptedException { + server.enqueue(jsonResponse("/plans-first.json")); + server.enqueue(jsonResponse("/plans-last.json")); + + Iterable<Plan> plans = api.planApi().list().concat(); + + assertEquals(size(plans), 7); // Force the PagedIterable to advance + assertEquals(server.getRequestCount(), 2); + + assertSent(server, "GET", "/plans"); + assertSent(server, "GET", "/plans?page=2"); + } + + public void testListPlansReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Plan> plans = api.planApi().list().concat(); + + assertTrue(isEmpty(plans)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/plans"); + } + + public void testListPlansWithOptions() throws InterruptedException { + server.enqueue(jsonResponse("/plans-first.json")); + + Iterable<Plan> plans = api.planApi().list(page(1).perPage(5)); + + assertEquals(size(plans), 4); + assertEquals(server.getRequestCount(), 1); + + assertSent(server, "GET", "/plans?page=1&per_page=5"); + } + + public void testListPlansWithOptionsReturns404() throws InterruptedException { + server.enqueue(response404()); + + Iterable<Plan> plans = api.planApi().list(page(1).perPage(5)); + + assertTrue(isEmpty(plans)); + + assertEquals(server.getRequestCount(), 1); + assertSent(server, "GET", "/plans?page=1&per_page=5"); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/test/java/org/jclouds/packet/features/ProjectApiLiveTest.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/test/java/org/jclouds/packet/features/ProjectApiLiveTest.java b/providers/packet/src/test/java/org/jclouds/packet/features/ProjectApiLiveTest.java index 133e5ef..65fba8f 100644 --- a/providers/packet/src/test/java/org/jclouds/packet/features/ProjectApiLiveTest.java +++ b/providers/packet/src/test/java/org/jclouds/packet/features/ProjectApiLiveTest.java @@ -32,7 +32,7 @@ import static org.testng.util.Strings.isNullOrEmpty; @Test(groups = "live", testName = "ProjectApiLiveTest") public class ProjectApiLiveTest extends BasePacketApiLiveTest { - public void testListProjects() { + public void testList() { final AtomicInteger found = new AtomicInteger(0); assertTrue(Iterables.all(api().list().concat(), new Predicate<Project>() { @Override @@ -43,8 +43,8 @@ public class ProjectApiLiveTest extends BasePacketApiLiveTest { }), "All projects must have the 'id' field populated"); assertTrue(found.get() > 0, "Expected some projects to be returned"); } - - public void testListActionsOnePage() { + + public void testListOnePage() { final AtomicInteger found = new AtomicInteger(0); assertTrue(api().list(page(1).perPage(5)).allMatch(new Predicate<Project>() { @Override @@ -55,7 +55,6 @@ public class ProjectApiLiveTest extends BasePacketApiLiveTest { }), "All projects must have the 'id' field populated"); assertTrue(found.get() > 0, "Expected some projects to be returned"); } - private ProjectApi api() { return api.projectApi(); http://git-wip-us.apache.org/repos/asf/jclouds/blob/49f1d076/providers/packet/src/test/java/org/jclouds/packet/features/ProjectApiMockTest.java ---------------------------------------------------------------------- diff --git a/providers/packet/src/test/java/org/jclouds/packet/features/ProjectApiMockTest.java b/providers/packet/src/test/java/org/jclouds/packet/features/ProjectApiMockTest.java index 2899020..d972395 100644 --- a/providers/packet/src/test/java/org/jclouds/packet/features/ProjectApiMockTest.java +++ b/providers/packet/src/test/java/org/jclouds/packet/features/ProjectApiMockTest.java @@ -74,6 +74,5 @@ public class ProjectApiMockTest extends BasePacketApiMockTest { assertEquals(server.getRequestCount(), 1); assertSent(server, "GET", "/projects?page=1&per_page=5"); } - }
