http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a6044372/digitalocean2/src/main/java/org/jclouds/digitalocean2/features/DropletApi.java ---------------------------------------------------------------------- diff --git a/digitalocean2/src/main/java/org/jclouds/digitalocean2/features/DropletApi.java b/digitalocean2/src/main/java/org/jclouds/digitalocean2/features/DropletApi.java deleted file mode 100644 index c2d9b71..0000000 --- a/digitalocean2/src/main/java/org/jclouds/digitalocean2/features/DropletApi.java +++ /dev/null @@ -1,350 +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.digitalocean2.features; - -import java.beans.ConstructorProperties; -import java.io.Closeable; -import java.net.URI; -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.EmptyIterableWithMarkerOnNotFoundOr404; -import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404; -import org.jclouds.Fallbacks.NullOnNotFoundOr404; -import org.jclouds.Fallbacks.VoidOnNotFoundOr404; -import org.jclouds.collect.IterableWithMarker; -import org.jclouds.collect.PagedIterable; -import org.jclouds.digitalocean2.DigitalOcean2Api; -import org.jclouds.digitalocean2.domain.Action; -import org.jclouds.digitalocean2.domain.Backup; -import org.jclouds.digitalocean2.domain.Droplet; -import org.jclouds.digitalocean2.domain.DropletCreate; -import org.jclouds.digitalocean2.domain.Kernel; -import org.jclouds.digitalocean2.domain.Snapshot; -import org.jclouds.digitalocean2.domain.internal.PaginatedCollection; -import org.jclouds.digitalocean2.domain.options.CreateDropletOptions; -import org.jclouds.digitalocean2.domain.options.ListOptions; -import org.jclouds.digitalocean2.functions.BaseToPagedIterable; -import org.jclouds.http.functions.ParseJson; -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.Json; -import org.jclouds.oauth.v2.filters.OAuthFilter; -import org.jclouds.rest.annotations.Fallback; -import org.jclouds.rest.annotations.MapBinder; -import org.jclouds.rest.annotations.Payload; -import org.jclouds.rest.annotations.PayloadParam; -import org.jclouds.rest.annotations.RequestFilters; -import org.jclouds.rest.annotations.ResponseParser; -import org.jclouds.rest.annotations.SelectJson; -import org.jclouds.rest.annotations.Transform; -import org.jclouds.rest.binders.BindToJsonPayload; - -import com.google.common.base.Function; -import com.google.common.base.Optional; -import com.google.inject.TypeLiteral; - -/** - * Provides access to Droplets via their REST API. - * - * @see <a href="https://developers.digitalocean.com/v2/#droplets"/> - * @see DropletApi - */ -@Path("/droplets") -@RequestFilters(OAuthFilter.class) -@Consumes(MediaType.APPLICATION_JSON) -public interface DropletApi extends Closeable { - - @Named("droplet:list") - @GET - @ResponseParser(ParseDroplets.class) - @Transform(ParseDroplets.ToPagedIterable.class) - @Fallback(EmptyPagedIterableOnNotFoundOr404.class) - PagedIterable<Droplet> list(); - - @Named("droplet:list") - @GET - @ResponseParser(ParseDroplets.class) - @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class) - IterableWithMarker<Droplet> list(ListOptions options); - - static final class ParseDroplets extends ParseJson<ParseDroplets.Droplets> { - @Inject ParseDroplets(Json json) { - super(json, TypeLiteral.get(Droplets.class)); - } - - private static class Droplets extends PaginatedCollection<Droplet> { - @ConstructorProperties({ "droplets", "meta", "links" }) - public Droplets(List<Droplet> items, Meta meta, Links links) { - super(items, meta, links); - } - } - - private static class ToPagedIterable extends BaseToPagedIterable<Droplet, ListOptions> { - @Inject ToPagedIterable(DigitalOcean2Api api, Function<URI, ListOptions> linkToOptions) { - super(api, linkToOptions); - } - - @Override - protected IterableWithMarker<Droplet> fetchPageUsingOptions(ListOptions options, Optional<Object> arg0) { - return api.dropletApi().list(options); - } - } - } - - @Named("droplet:listkernels") - @GET - @Path("/{id}/kernels") - @ResponseParser(ParseKernels.class) - @Transform(ParseKernels.ToPagedIterable.class) - @Fallback(EmptyPagedIterableOnNotFoundOr404.class) - PagedIterable<Kernel> listKernels(@PathParam("id") int id); - - @Named("droplet:listkernels") - @GET - @Path("/{id}/kernels") - @ResponseParser(ParseKernels.class) - @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class) - IterableWithMarker<Kernel> listKernels(@PathParam("id") int id, ListOptions options); - - static final class ParseKernels extends ParseJson<ParseKernels.Kernels> { - @Inject ParseKernels(Json json) { - super(json, TypeLiteral.get(Kernels.class)); - } - - private static class Kernels extends PaginatedCollection<Kernel> { - @ConstructorProperties({ "kernels", "meta", "links" }) - public Kernels(List<Kernel> items, Meta meta, Links links) { - super(items, meta, links); - } - } - - private static class ToPagedIterable extends BaseToPagedIterable<Kernel, ListOptions> { - @Inject ToPagedIterable(DigitalOcean2Api api, Function<URI, ListOptions> linkToOptions) { - super(api, linkToOptions); - } - - @Override - protected IterableWithMarker<Kernel> fetchPageUsingOptions(ListOptions options, Optional<Object> arg0) { - return api.dropletApi().listKernels((Integer) arg0.get(), options); - } - } - } - - @Named("droplet:listsnapshots") - @GET - @Path("/{id}/snapshots") - @ResponseParser(ParseSnapshots.class) - @Transform(ParseSnapshots.ToPagedIterable.class) - @Fallback(EmptyPagedIterableOnNotFoundOr404.class) - PagedIterable<Snapshot> listSnapshots(@PathParam("id") int id); - - @Named("droplet:listsnapshots") - @GET - @Path("/{id}/snapshots") - @ResponseParser(ParseSnapshots.class) - @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class) - IterableWithMarker<Snapshot> listSnapshots(@PathParam("id") int id, ListOptions options); - - static final class ParseSnapshots extends ParseJson<ParseSnapshots.Snapshots> { - @Inject ParseSnapshots(Json json) { - super(json, TypeLiteral.get(Snapshots.class)); - } - - private static class Snapshots extends PaginatedCollection<Snapshot> { - @ConstructorProperties({ "snapshots", "meta", "links" }) - public Snapshots(List<Snapshot> items, Meta meta, Links links) { - super(items, meta, links); - } - } - - private static class ToPagedIterable extends BaseToPagedIterable<Snapshot, ListOptions> { - @Inject ToPagedIterable(DigitalOcean2Api api, Function<URI, ListOptions> linkToOptions) { - super(api, linkToOptions); - } - - @Override - protected IterableWithMarker<Snapshot> fetchPageUsingOptions(ListOptions options, Optional<Object> arg0) { - return api.dropletApi().listSnapshots((Integer) arg0.get(), options); - } - } - } - - @Named("droplet:listbackups") - @GET - @Path("/{id}/backups") - @ResponseParser(ParseBackups.class) - @Transform(ParseBackups.ToPagedIterable.class) - @Fallback(EmptyPagedIterableOnNotFoundOr404.class) - PagedIterable<Backup> listBackups(@PathParam("id") int id); - - @Named("droplet:listbackups") - @GET - @Path("/{id}/backups") - @ResponseParser(ParseBackups.class) - @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class) - IterableWithMarker<Backup> listBackups(@PathParam("id") int id, ListOptions options); - - static final class ParseBackups extends ParseJson<ParseBackups.Backups> { - @Inject ParseBackups(Json json) { - super(json, TypeLiteral.get(Backups.class)); - } - - private static class Backups extends PaginatedCollection<Backup> { - @ConstructorProperties({ "backups", "meta", "links" }) - public Backups(List<Backup> items, Meta meta, Links links) { - super(items, meta, links); - } - } - - private static class ToPagedIterable extends BaseToPagedIterable<Backup, ListOptions> { - @Inject ToPagedIterable(DigitalOcean2Api api, Function<URI, ListOptions> linkToOptions) { - super(api, linkToOptions); - } - - @Override - protected IterableWithMarker<Backup> fetchPageUsingOptions(ListOptions options, Optional<Object> arg0) { - return api.dropletApi().listBackups((Integer) arg0.get(), options); - } - } - } - - @Named("droplet:actions") - @GET - @Path("/{id}/actions") - @ResponseParser(ParseDropletActions.class) - @Transform(ParseDropletActions.ToPagedIterable.class) - @Fallback(EmptyPagedIterableOnNotFoundOr404.class) - PagedIterable<Action> listActions(@PathParam("id") int id); - - @Named("droplet:actions") - @GET - @Path("/{id}/actions") - @ResponseParser(ParseDropletActions.class) - @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class) - IterableWithMarker<Action> listActions(@PathParam("id") int id, ListOptions options); - - static final class ParseDropletActions extends ParseJson<ParseDropletActions.DropletActions> { - @Inject ParseDropletActions(Json json) { - super(json, TypeLiteral.get(DropletActions.class)); - } - - private static class DropletActions extends PaginatedCollection<Action> { - @ConstructorProperties({ "actions", "meta", "links" }) - public DropletActions(List<Action> items, Meta meta, Links links) { - super(items, meta, links); - } - } - - private static class ToPagedIterable extends BaseToPagedIterable<Action, ListOptions> { - @Inject ToPagedIterable(DigitalOcean2Api api, Function<URI, ListOptions> linkToOptions) { - super(api, linkToOptions); - } - - @Override - protected IterableWithMarker<Action> fetchPageUsingOptions(ListOptions options, Optional<Object> arg0) { - return api.dropletApi().listActions((Integer) arg0.get(), options); - } - } - } - - @Named("droplet:create") - @POST - @Produces(MediaType.APPLICATION_JSON) - @MapBinder(BindToJsonPayload.class) - DropletCreate create(@PayloadParam("name") String name, @PayloadParam("region") String region, - @PayloadParam("size") String size, @PayloadParam("image") String image); - - @Named("droplet:create") - @POST - @Produces(MediaType.APPLICATION_JSON) - @MapBinder(CreateDropletOptions.class) - DropletCreate create(@PayloadParam("name") String name, @PayloadParam("region") String region, - @PayloadParam("size") String size, @PayloadParam("image") String image, CreateDropletOptions options); - - @Named("droplet:get") - @GET - @SelectJson("droplet") - @Path("/{id}") - @Fallback(NullOnNotFoundOr404.class) - @Nullable - Droplet get(@PathParam("id") int id); - - @Named("droplet:delete") - @DELETE - @Path("/{id}") - @Fallback(VoidOnNotFoundOr404.class) - void delete(@PathParam("id") int id); - - @Named("droplet:reboot") - @POST - @Produces(MediaType.APPLICATION_JSON) - @SelectJson("action") - @Path("/{id}/actions") - @Payload("{\"type\":\"reboot\"}") - Action reboot(@PathParam("id") int id); - - @Named("droplet:powercycle") - @POST - @Produces(MediaType.APPLICATION_JSON) - @SelectJson("action") - @Path("/{id}/actions") - @Payload("{\"type\":\"power_cycle\"}") - Action powerCycle(@PathParam("id") int id); - - @Named("droplet:shutdown") - @POST - @Produces(MediaType.APPLICATION_JSON) - @SelectJson("action") - @Path("/{id}/actions") - @Payload("{\"type\":\"shutdown\"}") - Action shutdown(@PathParam("id") int id); - - @Named("droplet:poweroff") - @POST - @Produces(MediaType.APPLICATION_JSON) - @SelectJson("action") - @Path("/{id}/actions") - @Payload("{\"type\":\"power_off\"}") - Action powerOff(@PathParam("id") int id); - - @Named("droplet:poweron") - @POST - @Produces(MediaType.APPLICATION_JSON) - @SelectJson("action") - @Path("/{id}/actions") - @Payload("{\"type\":\"power_on\"}") - Action powerOn(@PathParam("id") int id); - - @Named("droplet:snapshot") - @POST - @Produces(MediaType.APPLICATION_JSON) - @SelectJson("action") - @Path("/{id}/actions") - @Payload("%7B\"type\":\"snapshot\",\"name\":\"{name}\"%7D") - Action snapshot(@PathParam("id") int id, @PayloadParam("name") String name); - -}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a6044372/digitalocean2/src/main/java/org/jclouds/digitalocean2/features/ImageApi.java ---------------------------------------------------------------------- diff --git a/digitalocean2/src/main/java/org/jclouds/digitalocean2/features/ImageApi.java b/digitalocean2/src/main/java/org/jclouds/digitalocean2/features/ImageApi.java deleted file mode 100644 index 9803ac3..0000000 --- a/digitalocean2/src/main/java/org/jclouds/digitalocean2/features/ImageApi.java +++ /dev/null @@ -1,131 +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.digitalocean2.features; - -import java.beans.ConstructorProperties; -import java.io.Closeable; -import java.net.URI; -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.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.core.MediaType; - -import org.jclouds.Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404; -import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404; -import org.jclouds.Fallbacks.NullOnNotFoundOr404; -import org.jclouds.Fallbacks.VoidOnNotFoundOr404; -import org.jclouds.collect.IterableWithMarker; -import org.jclouds.collect.PagedIterable; -import org.jclouds.digitalocean2.DigitalOcean2Api; -import org.jclouds.digitalocean2.domain.Image; -import org.jclouds.digitalocean2.domain.internal.PaginatedCollection; -import org.jclouds.digitalocean2.domain.options.ImageListOptions; -import org.jclouds.digitalocean2.functions.BaseToPagedIterable; -import org.jclouds.http.functions.ParseJson; -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.Json; -import org.jclouds.oauth.v2.filters.OAuthFilter; -import org.jclouds.rest.annotations.Fallback; -import org.jclouds.rest.annotations.RequestFilters; -import org.jclouds.rest.annotations.ResponseParser; -import org.jclouds.rest.annotations.SelectJson; -import org.jclouds.rest.annotations.Transform; - -import com.google.common.base.Function; -import com.google.common.base.Optional; -import com.google.inject.TypeLiteral; - -/** - * Provides access to Images via the REST API. - * - * @see <a href="https://developers.digitalocean.com/v2/#images"/> - * @see ImageApi - */ -@Path("/images") -@RequestFilters(OAuthFilter.class) -@Consumes(MediaType.APPLICATION_JSON) -public interface ImageApi extends Closeable { - - @Named("image:list") - @GET - @ResponseParser(ParseImages.class) - @Transform(ParseImages.ToPagedIterable.class) - @Fallback(EmptyPagedIterableOnNotFoundOr404.class) - PagedIterable<Image> list(); - - @Named("image:list") - @GET - @ResponseParser(ParseImages.class) - @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class) - IterableWithMarker<Image> list(ImageListOptions options); - - static final class ParseImages extends ParseJson<ParseImages.Images> { - @Inject ParseImages(Json json) { - super(json, TypeLiteral.get(Images.class)); - } - - private static class Images extends PaginatedCollection<Image> { - @ConstructorProperties({ "images", "meta", "links" }) - public Images(List<Image> items, Meta meta, Links links) { - super(items, meta, links); - } - } - - private static class ToPagedIterable extends BaseToPagedIterable<Image, ImageListOptions> { - @Inject ToPagedIterable(DigitalOcean2Api api, Function<URI, ImageListOptions> linkToOptions) { - super(api, linkToOptions); - } - - @Override - protected IterableWithMarker<Image> fetchPageUsingOptions(ImageListOptions options, Optional<Object> arg0) { - return api.imageApi().list(options); - } - } - } - - @Named("image:get") - @GET - @SelectJson("image") - @Path("/{id}") - @Fallback(NullOnNotFoundOr404.class) - @Nullable - Image get(@PathParam("id") int id); - - @Named("image:get") - @GET - @SelectJson("image") - @Path("/{slug}") - @Fallback(NullOnNotFoundOr404.class) - @Nullable - Image get(@PathParam("slug") String slug); - - @Named("image:delete") - @DELETE - @Path("/{id}") - @Fallback(VoidOnNotFoundOr404.class) - void delete(@PathParam("id") int id); - - //TODO: Add delete and create - -} - http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a6044372/digitalocean2/src/main/java/org/jclouds/digitalocean2/features/KeyApi.java ---------------------------------------------------------------------- diff --git a/digitalocean2/src/main/java/org/jclouds/digitalocean2/features/KeyApi.java b/digitalocean2/src/main/java/org/jclouds/digitalocean2/features/KeyApi.java deleted file mode 100644 index 4889c5d..0000000 --- a/digitalocean2/src/main/java/org/jclouds/digitalocean2/features/KeyApi.java +++ /dev/null @@ -1,164 +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.digitalocean2.features; - -import java.beans.ConstructorProperties; -import java.io.Closeable; -import java.net.URI; -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.PUT; -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.EmptyIterableWithMarkerOnNotFoundOr404; -import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404; -import org.jclouds.Fallbacks.NullOnNotFoundOr404; -import org.jclouds.Fallbacks.VoidOnNotFoundOr404; -import org.jclouds.collect.IterableWithMarker; -import org.jclouds.collect.PagedIterable; -import org.jclouds.digitalocean2.DigitalOcean2Api; -import org.jclouds.digitalocean2.domain.Key; -import org.jclouds.digitalocean2.domain.internal.PaginatedCollection; -import org.jclouds.digitalocean2.domain.options.ListOptions; -import org.jclouds.digitalocean2.functions.BaseToPagedIterable; -import org.jclouds.http.functions.ParseJson; -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.Json; -import org.jclouds.oauth.v2.filters.OAuthFilter; -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.SelectJson; -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; - -/** - * Provides access to Keys via the REST API. - * - * @see <a href="https://developers.digitalocean.com/v2/#keys"/> - * @see KeyApi - */ -@Path("/account/keys") -@RequestFilters(OAuthFilter.class) -@Consumes(MediaType.APPLICATION_JSON) -public interface KeyApi extends Closeable { - - @Named("key:list") - @GET - @ResponseParser(ParseKeys.class) - @Transform(ParseKeys.ToPagedIterable.class) - @Fallback(EmptyPagedIterableOnNotFoundOr404.class) - PagedIterable<Key> list(); - - @Named("key:list") - @GET - @ResponseParser(ParseKeys.class) - @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class) - IterableWithMarker<Key> list(ListOptions options); - - static final class ParseKeys extends ParseJson<ParseKeys.Keys> { - @Inject ParseKeys(Json json) { - super(json, TypeLiteral.get(Keys.class)); - } - - private static class Keys extends PaginatedCollection<Key> { - @ConstructorProperties({ "ssh_keys", "meta", "links" }) - public Keys(List<Key> items, Meta meta, Links links) { - super(items, meta, links); - } - } - - private static class ToPagedIterable extends BaseToPagedIterable<Key, ListOptions> { - @Inject ToPagedIterable(DigitalOcean2Api api, Function<URI, ListOptions> linkToOptions) { - super(api, linkToOptions); - } - - @Override - protected IterableWithMarker<Key> fetchPageUsingOptions(ListOptions options, Optional<Object> arg0) { - return api.keyApi().list(options); - } - } - } - - @Named("key:create") - @POST - @Produces(MediaType.APPLICATION_JSON) - @SelectJson("ssh_key") - @MapBinder(BindToJsonPayload.class) - Key create(@PayloadParam("name") String name, @PayloadParam("public_key") String key); - - @Named("key:get") - @GET - @SelectJson("ssh_key") - @Path("/{id}") - @Fallback(NullOnNotFoundOr404.class) - @Nullable - Key get(@PathParam("id") int id); - - @Named("key:get") - @GET - @SelectJson("ssh_key") - @Path("/{fingerprint}") - @Fallback(NullOnNotFoundOr404.class) - @Nullable - Key get(@PathParam("fingerprint") String fingerprint); - - @Named("key:update") - @PUT - @Produces(MediaType.APPLICATION_JSON) - @SelectJson("ssh_key") - @Path("/{id}") - @MapBinder(BindToJsonPayload.class) - Key update(@PathParam("id") int id, @PayloadParam("name") String name); - - @Named("key:update") - @PUT - @Produces(MediaType.APPLICATION_JSON) - @SelectJson("ssh_key") - @Path("/{fingerprint}") - @MapBinder(BindToJsonPayload.class) - Key update(@PathParam("fingerprint") String fingerprint, @PayloadParam("name") String name); - - @Named("key:delete") - @DELETE - @Path("/{id}") - @Fallback(VoidOnNotFoundOr404.class) - void delete(@PathParam("id") int id); - - @Named("key:delete") - @DELETE - @Path("/{fingerprint}") - @Fallback(VoidOnNotFoundOr404.class) - void delete(@PathParam("fingerprint") String fingerprint); - -} - http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a6044372/digitalocean2/src/main/java/org/jclouds/digitalocean2/features/RegionApi.java ---------------------------------------------------------------------- diff --git a/digitalocean2/src/main/java/org/jclouds/digitalocean2/features/RegionApi.java b/digitalocean2/src/main/java/org/jclouds/digitalocean2/features/RegionApi.java deleted file mode 100644 index 9fb7128..0000000 --- a/digitalocean2/src/main/java/org/jclouds/digitalocean2/features/RegionApi.java +++ /dev/null @@ -1,107 +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.digitalocean2.features; - -import java.beans.ConstructorProperties; -import java.io.Closeable; -import java.net.URI; -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.EmptyIterableWithMarkerOnNotFoundOr404; -import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404; -import org.jclouds.collect.IterableWithMarker; -import org.jclouds.collect.PagedIterable; -import org.jclouds.digitalocean2.DigitalOcean2Api; -import org.jclouds.digitalocean2.domain.Region; -import org.jclouds.digitalocean2.domain.internal.PaginatedCollection; -import org.jclouds.digitalocean2.domain.options.ListOptions; -import org.jclouds.digitalocean2.functions.BaseToPagedIterable; -import org.jclouds.http.functions.ParseJson; -import org.jclouds.json.Json; -import org.jclouds.oauth.v2.filters.OAuthFilter; -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; - -/** - * Provides access to Regions via the REST API. - */ -@Path("/regions") -@RequestFilters(OAuthFilter.class) -@Consumes(MediaType.APPLICATION_JSON) -public interface RegionApi extends Closeable { - - /** - * Get the list of all regions. - * - * @return The (paginated) list of all regions. - */ - @Named("region:list") - @GET - @ResponseParser(ParseRegions.class) - @Transform(ParseRegions.ToPagedIterable.class) - @Fallback(EmptyPagedIterableOnNotFoundOr404.class) - PagedIterable<Region> list(); - - /** - * Get a single page of the region list. - * - * @param options The options to configure the page to get and the size of the page. - * @return The page with the requested regions. - */ - @Named("region:list") - @GET - @ResponseParser(ParseRegions.class) - @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class) - IterableWithMarker<Region> list(ListOptions options); - - static final class ParseRegions extends ParseJson<ParseRegions.Regions> { - @Inject ParseRegions(Json json) { - super(json, TypeLiteral.get(Regions.class)); - } - - private static class Regions extends PaginatedCollection<Region> { - @ConstructorProperties({ "regions", "meta", "links" }) - public Regions(List<Region> items, Meta meta, Links links) { - super(items, meta, links); - } - } - - static class ToPagedIterable extends BaseToPagedIterable<Region, ListOptions> { - @Inject ToPagedIterable(DigitalOcean2Api api, Function<URI, ListOptions> linkToOptions) { - super(api, linkToOptions); - } - - @Override - protected IterableWithMarker<Region> fetchPageUsingOptions(ListOptions options, Optional<Object> arg0) { - return api.regionApi().list(options); - } - } - } -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a6044372/digitalocean2/src/main/java/org/jclouds/digitalocean2/features/SizeApi.java ---------------------------------------------------------------------- diff --git a/digitalocean2/src/main/java/org/jclouds/digitalocean2/features/SizeApi.java b/digitalocean2/src/main/java/org/jclouds/digitalocean2/features/SizeApi.java deleted file mode 100644 index 9165809..0000000 --- a/digitalocean2/src/main/java/org/jclouds/digitalocean2/features/SizeApi.java +++ /dev/null @@ -1,100 +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.digitalocean2.features; - -import java.beans.ConstructorProperties; -import java.io.Closeable; -import java.net.URI; -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.EmptyIterableWithMarkerOnNotFoundOr404; -import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404; -import org.jclouds.collect.IterableWithMarker; -import org.jclouds.collect.PagedIterable; -import org.jclouds.digitalocean2.DigitalOcean2Api; -import org.jclouds.digitalocean2.domain.Size; -import org.jclouds.digitalocean2.domain.internal.PaginatedCollection; -import org.jclouds.digitalocean2.domain.options.ListOptions; -import org.jclouds.digitalocean2.functions.BaseToPagedIterable; -import org.jclouds.http.functions.ParseJson; -import org.jclouds.json.Json; -import org.jclouds.oauth.v2.filters.OAuthFilter; -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; - -/** - * Provides access to Sizes via the REST API. - * - * @see <a href="https://developers.digitalocean.com/v2/#sizes"/> - * @see org.jclouds.digitalocean2.features.SizeApi - */ -@Path("/sizes") -@RequestFilters(OAuthFilter.class) -@Consumes(MediaType.APPLICATION_JSON) -public interface SizeApi extends Closeable { - - @Named("size:list") - @GET - @ResponseParser(ParseSizes.class) - @Transform(ParseSizes.ToPagedIterable.class) - @Fallback(EmptyPagedIterableOnNotFoundOr404.class) - PagedIterable<Size> list(); - - @Named("size:list") - @GET - @ResponseParser(ParseSizes.class) - @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class) - IterableWithMarker<Size> list(ListOptions options); - - static final class ParseSizes extends ParseJson<ParseSizes.Sizes> { - @Inject ParseSizes(Json json) { - super(json, TypeLiteral.get(Sizes.class)); - } - - private static class Sizes extends PaginatedCollection<Size> { - @ConstructorProperties({ "sizes", "meta", "links" }) - public Sizes(List<Size> items, Meta meta, Links links) { - super(items, meta, links); - } - } - - private static class ToPagedIterable extends BaseToPagedIterable<Size, ListOptions> { - @Inject ToPagedIterable(DigitalOcean2Api api, Function<URI, ListOptions> linkToOptions) { - super(api, linkToOptions); - } - - @Override - protected IterableWithMarker<Size> fetchPageUsingOptions(ListOptions options, Optional<Object> arg0) { - return api.sizeApi().list(options); - } - } - } -} - http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a6044372/digitalocean2/src/main/java/org/jclouds/digitalocean2/functions/BaseToPagedIterable.java ---------------------------------------------------------------------- diff --git a/digitalocean2/src/main/java/org/jclouds/digitalocean2/functions/BaseToPagedIterable.java b/digitalocean2/src/main/java/org/jclouds/digitalocean2/functions/BaseToPagedIterable.java deleted file mode 100644 index ebedef5..0000000 --- a/digitalocean2/src/main/java/org/jclouds/digitalocean2/functions/BaseToPagedIterable.java +++ /dev/null @@ -1,59 +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.digitalocean2.functions; - -import java.net.URI; - -import javax.inject.Inject; - -import org.jclouds.collect.IterableWithMarker; -import org.jclouds.collect.internal.Arg0ToPagedIterable; -import org.jclouds.digitalocean2.DigitalOcean2Api; -import org.jclouds.digitalocean2.domain.options.ListOptions; - -import com.google.common.base.Function; -import com.google.common.base.Optional; - -/** - * Base class to implement the functions that build the - * <code>PagedIterable</code>. Subclasses just need to override the - * {@link #fetchPageUsingOptions(ListOptions, Optional)} to invoke the right API - * method with the given options parameter to get the next page. - */ -public abstract class BaseToPagedIterable<T, O extends ListOptions> extends - Arg0ToPagedIterable<T, BaseToPagedIterable<T, O>> { - private final Function<URI, O> linkToOptions; - protected final DigitalOcean2Api api; - - @Inject protected BaseToPagedIterable(DigitalOcean2Api api, Function<URI, O> linkToOptions) { - this.api = api; - this.linkToOptions = linkToOptions; - } - - protected abstract IterableWithMarker<T> fetchPageUsingOptions(O options, Optional<Object> arg0); - - @Override protected Function<Object, IterableWithMarker<T>> markerToNextForArg0(final Optional<Object> arg0) { - return new Function<Object, IterableWithMarker<T>>() { - @Override - public IterableWithMarker<T> apply(Object input) { - O nextOptions = linkToOptions.apply(URI.class.cast(input)); - return fetchPageUsingOptions(nextOptions, arg0); - } - }; - } - -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a6044372/digitalocean2/src/main/java/org/jclouds/digitalocean2/functions/LinkToImageListOptions.java ---------------------------------------------------------------------- diff --git a/digitalocean2/src/main/java/org/jclouds/digitalocean2/functions/LinkToImageListOptions.java b/digitalocean2/src/main/java/org/jclouds/digitalocean2/functions/LinkToImageListOptions.java deleted file mode 100644 index 85701e5..0000000 --- a/digitalocean2/src/main/java/org/jclouds/digitalocean2/functions/LinkToImageListOptions.java +++ /dev/null @@ -1,67 +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.digitalocean2.functions; - -import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.digitalocean2.domain.options.ImageListOptions.PRIVATE_PARAM; -import static org.jclouds.digitalocean2.domain.options.ImageListOptions.TYPE_PARAM; -import static org.jclouds.digitalocean2.domain.options.ListOptions.PAGE_PARAM; -import static org.jclouds.digitalocean2.domain.options.ListOptions.PER_PAGE_PARAM; -import static org.jclouds.digitalocean2.functions.LinkToListOptions.getFirstOrNull; -import static org.jclouds.http.utils.Queries.queryParser; - -import java.net.URI; - -import org.jclouds.digitalocean2.domain.options.ImageListOptions; -import org.jclouds.digitalocean2.domain.options.ListOptions; - -import com.google.common.base.Function; -import com.google.common.collect.Multimap; - -/** - * Transforms a link 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 LinkToImageListOptions implements Function<URI, ImageListOptions> { - - @Override public ImageListOptions apply(URI input) { - checkNotNull(input, "input cannot be null"); - - Multimap<String, String> queryParams = queryParser().apply(input.getQuery()); - String nextPage = getFirstOrNull(PAGE_PARAM, queryParams); - String nextPerPage = getFirstOrNull(PER_PAGE_PARAM, queryParams); - String nextType = getFirstOrNull(TYPE_PARAM, queryParams); - String nextPrivate = getFirstOrNull(PRIVATE_PARAM, queryParams); - - ImageListOptions options = new ImageListOptions(); - if (nextPage != null) { - options.page(Integer.parseInt(nextPage)); - } - if (nextPerPage != null) { - options.perPage(Integer.parseInt(nextPerPage)); - } - if (nextType != null) { - options.type(nextType); - } - if (nextPrivate != null) { - options.privateImages(Boolean.parseBoolean(nextPrivate)); - } - - return options; - } - -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a6044372/digitalocean2/src/main/java/org/jclouds/digitalocean2/functions/LinkToListOptions.java ---------------------------------------------------------------------- diff --git a/digitalocean2/src/main/java/org/jclouds/digitalocean2/functions/LinkToListOptions.java b/digitalocean2/src/main/java/org/jclouds/digitalocean2/functions/LinkToListOptions.java deleted file mode 100644 index 1dc22db..0000000 --- a/digitalocean2/src/main/java/org/jclouds/digitalocean2/functions/LinkToListOptions.java +++ /dev/null @@ -1,61 +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.digitalocean2.functions; - -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.digitalocean2.domain.options.ListOptions.PAGE_PARAM; -import static org.jclouds.digitalocean2.domain.options.ListOptions.PER_PAGE_PARAM; -import static org.jclouds.http.utils.Queries.queryParser; - -import java.net.URI; - -import org.jclouds.digitalocean2.domain.options.ListOptions; - -import com.google.common.base.Function; -import com.google.common.collect.Multimap; - -/** - * Transforms a link 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<URI, ListOptions> { - - @Override public ListOptions apply(URI input) { - checkNotNull(input, "input cannot be null"); - - Multimap<String, String> queryParams = queryParser().apply(input.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/a6044372/digitalocean2/src/main/java/org/jclouds/digitalocean2/handlers/DigitalOcean2ErrorHandler.java ---------------------------------------------------------------------- diff --git a/digitalocean2/src/main/java/org/jclouds/digitalocean2/handlers/DigitalOcean2ErrorHandler.java b/digitalocean2/src/main/java/org/jclouds/digitalocean2/handlers/DigitalOcean2ErrorHandler.java deleted file mode 100644 index 29b7eba..0000000 --- a/digitalocean2/src/main/java/org/jclouds/digitalocean2/handlers/DigitalOcean2ErrorHandler.java +++ /dev/null @@ -1,72 +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.digitalocean2.handlers; - -import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream; - -import javax.inject.Singleton; - -import org.jclouds.digitalocean2.exceptions.DigitalOcean2RateLimitExceededException; -import org.jclouds.http.HttpCommand; -import org.jclouds.http.HttpErrorHandler; -import org.jclouds.http.HttpResponse; -import org.jclouds.http.HttpResponseException; -import org.jclouds.rest.AuthorizationException; -import org.jclouds.rest.InsufficientResourcesException; -import org.jclouds.rest.ResourceNotFoundException; - -/** - * This will parse and set an appropriate exception on the command object. - */ -@Singleton -public class DigitalOcean2ErrorHandler implements HttpErrorHandler { - - public void handleError(HttpCommand command, HttpResponse response) { - // it is important to always read fully and close streams - byte[] data = closeClientButKeepContentStream(response); - String message = data != null ? new String(data) : null; - - Exception exception = message != null ? new HttpResponseException(command, response, message) - : new HttpResponseException(command, response); - message = message != null ? message : String.format("%s -> %s", command.getCurrentRequest().getRequestLine(), - response.getStatusLine()); - switch (response.getStatusCode()) { - case 400: - break; - case 401: - case 403: - if (message.contains("droplet limit")) { - exception = new InsufficientResourcesException(message, exception); - } else { - exception = new AuthorizationException(message, exception); - } - break; - case 404: - if (!command.getCurrentRequest().getMethod().equals("DELETE")) { - exception = new ResourceNotFoundException(message, exception); - } - break; - case 409: - exception = new IllegalStateException(message, exception); - break; - case 429: - exception = new DigitalOcean2RateLimitExceededException(response, exception); - break; - } - command.setException(exception); - } -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a6044372/digitalocean2/src/main/java/org/jclouds/digitalocean2/handlers/RateLimitRetryHandler.java ---------------------------------------------------------------------- diff --git a/digitalocean2/src/main/java/org/jclouds/digitalocean2/handlers/RateLimitRetryHandler.java b/digitalocean2/src/main/java/org/jclouds/digitalocean2/handlers/RateLimitRetryHandler.java deleted file mode 100644 index d72a9fa..0000000 --- a/digitalocean2/src/main/java/org/jclouds/digitalocean2/handlers/RateLimitRetryHandler.java +++ /dev/null @@ -1,111 +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.digitalocean2.handlers; - -import static org.jclouds.Constants.PROPERTY_MAX_RETRIES; -import static org.jclouds.digitalocean2.config.DigitalOcean2Properties.MAX_RATE_LIMIT_WAIT; - -import javax.annotation.Resource; -import javax.inject.Named; -import javax.inject.Singleton; - -import org.jclouds.http.HttpCommand; -import org.jclouds.http.HttpResponse; -import org.jclouds.http.HttpRetryHandler; -import org.jclouds.logging.Logger; - -import com.google.common.annotations.Beta; -import com.google.inject.Inject; - -/** - * Retry handler that takes into account the DigitalOcean rate limit and delays - * the requests until they are known to succeed. - */ -@Beta -@Singleton -public class RateLimitRetryHandler implements HttpRetryHandler { - - static final String RATE_LIMIT_RESET_HEADER = "RateLimit-Reset"; - - @Resource - protected Logger logger = Logger.NULL; - - @Inject(optional = true) - @Named(PROPERTY_MAX_RETRIES) - private int retryCountLimit = 5; - - @Inject(optional = true) - @Named(MAX_RATE_LIMIT_WAIT) - private int maxRateLimitWait = 120000; - - @Override - public boolean shouldRetryRequest(final HttpCommand command, final HttpResponse response) { - command.incrementFailureCount(); - - // Do not retry client errors that are not rate limit errors - if (response.getStatusCode() != 429) { - return false; - } else if (!command.isReplayable()) { - logger.error("Cannot retry after rate limit error, command is not replayable: %1$s", command); - return false; - } else if (command.getFailureCount() > retryCountLimit) { - logger.error("Cannot retry after rate limit error, command has exceeded retry limit %1$d: %2$s", - retryCountLimit, command); - return false; - } else { - return delayRequestUntilAllowed(command, response); - } - } - - private boolean delayRequestUntilAllowed(final HttpCommand command, final HttpResponse response) { - // The header is the Unix epoch time when the next request can be done - String epochForNextAvailableRequest = response.getFirstHeaderOrNull(RATE_LIMIT_RESET_HEADER); - if (epochForNextAvailableRequest == null) { - logger.error("Cannot retry after rate limit error, no retry information provided in the response"); - return false; - } - - long waitPeriod = millisUntilNextAvailableRequest(Long.parseLong(epochForNextAvailableRequest)); - - if (waitPeriod > 0) { - if (waitPeriod > maxRateLimitWait) { - logger.error("Max wait for rate limited requests is %s seconds but need to wait %s seconds, aborting", - maxRateLimitWait, waitPeriod); - return false; - } - - try { - logger.debug("Waiting %s seconds before retrying, as defined by the rate limit", waitPeriod); - // Do not use Uninterrumpibles or similar, to let the jclouds - // tiemout configuration interrupt this thread - Thread.sleep(waitPeriod); - } catch (InterruptedException ex) { - // If the request is being executed and has a timeout configured, - // the thread may be interrupted when the timeout is reached. - logger.error("Request execution was interrupted, aborting"); - Thread.currentThread().interrupt(); - return false; - } - } - - return true; - } - - public static long millisUntilNextAvailableRequest(long epochForNextAvailableRequest) { - return (epochForNextAvailableRequest * 1000) - System.currentTimeMillis(); - } -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a6044372/digitalocean2/src/main/java/org/jclouds/digitalocean2/ssh/DSAKeys.java ---------------------------------------------------------------------- diff --git a/digitalocean2/src/main/java/org/jclouds/digitalocean2/ssh/DSAKeys.java b/digitalocean2/src/main/java/org/jclouds/digitalocean2/ssh/DSAKeys.java deleted file mode 100644 index b3c0760..0000000 --- a/digitalocean2/src/main/java/org/jclouds/digitalocean2/ssh/DSAKeys.java +++ /dev/null @@ -1,172 +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.digitalocean2.ssh; - -import static com.google.common.base.Joiner.on; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Splitter.fixedLength; -import static com.google.common.base.Throwables.propagate; -import static com.google.common.collect.Iterables.get; -import static com.google.common.collect.Iterables.size; -import static com.google.common.io.BaseEncoding.base16; -import static com.google.common.io.BaseEncoding.base64; -import static org.jclouds.util.Strings2.toStringAndClose; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.math.BigInteger; -import java.security.interfaces.DSAParams; -import java.security.interfaces.DSAPublicKey; -import java.security.spec.DSAPublicKeySpec; - -import com.google.common.base.Charsets; -import com.google.common.base.Splitter; -import com.google.common.hash.HashCode; -import com.google.common.hash.Hashing; -import com.google.common.io.ByteSource; -import com.google.common.io.ByteStreams; - -/** - * Utility methods to work with DSA SSH keys. - * <p> - * Methods in this class should be moved to the {@link org.jclouds.ssh.SshKeys} class. - * - * - * @see org.jclouds.ssh.SshKeys - */ -public class DSAKeys { - - public static String encodeAsOpenSSH(DSAPublicKey key) { - DSAParams params = key.getParams(); - byte[] keyBlob = keyBlob(params.getP(), params.getQ(), params.getG(), key.getY()); - return "ssh-dss " + base64().encode(keyBlob); - } - - /** - * Executes {@link org.jclouds.crypto.Pems#publicKeySpecFromOpenSSH(com.google.common.io.InputSupplier)} on the - * string which was OpenSSH Base64 Encoded {@code id_rsa.pub} - * - * @param idRsaPub formatted {@code ssh-dss AAAAB3NzaC1yc2EAAAADAQABAAAB...} - * @see org.jclouds.crypto.Pems#publicKeySpecFromOpenSSH(com.google.common.io.InputSupplier) - */ - public static DSAPublicKeySpec publicKeySpecFromOpenSSH(String idDsaPub) { - try { - return publicKeySpecFromOpenSSH(ByteSource.wrap(idDsaPub.getBytes(Charsets.UTF_8))); - } catch (IOException e) { - throw propagate(e); - } - } - - /** - * Returns {@link java.security.spec.DSAPublicKeySpec} which was OpenSSH Base64 Encoded {@code id_rsa.pub} - * - * @param supplier the input stream factory, formatted {@code ssh-dss AAAAB3NzaC1yc2EAAAADAQABAAAB...} - * - * @return the {@link java.security.spec.DSAPublicKeySpec} which was OpenSSH Base64 Encoded {@code id_rsa.pub} - * @throws java.io.IOException if an I/O error occurs - */ - public static DSAPublicKeySpec publicKeySpecFromOpenSSH(ByteSource supplier) throws IOException { - InputStream stream = supplier.openStream(); - Iterable<String> parts = Splitter.on(' ').split(toStringAndClose(stream).trim()); - checkArgument(size(parts) >= 2 && "ssh-dss".equals(get(parts, 0)), "bad format, should be: ssh-dss AAAAB3..."); - stream = new ByteArrayInputStream(base64().decode(get(parts, 1))); - String marker = new String(readLengthFirst(stream)); - checkArgument("ssh-dss".equals(marker), "looking for marker ssh-dss but got %s", marker); - BigInteger p = new BigInteger(readLengthFirst(stream)); - BigInteger q = new BigInteger(readLengthFirst(stream)); - BigInteger g = new BigInteger(readLengthFirst(stream)); - BigInteger y = new BigInteger(readLengthFirst(stream)); - return new DSAPublicKeySpec(y, p, q, g); - } - - /** - * @param publicKeyOpenSSH RSA public key in OpenSSH format - * @return fingerprint ex. {@code 2b:a9:62:95:5b:8b:1d:61:e0:92:f7:03:10:e9:db:d9} - */ - public static String fingerprintPublicKey(String publicKeyOpenSSH) { - DSAPublicKeySpec publicKeySpec = publicKeySpecFromOpenSSH(publicKeyOpenSSH); - return fingerprint(publicKeySpec.getP(), publicKeySpec.getQ(), publicKeySpec.getG(), publicKeySpec.getY()); - } - - /** - * Create a fingerprint per the following <a href="http://tools.ietf.org/html/draft-friedl-secsh-fingerprint-00" - * >spec</a> - * - * @return hex fingerprint ex. {@code 2b:a9:62:95:5b:8b:1d:61:e0:92:f7:03:10:e9:db:d9} - */ - public static String fingerprint(BigInteger p, BigInteger q, BigInteger g, BigInteger y) { - byte[] keyBlob = keyBlob(p, q, g, y); - return hexColonDelimited(Hashing.md5().hashBytes(keyBlob)); - } - - /** - * @see org.jclouds.ssh.SshKeys - */ - private static String hexColonDelimited(HashCode hc) { - return on(':').join(fixedLength(2).split(base16().lowerCase().encode(hc.asBytes()))); - } - - /** - * @see org.jclouds.ssh.SshKeys - */ - private static byte[] keyBlob(BigInteger p, BigInteger q, BigInteger g, BigInteger y) { - try { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - writeLengthFirst("ssh-dss".getBytes(), out); - writeLengthFirst(p.toByteArray(), out); - writeLengthFirst(q.toByteArray(), out); - writeLengthFirst(g.toByteArray(), out); - writeLengthFirst(y.toByteArray(), out); - return out.toByteArray(); - } catch (IOException e) { - throw propagate(e); - } - } - - /** - * @see org.jclouds.ssh.SshKeys - */ - // http://www.ietf.org/rfc/rfc4253.txt - private static byte[] readLengthFirst(InputStream in) throws IOException { - int byte1 = in.read(); - int byte2 = in.read(); - int byte3 = in.read(); - int byte4 = in.read(); - int length = (byte1 << 24) + (byte2 << 16) + (byte3 << 8) + (byte4 << 0); - byte[] val = new byte[length]; - ByteStreams.readFully(in, val); - return val; - } - - /** - * @see org.jclouds.ssh.SshKeys - */ - // http://www.ietf.org/rfc/rfc4253.txt - private static void writeLengthFirst(byte[] array, ByteArrayOutputStream out) throws IOException { - out.write(array.length >>> 24 & 0xFF); - out.write(array.length >>> 16 & 0xFF); - out.write(array.length >>> 8 & 0xFF); - out.write(array.length >>> 0 & 0xFF); - if (array.length == 1 && array[0] == (byte) 0x00) { - out.write(new byte[0]); - } else { - out.write(array); - } - } -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a6044372/digitalocean2/src/main/java/org/jclouds/digitalocean2/ssh/ECDSAKeys.java ---------------------------------------------------------------------- diff --git a/digitalocean2/src/main/java/org/jclouds/digitalocean2/ssh/ECDSAKeys.java b/digitalocean2/src/main/java/org/jclouds/digitalocean2/ssh/ECDSAKeys.java deleted file mode 100644 index f17098a..0000000 --- a/digitalocean2/src/main/java/org/jclouds/digitalocean2/ssh/ECDSAKeys.java +++ /dev/null @@ -1,343 +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.digitalocean2.ssh; - -import static com.google.common.base.Joiner.on; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Splitter.fixedLength; -import static com.google.common.base.Throwables.propagate; -import static com.google.common.collect.Iterables.get; -import static com.google.common.collect.Iterables.size; -import static com.google.common.io.BaseEncoding.base16; -import static com.google.common.io.BaseEncoding.base64; -import static org.jclouds.util.Strings2.toStringAndClose; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.math.BigInteger; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.interfaces.ECPublicKey; -import java.security.spec.ECFieldFp; -import java.security.spec.ECParameterSpec; -import java.security.spec.ECPoint; -import java.security.spec.ECPublicKeySpec; -import java.security.spec.EllipticCurve; -import java.security.spec.InvalidKeySpecException; -import java.util.Map; -import java.util.TreeMap; - -import com.google.common.base.Charsets; -import com.google.common.base.Splitter; -import com.google.common.hash.HashCode; -import com.google.common.hash.Hashing; -import com.google.common.io.ByteSource; -import com.google.common.io.ByteStreams; - -/** - * Utility methods to work with ECDSA Elliptic Curve DSA keys. - * <p> - * Methods in this class should be moved to the {@link org.jclouds.ssh.SshKeys} class. - * - * @see org.jclouds.ssh.SshKeys - */ -public class ECDSAKeys { - public static final String ECDSA_SHA2_PREFIX = "ecdsa-sha2-"; - - private static final String NISTP256 = "nistp256"; - private static final String NISTP384 = "nistp384"; - private static final String NISTP521 = "nistp521"; - - private static final Map<String, ECParameterSpec> CURVES = new TreeMap<String, ECParameterSpec>(); - static { - CURVES.put(NISTP256, EllipticCurves.nistp256); - CURVES.put(NISTP384, EllipticCurves.nistp384); - CURVES.put(NISTP521, EllipticCurves.nistp521); - } - - private static final Map<Integer, String> CURVE_SIZES = new TreeMap<Integer, String>(); - static { - CURVE_SIZES.put(256, NISTP256); - CURVE_SIZES.put(384, NISTP384); - CURVE_SIZES.put(521, NISTP521); - } - - public static String encodeAsOpenSSH(ECPublicKey key) { - - String curveName = null; - try { - curveName = getCurveName(key.getParams()); - } catch (IOException e) { - propagate(e); - } - - String keyFormat = ECDSA_SHA2_PREFIX + curveName; - - byte[] keyBlob = keyBlob(key); - return keyFormat + " " + base64().encode(keyBlob); - } - - /** - * Executes {@link org.jclouds.crypto.Pems#publicKeySpecFromOpenSSH(com.google.common.io.InputSupplier)} on the - * string which was OpenSSH Base64 Encoded {@code id_rsa.pub} - * - * @param idRsaPub formatted {@code ssh-dss AAAAB3NzaC1yc2EAAAADAQABAAAB...} - * @see org.jclouds.crypto.Pems#publicKeySpecFromOpenSSH(com.google.common.io.InputSupplier) - */ - public static ECPublicKeySpec publicKeySpecFromOpenSSH(String ecDsaPub) { - try { - return publicKeySpecFromOpenSSH(ByteSource.wrap(ecDsaPub.getBytes(Charsets.UTF_8))); - } catch (IOException e) { - throw propagate(e); - } - } - - /** - * Returns {@link java.security.spec.DSAPublicKeySpec} which was OpenSSH Base64 Encoded {@code id_rsa.pub} - * - * @param supplier the input stream factory, formatted {@code ssh-dss AAAAB3NzaC1yc2EAAAADAQABAAAB...} - * - * @return the {@link java.security.spec.DSAPublicKeySpec} which was OpenSSH Base64 Encoded {@code id_rsa.pub} - * @throws java.io.IOException if an I/O error occurs - */ - public static ECPublicKeySpec publicKeySpecFromOpenSSH(ByteSource supplier) throws IOException { - InputStream stream = supplier.openStream(); - Iterable<String> parts = Splitter.on(' ').split(toStringAndClose(stream).trim()); - String signatureFormat = get(parts, 0); - checkArgument(size(parts) >= 2 && signatureFormat.startsWith(ECDSA_SHA2_PREFIX), "bad format, should be: ecdsa-sha2-xxx AAAAB3..."); - - String curveName = signatureFormat.substring(ECDSA_SHA2_PREFIX.length()); - if (!CURVES.containsKey(curveName)) { - throw new IOException("Unsupported curve: " + curveName); - } - ECParameterSpec spec = CURVES.get(curveName); - stream = new ByteArrayInputStream(base64().decode(get(parts, 1))); - @SuppressWarnings("unused") - String keyType = new String(readLengthFirst(stream)); - String curveMarker = new String(readLengthFirst(stream)); - checkArgument(curveName.equals(curveMarker), "looking for marker %s but got %s", curveName, curveMarker); - - ECPoint ecPoint = decodeECPoint(readLengthFirst(stream), spec.getCurve()); - - return new ECPublicKeySpec(ecPoint, spec); - } - - /** - * @param publicKeyOpenSSH RSA public key in OpenSSH format - * @return fingerprint ex. {@code 2b:a9:62:95:5b:8b:1d:61:e0:92:f7:03:10:e9:db:d9} - */ - public static String fingerprintPublicKey(String publicKeyOpenSSH) throws IOException { - ECPublicKeySpec publicKeySpec = publicKeySpecFromOpenSSH(publicKeyOpenSSH); - String fingerprint = null; - try { - ECPublicKey pk = (ECPublicKey) KeyFactory.getInstance("EC").generatePublic(publicKeySpec); - fingerprint = fingerprint(pk); - } catch (InvalidKeySpecException e) { - e.printStackTrace(); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } - return fingerprint; - } - - /** - * Create a fingerprint per the following <a href="http://tools.ietf.org/html/draft-friedl-secsh-fingerprint-00" - * >spec</a> - * - * @return hex fingerprint ex. {@code 2b:a9:62:95:5b:8b:1d:61:e0:92:f7:03:10:e9:db:d9} - */ - public static String fingerprint(ECPublicKey publicKey) { - byte[] keyBlob = keyBlob(publicKey); - return hexColonDelimited(Hashing.md5().hashBytes(keyBlob)); - } - - /** - * @see org.jclouds.ssh.SshKeys - */ - private static String hexColonDelimited(HashCode hc) { - return on(':').join(fixedLength(2).split(base16().lowerCase().encode(hc.asBytes()))); - } - - private static byte[] keyBlob(ECPublicKey key) { - try { - String curveName = getCurveName(key.getParams()); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - writeLengthFirst((ECDSA_SHA2_PREFIX + curveName).getBytes(), out); - writeLengthFirst(curveName.getBytes(), out); - writeLengthFirst(encodeECPoint(key.getW(), key.getParams().getCurve()), out); - return out.toByteArray(); - } catch (IOException e) { - throw propagate(e); - } - } - - /** - * @see org.jclouds.ssh.SshKeys - */ - // http://www.ietf.org/rfc/rfc4253.txt - private static byte[] readLengthFirst(InputStream in) throws IOException { - int byte1 = in.read(); - int byte2 = in.read(); - int byte3 = in.read(); - int byte4 = in.read(); - int length = (byte1 << 24) + (byte2 << 16) + (byte3 << 8) + (byte4 << 0); - byte[] val = new byte[length]; - ByteStreams.readFully(in, val); - return val; - } - - /** - * @see org.jclouds.ssh.SshKeys - */ - // http://www.ietf.org/rfc/rfc4253.txt - private static void writeLengthFirst(byte[] array, ByteArrayOutputStream out) throws IOException { - out.write(array.length >>> 24 & 0xFF); - out.write(array.length >>> 16 & 0xFF); - out.write(array.length >>> 8 & 0xFF); - out.write(array.length >>> 0 & 0xFF); - if (array.length == 1 && array[0] == (byte) 0x00) { - out.write(new byte[0]); - } else { - out.write(array); - } - } - - private static String getCurveName(ECParameterSpec params) throws IOException { - int fieldSize = getCurveSize(params); - String curveName = CURVE_SIZES.get(fieldSize); - if (curveName == null) { - throw new IOException("Unsupported curve field size: " + fieldSize); - } - return curveName; - } - - private static int getCurveSize(ECParameterSpec params) { - return params.getCurve().getField().getFieldSize(); - } - - /** - * Encode EllipticCurvePoint to an OctetString - */ - public static byte[] encodeECPoint(ECPoint group, EllipticCurve curve) - { - // M has len 2 ceil(log_2(q)/8) + 1 ? - int elementSize = (curve.getField().getFieldSize() + 7) / 8; - byte[] M = new byte[2 * elementSize + 1]; - - // Uncompressed format - M[0] = 0x04; - - { - byte[] affineX = removeLeadingZeroes(group.getAffineX().toByteArray()); - System.arraycopy(affineX, 0, M, 1 + elementSize - affineX.length, affineX.length); - } - - { - byte[] affineY = removeLeadingZeroes(group.getAffineY().toByteArray()); - System.arraycopy(affineY, 0, M, 1 + elementSize + elementSize - affineY.length, - affineY.length); - } - - return M; - } - - private static byte[] removeLeadingZeroes(byte[] input) { - if (input[0] != 0x00) { - return input; - } - - int pos = 1; - while (pos < input.length - 1 && input[pos] == 0x00) { - pos++; - } - - byte[] output = new byte[input.length - pos]; - System.arraycopy(input, pos, output, 0, output.length); - return output; - } - - /** - * Decode an OctetString to EllipticCurvePoint according to SECG 2.3.4 - */ - public static ECPoint decodeECPoint(byte[] M, EllipticCurve curve) { - if (M.length == 0) { - return null; - } - - // M has len 2 ceil(log_2(q)/8) + 1 ? - int elementSize = (curve.getField().getFieldSize() + 7) / 8; - if (M.length != 2 * elementSize + 1) { - return null; - } - - // step 3.2 - if (M[0] != 0x04) { - return null; - } - - // Step 3.3 - byte[] xp = new byte[elementSize]; - System.arraycopy(M, 1, xp, 0, elementSize); - - // Step 3.4 - byte[] yp = new byte[elementSize]; - System.arraycopy(M, 1 + elementSize, yp, 0, elementSize); - - ECPoint P = new ECPoint(new BigInteger(1, xp), new BigInteger(1, yp)); - - // TODO check point 3.5 - - // Step 3.6 - return P; - } - - public static class EllipticCurves { - public static ECParameterSpec nistp256 = new ECParameterSpec( - new EllipticCurve( - new ECFieldFp(new BigInteger("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", 16)), - new BigInteger("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", 16), - new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16)), - new ECPoint(new BigInteger("6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", 16), - new BigInteger("4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", 16)), - new BigInteger("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", 16), - 1); - - public static ECParameterSpec nistp384 = new ECParameterSpec( - new EllipticCurve( - new ECFieldFp(new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", 16)), - new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", 16), - new BigInteger("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", 16)), - new ECPoint(new BigInteger("AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", 16), - new BigInteger("3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", 16)), - new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", 16), - 1); - - public static ECParameterSpec nistp521 = new ECParameterSpec( - new EllipticCurve( - new ECFieldFp(new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16)), - new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", 16), - new BigInteger("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", 16) - ), - new ECPoint(new BigInteger("00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", 16), - new BigInteger("011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", 16) - ), - new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 16), - 1); - } -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a6044372/digitalocean2/src/test/java/org/jclouds/digitalocean2/DigitalOcean2ProviderMetadataTest.java ---------------------------------------------------------------------- diff --git a/digitalocean2/src/test/java/org/jclouds/digitalocean2/DigitalOcean2ProviderMetadataTest.java b/digitalocean2/src/test/java/org/jclouds/digitalocean2/DigitalOcean2ProviderMetadataTest.java deleted file mode 100644 index 7756813..0000000 --- a/digitalocean2/src/test/java/org/jclouds/digitalocean2/DigitalOcean2ProviderMetadataTest.java +++ /dev/null @@ -1,29 +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.digitalocean2; - -import org.jclouds.providers.internal.BaseProviderMetadataTest; -import org.testng.annotations.Test; - -@Test(groups = "unit", testName = "DigitalOcean2ProviderMetadataTest") -public class DigitalOcean2ProviderMetadataTest extends BaseProviderMetadataTest { - - public DigitalOcean2ProviderMetadataTest() { - super(new DigitalOcean2ProviderMetadata(), new DigitalOcean2ApiMetadata()); - } - -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a6044372/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/DigitalOcean2ComputeServiceLiveTest.java ---------------------------------------------------------------------- diff --git a/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/DigitalOcean2ComputeServiceLiveTest.java b/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/DigitalOcean2ComputeServiceLiveTest.java deleted file mode 100644 index f45a73f..0000000 --- a/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/DigitalOcean2ComputeServiceLiveTest.java +++ /dev/null @@ -1,66 +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.digitalocean2.compute; - -import org.jclouds.compute.domain.NodeMetadata; -import org.jclouds.compute.internal.BaseComputeServiceLiveTest; -import org.jclouds.digitalocean2.config.DigitalOcean2RateLimitModule; -import org.jclouds.sshj.config.SshjSshClientModule; -import org.testng.annotations.Test; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.inject.Module; - -/** - * Live tests for the {@link org.jclouds.compute.ComputeService} integration. - */ -@Test(groups = "live", singleThreaded = true, testName = "DigitalOcean2ComputeServiceLiveTest") -public class DigitalOcean2ComputeServiceLiveTest extends BaseComputeServiceLiveTest { - - public DigitalOcean2ComputeServiceLiveTest() { - provider = "digitalocean2"; - } - - @Override - protected Module getSshModule() { - return new SshjSshClientModule(); - } - - @Override - protected Iterable<Module> setupModules() { - return ImmutableSet.<Module> builder().addAll(super.setupModules()).add(new DigitalOcean2RateLimitModule()) - .build(); - } - - @Override - public void testOptionToNotBlock() throws Exception { - // DigitalOcean ComputeService implementation has to block until the node - // is provisioned, to be able to return it. - } - - @Override - protected void checkTagsInNodeEquals(NodeMetadata node, ImmutableSet<String> tags) { - // We encode the tags in the user data but the DigitalOcean API does not return it - } - - @Override - protected void checkUserMetadataContains(NodeMetadata node, ImmutableMap<String, String> userMetadata) { - // The DigitalOcean API does not return the user data - } - -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a6044372/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/DigitalOcean2TemplateBuilderLiveTest.java ---------------------------------------------------------------------- diff --git a/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/DigitalOcean2TemplateBuilderLiveTest.java b/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/DigitalOcean2TemplateBuilderLiveTest.java deleted file mode 100644 index ee7b962..0000000 --- a/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/DigitalOcean2TemplateBuilderLiveTest.java +++ /dev/null @@ -1,55 +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.digitalocean2.compute; - -import static org.jclouds.compute.util.ComputeServiceUtils.getCores; -import static org.testng.Assert.assertEquals; - -import java.io.IOException; -import java.util.Set; - -import org.jclouds.compute.domain.OsFamily; -import org.jclouds.compute.domain.Template; -import org.jclouds.compute.internal.BaseTemplateBuilderLiveTest; -import org.testng.annotations.Test; - -import com.google.common.collect.ImmutableSet; - -@Test(groups = "live", testName = "DigitalOcean2TemplateBuilderLiveTest") -public class DigitalOcean2TemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { - - public DigitalOcean2TemplateBuilderLiveTest() { - provider = "digitalocean2"; - } - - @Test - @Override - public void testDefaultTemplateBuilder() throws IOException { - Template defaultTemplate = view.getComputeService().templateBuilder().build(); - assert defaultTemplate.getImage().getOperatingSystem().getVersion().equals("15.10") : defaultTemplate - .getImage().getOperatingSystem().getVersion(); - assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); - assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); - assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); - } - - @Override - protected Set<String> getIso3166Codes() { - return ImmutableSet.<String> of(); - } - -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a6044372/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/config/ActionDonePredicateTest.java ---------------------------------------------------------------------- diff --git a/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/config/ActionDonePredicateTest.java b/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/config/ActionDonePredicateTest.java deleted file mode 100644 index 0c852a1..0000000 --- a/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/config/ActionDonePredicateTest.java +++ /dev/null @@ -1,74 +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.digitalocean2.compute.config; - -import static org.easymock.EasyMock.anyInt; -import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.replay; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.fail; - -import java.util.Date; - -import org.easymock.EasyMock; -import org.jclouds.digitalocean2.DigitalOcean2Api; -import org.jclouds.digitalocean2.compute.config.DigitalOcean2ComputeServiceContextModule.ActionDonePredicate; -import org.jclouds.digitalocean2.domain.Action; -import org.jclouds.digitalocean2.features.ActionApi; -import org.testng.annotations.Test; - -@Test(groups = "unit", testName = "ActionDonePredicateTest") -public class ActionDonePredicateTest { - - public void testActionStatusOk() { - ActionApi actionApi = EasyMock.createMock(ActionApi.class); - DigitalOcean2Api api = EasyMock.createMock(DigitalOcean2Api.class); - - expect(actionApi.get(1)).andReturn(action(Action.Status.COMPLETED)); - expect(actionApi.get(2)).andReturn(action(Action.Status.IN_PROGRESS)); - expect(api.actionApi()).andReturn(actionApi).times(2); - replay(actionApi, api); - - ActionDonePredicate predicate = new ActionDonePredicate(api); - assertTrue(predicate.apply(1)); - assertFalse(predicate.apply(2)); - } - - public void testActionStatusError() { - ActionApi actionApi = EasyMock.createMock(ActionApi.class); - DigitalOcean2Api api = EasyMock.createMock(DigitalOcean2Api.class); - - expect(actionApi.get(anyInt())).andReturn(action(Action.Status.ERRORED)); - expect(api.actionApi()).andReturn(actionApi); - replay(actionApi, api); - - ActionDonePredicate predicate = new ActionDonePredicate(api); - - try { - predicate.apply(1); - fail("Method should have thrown an IllegalStateException"); - } catch (IllegalStateException ex) { - assertEquals(ex.getMessage(), "Resource is in invalid status: ERRORED"); - } - } - - private static Action action(Action.Status status) { - return Action.create(1, status, "foo", new Date(), new Date(), 1, "", null, ""); - } -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/a6044372/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/config/DropletInStatusPredicateTest.java ---------------------------------------------------------------------- diff --git a/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/config/DropletInStatusPredicateTest.java b/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/config/DropletInStatusPredicateTest.java deleted file mode 100644 index 4445907..0000000 --- a/digitalocean2/src/test/java/org/jclouds/digitalocean2/compute/config/DropletInStatusPredicateTest.java +++ /dev/null @@ -1,58 +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.digitalocean2.compute.config; - -import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.replay; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; - -import java.util.Date; - -import org.easymock.EasyMock; -import org.jclouds.digitalocean2.DigitalOcean2Api; -import org.jclouds.digitalocean2.compute.config.DigitalOcean2ComputeServiceContextModule.DropletInStatusPredicate; -import org.jclouds.digitalocean2.domain.Droplet; -import org.jclouds.digitalocean2.domain.Droplet.Status; -import org.jclouds.digitalocean2.features.DropletApi; -import org.testng.annotations.Test; - -import com.google.common.collect.ImmutableList; - -@Test(groups = "unit", testName = "DropletInStatusPredicateTest") -public class DropletInStatusPredicateTest { - - public void testDropletSuspended() { - DropletApi dropletApi = EasyMock.createMock(DropletApi.class); - DigitalOcean2Api api = EasyMock.createMock(DigitalOcean2Api.class); - - expect(dropletApi.get(1)).andReturn(mockDroplet(Status.ACTIVE)); - expect(dropletApi.get(2)).andReturn(mockDroplet(Status.OFF)); - expect(api.dropletApi()).andReturn(dropletApi).times(2); - replay(dropletApi, api); - - DropletInStatusPredicate predicate = new DropletInStatusPredicate(api, Status.OFF); - assertFalse(predicate.apply(1)); - assertTrue(predicate.apply(2)); - } - - private static Droplet mockDroplet(Status status) { - return Droplet.create(1, "foo", 1024, 1, 20, false, new Date(), status, - ImmutableList.<Integer> of(), ImmutableList.<Integer> of(), ImmutableList.<String> of(), null, null, null, - "", null, null); - } -}
