migrated sts and route53 entirely off deprecated async interfaces

This commit is contained in:
adriancole 2013-04-09 14:02:23 -07:00
parent 61067d3683
commit dce0ecd889
20 changed files with 393 additions and 578 deletions

View File

@ -20,22 +20,35 @@ package org.jclouds.route53;
import java.io.Closeable; import java.io.Closeable;
import javax.inject.Named;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam; import javax.ws.rs.PathParam;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.route53.domain.Change; import org.jclouds.route53.domain.Change;
import org.jclouds.route53.features.ResourceRecordSetApi;
import org.jclouds.route53.features.HostedZoneApi; import org.jclouds.route53.features.HostedZoneApi;
import org.jclouds.route53.features.ResourceRecordSetApi;
import org.jclouds.route53.filters.RestAuthentication;
import org.jclouds.route53.xml.ChangeHandler;
/** /**
* Provides access to Amazon Route53 via the Query API * Provides access to Amazon Route53 via the Query API
* <p/> * <p/>
* *
* @see Route53AsyncApi
* @see <a href="http://docs.amazonwebservices.com/Route53/latest/APIReference" * @see <a href="http://docs.amazonwebservices.com/Route53/latest/APIReference"
* /> * />
* @author Adrian Cole * @author Adrian Cole
*/ */
@RequestFilters(RestAuthentication.class)
@VirtualHost
@Path("/{jclouds.api-version}")
public interface Route53Api extends Closeable { public interface Route53Api extends Closeable {
/** /**
@ -45,17 +58,24 @@ public interface Route53Api extends Closeable {
* The ID of the change batch request. * The ID of the change batch request.
* @return null, if not found * @return null, if not found
*/ */
Change getChange(String changeID); @Named("GetChange")
@GET
@Path("/change/{changeId}")
@XMLResponseParser(ChangeHandler.class)
@Fallback(NullOnNotFoundOr404.class)
@Nullable
Change getChange(@PathParam("changeId") String changeID);
/** /**
* Provides synchronous access to Zone features. * Provides access to Zone features.
*/ */
@Delegate @Delegate
HostedZoneApi getHostedZoneApi(); HostedZoneApi getHostedZoneApi();
/** /**
* Provides synchronous access to record set features. * Provides access to record set features.
*/ */
@Delegate @Delegate
@Path("/hostedzone/{zoneId}")
ResourceRecordSetApi getResourceRecordSetApiForHostedZone(@PathParam("zoneId") String zoneId); ResourceRecordSetApi getResourceRecordSetApiForHostedZone(@PathParam("zoneId") String zoneId);
} }

View File

