You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2017/02/02 14:34:25 UTC
[8/9] jclouds-labs git commit: Add remaining features to support the
abstraction
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-labs/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/a812591f
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/a812591f
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/a812591f
Branch: refs/heads/2.0.x
Commit: a812591f2387b2809e404b83e2af8ed07aa6b95d
Parents: 86bfeab
Author: Andrea Turli <an...@gmail.com>
Authored: Wed Jan 18 19:13:28 2017 +0100
Committer: Ignasi Barrera <na...@apache.org>
Committed: Thu Feb 2 15:23:25 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 +++++
packet/src/test/resources/device.json | 278 ++++++
packet/src/test/resources/devices-first.json | 910 +++++++++++++++++++
packet/src/test/resources/devices-last.json | 376 ++++++++
packet/src/test/resources/devices.json | 282 ++++++
packet/src/test/resources/facilities-first.json | 39 +
packet/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 +++
packet/src/test/resources/operatingSystems.json | 166 ++++
packet/src/test/resources/plans-first.json | 222 +++++
packet/src/test/resources/plans-last.json | 98 ++
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 +-
packet/src/test/resources/reboot.json | 3 +
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 +
packet/src/test/resources/sshKeys-first.json | 80 ++
packet/src/test/resources/sshKeys-last.json | 56 ++
packet/src/test/resources/sshKeys.json | 16 +
packet/src/test/resources/user.json | 19 +
54 files changed, 5244 insertions(+), 138 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a812591f/packet/src/main/java/org/jclouds/packet/PacketApi.java
----------------------------------------------------------------------
diff --git a/packet/src/main/java/org/jclouds/packet/PacketApi.java b/packet/src/main/java/org/jclouds/packet/PacketApi.java
index 1cb8e9b..e5f84e3 100644
--- a/packet/src/main/java/org/jclouds/packet/PacketApi.java
+++ b/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-labs/blob/a812591f/packet/src/main/java/org/jclouds/packet/config/PacketHttpApiModule.java
----------------------------------------------------------------------
diff --git a/packet/src/main/java/org/jclouds/packet/config/PacketHttpApiModule.java b/packet/src/main/java/org/jclouds/packet/config/PacketHttpApiModule.java
index e74bb19..6edeebd 100644
--- a/packet/src/main/java/org/jclouds/packet/config/PacketHttpApiModule.java
+++ b/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-labs/blob/a812591f/packet/src/main/java/org/jclouds/packet/domain/Device.java
----------------------------------------------------------------------
diff --git a/packet/src/main/java/org/jclouds/packet/domain/Device.java b/packet/src/main/java/org/jclouds/packet/domain/Device.java
index af59970..96e0b53 100644
--- a/packet/src/main/java/org/jclouds/packet/domain/Device.java
+++ b/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-labs/blob/a812591f/packet/src/main/java/org/jclouds/packet/domain/ProvisioningEvent.java
----------------------------------------------------------------------
diff --git a/packet/src/main/java/org/jclouds/packet/domain/ProvisioningEvent.java b/packet/src/main/java/org/jclouds/packet/domain/ProvisioningEvent.java
new file mode 100644
index 0000000..3df979f
--- /dev/null
+++ b/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-labs/blob/a812591f/packet/src/main/java/org/jclouds/packet/features/DeviceApi.java
----------------------------------------------------------------------
diff --git a/packet/src/main/java/org/jclouds/packet/features/DeviceApi.java b/packet/src/main/java/org/jclouds/packet/features/DeviceApi.java
new file mode 100644
index 0000000..9f4c672
--- /dev/null
+++ b/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-labs/blob/a812591f/packet/src/main/java/org/jclouds/packet/features/FacilityApi.java
----------------------------------------------------------------------
diff --git a/packet/src/main/java/org/jclouds/packet/features/FacilityApi.java b/packet/src/main/java/org/jclouds/packet/features/FacilityApi.java
new file mode 100644
index 0000000..bde9898
--- /dev/null
+++ b/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-labs/blob/a812591f/packet/src/main/java/org/jclouds/packet/features/OperatingSystemApi.java
----------------------------------------------------------------------
diff --git a/packet/src/main/java/org/jclouds/packet/features/OperatingSystemApi.java b/packet/src/main/java/org/jclouds/packet/features/OperatingSystemApi.java
new file mode 100644
index 0000000..401b1e9
--- /dev/null
+++ b/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-labs/blob/a812591f/packet/src/main/java/org/jclouds/packet/features/PlanApi.java
----------------------------------------------------------------------
diff --git a/packet/src/main/java/org/jclouds/packet/features/PlanApi.java b/packet/src/main/java/org/jclouds/packet/features/PlanApi.java
new file mode 100644
index 0000000..7ed5c3a
--- /dev/null
+++ b/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-labs/blob/a812591f/packet/src/main/java/org/jclouds/packet/features/ProjectApi.java
----------------------------------------------------------------------
diff --git a/packet/src/main/java/org/jclouds/packet/features/ProjectApi.java b/packet/src/main/java/org/jclouds/packet/features/ProjectApi.java
index afdf1ef..9da50d0 100644
--- a/packet/src/main/java/org/jclouds/packet/features/ProjectApi.java
+++ b/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-labs/blob/a812591f/packet/src/main/java/org/jclouds/packet/features/SshKeyApi.java
----------------------------------------------------------------------
diff --git a/packet/src/main/java/org/jclouds/packet/features/SshKeyApi.java b/packet/src/main/java/org/jclouds/packet/features/SshKeyApi.java
new file mode 100644
index 0000000..cd22107
--- /dev/null
+++ b/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-labs/blob/a812591f/packet/src/main/java/org/jclouds/packet/functions/BaseToPagedIterable.java
----------------------------------------------------------------------
diff --git a/packet/src/main/java/org/jclouds/packet/functions/BaseToPagedIterable.java b/packet/src/main/java/org/jclouds/packet/functions/BaseToPagedIterable.java
index c5c275b..abc59a2 100644
--- a/packet/src/main/java/org/jclouds/packet/functions/BaseToPagedIterable.java
+++ b/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-labs/blob/a812591f/packet/src/main/java/org/jclouds/packet/functions/HrefToListOptions.java
----------------------------------------------------------------------
diff --git a/packet/src/main/java/org/jclouds/packet/functions/HrefToListOptions.java b/packet/src/main/java/org/jclouds/packet/functions/HrefToListOptions.java
new file mode 100644
index 0000000..d380b26
--- /dev/null
+++ b/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-labs/blob/a812591f/packet/src/main/java/org/jclouds/packet/functions/LinkToListOptions.java
----------------------------------------------------------------------
diff --git a/packet/src/main/java/org/jclouds/packet/functions/LinkToListOptions.java b/packet/src/main/java/org/jclouds/packet/functions/LinkToListOptions.java
deleted file mode 100644
index 4aef811..0000000
--- a/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-labs/blob/a812591f/packet/src/test/java/org/jclouds/packet/features/DeviceApiLiveTest.java
----------------------------------------------------------------------
diff --git a/packet/src/test/java/org/jclouds/packet/features/DeviceApiLiveTest.java b/packet/src/test/java/org/jclouds/packet/features/DeviceApiLiveTest.java
new file mode 100644
index 0000000..36c08f1
--- /dev/null
+++ b/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-labs/blob/a812591f/packet/src/test/java/org/jclouds/packet/features/DeviceApiMockTest.java
----------------------------------------------------------------------
diff --git a/packet/src/test/java/org/jclouds/packet/features/DeviceApiMockTest.java b/packet/src/test/java/org/jclouds/packet/features/DeviceApiMockTest.java
new file mode 100644
index 0000000..705955c
--- /dev/null
+++ b/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-labs/blob/a812591f/packet/src/test/java/org/jclouds/packet/features/FacilityApiLiveTest.java
----------------------------------------------------------------------
diff --git a/packet/src/test/java/org/jclouds/packet/features/FacilityApiLiveTest.java b/packet/src/test/java/org/jclouds/packet/features/FacilityApiLiveTest.java
new file mode 100644
index 0000000..95fc857
--- /dev/null
+++ b/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-labs/blob/a812591f/packet/src/test/java/org/jclouds/packet/features/FacilityApiMockTest.java
----------------------------------------------------------------------
diff --git a/packet/src/test/java/org/jclouds/packet/features/FacilityApiMockTest.java b/packet/src/test/java/org/jclouds/packet/features/FacilityApiMockTest.java
new file mode 100644
index 0000000..764fa7b
--- /dev/null
+++ b/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-labs/blob/a812591f/packet/src/test/java/org/jclouds/packet/features/OperatingSystemApiLiveTest.java
----------------------------------------------------------------------
diff --git a/packet/src/test/java/org/jclouds/packet/features/OperatingSystemApiLiveTest.java b/packet/src/test/java/org/jclouds/packet/features/OperatingSystemApiLiveTest.java
new file mode 100644
index 0000000..fd96a7e
--- /dev/null
+++ b/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-labs/blob/a812591f/packet/src/test/java/org/jclouds/packet/features/OperatingSystemApiMockTest.java
----------------------------------------------------------------------
diff --git a/packet/src/test/java/org/jclouds/packet/features/OperatingSystemApiMockTest.java b/packet/src/test/java/org/jclouds/packet/features/OperatingSystemApiMockTest.java
new file mode 100644
index 0000000..c0c332b
--- /dev/null
+++ b/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-labs/blob/a812591f/packet/src/test/java/org/jclouds/packet/features/PlanApiLiveTest.java
----------------------------------------------------------------------
diff --git a/packet/src/test/java/org/jclouds/packet/features/PlanApiLiveTest.java b/packet/src/test/java/org/jclouds/packet/features/PlanApiLiveTest.java
new file mode 100644
index 0000000..1b66e04
--- /dev/null
+++ b/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-labs/blob/a812591f/packet/src/test/java/org/jclouds/packet/features/PlanApiMockTest.java
----------------------------------------------------------------------
diff --git a/packet/src/test/java/org/jclouds/packet/features/PlanApiMockTest.java b/packet/src/test/java/org/jclouds/packet/features/PlanApiMockTest.java
new file mode 100644
index 0000000..82683c8
--- /dev/null
+++ b/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-labs/blob/a812591f/packet/src/test/java/org/jclouds/packet/features/ProjectApiLiveTest.java
----------------------------------------------------------------------
diff --git a/packet/src/test/java/org/jclouds/packet/features/ProjectApiLiveTest.java b/packet/src/test/java/org/jclouds/packet/features/ProjectApiLiveTest.java
index 133e5ef..65fba8f 100644
--- a/packet/src/test/java/org/jclouds/packet/features/ProjectApiLiveTest.java
+++ b/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-labs/blob/a812591f/packet/src/test/java/org/jclouds/packet/features/ProjectApiMockTest.java
----------------------------------------------------------------------
diff --git a/packet/src/test/java/org/jclouds/packet/features/ProjectApiMockTest.java b/packet/src/test/java/org/jclouds/packet/features/ProjectApiMockTest.java
index 2899020..d972395 100644
--- a/packet/src/test/java/org/jclouds/packet/features/ProjectApiMockTest.java
+++ b/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");
}
-
}