@ -25,35 +25,23 @@ import java.net.URI;
import java.util.Properties; import java.util.Properties;
import org.jclouds.apis.ApiMetadata; import org.jclouds.apis.ApiMetadata;
import org.jclouds.rest.internal.BaseRestApiMetadata; import org.jclouds.rest.internal.BaseHttpApiMetadata;
import org.jclouds.route53.config.Route53RestClientModule; import org.jclouds.route53.config.Route53HttpApiModule;
import com.google.common.reflect.TypeToken;
/** /**
* Implementation of {@link ApiMetadata} for Amazon's Route53 api. * Implementation of {@link ApiMetadata} for Amazon's Route53 api.
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public class Route53ApiMetadata extends BaseRestApiMetadata { public class Route53ApiMetadata extends BaseHttpApiMetadata<Route53Api> {
/**
* @deprecated please use {@code org.jclouds.ContextBuilder#buildApi(Route53Api.class)} as
* {@link Route53AsyncApi} interface will be removed in jclouds 1.7.
*/
@Deprecated
public static final TypeToken<org.jclouds.rest.RestContext<? extends Route53Api, ? extends Route53AsyncApi>> CONTEXT_TOKEN = new TypeToken<org.jclouds.rest.RestContext<? extends Route53Api, ? extends Route53AsyncApi>>() {
private static final long serialVersionUID = 1L;
};
@Override @Override
public Builder toBuilder() { public Builder toBuilder() {
return new Builder(getApi(), getAsyncApi()).fromApiMetadata(this); return new Builder().fromApiMetadata(this);
} }
@SuppressWarnings("deprecation")
public Route53ApiMetadata() { public Route53ApiMetadata() {
this(new Builder(Route53Api.class, Route53AsyncApi.class)); this(new Builder());
} }
protected Route53ApiMetadata(Builder builder) { protected Route53ApiMetadata(Builder builder) {
@ -61,16 +49,15 @@ public class Route53ApiMetadata extends BaseRestApiMetadata {
} }
public static Properties defaultProperties() { public static Properties defaultProperties() {
Properties properties = BaseRestApiMetadata.defaultProperties(); Properties properties = BaseHttpApiMetadata.defaultProperties();
properties.setProperty(PROPERTY_AUTH_TAG, "AWS"); properties.setProperty(PROPERTY_AUTH_TAG, "AWS");
properties.setProperty(PROPERTY_HEADER_TAG, "amz"); properties.setProperty(PROPERTY_HEADER_TAG, "amz");
return properties; return properties;
} }
public static class Builder extends BaseRestApiMetadata.Builder<Builder> { public static class Builder extends BaseHttpApiMetadata.Builder<Route53Api, Builder> {
protected Builder(Class<?> api, Class<?> asyncApi) { protected Builder() {
super(api, asyncApi);
id("route53") id("route53")
.name("Amazon Route 53 Api") .name("Amazon Route 53 Api")
.identityName("Access Key ID") .identityName("Access Key ID")
@ -79,7 +66,7 @@ public class Route53ApiMetadata extends BaseRestApiMetadata {
.documentation(URI.create("http://docs.aws.amazon.com/Route53/latest/APIReference/")) .documentation(URI.create("http://docs.aws.amazon.com/Route53/latest/APIReference/"))
.defaultEndpoint("https://route53.amazonaws.com") .defaultEndpoint("https://route53.amazonaws.com")
.defaultProperties(Route53ApiMetadata.defaultProperties()) .defaultProperties(Route53ApiMetadata.defaultProperties())
.defaultModule(Route53RestClientModule.class); .defaultModule(Route53HttpApiModule.class);
} }
@Override @Override

View File

@ -1,79 +0,0 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.route53;
import java.io.Closeable;
import javax.inject.Named;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.route53.domain.Change;
import org.jclouds.route53.features.ResourceRecordSetAsyncApi;
import org.jclouds.route53.features.HostedZoneAsyncApi;
import org.jclouds.route53.filters.RestAuthentication;
import org.jclouds.route53.xml.ChangeHandler;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides access to Amazon Route53 via the Query API
* <p/>
*
* @see <a href="http://docs.amazonwebservices.com/Route53/latest/APIReference"
* />
* @author Adrian Cole
* @deprecated please use {@code org.jclouds.ContextBuilder#buildApi(Route53Api.class)} as
* {@link Route53AsyncApi} interface will be removed in jclouds 1.7.
*/
@Deprecated
@RequestFilters(RestAuthentication.class)
@VirtualHost
@Path("/{jclouds.api-version}")
public interface Route53AsyncApi extends Closeable {
/**
* @see Route53Api#getChange()
*/
@Named("GetChange")
@GET
@Path("/change/{changeId}")
@XMLResponseParser(ChangeHandler.class)
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<Change> getChange(@PathParam("changeId") String changeID);
/**
* Provides asynchronous access to Zone features.
*/
@Delegate
HostedZoneAsyncApi getHostedZoneApi();
/**
* Provides asynchronous access to record set features.
*/
@Delegate
ResourceRecordSetAsyncApi getResourceRecordSetApiForHostedZone(@PathParam("zoneId") String zoneId);
}

View File

@ -18,32 +18,23 @@
*/ */
package org.jclouds.route53.config; package org.jclouds.route53.config;
import static org.jclouds.reflect.Reflection2.typeToken;
import java.util.Date; import java.util.Date;
import java.util.Map;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.aws.config.AWSRestClientModule; import org.jclouds.aws.config.AWSHttpApiModule;
import org.jclouds.date.DateService; import org.jclouds.date.DateService;
import org.jclouds.date.TimeStamp; import org.jclouds.date.TimeStamp;
import org.jclouds.http.HttpErrorHandler; import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.annotation.ClientError; import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection; import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError; import org.jclouds.http.annotation.ServerError;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.rest.RequestSigner; import org.jclouds.rest.RequestSigner;
import org.jclouds.route53.Route53Api; import org.jclouds.route53.Route53Api;
import org.jclouds.route53.Route53AsyncApi;
import org.jclouds.route53.features.ResourceRecordSetApi;
import org.jclouds.route53.features.ResourceRecordSetAsyncApi;
import org.jclouds.route53.features.HostedZoneApi;
import org.jclouds.route53.features.HostedZoneAsyncApi;
import org.jclouds.route53.filters.RestAuthentication; import org.jclouds.route53.filters.RestAuthentication;
import org.jclouds.route53.handlers.Route53ErrorHandler; import org.jclouds.route53.handlers.Route53ErrorHandler;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Provides; import com.google.inject.Provides;
/** /**
@ -51,14 +42,9 @@ import com.google.inject.Provides;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@ConfiguresRestClient @ConfiguresHttpApi
public class Route53RestClientModule extends AWSRestClientModule<Route53Api, Route53AsyncApi> { public class Route53HttpApiModule extends AWSHttpApiModule<Route53Api> {
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()// public Route53HttpApiModule() {
.put(HostedZoneApi.class, HostedZoneAsyncApi.class)
.put(ResourceRecordSetApi.class, ResourceRecordSetAsyncApi.class).build();
public Route53RestClientModule() {
super(typeToken(Route53Api.class), typeToken(Route53AsyncApi.class), DELEGATE_MAP);
} }
@Provides @Provides

View File

@ -18,22 +18,48 @@
*/ */
package org.jclouds.route53.features; package org.jclouds.route53.features;
import static javax.ws.rs.core.MediaType.APPLICATION_XML;
import javax.inject.Named;
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.QueryParam;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.collect.IterableWithMarker; import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.PagedIterable; import org.jclouds.collect.PagedIterable;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.Payload;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.Transform;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.route53.domain.Change; import org.jclouds.route53.domain.Change;
import org.jclouds.route53.domain.Change.Status; import org.jclouds.route53.domain.Change.Status;
import org.jclouds.route53.domain.HostedZone; import org.jclouds.route53.domain.HostedZone;
import org.jclouds.route53.domain.HostedZoneAndNameServers; import org.jclouds.route53.domain.HostedZoneAndNameServers;
import org.jclouds.route53.domain.NewHostedZone; import org.jclouds.route53.domain.NewHostedZone;
import org.jclouds.route53.filters.RestAuthentication;
import org.jclouds.route53.functions.HostedZonesToPagedIterable;
import org.jclouds.route53.xml.ChangeHandler;
import org.jclouds.route53.xml.CreateHostedZoneResponseHandler;
import org.jclouds.route53.xml.GetHostedZoneResponseHandler;
import org.jclouds.route53.xml.ListHostedZonesResponseHandler;
/** /**
* @see HostedZoneAsyncApi
* @see <a href= * @see <a href=
* "http://docs.aws.amazon.com/Route53/latest/APIReference/ActionsOnHostedZones.html" * "http://docs.aws.amazon.com/Route53/latest/APIReference/ActionsOnHostedZones.html"
* /> * />
* @author Adrian Cole * @author Adrian Cole
*/ */
@RequestFilters(RestAuthentication.class)
@VirtualHost
public interface HostedZoneApi { public interface HostedZoneApi {
/** /**
@ -51,28 +77,55 @@ public interface HostedZoneApi {
* retries. ex. {@code MyDNSMigration_01} * retries. ex. {@code MyDNSMigration_01}
* @return the new zone in progress, in {@link Status#PENDING}. * @return the new zone in progress, in {@link Status#PENDING}.
*/ */
NewHostedZone createWithReference(String name, String callerReference); @Named("CreateHostedZone")
@POST
@Produces(APPLICATION_XML)
@Path("/hostedzone")
@Payload("<CreateHostedZoneRequest xmlns=\"https://route53.amazonaws.com/doc/2012-02-29/\"><Name>{name}</Name><CallerReference>{callerReference}</CallerReference></CreateHostedZoneRequest>")
@XMLResponseParser(CreateHostedZoneResponseHandler.class)
NewHostedZone createWithReference(@PayloadParam("name") String name,
@PayloadParam("callerReference") String callerReference);
/** /**
* like {@link #createWithReference(String, String)}, except you can specify * like {@link #createWithReference(String, String)}, except you can specify
* a comment. * a comment.
*/ */
NewHostedZone createWithReferenceAndComment(String name, String callerReference, String comment); @Named("CreateHostedZone")
@POST
@Produces(APPLICATION_XML)
@Path("/hostedzone")
@Payload("<CreateHostedZoneRequest xmlns=\"https://route53.amazonaws.com/doc/2012-02-29/\"><Name>{name}</Name><CallerReference>{callerReference}</CallerReference><HostedZoneConfig><Comment>{comment}</Comment></HostedZoneConfig></CreateHostedZoneRequest>")
@XMLResponseParser(CreateHostedZoneResponseHandler.class)
NewHostedZone createWithReferenceAndComment(@PayloadParam("name") String name,
@PayloadParam("callerReference") String callerReference, @PayloadParam("comment") String comment);
/** /**
* returns all zones in order. * returns all zones in order.
*/ */
@Named("ListHostedZones")
@GET
@Path("/hostedzone")
@XMLResponseParser(ListHostedZonesResponseHandler.class)
@Transform(HostedZonesToPagedIterable.class)
PagedIterable<HostedZone> list(); PagedIterable<HostedZone> list();
/** /**
* retrieves up to 100 zones in order. * retrieves up to 100 zones in order.
*/ */
@Named("ListHostedZones")
@GET
@Path("/hostedzone")
@XMLResponseParser(ListHostedZonesResponseHandler.class)
IterableWithMarker<HostedZone> listFirstPage(); IterableWithMarker<HostedZone> listFirstPage();
/** /**
* retrieves up to 100 zones in order, starting at {@code nextMarker} * retrieves up to 100 zones in order, starting at {@code nextMarker}
*/ */
IterableWithMarker<HostedZone> listAt(String nextMarker); @Named("ListHostedZones")
@GET
@Path("/hostedzone")
@XMLResponseParser(ListHostedZonesResponseHandler.class)
IterableWithMarker<HostedZone> listAt(@QueryParam("marker") String nextMarker);
/** /**
* Retrieves information about the specified zone, including its nameserver * Retrieves information about the specified zone, including its nameserver
@ -83,8 +136,13 @@ public interface HostedZoneApi {
* {@code Z1PA6795UKMFR9} * {@code Z1PA6795UKMFR9}
* @return null if not found * @return null if not found
*/ */
@Named("GetHostedZone")
@GET
@Path("/hostedzone/{zoneId}")
@XMLResponseParser(GetHostedZoneResponseHandler.class)
@Fallback(NullOnNotFoundOr404.class)
@Nullable @Nullable
HostedZoneAndNameServers get(String id); HostedZoneAndNameServers get(@PathParam("zoneId") String zoneId);
/** /**
* This action deletes a hosted zone. * This action deletes a hosted zone.
@ -93,6 +151,11 @@ public interface HostedZoneApi {
* id of the zone to delete. ex {@code Z1PA6795UKMFR9} * id of the zone to delete. ex {@code Z1PA6795UKMFR9}
* @return null if not found or the change in progress * @return null if not found or the change in progress
*/ */
@Named("DeleteHostedZone")
@DELETE
@Path("/hostedzone/{zoneId}")
@XMLResponseParser(ChangeHandler.class)
@Fallback(NullOnNotFoundOr404.class)
@Nullable @Nullable
Change delete(String id); Change delete(@PathParam("zoneId") String zoneId);
} }

View File

@ -1,137 +0,0 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.route53.features;
import static javax.ws.rs.core.MediaType.APPLICATION_XML;
import javax.inject.Named;
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.QueryParam;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.PagedIterable;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.Payload;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.Transform;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.route53.domain.Change;
import org.jclouds.route53.domain.HostedZone;
import org.jclouds.route53.domain.HostedZoneAndNameServers;
import org.jclouds.route53.domain.NewHostedZone;
import org.jclouds.route53.filters.RestAuthentication;
import org.jclouds.route53.functions.HostedZonesToPagedIterable;
import org.jclouds.route53.xml.ChangeHandler;
import org.jclouds.route53.xml.CreateHostedZoneResponseHandler;
import org.jclouds.route53.xml.GetHostedZoneResponseHandler;
import org.jclouds.route53.xml.ListHostedZonesResponseHandler;
import com.google.common.util.concurrent.ListenableFuture;
/**
* @see HostedZoneApi
* @see <a href=
* "http://docs.aws.amazon.com/Route53/latest/APIReference/ActionsOnHostedZones.html"
* />
* @author Adrian Cole
*/
@RequestFilters(RestAuthentication.class)
@VirtualHost
@Path("/{jclouds.api-version}")
public interface HostedZoneAsyncApi {
/**
* @see HostedZoneApi#createWithReference
*/
@Named("CreateHostedZone")
@POST
@Produces(APPLICATION_XML)
@Path("/hostedzone")
@Payload("<CreateHostedZoneRequest xmlns=\"https://route53.amazonaws.com/doc/2012-02-29/\"><Name>{name}</Name><CallerReference>{callerReference}</CallerReference></CreateHostedZoneRequest>")
@XMLResponseParser(CreateHostedZoneResponseHandler.class)
ListenableFuture<NewHostedZone> createWithReference(@PayloadParam("name") String name,
@PayloadParam("callerReference") String callerReference);
/**
* @see HostedZoneApi#createWithReferenceAndComment
*/
@Named("CreateHostedZone")
@POST
@Produces(APPLICATION_XML)
@Path("/hostedzone")
@Payload("<CreateHostedZoneRequest xmlns=\"https://route53.amazonaws.com/doc/2012-02-29/\"><Name>{name}</Name><CallerReference>{callerReference}</CallerReference><HostedZoneConfig><Comment>{comment}</Comment></HostedZoneConfig></CreateHostedZoneRequest>")
@XMLResponseParser(CreateHostedZoneResponseHandler.class)
ListenableFuture<NewHostedZone> createWithReferenceAndComment(@PayloadParam("name") String name,
@PayloadParam("callerReference") String callerReference, @PayloadParam("comment") String comment);
/**
* @see HostedZoneApi#list()
*/
@Named("ListHostedZones")
@GET
@Path("/hostedzone")
@XMLResponseParser(ListHostedZonesResponseHandler.class)
@Transform(HostedZonesToPagedIterable.class)
ListenableFuture<PagedIterable<HostedZone>> list();
/**
* @see HostedZoneApi#listFirstPage
*/
@Named("ListHostedZones")
@GET
@Path("/hostedzone")
@XMLResponseParser(ListHostedZonesResponseHandler.class)
ListenableFuture<IterableWithMarker<HostedZone>> listFirstPage();
/**
* @see HostedZoneApi#listAt(String)
*/
@Named("ListHostedZones")
@GET
@Path("/hostedzone")
@XMLResponseParser(ListHostedZonesResponseHandler.class)
ListenableFuture<IterableWithMarker<HostedZone>> listAt(@QueryParam("marker") String nextMarker);
/**
* @see HostedZoneApi#get()
*/
@Named("GetHostedZone")
@GET
@Path("/hostedzone/{zoneId}")
@XMLResponseParser(GetHostedZoneResponseHandler.class)
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<HostedZoneAndNameServers> get(@PathParam("zoneId") String zoneId);
/**
* @see HostedZoneApi#delete()
*/
@Named("DeleteHostedZone")
@DELETE
@Path("/hostedzone/{zoneId}")
@XMLResponseParser(ChangeHandler.class)
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<Change> delete(@PathParam("zoneId") String zoneId);
}

View File

@ -18,48 +18,98 @@
*/ */
package org.jclouds.route53.features; package org.jclouds.route53.features;
import static javax.ws.rs.core.MediaType.APPLICATION_XML;
import javax.inject.Named;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.collect.PagedIterable; import org.jclouds.collect.PagedIterable;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.ParamParser;
import org.jclouds.rest.annotations.Payload;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.Transform;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.route53.binders.BindChangeBatch;
import org.jclouds.route53.binders.BindNextRecord;
import org.jclouds.route53.domain.Change; import org.jclouds.route53.domain.Change;
import org.jclouds.route53.domain.ChangeBatch; import org.jclouds.route53.domain.ChangeBatch;
import org.jclouds.route53.domain.ResourceRecordSet; import org.jclouds.route53.domain.ResourceRecordSet;
import org.jclouds.route53.domain.ResourceRecordSetIterable; import org.jclouds.route53.domain.ResourceRecordSetIterable;
import org.jclouds.route53.domain.ResourceRecordSetIterable.NextRecord; import org.jclouds.route53.domain.ResourceRecordSetIterable.NextRecord;
import org.jclouds.route53.filters.RestAuthentication;
import org.jclouds.route53.functions.ResourceRecordSetIterableToPagedIterable;
import org.jclouds.route53.functions.SerializeRRS;
import org.jclouds.route53.xml.ChangeHandler;
import org.jclouds.route53.xml.ListResourceRecordSetsResponseHandler;
/** /**
* @see ResourceRecordSetAsyncApi
* @see <a href= * @see <a href=
* "http://docs.aws.amazon.com/Route53/latest/APIReference/ActionsOnRRS.html" * "http://docs.aws.amazon.com/Route53/latest/APIReference/ActionsOnRRS.html"
* /> * />
* @author Adrian Cole * @author Adrian Cole
*/ */
@RequestFilters(RestAuthentication.class)
@VirtualHost
public interface ResourceRecordSetApi { public interface ResourceRecordSetApi {
/** /**
* schedules creation of the resource record set. * schedules creation of the resource record set.
*/ */
Change create(ResourceRecordSet rrs); @Named("ChangeResourceRecordSets")
@POST
@Produces(APPLICATION_XML)
@Path("/rrset")
@Payload("<ChangeResourceRecordSetsRequest xmlns=\"https://route53.amazonaws.com/doc/2012-02-29/\"><ChangeBatch><Changes><Change><Action>CREATE</Action>{rrs}</Change></Changes></ChangeBatch></ChangeResourceRecordSetsRequest>")
@XMLResponseParser(ChangeHandler.class)
Change create(@PayloadParam("rrs") @ParamParser(SerializeRRS.class) ResourceRecordSet rrs);
/** /**
* applies a batch of changes atomically. * applies a batch of changes atomically.
*/ */
Change apply(ChangeBatch changes); @Named("ChangeResourceRecordSets")
@POST
@Produces(APPLICATION_XML)
@Path("/rrset")
@XMLResponseParser(ChangeHandler.class)
Change apply(@BinderParam(BindChangeBatch.class) ChangeBatch changes);
/** /**
* returns all resource record sets in order. * returns all resource record sets in order.
*/ */
@Named("ListResourceRecordSets")
@GET
@Path("/rrset")
@XMLResponseParser(ListResourceRecordSetsResponseHandler.class)
@Transform(ResourceRecordSetIterableToPagedIterable.class)
PagedIterable<ResourceRecordSet> list(); PagedIterable<ResourceRecordSet> list();
/** /**
* retrieves up to 100 resource record sets in order. * retrieves up to 100 resource record sets in order.
*/ */
@Named("ListResourceRecordSets")
@GET
@Path("/rrset")
@XMLResponseParser(ListResourceRecordSetsResponseHandler.class)
ResourceRecordSetIterable listFirstPage(); ResourceRecordSetIterable listFirstPage();
/** /**
* retrieves up to 100 resource record sets in order, starting at * retrieves up to 100 resource record sets in order, starting at
* {@code nextRecord} * {@code nextRecord}
*/ */
ResourceRecordSetIterable listAt(NextRecord nextRecord); @Named("ListResourceRecordSets")
@GET
@Path("/rrset")
@XMLResponseParser(ListResourceRecordSetsResponseHandler.class)
ResourceRecordSetIterable listAt(@BinderParam(BindNextRecord.class) NextRecord nextRecord);
/** /**
* This action deletes a resource record set. * This action deletes a resource record set.
@ -68,6 +118,13 @@ public interface ResourceRecordSetApi {
* the resource record set to delete * the resource record set to delete
* @return null if not found or the change in progress * @return null if not found or the change in progress
*/ */
@Named("ChangeResourceRecordSets")
@POST
@Produces(APPLICATION_XML)
@Path("/rrset")
@Payload("<ChangeResourceRecordSetsRequest xmlns=\"https://route53.amazonaws.com/doc/2012-02-29/\"><ChangeBatch><Changes><Change><Action>DELETE</Action>{rrs}</Change></Changes></ChangeBatch></ChangeResourceRecordSetsRequest>")
@XMLResponseParser(ChangeHandler.class)
@Fallback(NullOnNotFoundOr404.class)
@Nullable @Nullable
Change delete(ResourceRecordSet rrs); Change delete(@PayloadParam("rrs") @ParamParser(SerializeRRS.class) ResourceRecordSet rrs);
} }

View File

@ -1,126 +0,0 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.route53.features;
import static javax.ws.rs.core.MediaType.APPLICATION_XML;
import javax.inject.Named;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.collect.PagedIterable;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.ParamParser;
import org.jclouds.rest.annotations.Payload;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.Transform;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.route53.binders.BindChangeBatch;
import org.jclouds.route53.binders.BindNextRecord;
import org.jclouds.route53.domain.Change;
import org.jclouds.route53.domain.ChangeBatch;
import org.jclouds.route53.domain.ResourceRecordSet;
import org.jclouds.route53.domain.ResourceRecordSetIterable;
import org.jclouds.route53.domain.ResourceRecordSetIterable.NextRecord;
import org.jclouds.route53.filters.RestAuthentication;
import org.jclouds.route53.functions.ResourceRecordSetIterableToPagedIterable;
import org.jclouds.route53.functions.SerializeRRS;
import org.jclouds.route53.xml.ChangeHandler;
import org.jclouds.route53.xml.ListResourceRecordSetsResponseHandler;
import com.google.common.util.concurrent.ListenableFuture;
/**
* @see ResourceRecordSetApi
* @see <a href=
* "http://docs.aws.amazon.com/Route53/latest/APIReference/ActionsOnRRS.html"
* />
* @author Adrian Cole
*/
@RequestFilters(RestAuthentication.class)
@VirtualHost
@Path("/{jclouds.api-version}/hostedzone/{zoneId}")
public interface ResourceRecordSetAsyncApi {
/**
* @see ResourceRecordSetApi#create
*/
@Named("ChangeResourceRecordSets")
@POST
@Produces(APPLICATION_XML)
@Path("/rrset")
@Payload("<ChangeResourceRecordSetsRequest xmlns=\"https://route53.amazonaws.com/doc/2012-02-29/\"><ChangeBatch><Changes><Change><Action>CREATE</Action>{rrs}</Change></Changes></ChangeBatch></ChangeResourceRecordSetsRequest>")
@XMLResponseParser(ChangeHandler.class)
ListenableFuture<Change> create(@PayloadParam("rrs") @ParamParser(SerializeRRS.class) ResourceRecordSet rrs);
/**
* @see ResourceRecordSetApi#apply
*/
@Named("ChangeResourceRecordSets")
@POST
@Produces(APPLICATION_XML)
@Path("/rrset")
@XMLResponseParser(ChangeHandler.class)
ListenableFuture<Change> apply(@BinderParam(BindChangeBatch.class) ChangeBatch changes);
/**
* @see ResourceRecordSetApi#list()
*/
@Named("ListResourceRecordSets")
@GET
@Path("/rrset")
@XMLResponseParser(ListResourceRecordSetsResponseHandler.class)
@Transform(ResourceRecordSetIterableToPagedIterable.class)
ListenableFuture<PagedIterable<ResourceRecordSet>> list();
/**
* @see ResourceRecordSetApi#listFirstPage
*/
@Named("ListResourceRecordSets")
@GET
@Path("/rrset")
@XMLResponseParser(ListResourceRecordSetsResponseHandler.class)
ListenableFuture<ResourceRecordSetIterable> listFirstPage();
/**
* @see ResourceRecordSetApi#listAt(NextRecord)
*/
@Named("ListResourceRecordSets")
@GET
@Path("/rrset")
@XMLResponseParser(ListResourceRecordSetsResponseHandler.class)
ListenableFuture<ResourceRecordSetIterable> listAt(@BinderParam(BindNextRecord.class) NextRecord nextRecord);
/**
* @see ResourceRecordSetApi#delete
*/
@Named("ChangeResourceRecordSets")
@POST
@Produces(APPLICATION_XML)
@Path("/rrset")
@Payload("<ChangeResourceRecordSetsRequest xmlns=\"https://route53.amazonaws.com/doc/2012-02-29/\"><ChangeBatch><Changes><Change><Action>DELETE</Action>{rrs}</Change></Changes></ChangeBatch></ChangeResourceRecordSetsRequest>")
@XMLResponseParser(ChangeHandler.class)
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<Change> delete(@PayloadParam("rrs") @ParamParser(SerializeRRS.class) ResourceRecordSet rrs);
}

View File

@ -19,7 +19,7 @@
package org.jclouds.route53; package org.jclouds.route53;
import org.jclouds.View; import org.jclouds.View;
import org.jclouds.rest.internal.BaseRestApiMetadataTest; import org.jclouds.rest.internal.BaseHttpApiMetadataTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
@ -30,9 +30,9 @@ import com.google.common.reflect.TypeToken;
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "unit", testName = "Route53ApiMetadataTest") @Test(groups = "unit", testName = "Route53ApiMetadataTest")
public class Route53ApiMetadataTest extends BaseRestApiMetadataTest { public class Route53ApiMetadataTest extends BaseHttpApiMetadataTest {
// no tenant abstraction, yet // no dns abstraction, yet
public Route53ApiMetadataTest() { public Route53ApiMetadataTest() {
super(new Route53ApiMetadata(), ImmutableSet.<TypeToken<? extends View>> of()); super(new Route53ApiMetadata(), ImmutableSet.<TypeToken<? extends View>> of());
} }

View File

@ -49,7 +49,8 @@ public class BaseRoute53ApiLiveTest extends BaseApiLiveTest<Route53Api> {
super.setup(); super.setup();
inSync = retry(new Predicate<Change>() { inSync = retry(new Predicate<Change>() {
public boolean apply(Change input) { public boolean apply(Change input) {
return api.getChange(input.getId()).getStatus() == INSYNC; Change change = api.getChange(input.getId());
return change != null && change.getStatus() == INSYNC;
} }
}, 600, 1, 5, SECONDS); }, 600, 1, 5, SECONDS);
} }

View File

@ -20,9 +20,9 @@ package org.jclouds.route53.internal;
import org.jclouds.date.DateService; import org.jclouds.date.DateService;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.rest.internal.BaseRestApiExpectTest; import org.jclouds.rest.internal.BaseRestApiExpectTest;
import org.jclouds.route53.config.Route53RestClientModule; import org.jclouds.route53.config.Route53HttpApiModule;
import com.google.inject.Module; import com.google.inject.Module;
@ -36,8 +36,8 @@ public class BaseRoute53ExpectTest<T> extends BaseRestApiExpectTest<T> {
provider = "route53"; provider = "route53";
} }
@ConfiguresRestClient @ConfiguresHttpApi
private static final class TestRoute53RestClientModule extends Route53RestClientModule { private static final class TestRoute53HttpApiModule extends Route53HttpApiModule {
@Override @Override
protected String provideTimeStamp(final DateService dateService) { protected String provideTimeStamp(final DateService dateService) {
@ -50,6 +50,6 @@ public class BaseRoute53ExpectTest<T> extends BaseRestApiExpectTest<T> {
@Override @Override
protected Module createModule() { protected Module createModule() {
return new TestRoute53RestClientModule(); return new TestRoute53HttpApiModule();
} }
} }

View File

@ -0,0 +1,73 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.aws.config;
import java.util.Set;
import javax.inject.Singleton;
import org.jclouds.aws.handlers.AWSClientErrorRetryHandler;
import org.jclouds.aws.handlers.ParseAWSErrorFromXmlContent;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.rest.config.HttpApiModule;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Provides;
/**
*
* @author Adrian Cole
*/
@ConfiguresHttpApi
public abstract class AWSHttpApiModule<A> extends HttpApiModule<A> {
protected AWSHttpApiModule() {
}
protected AWSHttpApiModule(Class<A> api) {
super(api);
}
@Provides
@ClientError
@Singleton
protected Set<String> provideRetryableCodes(){
return ImmutableSet.of("RequestTimeout", "OperationAborted", "SignatureDoesNotMatch");
}
@Override
protected void bindErrorHandlers() {
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseAWSErrorFromXmlContent.class);
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(ParseAWSErrorFromXmlContent.class);
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseAWSErrorFromXmlContent.class);
}
@Override
protected void bindRetryHandlers() {
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(AWSClientErrorRetryHandler.class);
}
}

View File

@ -0,0 +1,59 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.aws.config;
import java.util.Date;
import javax.inject.Singleton;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.date.DateService;
import org.jclouds.date.TimeStamp;
import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.rest.RequestSigner;
import com.google.inject.Provides;
/**
*
* @author Adrian Cole
*/
@ConfiguresHttpApi
public abstract class FormSigningHttpApiModule<A> extends AWSHttpApiModule<A> {
protected FormSigningHttpApiModule() {
}
protected FormSigningHttpApiModule(Class<A> api) {
super(api);
}
@Provides
@TimeStamp
protected String provideTimeStamp(DateService dateService) {
return dateService.iso8601DateFormat(new Date(System.currentTimeMillis()));
}
@Provides
@Singleton
RequestSigner provideRequestSigner(FormSigner in) {
return in;
}
}

View File

@ -18,12 +18,13 @@
*/ */
package org.jclouds.aws.xml; package org.jclouds.aws.xml;
import static org.jclouds.util.SaxUtils.currentOrNull;
import javax.inject.Inject; import javax.inject.Inject;
import org.jclouds.aws.domain.SessionCredentials; import org.jclouds.aws.domain.SessionCredentials;
import org.jclouds.date.DateService; import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.util.SaxUtils;
/** /**
* @see <a href= * @see <a href=
@ -55,13 +56,17 @@ public class SessionCredentialsHandler extends ParseSax.HandlerForGeneratedReque
@Override @Override
public void endElement(String uri, String name, String qName) { public void endElement(String uri, String name, String qName) {
if (qName.equals("AccessKeyId")) { if (qName.equals("AccessKeyId")) {
builder.accessKeyId(SaxUtils.currentOrNull(currentText)); builder.accessKeyId(currentOrNull(currentText));
} else if (qName.equals("SecretAccessKey")) { } else if (qName.equals("SecretAccessKey")) {
builder.secretAccessKey(SaxUtils.currentOrNull(currentText)); builder.secretAccessKey(currentOrNull(currentText));
} else if (qName.equals("SessionToken")) { } else if (qName.equals("SessionToken")) {
builder.sessionToken(SaxUtils.currentOrNull(currentText)); builder.sessionToken(currentOrNull(currentText));
} else if (qName.equals("Expiration")) { } else if (qName.equals("Expiration")) {
builder.expiration(dateService.iso8601DateParse(SaxUtils.currentOrNull(currentText))); try {
builder.expiration(dateService.iso8601SecondsDateParse(currentOrNull(currentText)));
} catch (IllegalArgumentException e) {
builder.expiration(dateService.iso8601DateParse(currentOrNull(currentText)));
}
} }
currentText = new StringBuilder(); currentText = new StringBuilder();
} }

View File

@ -20,32 +20,55 @@ package org.jclouds.sts;
import java.io.Closeable; import java.io.Closeable;
import javax.inject.Named;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.aws.domain.SessionCredentials; import org.jclouds.aws.domain.SessionCredentials;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.aws.xml.SessionCredentialsHandler;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.sts.domain.User; import org.jclouds.sts.domain.User;
import org.jclouds.sts.domain.UserAndSessionCredentials; import org.jclouds.sts.domain.UserAndSessionCredentials;
import org.jclouds.sts.options.AssumeRoleOptions; import org.jclouds.sts.options.AssumeRoleOptions;
import org.jclouds.sts.options.FederatedUserOptions; import org.jclouds.sts.options.FederatedUserOptions;
import org.jclouds.sts.options.SessionCredentialsOptions; import org.jclouds.sts.options.SessionCredentialsOptions;
import org.jclouds.sts.xml.UserAndSessionCredentialsHandler;
/** /**
* Provides access to Amazon STS via the Query API * Provides access to Amazon STS via the Query API
* <p/> * <p/>
* *
* @see STSAsyncApi
* @see <a href="http://docs.amazonwebservices.com/STS/latest/APIReference" /> * @see <a href="http://docs.amazonwebservices.com/STS/latest/APIReference" />
* @author Adrian Cole * @author Adrian Cole
*/ */
@RequestFilters(FormSigner.class)
@VirtualHost
public interface STSApi extends Closeable { public interface STSApi extends Closeable {
/** /**
* Returns a set of temporary credentials for an AWS account or IAM user, * Returns a set of temporary credentials for an AWS account or IAM user,
* with a default timeout * with a default timeout
*/ */
@Named("GetSessionToken")
@POST
@Path("/")
@XMLResponseParser(SessionCredentialsHandler.class)
@FormParams(keys = "Action", values = "GetSessionToken")
SessionCredentials createTemporaryCredentials(); SessionCredentials createTemporaryCredentials();
/** /**
* like {@link #createTemporaryCredentials()}, except you can modify the * like {@link #createTemporaryCredentials()}, except you can modify the
* timeout and other parameters. * timeout and other parameters.
*/ */
@Named("GetSessionToken")
@POST
@Path("/")
@XMLResponseParser(SessionCredentialsHandler.class)
@FormParams(keys = "Action", values = "GetSessionToken")
SessionCredentials createTemporaryCredentials(SessionCredentialsOptions options); SessionCredentials createTemporaryCredentials(SessionCredentialsOptions options);
/** /**
@ -58,13 +81,25 @@ public interface STSApi extends Closeable {
* The Amazon Resource Name (ARN) of the role that the caller is * The Amazon Resource Name (ARN) of the role that the caller is
* assuming. * assuming.
*/ */
UserAndSessionCredentials assumeRole(String roleArn, String sessionName); @Named("AssumeRole")
@POST
@Path("/")
@XMLResponseParser(UserAndSessionCredentialsHandler.class)
@FormParams(keys = "Action", values = "AssumeRole")
UserAndSessionCredentials assumeRole(@FormParam("RoleArn") String roleArn,
@FormParam("RoleSessionName") String sessionName);
/** /**
* like {@link #assumeRole(String, String)}, except you can modify the * like {@link #assumeRole(String, String)}, except you can modify the
* timeout and other parameters. * timeout and other parameters.
*/ */
UserAndSessionCredentials assumeRole(String roleArn, String sessionName, AssumeRoleOptions options); @Named("AssumeRole")
@POST
@Path("/")
@XMLResponseParser(UserAndSessionCredentialsHandler.class)
@FormParams(keys = "Action", values = "AssumeRole")
UserAndSessionCredentials assumeRole(@FormParam("RoleArn") String roleArn,
@FormParam("RoleSessionName") String sessionName, AssumeRoleOptions options);
/** /**
* Returns a set of temporary credentials for a federated user with the user * Returns a set of temporary credentials for a federated user with the user
@ -74,12 +109,21 @@ public interface STSApi extends Closeable {
* The name of the federated user, included as part of * The name of the federated user, included as part of
* {@link User#getId}. * {@link User#getId}.
*/ */
UserAndSessionCredentials createFederatedUser(String userName); @Named("GetFederationToken")
@POST
@Path("/")
@XMLResponseParser(UserAndSessionCredentialsHandler.class)
@FormParams(keys = "Action", values = "GetFederationToken")
UserAndSessionCredentials createFederatedUser(@FormParam("Name") String userName);
/** /**
* like {@link #createFederatedUser(String)}, except you can modify the * like {@link #createFederatedUser(String)}, except you can modify the
* timeout and other parameters. * timeout and other parameters.
*/ */
UserAndSessionCredentials createFederatedUser(String userName, FederatedUserOptions options); @Named("GetFederationToken")
@POST
@Path("/")
@XMLResponseParser(UserAndSessionCredentialsHandler.class)
@FormParams(keys = "Action", values = "GetFederationToken")
UserAndSessionCredentials createFederatedUser(@FormParam("Name") String userName, FederatedUserOptions options);
} }

View File

@ -25,35 +25,23 @@ import java.net.URI;
import java.util.Properties; import java.util.Properties;
import org.jclouds.apis.ApiMetadata; import org.jclouds.apis.ApiMetadata;
import org.jclouds.rest.internal.BaseRestApiMetadata; import org.jclouds.rest.internal.BaseHttpApiMetadata;
import org.jclouds.sts.config.STSRestClientModule; import org.jclouds.sts.config.STSHttpApiModule;
import com.google.common.reflect.TypeToken;
/** /**
* Implementation of {@link ApiMetadata} for Amazon's STS api. * Implementation of {@link ApiMetadata} for Amazon's STS api.
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public class STSApiMetadata extends BaseRestApiMetadata { public class STSApiMetadata extends BaseHttpApiMetadata<STSApi> {
/**
* @deprecated please use {@code org.jclouds.ContextBuilder#buildApi(STSApi.class)} as
* {@link STSAsyncApi} interface will be removed in jclouds 1.7.
*/
@Deprecated
public static final TypeToken<org.jclouds.rest.RestContext<STSApi, STSAsyncApi>> CONTEXT_TOKEN = new TypeToken<org.jclouds.rest.RestContext<STSApi, STSAsyncApi>>() {
private static final long serialVersionUID = 1L;
};
@Override @Override
public Builder toBuilder() { public Builder toBuilder() {
return new Builder(getApi(), getAsyncApi()).fromApiMetadata(this); return new Builder().fromApiMetadata(this);
} }
@SuppressWarnings("deprecation")
public STSApiMetadata() { public STSApiMetadata() {
this(new Builder(STSApi.class, STSAsyncApi.class)); this(new Builder());
} }
protected STSApiMetadata(Builder builder) { protected STSApiMetadata(Builder builder) {
@ -61,16 +49,15 @@ public class STSApiMetadata extends BaseRestApiMetadata {
} }
public static Properties defaultProperties() { public static Properties defaultProperties() {
Properties properties = BaseRestApiMetadata.defaultProperties(); Properties properties = BaseHttpApiMetadata.defaultProperties();
properties.setProperty(PROPERTY_AUTH_TAG, "AWS"); properties.setProperty(PROPERTY_AUTH_TAG, "AWS");
properties.setProperty(PROPERTY_HEADER_TAG, "amz"); properties.setProperty(PROPERTY_HEADER_TAG, "amz");
return properties; return properties;
} }
public static class Builder extends BaseRestApiMetadata.Builder<Builder> { public static class Builder extends BaseHttpApiMetadata.Builder<STSApi, Builder> {
protected Builder(Class<?> api, Class<?> asyncApi) { protected Builder() {
super(api, asyncApi);
id("sts") id("sts")
.name("Amazon STS Api") .name("Amazon STS Api")
.identityName("Access Key ID") .identityName("Access Key ID")
@ -79,7 +66,7 @@ public class STSApiMetadata extends BaseRestApiMetadata {
.documentation(URI.create("http://docs.amazonwebservices.com/STS/latest/APIReference/")) .documentation(URI.create("http://docs.amazonwebservices.com/STS/latest/APIReference/"))
.defaultEndpoint("https://sts.amazonaws.com") .defaultEndpoint("https://sts.amazonaws.com")
.defaultProperties(STSApiMetadata.defaultProperties()) .defaultProperties(STSApiMetadata.defaultProperties())
.defaultModule(STSRestClientModule.class); .defaultModule(STSHttpApiModule.class);
} }
@Override @Override

View File

@ -1,118 +0,0 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.sts;
import java.io.Closeable;
import javax.inject.Named;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.aws.domain.SessionCredentials;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.aws.xml.SessionCredentialsHandler;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.sts.domain.UserAndSessionCredentials;
import org.jclouds.sts.options.AssumeRoleOptions;
import org.jclouds.sts.options.FederatedUserOptions;
import org.jclouds.sts.options.SessionCredentialsOptions;
import org.jclouds.sts.xml.UserAndSessionCredentialsHandler;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides access to Amazon STS via the Query API
* <p/>
*
* @see <a href="http://docs.amazonwebservices.com/STS/latest/APIReference" />
* @author Adrian Cole
* @deprecated please use {@code org.jclouds.ContextBuilder#buildApi(STSApi.class)} as
* {@link STSAsyncApi} interface will be removed in jclouds 1.7.
*/
@Deprecated
@RequestFilters(FormSigner.class)
@VirtualHost
public interface STSAsyncApi extends Closeable {
/**
* @see STSApi#createTemporaryCredentials()
*/
@Named("GetSessionToken")
@POST
@Path("/")
@XMLResponseParser(SessionCredentialsHandler.class)
@FormParams(keys = "Action", values = "GetSessionToken")
ListenableFuture<SessionCredentials> createTemporaryCredentials();
/**
* @see STSApi#createTemporaryCredentials(SessionCredentialsOptions)
*/
@Named("GetSessionToken")
@POST
@Path("/")
@XMLResponseParser(SessionCredentialsHandler.class)
@FormParams(keys = "Action", values = "GetSessionToken")
ListenableFuture<SessionCredentials> createTemporaryCredentials(SessionCredentialsOptions options);
/**
* @see STSApi#assumeRole(String, String)
*/
@Named("AssumeRole")
@POST
@Path("/")
@XMLResponseParser(UserAndSessionCredentialsHandler.class)
@FormParams(keys = "Action", values = "AssumeRole")
ListenableFuture<UserAndSessionCredentials> assumeRole(@FormParam("RoleArn") String roleArn,
@FormParam("RoleSessionName") String sessionName);
/**
* @see STSApi#assumeRole(String, String, AssumeRoleOptions)
*/
@Named("AssumeRole")
@POST
@Path("/")
@XMLResponseParser(UserAndSessionCredentialsHandler.class)
@FormParams(keys = "Action", values = "AssumeRole")
ListenableFuture<UserAndSessionCredentials> assumeRole(@FormParam("RoleArn") String roleArn,
@FormParam("RoleSessionName") String sessionName, AssumeRoleOptions options);
/**
* @see STSApi#createFederatedUser(String)
*/
@Named("GetFederationToken")
@POST
@Path("/")
@XMLResponseParser(UserAndSessionCredentialsHandler.class)
@FormParams(keys = "Action", values = "GetFederationToken")
ListenableFuture<UserAndSessionCredentials> createFederatedUser(@FormParam("Name") String userName);
/**
* @see STSApi#createFederatedUser(FederatedUserOptions)
*/
@Named("GetFederationToken")
@POST
@Path("/")
@XMLResponseParser(UserAndSessionCredentialsHandler.class)
@FormParams(keys = "Action", values = "GetFederationToken")
ListenableFuture<UserAndSessionCredentials> createFederatedUser(@FormParam("Name") String userName, FederatedUserOptions options);
}

View File

@ -18,23 +18,16 @@
*/ */
package org.jclouds.sts.config; package org.jclouds.sts.config;
import static org.jclouds.reflect.Reflection2.typeToken; import org.jclouds.aws.config.FormSigningHttpApiModule;
import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.aws.config.FormSigningRestClientModule;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.sts.STSApi; import org.jclouds.sts.STSApi;
import org.jclouds.sts.STSAsyncApi;
/** /**
* Configures the STS connection. * Configures the STS connection.
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@ConfiguresRestClient @ConfiguresHttpApi
public class STSRestClientModule extends FormSigningRestClientModule<STSApi, STSAsyncApi> { public class STSHttpApiModule extends FormSigningHttpApiModule<STSApi> {
public STSRestClientModule() {
super(typeToken(STSApi.class), typeToken(STSAsyncApi.class));
}
} }

View File

@ -19,7 +19,7 @@
package org.jclouds.sts; package org.jclouds.sts;
import org.jclouds.View; import org.jclouds.View;
import org.jclouds.rest.internal.BaseRestApiMetadataTest; import org.jclouds.rest.internal.BaseHttpApiMetadataTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
@ -30,9 +30,9 @@ import com.google.common.reflect.TypeToken;
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "unit", testName = "STSApiMetadataTest") @Test(groups = "unit", testName = "STSApiMetadataTest")
public class STSApiMetadataTest extends BaseRestApiMetadataTest { public class STSApiMetadataTest extends BaseHttpApiMetadataTest {
// no tenant abstraction, yet // no token abstraction, yet
public STSApiMetadataTest() { public STSApiMetadataTest() {
super(new STSApiMetadata(), ImmutableSet.<TypeToken<? extends View>> of()); super(new STSApiMetadata(), ImmutableSet.<TypeToken<? extends View>> of());
} }

View File

@ -19,8 +19,8 @@
package org.jclouds.sts.internal; package org.jclouds.sts.internal;
import org.jclouds.date.DateService; import org.jclouds.date.DateService;
import org.jclouds.sts.config.STSRestClientModule; import org.jclouds.sts.config.STSHttpApiModule;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.rest.internal.BaseRestApiExpectTest; import org.jclouds.rest.internal.BaseRestApiExpectTest;
import com.google.inject.Module; import com.google.inject.Module;
@ -35,8 +35,8 @@ public class BaseSTSExpectTest<T> extends BaseRestApiExpectTest<T> {
provider = "sts"; provider = "sts";
} }
@ConfiguresRestClient @ConfiguresHttpApi
private static final class TestSTSRestClientModule extends STSRestClientModule { private static final class TestSTSHttpApiModule extends STSHttpApiModule {
@Override @Override
protected String provideTimeStamp(final DateService dateService) { protected String provideTimeStamp(final DateService dateService) {
@ -46,6 +46,6 @@ public class BaseSTSExpectTest<T> extends BaseRestApiExpectTest<T> {
@Override @Override
protected Module createModule() { protected Module createModule() {
return new TestSTSRestClientModule(); return new TestSTSHttpApiModule();
} }
} }