Merge pull request #1511 from jclouds/async-is-an-option

remove requirement to support AsyncApi
This commit is contained in:
Adrian Cole 2013-04-09 23:10:56 -07:00
commit 0b9eedbc06
154 changed files with 4243 additions and 4283 deletions

View File

@ -18,7 +18,7 @@
*/
package org.jclouds.cloudstack.config;
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
import static org.jclouds.rest.config.BinderUtils.bindMappedHttpApi;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@ -207,9 +207,9 @@ public class CloudStackRestClientModule extends RestClientModule<CloudStackClien
});
bind(CredentialType.class).toProvider(CredentialTypeFromPropertyOrDefault.class);
// session client is used directly for filters and retry handlers, so let's bind it explicitly
bindHttpApi(binder(), SessionClient.class, SessionAsyncClient.class);
bindHttpApi(binder(), CloudStackDomainClient.class, CloudStackDomainAsyncClient.class);
bindHttpApi(binder(), CloudStackGlobalClient.class, CloudStackGlobalAsyncClient.class);
bindMappedHttpApi(binder(), SessionClient.class, SessionAsyncClient.class);
bindMappedHttpApi(binder(), CloudStackDomainClient.class, CloudStackDomainAsyncClient.class);
bindMappedHttpApi(binder(), CloudStackGlobalClient.class, CloudStackGlobalAsyncClient.class);
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(InvalidateSessionAndRetryOn401AndLogoutOnClose.class);
super.configure();

View File

@ -18,7 +18,7 @@
*/
package org.jclouds.filesystem.config;
import static org.jclouds.rest.config.BinderUtils.bindBlockingApi;
import static org.jclouds.rest.config.BinderUtils.bindMappedApi;
import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.BlobRequestSigner;
@ -50,7 +50,7 @@ public class FilesystemBlobStoreContextModule extends AbstractModule {
protected void configure() {
bind(AsyncBlobStore.class).to(LocalAsyncBlobStore.class).asEagerSingleton();
// forward all requests from TransientBlobStore to TransientAsyncBlobStore. needs above binding as cannot proxy a class
bindBlockingApi(binder(), LocalBlobStore.class, AsyncBlobStore.class);
bindMappedApi(binder(), LocalBlobStore.class, AsyncBlobStore.class);
bind(BlobStore.class).to(LocalBlobStore.class);
install(new BlobStoreObjectModule());

View File

@ -30,6 +30,7 @@ import org.jclouds.openstack.cinder.v1.config.CinderRestClientModule;
import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule;
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.ZoneModule;
import org.jclouds.openstack.keystone.v2_0.config.MappedAuthenticationApiModule;
import org.jclouds.openstack.v2_0.ServiceType;
import org.jclouds.rest.internal.BaseRestApiMetadata;
@ -88,6 +89,7 @@ public class CinderApiMetadata extends BaseRestApiMetadata {
.defaultEndpoint("http://localhost:5000/v2.0/")
.defaultProperties(CinderApiMetadata.defaultProperties())
.defaultModules(ImmutableSet.<Class<? extends Module>>builder()
.add(MappedAuthenticationApiModule.class)
.add(KeystoneAuthenticationModule.class)
.add(ZoneModule.class)
.add(CinderParserModule.class)

View File

@ -18,47 +18,88 @@
*/
package org.jclouds.openstack.keystone.v2_0;
import java.io.Closeable;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.openstack.keystone.v2_0.binders.BindAuthToJsonPayload;
import org.jclouds.openstack.keystone.v2_0.domain.Access;
import org.jclouds.openstack.keystone.v2_0.domain.ApiAccessKeyCredentials;
import org.jclouds.openstack.keystone.v2_0.domain.PasswordCredentials;
import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.SelectJson;
import com.google.inject.name.Named;
/**
* Provides synchronous access to the KeyStone Service API.
* <p/>
*
* @see AuthenticationAsyncApi
* @see <a href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/Service_API_Api_Operations.html"
* @see <a href=
* "http://docs.openstack.org/api/openstack-identity-service/2.0/content/Service_API_Api_Operations.html"
* />
* @author Adrian Cole
*/
public interface AuthenticationApi {
public interface AuthenticationApi extends Closeable {
/**
* Authenticate to generate a token.
*
* @return access with token
*/
Access authenticateWithTenantNameAndCredentials(@Nullable String tenantId, PasswordCredentials passwordCredentials);
@Named("authenticate")
@POST
@SelectJson("access")
@Consumes(MediaType.APPLICATION_JSON)
@Path("/tokens")
@MapBinder(BindAuthToJsonPayload.class)
Access authenticateWithTenantNameAndCredentials(@Nullable @PayloadParam("tenantName") String tenantName,
PasswordCredentials passwordCredentials);
/**
* Authenticate to generate a token.
*
* @return access with token
*/
Access authenticateWithTenantIdAndCredentials(@Nullable String tenantId, PasswordCredentials passwordCredentials);
@Named("authenticate")
@POST
@SelectJson("access")
@Consumes(MediaType.APPLICATION_JSON)
@Path("/tokens")
@MapBinder(BindAuthToJsonPayload.class)
Access authenticateWithTenantIdAndCredentials(@Nullable @PayloadParam("tenantId") String tenantId,
PasswordCredentials passwordCredentials);
/**
* Authenticate to generate a token.
*
* @return access with token
*/
Access authenticateWithTenantNameAndCredentials(@Nullable String tenantId, ApiAccessKeyCredentials passwordCredentials);
@Named("authenticate")
@POST
@SelectJson("access")
@Consumes(MediaType.APPLICATION_JSON)
@Path("/tokens")
@MapBinder(BindAuthToJsonPayload.class)
Access authenticateWithTenantNameAndCredentials(@Nullable @PayloadParam("tenantName") String tenantName,
ApiAccessKeyCredentials apiAccessKeyCredentials);
/**
* Authenticate to generate a token.
*
* @return access with token
*/
Access authenticateWithTenantIdAndCredentials(@Nullable String tenantId, ApiAccessKeyCredentials passwordCredentials);
@Named("authenticate")
@POST
@SelectJson("access")
@Consumes(MediaType.APPLICATION_JSON)
@Path("/tokens")
@MapBinder(BindAuthToJsonPayload.class)
Access authenticateWithTenantIdAndCredentials(@Nullable @PayloadParam("tenantId") String tenantId,
ApiAccessKeyCredentials apiAccessKeyCredentials);
}

View File

@ -18,6 +18,8 @@
*/
package org.jclouds.openstack.keystone.v2_0;
import java.io.Closeable;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
@ -42,8 +44,11 @@ import com.google.common.util.concurrent.ListenableFuture;
* @see <a href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/Service_API_Api_Operations.html"
* />
* @author Adrian Cole
* @deprecated will be removed in jclouds 1.7, as async interfaces are no longer
* supported. please use {@link AuthenticationApi}
*/
public interface AuthenticationAsyncApi {
@Deprecated
public interface AuthenticationAsyncApi extends Closeable {
/**
* @see AuthenticationApi#authenticateWithTenantNameAndCredentials(String,PasswordCredentials)

View File

@ -29,6 +29,7 @@ import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule;
import org.jclouds.openstack.keystone.v2_0.config.KeystoneParserModule;
import org.jclouds.openstack.keystone.v2_0.config.KeystoneRestClientModule;
import org.jclouds.openstack.keystone.v2_0.config.KeystoneRestClientModule.KeystoneAdminURLModule;
import org.jclouds.openstack.keystone.v2_0.config.MappedAuthenticationApiModule;
import org.jclouds.openstack.v2_0.ServiceType;
import org.jclouds.rest.internal.BaseRestApiMetadata;
@ -90,6 +91,7 @@ public class KeystoneApiMetadata extends BaseRestApiMetadata {
.defaultEndpoint("http://localhost:5000/v${jclouds.api-version}/")
.defaultProperties(KeystoneApiMetadata.defaultProperties())
.defaultModules(ImmutableSet.<Class<? extends Module>>builder()
.add(MappedAuthenticationApiModule.class)
.add(KeystoneAuthenticationModule.class)
.add(KeystoneAdminURLModule.class)
.add(KeystoneParserModule.class)

View File

@ -0,0 +1,39 @@
/**
* 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.openstack.keystone.v2_0.config;
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
import org.jclouds.openstack.keystone.v2_0.AuthenticationApi;
import com.google.inject.AbstractModule;
/**
*
* @author Adrian Cole
*/
public class AuthenticationApiModule extends AbstractModule {
@Override
protected void configure() {
// AuthenticationApi is used directly for filters and retry handlers, so let's bind it explicitly
bindHttpApi(binder(), AuthenticationApi.class);
}
}

View File

@ -19,7 +19,6 @@
package org.jclouds.openstack.keystone.v2_0.config;
import static com.google.common.base.Preconditions.checkArgument;
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
import static org.jclouds.util.Suppliers2.getLastValueInMap;
import java.net.URI;
@ -47,8 +46,6 @@ import org.jclouds.location.suppliers.derived.RegionIdsFromRegionIdToURIKeySet;
import org.jclouds.location.suppliers.derived.ZoneIdsFromZoneIdToURIKeySet;
import org.jclouds.location.suppliers.implicit.FirstRegion;
import org.jclouds.location.suppliers.implicit.FirstZone;
import org.jclouds.openstack.keystone.v2_0.AuthenticationApi;
import org.jclouds.openstack.keystone.v2_0.AuthenticationAsyncApi;
import org.jclouds.openstack.keystone.v2_0.domain.Access;
import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
import org.jclouds.openstack.keystone.v2_0.functions.AuthenticateApiAccessKeyCredentials;
@ -60,7 +57,6 @@ import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToAdminURISupplier;
import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToURIFromAccessForTypeAndVersion;
import org.jclouds.openstack.keystone.v2_0.suppliers.ZoneIdToURIFromAccessForTypeAndVersion;
import org.jclouds.rest.annotations.ApiVersion;
import org.jclouds.rest.config.RestClientModule;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
@ -89,7 +85,7 @@ public class KeystoneAuthenticationModule extends AbstractModule {
* {@link javax.inject.Qualifier}</li>
* <li>add the above annotation to any {@link AsyncApi} classes by placing it on the type. ex.
* {@code @Endpoint(CloudDNS.class)}</li>
* <li>add the following to your {@link RestClientModule}</li>
* <li>add the following to your {@link org.jclouds.rest.config.RestClientModule}</li>
*
* <pre>
* bind(new TypeLiteral&lt;Supplier&lt;URI&gt;&gt;() {
@ -184,12 +180,6 @@ public class KeystoneAuthenticationModule extends AbstractModule {
@Override
protected void configure() {
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenew.class);
bindAuthenticationApi();
}
protected void bindAuthenticationApi() {
// AuthenticationApi is used directly for filters and retry handlers, so let's bind it explicitly
bindHttpApi(binder(), AuthenticationApi.class, AuthenticationAsyncApi.class);
}
/**

View File

@ -0,0 +1,43 @@
/**
* 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.openstack.keystone.v2_0.config;
import static org.jclouds.rest.config.BinderUtils.bindMappedHttpApi;
import org.jclouds.openstack.keystone.v2_0.AuthenticationApi;
import org.jclouds.openstack.keystone.v2_0.AuthenticationAsyncApi;
import com.google.inject.AbstractModule;
/**
*
* @author Adrian Cole
* @deprecated will be removed in jclouds 1.7, as async interfaces are no longer
* supported. please use {@link AuthenticationApiModule}
*/
@Deprecated
public class MappedAuthenticationApiModule extends AbstractModule {
@Override
protected void configure() {
// AuthenticationApi is used directly for filters and retry handlers, so let's bind it explicitly
bindMappedHttpApi(binder(), AuthenticationApi.class, AuthenticationAsyncApi.class);
}
}

View File

@ -1,9 +1,28 @@
/**
* 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.openstack.keystone.v2_0.config;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
import static org.jclouds.util.Suppliers2.getLastValueInMap;
import static org.testng.Assert.assertTrue;
import java.io.Closeable;
@ -13,6 +32,7 @@ import java.net.URI;
import java.util.Properties;
import javax.inject.Qualifier;
import javax.inject.Singleton;
import javax.ws.rs.HEAD;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
@ -23,21 +43,23 @@ import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.json.config.GsonModule.DateAdapter;
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.jclouds.location.suppliers.RegionIdToURISupplier;
import org.jclouds.openstack.keystone.v2_0.KeystoneApi;
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.ProviderModule;
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule;
import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneRestApiExpectTest;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.rest.annotations.ApiVersion;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.config.RestClientModule;
import org.jclouds.rest.config.HttpApiModule;
import org.jclouds.rest.internal.BaseHttpApiMetadata;
import org.jclouds.rest.internal.BaseRestApiExpectTest;
import org.jclouds.rest.internal.BaseRestApiMetadata;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
import com.google.inject.Provides;
/**
* Tests configuration via {@link ProviderModule}
@ -48,31 +70,34 @@ import com.google.inject.TypeLiteral;
public class ProviderModuleExpectTest extends BaseRestApiExpectTest<ProviderModuleExpectTest.DNSApi> {
@Retention(RUNTIME)
@Target(TYPE)
@Target(METHOD)
@Qualifier
static @interface DNS {
}
@ConfiguresRestClient
public static class DNSRestClientModule extends RestClientModule<DNSApi, DNSAsyncApi> {
@ConfiguresHttpApi
public static class DNSHttpApiModule extends HttpApiModule<DNSApi> {
@Override
public void configure() {
bind(new TypeLiteral<Supplier<URI>>() {}).annotatedWith(DNS.class).to(new TypeLiteral<Supplier<URI>>() {});
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
super.configure();
}
}
static interface DNSApi extends Closeable {
boolean zoneExists(@PathParam("zoneName") String zoneName);
@Provides
@Singleton
@DNS
protected Supplier<URI> provideCDNUrl(RegionIdToURISupplier.Factory factory, @ApiVersion String apiVersion) {
return getLastValueInMap(factory.createForApiTypeAndVersion("dns", apiVersion));
}
}
@org.jclouds.rest.annotations.Endpoint(DNS.class)
static interface DNSAsyncApi extends Closeable {
static interface DNSApi extends Closeable {
@HEAD
@Path("/zones/{zoneName}")
@Fallback(FalseOnNotFoundOr404.class)
public ListenableFuture<Boolean> zoneExists(@PathParam("zoneName") String zoneName);
boolean zoneExists(@PathParam("zoneName") String zoneName);
}
public void testDNSEndpointApplied() {
@ -86,7 +111,7 @@ public class ProviderModuleExpectTest extends BaseRestApiExpectTest<ProviderModu
assertTrue(api.zoneExists("foo.com"));
}
private static class DNSApiMetadata extends BaseRestApiMetadata {
private static class DNSApiMetadata extends BaseHttpApiMetadata<DNSApi> {
@Override
public Builder toBuilder() {
@ -102,31 +127,29 @@ public class ProviderModuleExpectTest extends BaseRestApiExpectTest<ProviderModu
}
public static Properties defaultProperties() {
Properties properties = BaseRestApiMetadata.defaultProperties();
Properties properties = BaseHttpApiMetadata.defaultProperties();
properties.setProperty(SERVICE_TYPE, "dns");
properties.setProperty(CREDENTIAL_TYPE, CredentialTypes.PASSWORD_CREDENTIALS);
return properties;
}
public static class Builder extends BaseRestApiMetadata.Builder<Builder> {
public static class Builder extends BaseHttpApiMetadata.Builder<DNSApi, Builder> {
protected Builder() {
super(DNSApi.class, DNSAsyncApi.class);
id("dns")
.name("DNS API")
.identityName("${tenantName}:${userName} or ${userName}, if your keystone supports a default tenant")
.credentialName("${password}")
.endpointName("Keystone base url ending in /v2.0/")
.documentation(URI.create("http://dns"))
.version("1.0")
.defaultEndpoint("http://localhost:5000/v2.0/")
.defaultProperties(DNSApiMetadata.defaultProperties())
.defaultModules(
ImmutableSet.<Class<? extends Module>> builder()
.add(KeystoneAuthenticationModule.class)
.add(ProviderModule.class)
.add(DNSRestClientModule.class)
.build());
.name("DNS API")
.identityName("${tenantName}:${userName} or ${userName}, if your keystone supports a default tenant")
.credentialName("${password}")
.endpointName("Keystone base url ending in /v2.0/")
.documentation(URI.create("http://dns"))
.version("1.0")
.defaultEndpoint("http://localhost:5000/v2.0/")
.defaultProperties(DNSApiMetadata.defaultProperties())
.defaultModules(ImmutableSet.<Class<? extends Module>>builder()
.add(AuthenticationApiModule.class)
.add(KeystoneAuthenticationModule.class)
.add(RegionModule.class)
.add(DNSHttpApiModule.class).build());
}
@Override

View File

@ -33,6 +33,7 @@ import org.jclouds.apis.ApiMetadata;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule;
import org.jclouds.openstack.keystone.v2_0.config.MappedAuthenticationApiModule;
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.ZoneModule;
import org.jclouds.openstack.nova.v2_0.compute.config.NovaComputeServiceContextModule;
import org.jclouds.openstack.nova.v2_0.config.NovaParserModule;
@ -106,6 +107,7 @@ public class NovaApiMetadata extends BaseRestApiMetadata {
.defaultProperties(NovaApiMetadata.defaultProperties())
.view(typeToken(ComputeServiceContext.class))
.defaultModules(ImmutableSet.<Class<? extends Module>>builder()
.add(MappedAuthenticationApiModule.class)
.add(KeystoneAuthenticationModule.class)
.add(ZoneModule.class)
.add(NovaParserModule.class)

View File

@ -1,4 +1,3 @@
package org.jclouds.rackspace.cloudidentity.v2_0;
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
@ -17,6 +16,8 @@ package org.jclouds.rackspace.cloudidentity.v2_0;
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.rackspace.cloudidentity.v2_0;
import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
@ -33,6 +34,7 @@ import org.jclouds.openstack.keystone.v2_0.config.KeystoneRestClientModule;
import org.jclouds.openstack.keystone.v2_0.config.KeystoneRestClientModule.KeystoneAdminURLModule;
import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule;
import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes;
import org.jclouds.rackspace.cloudidentity.v2_0.config.MappedCloudIdentityAuthenticationApiModule;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.TypeToken;
@ -87,6 +89,7 @@ public class CloudIdentityApiMetadata extends KeystoneApiMetadata {
.context(CONTEXT_TOKEN)
.documentation(URI.create("http://docs.rackspace.com/auth/api/v2.0/auth-api-devguide/"))
.defaultModules(ImmutableSet.<Class<? extends Module>>builder()
.add(MappedCloudIdentityAuthenticationApiModule.class)
.add(CloudIdentityAuthenticationModule.class)
.add(KeystoneAdminURLModule.class)
.add(KeystoneParserModule.class)

View File

@ -18,17 +18,27 @@
*/
package org.jclouds.rackspace.cloudidentity.v2_0;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.openstack.keystone.v2_0.AuthenticationApi;
import org.jclouds.openstack.keystone.v2_0.binders.BindAuthToJsonPayload;
import org.jclouds.openstack.keystone.v2_0.domain.Access;
import org.jclouds.rackspace.cloudidentity.v2_0.domain.ApiKeyCredentials;
import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.SelectJson;
/**
* Provides synchronous access to the KeyStone Service API.
* <p/>
*
* @see AuthenticationAsyncApi
* @see <a href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/Service_API_Api_Operations.html"
* @see <a href=
* "http://docs.openstack.org/api/openstack-identity-service/2.0/content/Service_API_Api_Operations.html"
* />
* @author Adrian Cole
*/
@ -39,13 +49,27 @@ public interface CloudIdentityAuthenticationApi extends AuthenticationApi {
*
* @return access with token
*/
Access authenticateWithTenantNameAndCredentials(@Nullable String tenantId, ApiKeyCredentials apiKeyCredentials);
@Named("authenticate")
@POST
@SelectJson("access")
@Consumes(MediaType.APPLICATION_JSON)
@Path("/tokens")
@MapBinder(BindAuthToJsonPayload.class)
Access authenticateWithTenantNameAndCredentials(@Nullable @PayloadParam("tenantName") String tenantName,
ApiKeyCredentials apiKeyCredentials);
/**
* Authenticate to generate a token.
*
* @return access with token
*/
Access authenticateWithTenantIdAndCredentials(@Nullable String tenantId, ApiKeyCredentials apiKeyCredentials);
@Named("authenticate")
@POST
@SelectJson("access")
@Consumes(MediaType.APPLICATION_JSON)
@Path("/tokens")
@MapBinder(BindAuthToJsonPayload.class)
Access authenticateWithTenantIdAndCredentials(@Nullable @PayloadParam("tenantId") String tenantId,
ApiKeyCredentials apiKeyCredentials);
}

View File

@ -43,7 +43,10 @@ import com.google.common.util.concurrent.ListenableFuture;
* @see <a href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/Service_API_Api_Operations.html"
* />
* @author Adrian Cole
* @deprecated will be removed in jclouds 1.7, as async interfaces are no longer
* supported. please use {@link CloudIdentityAuthenticationAsyncApi}
*/
@Deprecated
public interface CloudIdentityAuthenticationAsyncApi extends AuthenticationAsyncApi {
/**

View File

@ -0,0 +1,45 @@
/**
* 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.rackspace.cloudidentity.v2_0.config;
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
import org.jclouds.openstack.keystone.v2_0.AuthenticationApi;
import org.jclouds.rackspace.cloudidentity.v2_0.CloudIdentityAuthenticationApi;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
/**
*
* @author Adrian Cole
*/
public class CloudIdentityAuthenticationApiModule extends AbstractModule {
@Override
protected void configure() {
// AuthenticationApi is used directly for filters and retry handlers, so let's bind it explicitly
bindHttpApi(binder(), CloudIdentityAuthenticationApi.class);
}
@Provides
private AuthenticationApi provideAuthenticationApi(CloudIdentityAuthenticationApi in){
return in;
}
}

View File

@ -18,26 +18,19 @@
*/
package org.jclouds.rackspace.cloudidentity.v2_0.config;
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
import java.util.Map;
import org.jclouds.domain.Credentials;
import org.jclouds.openstack.keystone.v2_0.AuthenticationAsyncApi;
import org.jclouds.openstack.keystone.v2_0.AuthenticationApi;
import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule;
import org.jclouds.openstack.keystone.v2_0.domain.Access;
import org.jclouds.openstack.keystone.v2_0.functions.AuthenticatePasswordCredentials;
import org.jclouds.rackspace.cloudidentity.v2_0.CloudIdentityAuthenticationAsyncApi;
import org.jclouds.rackspace.cloudidentity.v2_0.CloudIdentityAuthenticationApi;
import org.jclouds.rackspace.cloudidentity.v2_0.functions.AuthenticateApiKeyCredentials;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import com.google.inject.Injector;
import com.google.inject.Scopes;
/**
*
@ -45,15 +38,6 @@ import com.google.inject.Scopes;
*/
public class CloudIdentityAuthenticationModule extends KeystoneAuthenticationModule {
@Override
protected void bindAuthenticationApi() {
// AuthenticationApi is used directly for filters and retry handlers, so let's bind it explicitly
bindHttpApi(binder(), CloudIdentityAuthenticationApi.class,
CloudIdentityAuthenticationAsyncApi.class);
bind(AuthenticationApi.class).to(CloudIdentityAuthenticationApi.class).in(Scopes.SINGLETON);
bind(AuthenticationAsyncApi.class).to(CloudIdentityAuthenticationAsyncApi.class).in(Scopes.SINGLETON);
}
@Override
protected Map<String, Function<Credentials, Access>> authenticationMethods(Injector i) {
Builder<Function<Credentials, Access>> fns = ImmutableSet.<Function<Credentials, Access>> builder();

View File

@ -0,0 +1,58 @@
/**
* 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.rackspace.cloudidentity.v2_0.config;
import static org.jclouds.rest.config.BinderUtils.bindMappedHttpApi;
import org.jclouds.openstack.keystone.v2_0.AuthenticationApi;
import org.jclouds.openstack.keystone.v2_0.AuthenticationAsyncApi;
import org.jclouds.rackspace.cloudidentity.v2_0.CloudIdentityAuthenticationApi;
import org.jclouds.rackspace.cloudidentity.v2_0.CloudIdentityAuthenticationAsyncApi;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
/**
*
* @author Adrian Cole
* @deprecated will be removed in jclouds 1.7, as async interfaces are no longer
* supported. please use
* {@link CloudIdentityAuthenticationApiModule}
*/
@Deprecated
public class MappedCloudIdentityAuthenticationApiModule extends AbstractModule {
@Override
protected void configure() {
// AuthenticationApi is used directly for filters and retry handlers, so
// let's bind it explicitly
bindMappedHttpApi(binder(), CloudIdentityAuthenticationApi.class, CloudIdentityAuthenticationAsyncApi.class);
}
@Provides
private AuthenticationApi provideAuthenticationApi(CloudIdentityAuthenticationApi in) {
return in;
}
@Provides
private AuthenticationAsyncApi provideAuthenticationAsyncApi(CloudIdentityAuthenticationAsyncApi in) {
return in;
}
}

View File

@ -37,8 +37,8 @@
<test.rackspace-cloudloadbalancers.endpoint>https://identity.api.rackspacecloud.com/v2.0/</test.rackspace-cloudloadbalancers.endpoint>
<test.rackspace-cloudloadbalancers.api-version>1</test.rackspace-cloudloadbalancers.api-version>
<test.rackspace-cloudloadbalancers.build-version />
<test.rackspace-cloudloadbalancers.identity>${test.rackspace.identity}</test.rackspace-cloudloadbalancers.identity>
<test.rackspace-cloudloadbalancers.credential>${test.rackspace.credential}</test.rackspace-cloudloadbalancers.credential>
<test.rackspace-cloudloadbalancers.identity>${test.rackspace-us.identity}</test.rackspace-cloudloadbalancers.identity>
<test.rackspace-cloudloadbalancers.credential>${test.rackspace-us.credential}</test.rackspace-cloudloadbalancers.credential>
<jclouds.osgi.export>org.jclouds.rackspace.cloudloadbalancers*;version="${project.version}"</jclouds.osgi.export>
<jclouds.osgi.import>org.jclouds*;version="${project.version}",*</jclouds.osgi.import>

View File

@ -43,11 +43,10 @@ import org.jclouds.rest.annotations.EndpointParam;
import com.google.inject.Provides;
/**
* Provides synchronous access to Rackspace Cloud Load Balancers.
* Provides access to Rackspace Cloud Load Balancers.
* <p/>
*
* @see CloudLoadBalancersAsyncApi
* @author Adrian Cole
* @author Everett Toews
*/
public interface CloudLoadBalancersApi extends Closeable {
/**
@ -58,14 +57,14 @@ public interface CloudLoadBalancersApi extends Closeable {
Set<String> getConfiguredZones();
/**
* Provides synchronous access to Load Balancer features.
* Provides access to Load Balancer features.
*/
@Delegate
LoadBalancerApi getLoadBalancerApiForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/**
* Provides synchronous access to Node features.
* Provides access to Node features.
*/
@Delegate
@Path("/loadbalancers/{lbId}")
@ -73,7 +72,7 @@ public interface CloudLoadBalancersApi extends Closeable {
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
/**
* Provides synchronous access to Access Rule features.
* Provides access to Access Rule features.
*/
@Delegate
@Path("/loadbalancers/{lbId}")
@ -81,7 +80,7 @@ public interface CloudLoadBalancersApi extends Closeable {
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
/**
* Provides synchronous access to Virtual IP features.
* Provides access to Virtual IP features.
*/
@Delegate
@Path("/loadbalancers/{lbId}")
@ -89,7 +88,7 @@ public interface CloudLoadBalancersApi extends Closeable {
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
/**
* Provides synchronous access to Connection features.
* Provides access to Connection features.
*/
@Delegate
@Path("/loadbalancers/{lbId}")
@ -97,7 +96,7 @@ public interface CloudLoadBalancersApi extends Closeable {
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
/**
* Provides synchronous access to Health Monitor features.
* Provides access to Health Monitor features.
*/
@Delegate
@Path("/loadbalancers/{lbId}")
@ -105,7 +104,7 @@ public interface CloudLoadBalancersApi extends Closeable {
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
/**
* Provides synchronous access to Session Persistence features.
* Provides access to Session Persistence features.
*/
@Delegate
@Path("/loadbalancers/{lbId}")
@ -113,7 +112,7 @@ public interface CloudLoadBalancersApi extends Closeable {
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
/**
* Provides synchronous access to Content Caching features.
* Provides access to Content Caching features.
*/
@Delegate
@Path("/loadbalancers/{lbId}")
@ -121,7 +120,7 @@ public interface CloudLoadBalancersApi extends Closeable {
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
/**
* Provides synchronous access to SSL Termination features.
* Provides access to SSL Termination features.
*/
@Delegate
@Path("/loadbalancers/{lbId}")
@ -129,7 +128,7 @@ public interface CloudLoadBalancersApi extends Closeable {
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
/**
* Provides synchronous access to Error Page features.
* Provides access to Error Page features.
*/
@Delegate
@Path("/loadbalancers/{lbId}")
@ -137,7 +136,7 @@ public interface CloudLoadBalancersApi extends Closeable {
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
/**
* Provides synchronous access to Report features.
* Provides access to Report features.
*/
@Delegate
ReportApi getReportApiForZone(

View File

@ -28,30 +28,21 @@ import org.jclouds.apis.ApiMetadata;
import org.jclouds.loadbalancer.LoadBalancerServiceContext;
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.ZoneModule;
import org.jclouds.rackspace.cloudidentity.v2_0.ServiceType;
import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationApiModule;
import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule;
import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes;
import org.jclouds.rackspace.cloudloadbalancers.v1.config.CloudLoadBalancersRestClientModule;
import org.jclouds.rackspace.cloudloadbalancers.v1.config.CloudLoadBalancersHttpApiModule;
import org.jclouds.rackspace.cloudloadbalancers.v1.loadbalancer.config.CloudLoadBalancersLoadBalancerContextModule;
import org.jclouds.rest.internal.BaseRestApiMetadata;
import org.jclouds.rest.internal.BaseHttpApiMetadata;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.TypeToken;
import com.google.inject.Module;
/**
* Implementation of {@link ApiMetadata} for CloudLoadBalancers 1.0 API
*
* @author Adrian Cole
*/
public class CloudLoadBalancersApiMetadata extends BaseRestApiMetadata {
/**
* @deprecated please use {@code org.jclouds.ContextBuilder#buildApi(CloudLoadBalancersApi.class)} as
* {@link CloudLoadBalancersAsyncApi} interface will be removed in jclouds 1.7.
*/
@Deprecated
public static final TypeToken<org.jclouds.rest.RestContext<CloudLoadBalancersApi, CloudLoadBalancersAsyncApi>> CONTEXT_TOKEN = new TypeToken<org.jclouds.rest.RestContext<CloudLoadBalancersApi, CloudLoadBalancersAsyncApi>>() {
private static final long serialVersionUID = 1L;
};
public class CloudLoadBalancersApiMetadata extends BaseHttpApiMetadata<CloudLoadBalancersApi> {
@Override
public Builder toBuilder() {
@ -67,17 +58,15 @@ public class CloudLoadBalancersApiMetadata extends BaseRestApiMetadata {
}
public static Properties defaultProperties() {
Properties properties = BaseRestApiMetadata.defaultProperties();
Properties properties = BaseHttpApiMetadata.defaultProperties();
properties.setProperty(SERVICE_TYPE, ServiceType.LOAD_BALANCERS);
properties.setProperty(CREDENTIAL_TYPE, CloudIdentityCredentialTypes.API_KEY_CREDENTIALS);
return properties;
}
public static class Builder extends BaseRestApiMetadata.Builder<Builder> {
public static class Builder extends BaseHttpApiMetadata.Builder<CloudLoadBalancersApi, Builder> {
@SuppressWarnings("deprecation")
protected Builder() {
super(CloudLoadBalancersApi.class, CloudLoadBalancersAsyncApi.class);
id("rackspace-cloudloadbalancers")
.name("Rackspace Cloud Load Balancers API")
.identityName("Username")
@ -87,12 +76,12 @@ public class CloudLoadBalancersApiMetadata extends BaseRestApiMetadata {
.defaultEndpoint("https://identity.api.rackspacecloud.com/v2.0/")
.defaultProperties(CloudLoadBalancersApiMetadata.defaultProperties())
.view(typeToken(LoadBalancerServiceContext.class))
.defaultModules(
ImmutableSet.<Class<? extends Module>> of(
CloudIdentityAuthenticationModule.class,
ZoneModule.class,
CloudLoadBalancersRestClientModule.class,
CloudLoadBalancersLoadBalancerContextModule.class));
.defaultModules(ImmutableSet.<Class<? extends Module>>builder()
.add(CloudIdentityAuthenticationApiModule.class)
.add(CloudIdentityAuthenticationModule.class)
.add(ZoneModule.class)
.add(CloudLoadBalancersHttpApiModule.class)
.add(CloudLoadBalancersLoadBalancerContextModule.class).build());
}
@Override

View File

@ -1,149 +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.rackspace.cloudloadbalancers.v1;
import java.io.Closeable;
import java.util.Set;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Zone;
import org.jclouds.location.functions.ZoneToEndpoint;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.AccessRuleAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.ConnectionAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.ContentCachingAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.ErrorPageAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.HealthMonitorAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.LoadBalancerAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.NodeAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.ReportAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.SSLTerminationAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.SessionPersistenceAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.VirtualIPAsyncApi;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.EndpointParam;
import com.google.inject.Provides;
/**
* Provides asynchronous access to Rackspace Cloud Load Balancers.
* <p/>
*
* @see CloudLoadBalancersApi
* @author Adrian Cole
* @deprecated please use {@code org.jclouds.ContextBuilder#buildApi(CloudLoadBalancersApi.class)} as
* {@link CloudLoadBalancersAsyncApi} interface will be removed in jclouds 1.7.
*/
@Deprecated
public interface CloudLoadBalancersAsyncApi extends Closeable {
/**
* @return the Zone codes configured
*/
@Provides
@Zone
Set<String> getConfiguredZones();
/**
* Provides asynchronous access to LoadBalancer features.
*/
@Delegate
LoadBalancerAsyncApi getLoadBalancerApiForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/**
* Provides asynchronous access to Node features.
*/
@Delegate
@Path("/loadbalancers/{lbId}")
NodeAsyncApi getNodeApiForZoneAndLoadBalancer(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
/**
* Provides asynchronous access to Access Rule features.
*/
@Delegate
@Path("/loadbalancers/{lbId}")
AccessRuleAsyncApi getAccessRuleApiForZoneAndLoadBalancer(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
/**
* Provides asynchronous access to Virtual IP features.
*/
@Delegate
@Path("/loadbalancers/{lbId}")
VirtualIPAsyncApi getVirtualIPApiForZoneAndLoadBalancer(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
/**
* Provides asynchronous access to Connection features.
*/
@Delegate
@Path("/loadbalancers/{lbId}")
ConnectionAsyncApi getConnectionApiForZoneAndLoadBalancer(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
/**
* Provides asynchronous access to Health Monitor features.
*/
@Delegate
@Path("/loadbalancers/{lbId}")
HealthMonitorAsyncApi getHealthMonitorApiForZoneAndLoadBalancer(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
/**
* Provides asynchronous access to Session Persistence features.
*/
@Delegate
@Path("/loadbalancers/{lbId}")
SessionPersistenceAsyncApi getSessionPersistenceApiForZoneAndLoadBalancer(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
/**
* Provides asynchronous access to Content Caching features.
*/
@Delegate
@Path("/loadbalancers/{lbId}")
ContentCachingAsyncApi getContentCachingApiForZoneAndLoadBalancer(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
/**
* Provides asynchronous access to SSL Termination features.
*/
@Delegate
@Path("/loadbalancers/{lbId}")
SSLTerminationAsyncApi getSSLTerminationApiForZoneAndLoadBalancer(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
/**
* Provides asynchronous access to Error Page features.
*/
@Delegate
@Path("/loadbalancers/{lbId}")
ErrorPageAsyncApi getErrorPageApiForZoneAndLoadBalancer(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone, @PathParam("lbId") int lbId);
/**
* Provides asynchronous access to Report features.
*/
@Delegate
ReportAsyncApi getReportApiForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
}

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.rackspace.cloudloadbalancers.v1.config;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
import org.jclouds.json.config.GsonModule.DateAdapter;
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.jclouds.rackspace.cloudloadbalancers.v1.CloudLoadBalancersApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ConvertLB;
import org.jclouds.rackspace.cloudloadbalancers.v1.handlers.ParseCloudLoadBalancersErrorFromHttpResponse;
import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.rest.config.HttpApiModule;
import com.google.inject.assistedinject.FactoryModuleBuilder;
/**
* Configures the Rackspace Cloud Load Balancers connection.
*
* @author Adrian Cole
*/
@ConfiguresHttpApi
public class CloudLoadBalancersHttpApiModule extends HttpApiModule<CloudLoadBalancersApi> {
@Override
protected void configure() {
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
install(new FactoryModuleBuilder().build(ConvertLB.Factory.class));
super.configure();
}
@Override
protected void bindErrorHandlers() {
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(
ParseCloudLoadBalancersErrorFromHttpResponse.class);
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(
ParseCloudLoadBalancersErrorFromHttpResponse.class);
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(
ParseCloudLoadBalancersErrorFromHttpResponse.class);
}
}

View File

@ -1,104 +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.rackspace.cloudloadbalancers.v1.config;
import java.util.Map;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
import org.jclouds.json.config.GsonModule.DateAdapter;
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.jclouds.rackspace.cloudloadbalancers.v1.CloudLoadBalancersApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.CloudLoadBalancersAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.AccessRuleApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.AccessRuleAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.ConnectionApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.ConnectionAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.ContentCachingApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.ContentCachingAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.ErrorPageApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.ErrorPageAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.HealthMonitorApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.HealthMonitorAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.LoadBalancerApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.LoadBalancerAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.NodeApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.NodeAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.ReportApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.ReportAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.SSLTerminationApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.SSLTerminationAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.SessionPersistenceApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.SessionPersistenceAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.VirtualIPApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.features.VirtualIPAsyncApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ConvertLB;
import org.jclouds.rackspace.cloudloadbalancers.v1.handlers.ParseCloudLoadBalancersErrorFromHttpResponse;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule;
import com.google.common.collect.ImmutableMap;
import com.google.inject.assistedinject.FactoryModuleBuilder;
/**
* Configures the Rackspace Cloud Load Balancers connection.
*
* @author Adrian Cole
*/
@ConfiguresRestClient
public class CloudLoadBalancersRestClientModule extends
RestClientModule<CloudLoadBalancersApi, CloudLoadBalancersAsyncApi> {
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()
.put(LoadBalancerApi.class, LoadBalancerAsyncApi.class)
.put(NodeApi.class, NodeAsyncApi.class)
.put(AccessRuleApi.class, AccessRuleAsyncApi.class)
.put(VirtualIPApi.class, VirtualIPAsyncApi.class)
.put(ConnectionApi.class, ConnectionAsyncApi.class)
.put(HealthMonitorApi.class, HealthMonitorAsyncApi.class)
.put(SessionPersistenceApi.class, SessionPersistenceAsyncApi.class)
.put(ContentCachingApi.class, ContentCachingAsyncApi.class)
.put(SSLTerminationApi.class, SSLTerminationAsyncApi.class)
.put(ErrorPageApi.class, ErrorPageAsyncApi.class)
.put(ReportApi.class, ReportAsyncApi.class)
.build();
public CloudLoadBalancersRestClientModule() {
super(DELEGATE_MAP);
}
@Override
protected void configure() {
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
install(new FactoryModuleBuilder().build(ConvertLB.Factory.class));
super.configure();
}
@Override
protected void bindErrorHandlers() {
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(
ParseCloudLoadBalancersErrorFromHttpResponse.class);
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(
ParseCloudLoadBalancersErrorFromHttpResponse.class);
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(
ParseCloudLoadBalancersErrorFromHttpResponse.class);
}
}

View File

@ -18,17 +18,35 @@
*/
package org.jclouds.rackspace.cloudloadbalancers.v1.features;
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.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.AccessRule;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.AccessRuleWithId;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.WrapWith;
/**
* The access list management feature allows fine-grained network access controls to be applied to the load balancer's
* virtual IP address.
* <p/>
*
* @see AccessRuleAsyncApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface AccessRuleApi {
/**
* Create new access rules or append to existing access rules.
@ -38,11 +56,22 @@ public interface AccessRuleApi {
* AccessRules. A single address or subnet definition is considered unique and cannot be duplicated between rules
* in an access list.
*/
void create(Iterable<AccessRule> accessRules);
@Named("accessrule:create")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Path("/accesslist")
void create(@WrapWith("accessList") Iterable<AccessRule> accessRules);
/**
* List the AccessRules.
*/
@Named("accessrule:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
@SelectJson("accessList")
@Path("/accesslist")
Iterable<AccessRuleWithId> list();
/**
@ -50,19 +79,34 @@ public interface AccessRuleApi {
*
* @return true on a successful delete, false if the access rule was not found
*/
boolean delete(int id);
@Named("accessrule:delete")
@DELETE
@Fallback(FalseOnNotFoundOr404.class)
@Path("/accesslist/{id}")
@Consumes("*/*")
boolean delete(@PathParam("id") int id);
/**
* Batch delete the access rules given the specified ids.
*
* @return true on a successful delete, false if the access rule was not found
*/
boolean delete(Iterable<Integer> ids);
@Named("accessrule:delete")
@DELETE
@Fallback(FalseOnNotFoundOr404.class)
@Path("/accesslist")
@Consumes("*/*")
boolean delete(@QueryParam("id") Iterable<Integer> ids);
/**
* Delete the entire access list.
*
* @return true on a successful delete, false if the access rule was not found
*/
@Named("accessrule:delete")
@DELETE
@Fallback(FalseOnNotFoundOr404.class)
@Path("/accesslist")
@Consumes("*/*")
boolean deleteAll();
}

View File

@ -1,104 +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.rackspace.cloudloadbalancers.v1.features;
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.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.AccessRule;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.AccessRuleWithId;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.WrapWith;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to Rackspace Cloud Load Balancers via their REST API.
* <p/>
*
* @see AccessRuleApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface AccessRuleAsyncApi {
/**
* @see AccessRuleApi#create(Iterable)
*/
@Named("accessrule:create")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Path("/accesslist")
ListenableFuture<Void> create(@WrapWith("accessList") Iterable<AccessRule> accessRules);
/**
* @see AccessRuleApi#list()
*/
@Named("accessrule:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
@SelectJson("accessList")
@Path("/accesslist")
ListenableFuture<Iterable<AccessRuleWithId>> list();
/**
* @see AccessRuleApi#delete(int)
*/
@Named("accessrule:delete")
@DELETE
@Fallback(FalseOnNotFoundOr404.class)
@Path("/accesslist/{id}")
@Consumes("*/*")
ListenableFuture<Boolean> delete(@PathParam("id") int id);
/**
* @see AccessRuleApi#delete(Iterable)
*/
@Named("accessrule:delete")
@DELETE
@Fallback(FalseOnNotFoundOr404.class)
@Path("/accesslist")
@Consumes("*/*")
ListenableFuture<Boolean> delete(@QueryParam("id") Iterable<Integer> ids);
/**
* @see AccessRuleApi#deleteAll()
*/
@Named("accessrule:delete")
@DELETE
@Fallback(FalseOnNotFoundOr404.class)
@Path("/accesslist")
@Consumes("*/*")
ListenableFuture<Boolean> deleteAll();
}

View File

@ -18,25 +18,58 @@
*/
package org.jclouds.rackspace.cloudloadbalancers.v1.features;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
import org.jclouds.Fallbacks.FalseOnNotFoundOr422;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.ConnectionThrottle;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseNestedBoolean;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.Payload;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.WrapWith;
/**
* Connection management features.
* <p/>
*
* @see ConnectionAsyncApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface ConnectionApi {
/**
* The connection throttling feature imposes limits on the number of connections per IP address to help mitigate
* malicious or abusive traffic to your applications.
*/
void createOrUpdateConnectionThrottle(ConnectionThrottle connectionThrottle);
@Named("connectionthrottle:create")
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Path("/connectionthrottle")
void createOrUpdateConnectionThrottle(
@WrapWith("connectionThrottle") ConnectionThrottle connectionThrottle);
/**
* Get connection throttle.
*/
@Named("connectionthrottle:get")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@SelectJson("connectionThrottle")
@Fallback(NullOnNotFoundOr404.class)
@Path("/connectionthrottle")
ConnectionThrottle getConnectionThrottle();
/**
@ -44,20 +77,45 @@ public interface ConnectionApi {
*
* @return true on a successful delete, false if the connection throttle was not found.
*/
@Named("connectionthrottle:delete")
@DELETE
@Fallback(FalseOnNotFoundOr422.class)
@Path("/connectionthrottle")
@Consumes("*/*")
boolean deleteConnectionThrottle();
/**
* Determine if the load balancer is logging connections.
*/
@Named("connectionlogging:state")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseNestedBoolean.class)
@Fallback(FalseOnNotFoundOr404.class)
@Path("/connectionlogging")
boolean isConnectionLogging();
/**
* Enable logging connections.
*/
@Named("connectionlogging:state")
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Payload("{\"connectionLogging\":{\"enabled\":true}}")
@Path("/connectionlogging")
void enableConnectionLogging();
/**
* Disable logging connections.
*/
@Named("connectionlogging:state")
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Payload("{\"connectionLogging\":{\"enabled\":false}}")
@Path("/connectionlogging")
void disableConnectionLogging();
}

View File

@ -1,122 +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.rackspace.cloudloadbalancers.v1.features;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
import org.jclouds.Fallbacks.FalseOnNotFoundOr422;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.ConnectionThrottle;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseNestedBoolean;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.Payload;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.WrapWith;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to Rackspace Cloud Load Balancers via their REST API.
* <p/>
*
* @see ConnectionApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface ConnectionAsyncApi {
/**
* @see ConnectionApi#createOrUpdateConnectionThrottle(ConnectionThrottle)
*/
@Named("connectionthrottle:create")
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Path("/connectionthrottle")
ListenableFuture<Void> createOrUpdateConnectionThrottle(
@WrapWith("connectionThrottle") ConnectionThrottle connectionThrottle);
/**
* @see ConnectionApi#getConnectionThrottle()
*/
@Named("connectionthrottle:get")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@SelectJson("connectionThrottle")
@Fallback(NullOnNotFoundOr404.class)
@Path("/connectionthrottle")
ListenableFuture<ConnectionThrottle> getConnectionThrottle();
/**
* @see ConnectionApi#deleteConnectionThrottle()
*/
@Named("connectionthrottle:delete")
@DELETE
@Fallback(FalseOnNotFoundOr422.class)
@Path("/connectionthrottle")
@Consumes("*/*")
ListenableFuture<Boolean> deleteConnectionThrottle();
/**
* @see ConnectionApi#isConnectionLogging()
*/
@Named("connectionlogging:state")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseNestedBoolean.class)
@Fallback(FalseOnNotFoundOr404.class)
@Path("/connectionlogging")
ListenableFuture<Boolean> isConnectionLogging();
/**
* @see ConnectionApi#enableConnectionLogging()
*/
@Named("connectionlogging:state")
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Payload("{\"connectionLogging\":{\"enabled\":true}}")
@Path("/connectionlogging")
ListenableFuture<Void> enableConnectionLogging();
/**
* @see ConnectionApi#disableConnectionLogging()
*/
@Named("connectionlogging:state")
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Payload("{\"connectionLogging\":{\"enabled\":false}}")
@Path("/connectionlogging")
ListenableFuture<Void> disableConnectionLogging();
}

View File

@ -18,6 +18,23 @@
*/
package org.jclouds.rackspace.cloudloadbalancers.v1.features;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseNestedBoolean;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.Payload;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
/**
* When content caching is enabled, recently-accessed files are stored on the load balancer for easy retrieval by web
* clients. Content caching improves the performance of high traffic web sites by temporarily storing data that was
@ -26,22 +43,42 @@ package org.jclouds.rackspace.cloudloadbalancers.v1.features;
* web server.
* <p/>
*
* @see ContentCachingAsyncApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface ContentCachingApi {
/**
* Determine if the load balancer is content caching.
*/
@Named("contentcaching:state")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseNestedBoolean.class)
@Fallback(FalseOnNotFoundOr404.class)
@Path("/contentcaching")
boolean isContentCaching();
/**
* Enable content caching.
*/
@Named("contentcaching:state")
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Payload("{\"contentCaching\":{\"enabled\":true}}")
@Path("/contentcaching")
void enable();
/**
* Disable content caching.
*/
@Named("contentcaching:state")
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Payload("{\"contentCaching\":{\"enabled\":false}}")
@Path("/contentcaching")
void disable();
}

View File

@ -1,84 +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.rackspace.cloudloadbalancers.v1.features;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseNestedBoolean;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.Payload;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to Rackspace Cloud Load Balancers via their REST API.
* <p/>
*
* @see ContentCachingApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface ContentCachingAsyncApi {
/**
* @see ContentCachingApi#isContentCaching()
*/
@Named("contentcaching:state")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseNestedBoolean.class)
@Fallback(FalseOnNotFoundOr404.class)
@Path("/contentcaching")
ListenableFuture<Boolean> isContentCaching();
/**
* @see ContentCachingApi#enable()
*/
@Named("contentcaching:state")
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Payload("{\"contentCaching\":{\"enabled\":true}}")
@Path("/contentcaching")
ListenableFuture<Void> enable();
/**
* @see ContentCachingApi#disableConnectionLogging()
*/
@Named("contentcaching:state")
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Payload("{\"contentCaching\":{\"enabled\":false}}")
@Path("/contentcaching")
ListenableFuture<Void> disable();
}

View File

@ -18,6 +18,25 @@
*/
package org.jclouds.rackspace.cloudloadbalancers.v1.features;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseNestedString;
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.ResponseParser;
/**
* An error page is the html file that is shown to an end user who is attempting to access a load balancer node that
* is offline/unavailable. During provisioning, every load balancer is configured with a default error page that gets
@ -25,23 +44,41 @@ package org.jclouds.rackspace.cloudloadbalancers.v1.features;
* balancer with an HTTP-based protocol. Page updates will override existing content.
* <p/>
*
* @see ErrorPageAsyncApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface ErrorPageApi {
/**
* Specify the HTML content for the custom error page. Must be 65536 characters or less.
*/
void create(String content);
@Named("errorpage:create")
@PUT
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Payload("%7B\"errorpage\":%7B\"content\":\"{content}\"%7D%7D")
@Path("/errorpage")
void create(@PayloadParam("content") String content);
/**
* Get the error page HTML content.
*/
@Named("errorpage:get")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseNestedString.class)
@Fallback(VoidOnNotFoundOr404.class)
@Path("/errorpage")
String get();
/**
* If a custom error page is deleted, or the load balancer is changed to a non-HTTP protocol, the default error
* page will be restored.
*/
@Named("errorpage:delete")
@DELETE
@Consumes(MediaType.WILDCARD)
@Fallback(FalseOnNotFoundOr404.class)
@Path("/errorpage")
boolean delete();
}

View File

@ -1,84 +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.rackspace.cloudloadbalancers.v1.features;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseNestedString;
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.ResponseParser;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to Rackspace Cloud Load Balancers via their REST API.
* <p/>
*
* @see ErrorPageApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface ErrorPageAsyncApi {
/**
* @see ErrorPageApi#create(String)
*/
@Named("errorpage:create")
@PUT
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Payload("%7B\"errorpage\":%7B\"content\":\"{content}\"%7D%7D")
@Path("/errorpage")
ListenableFuture<Void> create(@PayloadParam("content") String content);
/**
* @see ErrorPageApi#get()
*/
@Named("errorpage:get")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseNestedString.class)
@Fallback(VoidOnNotFoundOr404.class)
@Path("/errorpage")
ListenableFuture<String> get();
/**
* @see ErrorPageApi#delete()
*/
@Named("errorpage:delete")
@DELETE
@Consumes(MediaType.WILDCARD)
@Fallback(FalseOnNotFoundOr404.class)
@Path("/errorpage")
ListenableFuture<Boolean> delete();
}

View File

@ -18,7 +18,23 @@
*/
package org.jclouds.rackspace.cloudloadbalancers.v1.features;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.FalseOnNotFoundOr422;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.HealthMonitor;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.WrapWith;
/**
* The load balancing service includes a health monitoring operation which periodically checks your back-end nodes to
@ -31,18 +47,29 @@ import org.jclouds.rackspace.cloudloadbalancers.v1.domain.HealthMonitor;
* failover for effectively routing traffic in case the primary node fails. This is an additional feature that will
* ensure you remain up in case your primary node fails.
* <p/>
* @see HealthMonitorAsyncApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface HealthMonitorApi {
/**
* Create or update a health monitor.
*/
void createOrUpdate(HealthMonitor healthMonitor);
@Named("healthmonitor:create")
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Path("/healthmonitor")
void createOrUpdate(@WrapWith("healthMonitor") HealthMonitor healthMonitor);
/**
* Get health monitor.
*/
@Named("healthmonitor:get")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@SelectJson("healthMonitor")
@Fallback(NullOnNotFoundOr404.class)
@Path("/healthmonitor")
HealthMonitor get();
/**
@ -50,5 +77,10 @@ public interface HealthMonitorApi {
*
* @return true on a successful delete, false if the health monitor was not found
*/
@Named("healthmonitor:delete")
@DELETE
@Fallback(FalseOnNotFoundOr422.class)
@Path("/healthmonitor")
@Consumes("*/*")
boolean delete();
}

View File

@ -1,81 +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.rackspace.cloudloadbalancers.v1.features;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.FalseOnNotFoundOr422;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.HealthMonitor;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.WrapWith;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to Rackspace Cloud Load Balancers via their REST API.
* <p/>
*
* @see HealthMonitorApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface HealthMonitorAsyncApi {
/**
* @see HealthMonitorApi#createOrUpdate(HealthMonitor)
*/
@Named("healthmonitor:create")
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Path("/healthmonitor")
ListenableFuture<Void> createOrUpdate(@WrapWith("healthMonitor") HealthMonitor healthMonitor);
/**
* @see HealthMonitorApi#get()
*/
@Named("healthmonitor:get")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@SelectJson("healthMonitor")
@Fallback(NullOnNotFoundOr404.class)
@Path("/healthmonitor")
ListenableFuture<HealthMonitor> get();
/**
* @see HealthMonitorApi#delete()
*/
@Named("healthmonitor:delete")
@DELETE
@Fallback(FalseOnNotFoundOr422.class)
@Path("/healthmonitor")
@Consumes("*/*")
ListenableFuture<Boolean> delete();
}

View File

@ -20,21 +20,52 @@ package org.jclouds.rackspace.cloudloadbalancers.v1.features;
import java.util.Map;
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.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.EmptyMapOnNotFoundOr404;
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.PagedIterable;
import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.openstack.v2_0.options.PaginationOptions;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.LoadBalancer;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.UpdateLoadBalancer;
import org.jclouds.rackspace.cloudloadbalancers.v1.binders.BindMetadataToJsonPayload;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.CreateLoadBalancer;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.LoadBalancer;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.Metadata;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.UpdateLoadBalancer;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseLoadBalancer;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseLoadBalancers;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseMetadata;
import org.jclouds.rest.annotations.BinderParam;
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.ResponseParser;
import org.jclouds.rest.annotations.Transform;
import org.jclouds.rest.annotations.WrapWith;
/**
* Provides synchronous access to CloudLoadBalancers LoadBalancer features.
* Provides access to CloudLoadBalancers LoadBalancer features.
* <p/>
*
* @see LoadBalancerAsyncApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface LoadBalancerApi {
/**
* Create a new load balancer with the configuration defined by the request.
@ -43,7 +74,13 @@ public interface LoadBalancerApi {
* identifier, the caller can check on the progress of the operation by performing a
* {@link LoadBalancerApi#get}.
*/
LoadBalancer create(CreateLoadBalancer createLB);
@Named("lb:create")
@POST
@ResponseParser(ParseLoadBalancer.class)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(NullOnNotFoundOr404.class)
@Path("/loadbalancers")
LoadBalancer create(@WrapWith("loadBalancer") CreateLoadBalancer createLB);
/**
* Update the properties of a load balancer.
@ -52,46 +89,97 @@ public interface LoadBalancerApi {
* identifier, the caller can check on the progress of the operation by performing a
* {@link LoadBalancerApi#get}.
*/
void update(int id, UpdateLoadBalancer updateLB);
@Named("lb:update")
@PUT
@ResponseParser(ParseLoadBalancer.class)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/loadbalancers/{id}")
void update(@PathParam("id") int id, @WrapWith("loadBalancer") UpdateLoadBalancer updateLB);
/**
* List the load balancers.
*/
@Named("lb:list")
@GET
@ResponseParser(ParseLoadBalancers.class)
@Transform(ParseLoadBalancers.ToPagedIterable.class)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/loadbalancers")
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
PagedIterable<LoadBalancer> list();
/**
* List the load balancers with full control of pagination.
*/
@Named("lb:list")
@GET
@ResponseParser(ParseLoadBalancers.class)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
@Path("/loadbalancers")
IterableWithMarker<LoadBalancer> list(PaginationOptions options);
/**
* Get a load balancer.
*/
LoadBalancer get(int id);
@Named("lb:get")
@GET
@ResponseParser(ParseLoadBalancer.class)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(NullOnNotFoundOr404.class)
@Path("/loadbalancers/{id}")
LoadBalancer get(@PathParam("id") int id);
/**
* Delete a load balancer.
*/
void delete(int id);
@Named("lb:delete")
@DELETE
@Fallback(VoidOnNotFoundOr404.class)
@Path("/loadbalancers/{id}")
@Consumes("*/*")
void delete(@PathParam("id") int id);
/**
* When a metadata item is added, it is assigned a unique identifier that can be used for mutating operations such
* as changing the value attribute or removing it. Key and value must be 256 characters or less.
* All UTF-8 characters are valid.
*/
Metadata createMetadata(int id, Map<String, String> metadata);
@Named("lb:createmetadata")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseMetadata.class)
@Fallback(EmptyMapOnNotFoundOr404.class)
@Path("/loadbalancers/{id}/metadata")
Metadata createMetadata(@PathParam("id") int id,
@BinderParam(BindMetadataToJsonPayload.class) Map<String, String> metadata);
/**
* List a load balancer's metadata.
*/
Metadata getMetadata(int id);
@Named("lb:getmetadata")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseMetadata.class)
@Fallback(EmptyMapOnNotFoundOr404.class)
@Path("/loadbalancers/{id}/metadata")
Metadata getMetadata(@PathParam("id") int id);
/**
* Update metadatum. Key and value must be 256 characters or less. All UTF-8 characters are valid.
*
* @return true on a successful update, false if the metadatum was not found
*/
boolean updateMetadatum(int id, int metadatumId, String value);
@Named("lb:updatemetadatum")
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes("*/*")
@Fallback(FalseOnNotFoundOr404.class)
@Payload("%7B\"meta\":%7B\"value\":\"{value}\"%7D%7D")
@Path("/loadbalancers/{id}/metadata/{metadatumId}")
boolean updateMetadatum(@PathParam("id") int id,
@PathParam("metadatumId") int metadatumId,
@PayloadParam("value") String value);
/**
* Delete metadatum.
@ -100,7 +188,13 @@ public interface LoadBalancerApi {
*
* @return true on a successful removal, false if the metadatum was not found
*/
boolean deleteMetadatum(int id, int metadatumId);
@Named("lb:deletemetadatum")
@DELETE
@Fallback(FalseOnNotFoundOr404.class)
@Consumes("*/*")
@Path("/loadbalancers/{id}/metadata/{metadatumId}")
boolean deleteMetadatum(@PathParam("id") int id, @PathParam("metadatumId") int metadatumId);
/**
* Batch delete metadata given the specified ids.
@ -111,5 +205,11 @@ public interface LoadBalancerApi {
*
* @return true on a successful removal, false if the metadata was not found
*/
boolean deleteMetadata(int id, Iterable<Integer> metadataIds);
@Named("lb:deletemetadata")
@DELETE
@Fallback(FalseOnNotFoundOr404.class)
@Consumes("*/*")
@Path("/loadbalancers/{id}/metadata")
boolean deleteMetadata(@PathParam("id") int id,
@QueryParam("id") Iterable<Integer> metadataIds);
}

View File

@ -1,197 +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.rackspace.cloudloadbalancers.v1.features;
import java.util.Map;
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.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.EmptyMapOnNotFoundOr404;
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.PagedIterable;
import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.openstack.v2_0.options.PaginationOptions;
import org.jclouds.rackspace.cloudloadbalancers.v1.binders.BindMetadataToJsonPayload;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.LoadBalancer;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.UpdateLoadBalancer;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.CreateLoadBalancer;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.Metadata;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseLoadBalancer;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseLoadBalancers;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseMetadata;
import org.jclouds.rest.annotations.BinderParam;
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.ResponseParser;
import org.jclouds.rest.annotations.Transform;
import org.jclouds.rest.annotations.WrapWith;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to Rackspace Cloud Load Balancers via their REST API.
* <p/>
*
* @see LoadBalancerApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface LoadBalancerAsyncApi {
/**
* @see LoadBalancerApi#create(CreateLoadBalancer)
*/
@Named("lb:create")
@POST
@ResponseParser(ParseLoadBalancer.class)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(NullOnNotFoundOr404.class)
@Path("/loadbalancers")
ListenableFuture<LoadBalancer> create(@WrapWith("loadBalancer") CreateLoadBalancer createLB);
/**
* @see LoadBalancerApi#update(int, UpdateLoadBalancer)
*/
@Named("lb:update")
@PUT
@ResponseParser(ParseLoadBalancer.class)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/loadbalancers/{id}")
ListenableFuture<Void> update(@PathParam("id") int id, @WrapWith("loadBalancer") UpdateLoadBalancer updateLB);
/**
* @see LoadBalancerApi#list()
*/
@Named("lb:list")
@GET
@ResponseParser(ParseLoadBalancers.class)
@Transform(ParseLoadBalancers.ToPagedIterable.class)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/loadbalancers")
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
ListenableFuture<PagedIterable<LoadBalancer>> list();
/**
* @see LoadBalancerApi#list(PaginationOptions)
*/
@Named("lb:list")
@GET
@ResponseParser(ParseLoadBalancers.class)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
@Path("/loadbalancers")
ListenableFuture<IterableWithMarker<LoadBalancer>> list(PaginationOptions options);
/**
* @see LoadBalancerApi#get(int)
*/
@Named("lb:get")
@GET
@ResponseParser(ParseLoadBalancer.class)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(NullOnNotFoundOr404.class)
@Path("/loadbalancers/{id}")
ListenableFuture<LoadBalancer> get(@PathParam("id") int id);
/**
* @see LoadBalancerApi#delete(int)
*/
@Named("lb:delete")
@DELETE
@Fallback(VoidOnNotFoundOr404.class)
@Path("/loadbalancers/{id}")
@Consumes("*/*")
ListenableFuture<Void> delete(@PathParam("id") int id);
/**
* @see LoadBalancerApi#createMetadata(int, Iterable)
*/
@Named("lb:createmetadata")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseMetadata.class)
@Fallback(EmptyMapOnNotFoundOr404.class)
@Path("/loadbalancers/{id}/metadata")
ListenableFuture<Metadata> createMetadata(
@PathParam("id") int id,
@BinderParam(BindMetadataToJsonPayload.class) Map<String, String> metadata);
/**
* @see LoadBalancerApi#getMetadata(int)
*/
@Named("lb:getmetadata")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseMetadata.class)
@Fallback(EmptyMapOnNotFoundOr404.class)
@Path("/loadbalancers/{id}/metadata")
ListenableFuture<Metadata> getMetadata(@PathParam("id") int lb);
/**
* @see LoadBalancerApi#updateMetadatum(int, int, String)
*/
@Named("lb:updatemetadatum")
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes("*/*")
@Fallback(FalseOnNotFoundOr404.class)
@Payload("%7B\"meta\":%7B\"value\":\"{value}\"%7D%7D")
@Path("/loadbalancers/{id}/metadata/{metadatumId}")
ListenableFuture<Boolean> updateMetadatum(@PathParam("id") int id,
@PathParam("metadatumId") int metadatumId,
@PayloadParam("value") String value);
/**
* @see LoadBalancerApi#deleteMetadatum(int, int)
*/
@Named("lb:deletemetadatum")
@DELETE
@Fallback(FalseOnNotFoundOr404.class)
@Consumes("*/*")
@Path("/loadbalancers/{id}/metadata/{metadatumId}")
ListenableFuture<Boolean> deleteMetadatum(@PathParam("id") int id, @PathParam("metadatumId") int metadatumId);
/**
* @see LoadBalancerApi#deleteMetadata(int, Iterable)
*/
@Named("lb:deletemetadata")
@DELETE
@Fallback(FalseOnNotFoundOr404.class)
@Consumes("*/*")
@Path("/loadbalancers/{id}/metadata")
ListenableFuture<Boolean> deleteMetadata(@PathParam("id") int id,
@QueryParam("id") Iterable<Integer> metadataIds);
}

View File

@ -21,75 +21,168 @@ package org.jclouds.rackspace.cloudloadbalancers.v1.features;
import java.util.Map;
import java.util.Set;
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.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.EmptyMapOnNotFoundOr404;
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.PagedIterable;
import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.openstack.v2_0.options.PaginationOptions;
import org.jclouds.rackspace.cloudloadbalancers.v1.binders.BindMetadataToJsonPayload;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.AddNode;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.Metadata;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.Node;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.UpdateNode;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.AddNode;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseMetadata;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseNode;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseNodes;
import org.jclouds.rest.annotations.BinderParam;
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.ResponseParser;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.Transform;
import org.jclouds.rest.annotations.WrapWith;
/**
* Provides synchronous access to CloudLoadBalancers Node features.
* Provides access to CloudLoadBalancers Node features.
* <p/>
*
* @see NodeAsyncApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface NodeApi {
/**
* Add a new node with the configuration defined by the request.
*/
Set<Node> add(Iterable<AddNode> addNodes);
@Named("node:add")
@POST
@SelectJson("nodes")
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(NullOnNotFoundOr404.class)
@Path("/nodes")
Set<Node> add(@WrapWith("nodes") Iterable<AddNode> addNodes);
/**
* Update the attributes of a node.
*/
void update(int id, UpdateNode updateNode);
@Named("node:update")
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Path("/nodes/{id}")
void update(@PathParam("id") int id, @WrapWith("node") UpdateNode updateNode);
/**
* List the nodes.
*/
@Named("node:list")
@GET
@ResponseParser(ParseNodes.class)
@Transform(ParseNodes.ToPagedIterable.class)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/nodes")
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
PagedIterable<Node> list();
/**
* List the nodes with full control of pagination.
*/
@Named("node:list")
@GET
@ResponseParser(ParseNodes.class)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
@Path("/nodes")
IterableWithMarker<Node> list(PaginationOptions options);
/**
* Get a node.
*/
Node get(int id);
@Named("node:get")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseNode.class)
@Path("/nodes/{id}")
@Fallback(NullOnNotFoundOr404.class)
Node get(@PathParam("id") int id);
/**
* Remove a node from the load balancer.
*/
void remove(int id);
@Named("node:remove")
@DELETE
@Path("/nodes/{id}")
@Fallback(VoidOnNotFoundOr404.class)
@Consumes("*/*")
void remove(@PathParam("id") int id);
/**
* Batch remove nodes from the load balancer.
*/
void remove(Iterable<Integer> ids);
@Named("node:remove")
@DELETE
@Path("/nodes")
@Fallback(VoidOnNotFoundOr404.class)
@Consumes("*/*")
void remove(@QueryParam("id") Iterable<Integer> ids);
/**
* When a metadata item is added, it is assigned a unique identifier that can be used for mutating operations such
* as changing the value attribute or removing it. Key and value must be 256 characters or less.
* All UTF-8 characters are valid.
*/
Metadata createMetadata(int id, Map<String, String> metadata);
@Named("node:createmetadata")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseMetadata.class)
@Fallback(EmptyMapOnNotFoundOr404.class)
@Path("/nodes/{id}/metadata")
Metadata createMetadata(@PathParam("id") int id,
@BinderParam(BindMetadataToJsonPayload.class) Map<String, String> metadata);
/**
* List a load balancer's metadata.
*/
Metadata getMetadata(int id);
@Named("node:getmetadata")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseMetadata.class)
@Fallback(EmptyMapOnNotFoundOr404.class)
@Path("/nodes/{id}/metadata")
Metadata getMetadata(@PathParam("id") int lb);
/**
* Update metadatum. Key and value must be 256 characters or less. All UTF-8 characters are valid.
*
* @return true on a successful update, false if the metadatum was not found
*/
boolean updateMetadatum(int id, int metadatumId, String value);
@Named("node:updatemetadatum")
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes("*/*")
@Fallback(FalseOnNotFoundOr404.class)
@Payload("%7B\"meta\":%7B\"value\":\"{value}\"%7D%7D")
@Path("/nodes/{id}/metadata/{metadatumId}")
boolean updateMetadatum(@PathParam("id") int id,
@PathParam("metadatumId") int metadatumId,
@PayloadParam("value") String value);
/**
* Delete metadatum.
@ -98,7 +191,12 @@ public interface NodeApi {
*
* @return true on a successful removal, false if the metadatum was not found
*/
boolean deleteMetadatum(int id, int metadatumId);
@Named("node:deletemetadatum")
@DELETE
@Fallback(FalseOnNotFoundOr404.class)
@Consumes("*/*")
@Path("/nodes/{id}/metadata/{metadatumId}")
boolean deleteMetadatum(@PathParam("id") int id, @PathParam("metadatumId") int metadatumId);
/**
* Batch delete metadata given the specified ids.
@ -109,5 +207,11 @@ public interface NodeApi {
*
* @return true on a successful removal, false if the metadata was not found
*/
boolean deleteMetadata(int id, Iterable<Integer> metadataIds);
@Named("node:deletemetadata")
@DELETE
@Fallback(FalseOnNotFoundOr404.class)
@Consumes("*/*")
@Path("/nodes/{id}/metadata")
boolean deleteMetadata(@PathParam("id") int id,
@QueryParam("id") Iterable<Integer> metadataIds);
}

View File

@ -1,209 +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.rackspace.cloudloadbalancers.v1.features;
import java.util.Map;
import java.util.Set;
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.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.EmptyMapOnNotFoundOr404;
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.PagedIterable;
import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.openstack.v2_0.options.PaginationOptions;
import org.jclouds.rackspace.cloudloadbalancers.v1.binders.BindMetadataToJsonPayload;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.LoadBalancer;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.Metadata;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.Node;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.UpdateNode;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.AddNode;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseMetadata;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseNode;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseNodes;
import org.jclouds.rest.annotations.BinderParam;
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.ResponseParser;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.Transform;
import org.jclouds.rest.annotations.WrapWith;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to Cloud Load Balancers Node features.
* <p/>
*
* @see NodeAsyncApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface NodeAsyncApi {
/**
* @see NodeApi#add(Set)
*/
@Named("node:add")
@POST
@SelectJson("nodes")
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(NullOnNotFoundOr404.class)
@Path("/nodes")
ListenableFuture<Set<Node>> add(@WrapWith("nodes") Iterable<AddNode> addNodes);
/**
* @see NodeApi#update(int, UpdateNode)
*/
@Named("node:update")
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Path("/nodes/{id}")
ListenableFuture<Void> update(@PathParam("id") int id, @WrapWith("node") UpdateNode updateNode);
/**
* @see NodeApi#list()
*/
@Named("node:list")
@GET
@ResponseParser(ParseNodes.class)
@Transform(ParseNodes.ToPagedIterable.class)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/nodes")
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
ListenableFuture<PagedIterable<Node>> list();
/**
* @see NodeApi#list(PaginationOptions)
*/
@Named("node:list")
@GET
@ResponseParser(ParseNodes.class)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
@Path("/nodes")
ListenableFuture<IterableWithMarker<LoadBalancer>> list(PaginationOptions options);
/**
* @see NodeApi#get(int)
*/
@Named("node:get")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseNode.class)
@Path("/nodes/{id}")
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<Node> get(@PathParam("id") int id);
/**
* @see NodeApi#remove(int)
*/
@Named("node:remove")
@DELETE
@Path("/nodes/{id}")
@Fallback(VoidOnNotFoundOr404.class)
@Consumes("*/*")
ListenableFuture<Void> remove(@PathParam("id") int id);
/**
* @see NodeApi#remove(Set)
*/
@Named("node:remove")
@DELETE
@Path("/nodes")
@Fallback(VoidOnNotFoundOr404.class)
@Consumes("*/*")
ListenableFuture<Void> remove(@QueryParam("id") Iterable<Integer> ids);
/**
* @see NodeApi#createMetadata(int, Iterable)
*/
@Named("node:createmetadata")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseMetadata.class)
@Fallback(EmptyMapOnNotFoundOr404.class)
@Path("/nodes/{id}/metadata")
ListenableFuture<Metadata> createMetadata(
@PathParam("id") int id,
@BinderParam(BindMetadataToJsonPayload.class) Map<String, String> metadata);
/**
* @see NodeApi#getMetadata(int)
*/
@Named("node:getmetadata")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseMetadata.class)
@Fallback(EmptyMapOnNotFoundOr404.class)
@Path("/nodes/{id}/metadata")
ListenableFuture<Metadata> getMetadata(@PathParam("id") int lb);
/**
* @see NodeApi#updateMetadatum(int, int, String)
*/
@Named("node:updatemetadatum")
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes("*/*")
@Fallback(FalseOnNotFoundOr404.class)
@Payload("%7B\"meta\":%7B\"value\":\"{value}\"%7D%7D")
@Path("/nodes/{id}/metadata/{metadatumId}")
ListenableFuture<Boolean> updateMetadatum(@PathParam("id") int id,
@PathParam("metadatumId") int metadatumId,
@PayloadParam("value") String value);
/**
* @see NodeApi#deleteMetadatum(int, int)
*/
@Named("node:deletemetadatum")
@DELETE
@Fallback(FalseOnNotFoundOr404.class)
@Consumes("*/*")
@Path("/nodes/{id}/metadata/{metadatumId}")
ListenableFuture<Boolean> deleteMetadatum(@PathParam("id") int id, @PathParam("metadatumId") int metadatumId);
/**
* @see NodeApi#deleteMetadata(int, Iterable)
*/
@Named("node:deletemetadata")
@DELETE
@Fallback(FalseOnNotFoundOr404.class)
@Consumes("*/*")
@Path("/nodes/{id}/metadata")
ListenableFuture<Boolean> deleteMetadata(@PathParam("id") int id,
@QueryParam("id") Iterable<Integer> metadataIds);
}

View File

@ -20,63 +20,151 @@ package org.jclouds.rackspace.cloudloadbalancers.v1.features;
import java.util.Date;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.PagedIterable;
import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.openstack.v2_0.options.PaginationOptions;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.HistoricalUsage;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.LoadBalancer;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.LoadBalancerStats;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.LoadBalancerUsage;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.Protocol;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.DateParser;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseAlgorithms;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseLoadBalancerUsages;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseLoadBalancers;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.ParamParser;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.Transform;
/**
* Reporting for load balancers.
* <p/>
* @see ReportAsyncApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface ReportApi {
/**
* List billable load balancers for the given date range.
*/
PagedIterable<LoadBalancer> listBillableLoadBalancers(Date startTime, Date endTime);
@Named("report:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseLoadBalancers.class)
@Transform(ParseLoadBalancers.ToPagedIterable.class)
@Fallback(NullOnNotFoundOr404.class)
@Path("/loadbalancers/billable")
PagedIterable<LoadBalancer> listBillableLoadBalancers(
@ParamParser(DateParser.class) @QueryParam("startTime") Date startTime,
@ParamParser(DateParser.class) @QueryParam("endTime") Date endTime);
@Named("report:list")
@GET
@ResponseParser(ParseLoadBalancers.class)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
@Path("/loadbalancers/billable")
IterableWithMarker<LoadBalancer> listBillableLoadBalancers(PaginationOptions options);
/**
* View all transfer activity, average number of connections, and number of virtual IPs associated with the load
* balancing service. Historical usage data is available for up to 90 days of service activity.
*/
HistoricalUsage getHistoricalUsage(Date startTime, Date endTime);
@Named("report:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(NullOnNotFoundOr404.class)
@Path("/loadbalancers/usage")
HistoricalUsage getHistoricalUsage(
@ParamParser(DateParser.class) @QueryParam("startTime") Date startTime,
@ParamParser(DateParser.class) @QueryParam("endTime") Date endTime);
/**
* Historical usage data is available for up to 90 days of service activity.
*/
PagedIterable<LoadBalancerUsage> listLoadBalancerUsage(int loadBalancerId, Date startTime, Date endTime);
@Named("report:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseLoadBalancerUsages.class)
@Transform(ParseLoadBalancerUsages.ToPagedIterable.class)
@Fallback(NullOnNotFoundOr404.class)
@Path("/loadbalancers/{id}/usage")
PagedIterable<LoadBalancerUsage> listLoadBalancerUsage(@PathParam("id") int loadBalancerId,
@ParamParser(DateParser.class) @QueryParam("startTime") Date startTime,
@ParamParser(DateParser.class) @QueryParam("endTime") Date endTime);
@Named("report:list")
@GET
@ResponseParser(ParseLoadBalancerUsages.class)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
@Path("/loadbalancers/{id}/usage")
IterableWithMarker<LoadBalancerUsage> listLoadBalancerUsage(PaginationOptions options);
/**
* Current usage represents all usage recorded within the preceding 24 hours.
*/
PagedIterable<LoadBalancerUsage> listCurrentLoadBalancerUsage(int loadBalancerId);
@Named("report:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseLoadBalancerUsages.class)
@Transform(ParseLoadBalancerUsages.ToPagedIterable.class)
@Fallback(NullOnNotFoundOr404.class)
@Path("/loadbalancers/{id}/usage/current")
PagedIterable<LoadBalancerUsage> listCurrentLoadBalancerUsage(@PathParam("id") int loadBalancerId);
@Named("report:list")
@GET
@ResponseParser(ParseLoadBalancerUsages.class)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
@Path("/loadbalancers/{id}/usage/current")
IterableWithMarker<LoadBalancerUsage> listCurrentLoadBalancerUsage(PaginationOptions options);
/**
* Current usage represents all usage recorded within the preceding 24 hours.
*/
LoadBalancerStats getLoadBalancerStats(int loadBalancerId);
@Named("report:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(NullOnNotFoundOr404.class)
@Path("/loadbalancers/{id}/stats")
LoadBalancerStats getLoadBalancerStats(@PathParam("id") int loadBalancerId);
/**
* All load balancers must define the protocol of the service which is being load balanced. The protocol selection
* should be based on the protocol of the back-end nodes. When configuring a load balancer, the default port for
* the given protocol will be selected from this list unless otherwise specified.
*/
@Named("report:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@SelectJson("protocols")
@Fallback(NullOnNotFoundOr404.class)
@Path("/loadbalancers/protocols")
Iterable<Protocol> listProtocols();
/**
* Get all of the possible algorthims usable by load balancers.
*/
@Named("report:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseAlgorithms.class)
@Fallback(NullOnNotFoundOr404.class)
@Path("/loadbalancers/algorithms")
Iterable<String> listAlgorithms();
}

View File

@ -1,183 +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.rackspace.cloudloadbalancers.v1.features;
import java.util.Date;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.PagedIterable;
import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.openstack.v2_0.options.PaginationOptions;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.HistoricalUsage;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.LoadBalancer;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.LoadBalancerStats;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.LoadBalancerUsage;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.Protocol;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.DateParser;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseAlgorithms;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseLoadBalancerUsages;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseLoadBalancers;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.ParamParser;
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.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to Rackspace Cloud Load Balancers via their REST API.
* <p/>
*
* @see ReportApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface ReportAsyncApi {
/**
* @see ReportApi#listBillableLoadBalancers(Date, Date)
*/
@Named("report:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseLoadBalancers.class)
@Transform(ParseLoadBalancers.ToPagedIterable.class)
@Fallback(NullOnNotFoundOr404.class)
@Path("/loadbalancers/billable")
ListenableFuture<PagedIterable<LoadBalancer>> listBillableLoadBalancers(
@ParamParser(DateParser.class) @QueryParam("startTime") Date startTime,
@ParamParser(DateParser.class) @QueryParam("endTime") Date endTime);
/**
* @see ReportApi#listBillableLoadBalancers(PaginationOptions)
*/
@Named("report:list")
@GET
@ResponseParser(ParseLoadBalancers.class)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
@Path("/loadbalancers/billable")
ListenableFuture<IterableWithMarker<LoadBalancer>> listBillableLoadBalancers(PaginationOptions options);
/**
* @see ReportApi#getHistoricalUsage(Date, Date)
*/
@Named("report:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(NullOnNotFoundOr404.class)
@Path("/loadbalancers/usage")
ListenableFuture<HistoricalUsage> getHistoricalUsage(
@ParamParser(DateParser.class) @QueryParam("startTime") Date startTime,
@ParamParser(DateParser.class) @QueryParam("endTime") Date endTime);
/**
* @see ReportApi#listLoadBalancerUsage(int, Date, Date)
*/
@Named("report:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseLoadBalancerUsages.class)
@Transform(ParseLoadBalancerUsages.ToPagedIterable.class)
@Fallback(NullOnNotFoundOr404.class)
@Path("/loadbalancers/{id}/usage")
ListenableFuture<PagedIterable<LoadBalancerUsage>> listLoadBalancerUsage(
@PathParam("id") int loadBalancerId,
@ParamParser(DateParser.class) @QueryParam("startTime") Date startTime,
@ParamParser(DateParser.class) @QueryParam("endTime") Date endTime);
/**
* @see ReportApi#listLoadBalancerUsage(PaginationOptions)
*/
@Named("report:list")
@GET
@ResponseParser(ParseLoadBalancerUsages.class)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
@Path("/loadbalancers/{id}/usage")
ListenableFuture<IterableWithMarker<LoadBalancerUsage>> listLoadBalancerUsage(PaginationOptions options);
/**
* @see ReportApi#listCurrentLoadBalancerUsage(int)
*/
@Named("report:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseLoadBalancerUsages.class)
@Transform(ParseLoadBalancerUsages.ToPagedIterable.class)
@Fallback(NullOnNotFoundOr404.class)
@Path("/loadbalancers/{id}/usage/current")
ListenableFuture<PagedIterable<LoadBalancerUsage>> listCurrentLoadBalancerUsage(
@PathParam("id") int loadBalancerId);
/**
* @see ReportApi#listCurrentLoadBalancerUsage(PaginationOptions)
*/
@Named("report:list")
@GET
@ResponseParser(ParseLoadBalancerUsages.class)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(EmptyPaginatedCollectionOnNotFoundOr404.class)
@Path("/loadbalancers/{id}/usage/current")
ListenableFuture<IterableWithMarker<LoadBalancerUsage>> listCurrentLoadBalancerUsage(PaginationOptions options);
/**
* @see ReportApi#getLoadBalancerStats(int)
*/
@Named("report:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(NullOnNotFoundOr404.class)
@Path("/loadbalancers/{id}/stats")
ListenableFuture<LoadBalancerStats> getLoadBalancerStats(
@PathParam("id") int loadBalancerId);
/**
* @see ReportApi#listProtocols()
*/
@Named("report:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@SelectJson("protocols")
@Fallback(NullOnNotFoundOr404.class)
@Path("/loadbalancers/protocols")
ListenableFuture<Iterable<Protocol>> listProtocols();
/**
* @see ReportApi#listAlgorithms()
*/
@Named("report:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseAlgorithms.class)
@Fallback(NullOnNotFoundOr404.class)
@Path("/loadbalancers/algorithms")
ListenableFuture<Iterable<String>> listAlgorithms();
}

View File

@ -18,7 +18,23 @@
*/
package org.jclouds.rackspace.cloudloadbalancers.v1.features;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.FalseOnNotFoundOr422;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.SSLTermination;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.WrapWith;
/**
* The SSL Termination feature allows a load balancer user to terminate SSL traffic at the load balancer layer versus
@ -50,9 +66,9 @@ import org.jclouds.rackspace.cloudloadbalancers.v1.domain.SSLTermination;
* be secure.</li>
* </ol>
*
* @see SSLTerminationAsyncApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface SSLTerminationApi {
/**
* Create or update SSL termination.
@ -71,11 +87,22 @@ public interface SSLTerminationApi {
* If a user wants to replace the existing SSL configuration, a new certificate, privatekey, and securePort
* combination must be provided instead of, or in addition to, the optional/editable attributes.
*/
void createOrUpdate(SSLTermination sslTermination);
@Named("ssltermination:create")
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Path("/ssltermination")
void createOrUpdate(@WrapWith("sslTermination") SSLTermination sslTermination);
/**
* Get SSL termination info.
*/
@Named("ssltermination:get")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@SelectJson("sslTermination")
@Fallback(NullOnNotFoundOr404.class)
@Path("/ssltermination")
SSLTermination get();
/**
@ -83,5 +110,10 @@ public interface SSLTerminationApi {
*
* @return true on a successful delete, false if the SSL termination was not found
*/
@Named("ssltermination:delete")
@DELETE
@Fallback(FalseOnNotFoundOr422.class)
@Path("/ssltermination")
@Consumes("*/*")
boolean delete();
}

View File

@ -1,81 +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.rackspace.cloudloadbalancers.v1.features;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.FalseOnNotFoundOr422;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.SSLTermination;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.WrapWith;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to Rackspace Cloud Load Balancers via their REST API.
* <p/>
*
* @see SSLTerminationApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface SSLTerminationAsyncApi {
/**
* @see SSLTerminationApi#createOrUpdate(SSLTermination)
*/
@Named("ssltermination:create")
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Path("/ssltermination")
ListenableFuture<Void> createOrUpdate(@WrapWith("sslTermination") SSLTermination sslTermination);
/**
* @see SSLTerminationApi#get()
*/
@Named("ssltermination:get")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@SelectJson("sslTermination")
@Fallback(NullOnNotFoundOr404.class)
@Path("/ssltermination")
ListenableFuture<SSLTermination> get();
/**
* @see SSLTerminationApi#delete()
*/
@Named("ssltermination:delete")
@DELETE
@Fallback(FalseOnNotFoundOr422.class)
@Path("/ssltermination")
@Consumes("*/*")
ListenableFuture<Boolean> delete();
}

View File

@ -18,7 +18,25 @@
*/
package org.jclouds.rackspace.cloudloadbalancers.v1.features;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.SessionPersistence;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseSessionPersistence;
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.ResponseParser;
/**
@ -26,15 +44,21 @@ import org.jclouds.rackspace.cloudloadbalancers.v1.domain.SessionPersistence;
* directed to the same node. This is common with many web applications that do not inherently share application
* state between back-end servers. Two session persistence modes are available, HTTP Cookie and Source IP.
*
* @see SessionPersistenceAsyncApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface SessionPersistenceApi {
/**
* Get the current session persistence.
*
* @see SessionPersistence
*/
@Named("sessionpersistence:get")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseSessionPersistence.class)
@Fallback(NullOnNotFoundOr404.class)
@Path("/sessionpersistence")
SessionPersistence get();
/**
@ -42,12 +66,24 @@ public interface SessionPersistenceApi {
*
* @see SessionPersistence
*/
void create(SessionPersistence sessionPersistence);
@Named("sessionpersistence:create")
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Payload("%7B\"sessionPersistence\":%7B\"persistenceType\":\"{sessionPersistence}\"%7D%7D")
@Path("/sessionpersistence")
void create(@PayloadParam("sessionPersistence") SessionPersistence sessionPersistence);
/**
* Delete session persistence.
*
* @see SessionPersistence
*/
@Named("sessionpersistence:delete")
@DELETE
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Path("/sessionpersistence")
void delete();
}

View File

@ -1,85 +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.rackspace.cloudloadbalancers.v1.features;
import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.SessionPersistence;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseSessionPersistence;
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.ResponseParser;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to Rackspace Cloud Load Balancers via their REST API.
* <p/>
*
* @see SessionPersistenceApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface SessionPersistenceAsyncApi {
/**
* @see SessionPersistenceApi#get()
*/
@Named("sessionpersistence:get")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@ResponseParser(ParseSessionPersistence.class)
@Fallback(NullOnNotFoundOr404.class)
@Path("/sessionpersistence")
ListenableFuture<SessionPersistence> get();
/**
* @see SessionPersistenceApi#create(SessionPersistence)
*/
@Named("sessionpersistence:create")
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Payload("%7B\"sessionPersistence\":%7B\"persistenceType\":\"{sessionPersistence}\"%7D%7D")
@Path("/sessionpersistence")
ListenableFuture<Void> create(@PayloadParam("sessionPersistence") SessionPersistence sessionPersistence);
/**
* @see SessionPersistenceApi#delete()
*/
@Named("sessionpersistence:delete")
@DELETE
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(VoidOnNotFoundOr404.class)
@Path("/sessionpersistence")
ListenableFuture<Void> delete();
}

View File

@ -18,8 +18,27 @@
*/
package org.jclouds.rackspace.cloudloadbalancers.v1.features;
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.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.VirtualIP;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.VirtualIPWithId;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.binders.BindToJsonPayload;
/**
* A virtual IP makes a load balancer accessible by clients. The load balancing service supports either a public VIP,
@ -27,18 +46,29 @@ import org.jclouds.rackspace.cloudloadbalancers.v1.domain.VirtualIPWithId;
* resides.
* <p/>
*
* @see VirtualIPAsyncApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface VirtualIPApi {
/**
* Create a new virtual IP.
*/
VirtualIPWithId create(VirtualIP virtualIP);
@Named("virtualip:create")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(NullOnNotFoundOr404.class)
@Path("/virtualips")
VirtualIPWithId create(@BinderParam(BindToJsonPayload.class) VirtualIP virtualIP);
/**
* List the virtual IPs.
*/
@Named("virtualip:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
@SelectJson("virtualIps")
@Path("/virtualips")
Iterable<VirtualIPWithId> list();
/**
@ -48,7 +78,12 @@ public interface VirtualIPApi {
*
* @return true on a successful delete, false if the virtual IP was not found
*/
boolean delete(int id);
@Named("virtualip:delete")
@DELETE
@Fallback(FalseOnNotFoundOr404.class)
@Path("/virtualips/{id}")
@Consumes("*/*")
boolean delete(@PathParam("id") int id);
/**
* Batch delete virtual IPs given the specified ids.
@ -61,5 +96,10 @@ public interface VirtualIPApi {
*
* @return true on a successful delete, false if the virtual IP was not found
*/
boolean delete(Iterable<Integer> ids);
@Named("virtualip:delete")
@DELETE
@Fallback(FalseOnNotFoundOr404.class)
@Path("/virtualips")
@Consumes("*/*")
boolean delete(@QueryParam("id") Iterable<Integer> ids);
}

View File

@ -1,95 +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.rackspace.cloudloadbalancers.v1.features;
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.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.VirtualIP;
import org.jclouds.rackspace.cloudloadbalancers.v1.domain.VirtualIPWithId;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.binders.BindToJsonPayload;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to Rackspace Cloud Load Balancers via their REST API.
* <p/>
*
* @see VirtualIPApi
* @author Everett Toews
*/
@RequestFilters(AuthenticateRequest.class)
public interface VirtualIPAsyncApi {
/**
* @see VirtualIPApi#create(VirtualIP)
*/
@Named("virtualip:create")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(NullOnNotFoundOr404.class)
@Path("/virtualips")
ListenableFuture<VirtualIPWithId> create(@BinderParam(BindToJsonPayload.class) VirtualIP virtualIP);
/**
* @see VirtualIPApi#list()
*/
@Named("virtualip:list")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
@SelectJson("virtualIps")
@Path("/virtualips")
ListenableFuture<Iterable<VirtualIPWithId>> list();
/**
* @see VirtualIPApi#delete(int)
*/
@Named("virtualip:delete")
@DELETE
@Fallback(FalseOnNotFoundOr404.class)
@Path("/virtualips/{id}")
@Consumes("*/*")
ListenableFuture<Boolean> delete(@PathParam("id") int id);
/**
* @see VirtualIPApi#delete(Iterable)
*/
@Named("virtualip:delete")
@DELETE
@Fallback(FalseOnNotFoundOr404.class)
@Path("/virtualips")
@Consumes("*/*")
ListenableFuture<Boolean> delete(@QueryParam("id") Iterable<Integer> ids);
}

View File

@ -27,7 +27,7 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.internal.CallerArg0ToPagedIterable;
import org.jclouds.collect.internal.Arg0ToPagedIterable;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.json.Json;
import org.jclouds.openstack.keystone.v2_0.domain.PaginatedCollection;
@ -38,6 +38,7 @@ import org.jclouds.rackspace.cloudloadbalancers.v1.features.ReportApi;
import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseLoadBalancerUsages.LoadBalancerUsages;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.inject.TypeLiteral;
/**
@ -61,7 +62,7 @@ public class ParseLoadBalancerUsages extends ParseJson<LoadBalancerUsages> {
}
}
public static class ToPagedIterable extends CallerArg0ToPagedIterable<LoadBalancerUsage, ToPagedIterable> {
public static class ToPagedIterable extends Arg0ToPagedIterable.FromCaller<LoadBalancerUsage, ToPagedIterable> {
private final CloudLoadBalancersApi api;
@ -71,7 +72,8 @@ public class ParseLoadBalancerUsages extends ParseJson<LoadBalancerUsages> {
}
@Override
protected Function<Object, IterableWithMarker<LoadBalancerUsage>> markerToNextForCallingArg0(final String zone) {
protected Function<Object, IterableWithMarker<LoadBalancerUsage>> markerToNextForArg0(Optional<Object> arg0) {
String zone = arg0.isPresent() ? arg0.get().toString() : null;
final ReportApi reportApi = api.getReportApiForZone(zone);
return new Function<Object, IterableWithMarker<LoadBalancerUsage>>() {

View File

@ -27,7 +27,7 @@ import javax.inject.Inject;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.IterableWithMarkers;
import org.jclouds.collect.internal.CallerArg0ToPagedIterable;
import org.jclouds.collect.internal.Arg0ToPagedIterable;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ParseJson;
@ -40,6 +40,7 @@ import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ConvertLB.Factory;
import org.jclouds.rest.InvocationContext;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.Iterables;
/**
@ -92,7 +93,7 @@ public class ParseLoadBalancers implements Function<HttpResponse, IterableWithMa
}
public static class ToPagedIterable extends CallerArg0ToPagedIterable<LoadBalancer, ToPagedIterable> {
public static class ToPagedIterable extends Arg0ToPagedIterable.FromCaller<LoadBalancer, ToPagedIterable> {
private final CloudLoadBalancersApi api;
@ -102,7 +103,8 @@ public class ParseLoadBalancers implements Function<HttpResponse, IterableWithMa
}
@Override
protected Function<Object, IterableWithMarker<LoadBalancer>> markerToNextForCallingArg0(final String zone) {
protected Function<Object, IterableWithMarker<LoadBalancer>> markerToNextForArg0(Optional<Object> arg0) {
String zone = arg0.isPresent() ? arg0.get().toString() : null;
final LoadBalancerApi loadBalancerApi = api.getLoadBalancerApiForZone(zone);
return new Function<Object, IterableWithMarker<LoadBalancer>>() {

View File

@ -27,7 +27,7 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.internal.CallerArg0ToPagedIterable;
import org.jclouds.collect.internal.Arg0ToPagedIterable;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.json.Json;
@ -40,6 +40,7 @@ import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseNodes.Nodes;
import com.google.common.annotations.Beta;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.inject.TypeLiteral;
/**
@ -64,7 +65,7 @@ public class ParseNodes extends ParseJson<Nodes> {
super(json, new TypeLiteral<Nodes>() { });
}
public static class ToPagedIterable extends CallerArg0ToPagedIterable<Node, ToPagedIterable> {
public static class ToPagedIterable extends Arg0ToPagedIterable.FromCaller<Node, ToPagedIterable> {
private final CloudLoadBalancersApi api;
private int lbId;
@ -86,7 +87,8 @@ public class ParseNodes extends ParseJson<Nodes> {
}
@Override
protected Function<Object, IterableWithMarker<Node>> markerToNextForCallingArg0(final String zone) {
protected Function<Object, IterableWithMarker<Node>> markerToNextForArg0(Optional<Object> arg0) {
String zone = arg0.isPresent() ? arg0.get().toString() : null;
final NodeApi nodeApi = api.getNodeApiForZoneAndLoadBalancer(zone, lbId);
return new Function<Object, IterableWithMarker<Node>>() {

View File

@ -20,22 +20,35 @@ 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.javax.annotation.Nullable;
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.ResourceRecordSetApi;
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
* <p/>
*
* @see Route53AsyncApi
* @see <a href="http://docs.amazonwebservices.com/Route53/latest/APIReference"
* />
* @author Adrian Cole
*/
@RequestFilters(RestAuthentication.class)
@VirtualHost
@Path("/{jclouds.api-version}")
public interface Route53Api extends Closeable {
/**
@ -45,17 +58,24 @@ public interface Route53Api extends Closeable {
* The ID of the change batch request.
* @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
HostedZoneApi getHostedZoneApi();
/**
* Provides synchronous access to record set features.
* Provides access to record set features.
*/
@Delegate
@Path("/hostedzone/{zoneId}")
ResourceRecordSetApi getResourceRecordSetApiForHostedZone(@PathParam("zoneId") String zoneId);
}

View File

@ -25,35 +25,23 @@ import java.net.URI;
import java.util.Properties;
import org.jclouds.apis.ApiMetadata;
import org.jclouds.rest.internal.BaseRestApiMetadata;
import org.jclouds.route53.config.Route53RestClientModule;
import com.google.common.reflect.TypeToken;
import org.jclouds.rest.internal.BaseHttpApiMetadata;
import org.jclouds.route53.config.Route53HttpApiModule;
/**
* Implementation of {@link ApiMetadata} for Amazon's Route53 api.
*
* @author Adrian Cole
*/
public class Route53ApiMetadata extends BaseRestApiMetadata {
/**
* @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;
};
public class Route53ApiMetadata extends BaseHttpApiMetadata<Route53Api> {
@Override
public Builder toBuilder() {
return new Builder(getApi(), getAsyncApi()).fromApiMetadata(this);
return new Builder().fromApiMetadata(this);
}
@SuppressWarnings("deprecation")
public Route53ApiMetadata() {
this(new Builder(Route53Api.class, Route53AsyncApi.class));
this(new Builder());
}
protected Route53ApiMetadata(Builder builder) {
@ -61,16 +49,15 @@ public class Route53ApiMetadata extends BaseRestApiMetadata {
}
public static Properties defaultProperties() {
Properties properties = BaseRestApiMetadata.defaultProperties();
Properties properties = BaseHttpApiMetadata.defaultProperties();
properties.setProperty(PROPERTY_AUTH_TAG, "AWS");
properties.setProperty(PROPERTY_HEADER_TAG, "amz");
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) {
super(api, asyncApi);
protected Builder() {
id("route53")
.name("Amazon Route 53 Api")
.identityName("Access Key ID")
@ -79,7 +66,7 @@ public class Route53ApiMetadata extends BaseRestApiMetadata {
.documentation(URI.create("http://docs.aws.amazon.com/Route53/latest/APIReference/"))
.defaultEndpoint("https://route53.amazonaws.com")
.defaultProperties(Route53ApiMetadata.defaultProperties())
.defaultModule(Route53RestClientModule.class);
.defaultModule(Route53HttpApiModule.class);
}
@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;
import static org.jclouds.reflect.Reflection2.typeToken;
import java.util.Date;
import java.util.Map;
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.TimeStamp;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.rest.RequestSigner;
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.handlers.Route53ErrorHandler;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Provides;
/**
@ -51,14 +42,9 @@ import com.google.inject.Provides;
*
* @author Adrian Cole
*/
@ConfiguresRestClient
public class Route53RestClientModule extends AWSRestClientModule<Route53Api, Route53AsyncApi> {
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()//
.put(HostedZoneApi.class, HostedZoneAsyncApi.class)
.put(ResourceRecordSetApi.class, ResourceRecordSetAsyncApi.class).build();
public Route53RestClientModule() {
super(typeToken(Route53Api.class), typeToken(Route53AsyncApi.class), DELEGATE_MAP);
@ConfiguresHttpApi
public class Route53HttpApiModule extends AWSHttpApiModule<Route53Api> {
public Route53HttpApiModule() {
}
@Provides

View File

@ -18,22 +18,48 @@
*/
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.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.Status;
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;
/**
* @see HostedZoneAsyncApi
* @see <a href=
* "http://docs.aws.amazon.com/Route53/latest/APIReference/ActionsOnHostedZones.html"
* />
* @author Adrian Cole
*/
@RequestFilters(RestAuthentication.class)
@VirtualHost
public interface HostedZoneApi {
/**
@ -51,28 +77,55 @@ public interface HostedZoneApi {
* retries. ex. {@code MyDNSMigration_01}
* @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
* 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.
*/
@Named("ListHostedZones")
@GET
@Path("/hostedzone")
@XMLResponseParser(ListHostedZonesResponseHandler.class)
@Transform(HostedZonesToPagedIterable.class)
PagedIterable<HostedZone> list();
/**
* retrieves up to 100 zones in order.
*/
@Named("ListHostedZones")
@GET
@Path("/hostedzone")
@XMLResponseParser(ListHostedZonesResponseHandler.class)
IterableWithMarker<HostedZone> listFirstPage();
/**
* 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
@ -83,8 +136,13 @@ public interface HostedZoneApi {
* {@code Z1PA6795UKMFR9}
* @return null if not found
*/
@Named("GetHostedZone")
@GET
@Path("/hostedzone/{zoneId}")
@XMLResponseParser(GetHostedZoneResponseHandler.class)
@Fallback(NullOnNotFoundOr404.class)
@Nullable
HostedZoneAndNameServers get(String id);
HostedZoneAndNameServers get(@PathParam("zoneId") String zoneId);
/**
* This action deletes a hosted zone.
@ -93,6 +151,11 @@ public interface HostedZoneApi {
* id of the zone to delete. ex {@code Z1PA6795UKMFR9}
* @return null if not found or the change in progress
*/
@Named("DeleteHostedZone")
@DELETE
@Path("/hostedzone/{zoneId}")
@XMLResponseParser(ChangeHandler.class)
@Fallback(NullOnNotFoundOr404.class)
@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;
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.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.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;
/**
* @see ResourceRecordSetAsyncApi
* @see <a href=
* "http://docs.aws.amazon.com/Route53/latest/APIReference/ActionsOnRRS.html"
* />
* @author Adrian Cole
*/
@RequestFilters(RestAuthentication.class)
@VirtualHost
public interface ResourceRecordSetApi {
/**
* 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.
*/
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.
*/
@Named("ListResourceRecordSets")
@GET
@Path("/rrset")
@XMLResponseParser(ListResourceRecordSetsResponseHandler.class)
@Transform(ResourceRecordSetIterableToPagedIterable.class)
PagedIterable<ResourceRecordSet> list();
/**
* retrieves up to 100 resource record sets in order.
*/
@Named("ListResourceRecordSets")
@GET
@Path("/rrset")
@XMLResponseParser(ListResourceRecordSetsResponseHandler.class)
ResourceRecordSetIterable listFirstPage();
/**
* retrieves up to 100 resource record sets in order, starting at
* {@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.
@ -68,6 +118,13 @@ public interface ResourceRecordSetApi {
* the resource record set to delete
* @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
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;
import org.jclouds.View;
import org.jclouds.rest.internal.BaseRestApiMetadataTest;
import org.jclouds.rest.internal.BaseHttpApiMetadataTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
@ -30,9 +30,9 @@ import com.google.common.reflect.TypeToken;
* @author Adrian Cole
*/
@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() {
super(new Route53ApiMetadata(), ImmutableSet.<TypeToken<? extends View>> of());
}

View File

@ -49,7 +49,8 @@ public class BaseRoute53ApiLiveTest extends BaseApiLiveTest<Route53Api> {
super.setup();
inSync = retry(new Predicate<Change>() {
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);
}

View File

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

@ -32,6 +32,7 @@ import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.HttpApiModule;
import org.jclouds.rest.config.RestClientModule;
import com.google.common.collect.ImmutableSet;
@ -42,7 +43,10 @@ import com.google.inject.Provides;
/**
*
* @author Adrian Cole
*
* @deprecated will be removed in jclouds 1.7; use {@link AWSHttpApiModule}
*/
@Deprecated
@ConfiguresRestClient
public abstract class AWSRestClientModule<S, A> extends RestClientModule<S, A> {

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;
import static org.jclouds.util.SaxUtils.currentOrNull;
import javax.inject.Inject;
import org.jclouds.aws.domain.SessionCredentials;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.util.SaxUtils;
/**
* @see <a href=
@ -55,13 +56,17 @@ public class SessionCredentialsHandler extends ParseSax.HandlerForGeneratedReque
@Override
public void endElement(String uri, String name, String qName) {
if (qName.equals("AccessKeyId")) {
builder.accessKeyId(SaxUtils.currentOrNull(currentText));
builder.accessKeyId(currentOrNull(currentText));
} else if (qName.equals("SecretAccessKey")) {
builder.secretAccessKey(SaxUtils.currentOrNull(currentText));
builder.secretAccessKey(currentOrNull(currentText));
} else if (qName.equals("SessionToken")) {
builder.sessionToken(SaxUtils.currentOrNull(currentText));
builder.sessionToken(currentOrNull(currentText));
} 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();
}

View File

@ -20,32 +20,55 @@ 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.User;
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;
/**
* Provides access to Amazon STS via the Query API
* <p/>
*
* @see STSAsyncApi
* @see <a href="http://docs.amazonwebservices.com/STS/latest/APIReference" />
* @author Adrian Cole
*/
@RequestFilters(FormSigner.class)
@VirtualHost
public interface STSApi extends Closeable {
/**
* Returns a set of temporary credentials for an AWS account or IAM user,
* with a default timeout
*/
@Named("GetSessionToken")
@POST
@Path("/")
@XMLResponseParser(SessionCredentialsHandler.class)
@FormParams(keys = "Action", values = "GetSessionToken")
SessionCredentials createTemporaryCredentials();
/**
* like {@link #createTemporaryCredentials()}, except you can modify the
* timeout and other parameters.
*/
@Named("GetSessionToken")
@POST
@Path("/")
@XMLResponseParser(SessionCredentialsHandler.class)
@FormParams(keys = "Action", values = "GetSessionToken")
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
* 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
* 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
@ -74,12 +109,21 @@ public interface STSApi extends Closeable {
* The name of the federated user, included as part of
* {@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
* 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 org.jclouds.apis.ApiMetadata;
import org.jclouds.rest.internal.BaseRestApiMetadata;
import org.jclouds.sts.config.STSRestClientModule;
import com.google.common.reflect.TypeToken;
import org.jclouds.rest.internal.BaseHttpApiMetadata;
import org.jclouds.sts.config.STSHttpApiModule;
/**
* Implementation of {@link ApiMetadata} for Amazon's STS api.
*
* @author Adrian Cole
*/
public class STSApiMetadata extends BaseRestApiMetadata {
/**
* @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;
};
public class STSApiMetadata extends BaseHttpApiMetadata<STSApi> {
@Override
public Builder toBuilder() {
return new Builder(getApi(), getAsyncApi()).fromApiMetadata(this);
return new Builder().fromApiMetadata(this);
}
@SuppressWarnings("deprecation")
public STSApiMetadata() {
this(new Builder(STSApi.class, STSAsyncApi.class));
this(new Builder());
}
protected STSApiMetadata(Builder builder) {
@ -61,16 +49,15 @@ public class STSApiMetadata extends BaseRestApiMetadata {
}
public static Properties defaultProperties() {
Properties properties = BaseRestApiMetadata.defaultProperties();
Properties properties = BaseHttpApiMetadata.defaultProperties();
properties.setProperty(PROPERTY_AUTH_TAG, "AWS");
properties.setProperty(PROPERTY_HEADER_TAG, "amz");
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) {
super(api, asyncApi);
protected Builder() {
id("sts")
.name("Amazon STS Api")
.identityName("Access Key ID")
@ -79,7 +66,7 @@ public class STSApiMetadata extends BaseRestApiMetadata {
.documentation(URI.create("http://docs.amazonwebservices.com/STS/latest/APIReference/"))
.defaultEndpoint("https://sts.amazonaws.com")
.defaultProperties(STSApiMetadata.defaultProperties())
.defaultModule(STSRestClientModule.class);
.defaultModule(STSHttpApiModule.class);
}
@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;
import static org.jclouds.reflect.Reflection2.typeToken;
import org.jclouds.aws.config.FormSigningRestClientModule;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.aws.config.FormSigningHttpApiModule;
import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.sts.STSApi;
import org.jclouds.sts.STSAsyncApi;
/**
* Configures the STS connection.
*
* @author Adrian Cole
*/
@ConfiguresRestClient
public class STSRestClientModule extends FormSigningRestClientModule<STSApi, STSAsyncApi> {
public STSRestClientModule() {
super(typeToken(STSApi.class), typeToken(STSAsyncApi.class));
}
@ConfiguresHttpApi
public class STSHttpApiModule extends FormSigningHttpApiModule<STSApi> {
}

View File

@ -19,7 +19,7 @@
package org.jclouds.sts;
import org.jclouds.View;
import org.jclouds.rest.internal.BaseRestApiMetadataTest;
import org.jclouds.rest.internal.BaseHttpApiMetadataTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
@ -30,9 +30,9 @@ import com.google.common.reflect.TypeToken;
* @author Adrian Cole
*/
@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() {
super(new STSApiMetadata(), ImmutableSet.<TypeToken<? extends View>> of());
}

View File

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

View File

@ -27,6 +27,7 @@ import java.util.Properties;
import org.jclouds.apis.ApiMetadata;
import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule;
import org.jclouds.openstack.keystone.v2_0.config.MappedAuthenticationApiModule;
import org.jclouds.openstack.services.ServiceType;
import org.jclouds.openstack.swift.blobstore.config.SwiftBlobStoreContextModule;
import org.jclouds.openstack.swift.blobstore.config.TemporaryUrlExtensionModule.SwiftKeystoneTemporaryUrlExtensionModule;
@ -90,6 +91,7 @@ public class SwiftKeystoneApiMetadata extends SwiftApiMetadata {
.context(CONTEXT_TOKEN)
.defaultProperties(SwiftKeystoneApiMetadata.defaultProperties())
.defaultModules(ImmutableSet.<Class<? extends Module>>builder()
.add(MappedAuthenticationApiModule.class)
.add(KeystoneStorageEndpointModule.class)
.add(KeystoneAuthenticationModule.RegionModule.class)
.add(SwiftKeystoneRestClientModule.class)

View File

@ -18,7 +18,7 @@
*/
package org.jclouds.openstack.swift.blobstore.config;
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
import static org.jclouds.rest.config.BinderUtils.bindMappedHttpApi;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import java.util.concurrent.TimeUnit;
@ -70,7 +70,7 @@ public abstract class TemporaryUrlExtensionModule<A extends CommonSwiftAsyncClie
TemporaryUrlExtensionModule<SwiftKeystoneAsyncClient> {
protected void bindTemporaryUrlKeyApi() {
bindHttpApi(binder(), TemporaryUrlKeyApi.class, KeystoneTemporaryUrlKeyAsyncApi.class);
bindMappedHttpApi(binder(), TemporaryUrlKeyApi.class, KeystoneTemporaryUrlKeyAsyncApi.class);
}
@Override
@ -115,7 +115,7 @@ public abstract class TemporaryUrlExtensionModule<A extends CommonSwiftAsyncClie
protected abstract void bindRequestSigner();
protected void bindTemporaryUrlKeyApi() {
bindHttpApi(binder(), TemporaryUrlKeyApi.class, TemporaryUrlKeyAsyncApi.class);
bindMappedHttpApi(binder(), TemporaryUrlKeyApi.class, TemporaryUrlKeyAsyncApi.class);
}
}

View File

@ -29,6 +29,7 @@ import org.jclouds.blobstore.internal.BaseBlobSignerExpectTest;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule;
import org.jclouds.openstack.keystone.v2_0.config.MappedAuthenticationApiModule;
import org.jclouds.openstack.swift.SwiftKeystoneApiMetadata;
import org.jclouds.openstack.swift.blobstore.config.SwiftBlobStoreContextModule;
import org.jclouds.openstack.swift.blobstore.config.TemporaryUrlExtensionModule.SwiftKeystoneTemporaryUrlExtensionModule;
@ -139,6 +140,7 @@ public class SwiftKeystoneBlobSignerExpectTest extends BaseBlobSignerExpectTest
protected ApiMetadata createApiMetadata() {
return new SwiftKeystoneApiMetadata().toBuilder()
.defaultModules(ImmutableSet.<Class<? extends Module>>builder()
.add(MappedAuthenticationApiModule.class)
.add(KeystoneStorageEndpointModule.class)
.add(KeystoneAuthenticationModule.RegionModule.class)
.add(SwiftKeystoneRestClientModule.class)

View File

@ -28,7 +28,7 @@ import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Maps.transformValues;
import static com.google.common.collect.Maps.uniqueIndex;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
import static org.jclouds.rest.config.BinderUtils.bindMappedHttpApi;
import static org.jclouds.util.Predicates2.retry;
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_DEFAULT_FENCEMODE;
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED;
@ -206,8 +206,8 @@ public class VCloudRestClientModule extends RestClientModule<VCloudClient, VClou
bind(new TypeLiteral<Function<VAppTemplate, Envelope>>() {
}).to(new TypeLiteral<ValidateVAppTemplateAndReturnEnvelopeOrThrowIllegalArgumentException>() {
});
bindHttpApi(binder(), VCloudVersionsClient.class, VCloudVersionsAsyncClient.class);
bindHttpApi(binder(), VCloudLoginClient.class, VCloudLoginAsyncClient.class);
bindMappedHttpApi(binder(), VCloudVersionsClient.class, VCloudVersionsAsyncClient.class);
bindMappedHttpApi(binder(), VCloudLoginClient.class, VCloudLoginAsyncClient.class);
}
protected void bindCacheLoaders() {

View File

@ -18,7 +18,7 @@
*/
package org.jclouds.blobstore.config;
import static org.jclouds.rest.config.BinderUtils.bindBlockingApi;
import static org.jclouds.rest.config.BinderUtils.bindMappedApi;
import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.BlobRequestSigner;
@ -41,7 +41,7 @@ public class TransientBlobStoreContextModule extends AbstractModule {
protected void configure() {
bind(AsyncBlobStore.class).to(LocalAsyncBlobStore.class).asEagerSingleton();
// forward all requests from TransientBlobStore to TransientAsyncBlobStore. needs above binding as cannot proxy a class
bindBlockingApi(binder(), LocalBlobStore.class, AsyncBlobStore.class);
bindMappedApi(binder(), LocalBlobStore.class, AsyncBlobStore.class);
install(new BlobStoreObjectModule());
install(new BlobStoreMapModule());
bind(BlobStore.class).to(LocalBlobStore.class);

View File

@ -19,7 +19,7 @@
package org.jclouds.openstack.config;
import static com.google.common.base.Suppliers.memoizeWithExpiration;
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
import static org.jclouds.rest.config.BinderUtils.bindMappedHttpApi;
import java.util.Date;
import java.util.concurrent.ExecutionException;
@ -59,7 +59,7 @@ public class OpenStackAuthenticationModule extends AbstractModule {
@Override
protected void configure() {
// OpenStackAuthClient is used directly for filters and retry handlers, so let's bind it explicitly
bindHttpApi(binder(), OpenStackAuthClient.class, OpenStackAuthAsyncClient.class);
bindMappedHttpApi(binder(), OpenStackAuthClient.class, OpenStackAuthAsyncClient.class);
install(new FactoryModuleBuilder().build(URIFromAuthenticationResponseForService.Factory.class));
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenew.class);
}

View File

@ -18,7 +18,7 @@
*/
package org.jclouds.openstack.keystone.v1_1.config;
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
import static org.jclouds.rest.config.BinderUtils.bindMappedHttpApi;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import java.util.concurrent.ExecutionException;
@ -60,7 +60,7 @@ public class AuthenticationServiceModule extends AbstractModule {
@Override
protected void configure() {
// ServiceClient is used directly for filters and retry handlers, so let's bind it explicitly
bindHttpApi(binder(), AuthenticationClient.class, AuthenticationAsyncClient.class);
bindMappedHttpApi(binder(), AuthenticationClient.class, AuthenticationAsyncClient.class);
install(new FactoryModuleBuilder().implement(RegionIdToURISupplier.class,
RegionIdToURIFromAuthForServiceSupplier.class).build(RegionIdToURISupplier.Factory.class));
install(new FactoryModuleBuilder().implement(ImplicitRegionIdSupplier.class, V1DefaultRegionIdSupplier.class)

View File

@ -26,7 +26,7 @@ import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Maps.transformValues;
import static com.google.common.collect.Maps.uniqueIndex;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
import static org.jclouds.rest.config.BinderUtils.bindMappedHttpApi;
import static org.jclouds.trmk.vcloud_0_8.reference.VCloudConstants.PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED;
import static org.jclouds.util.Predicates2.retry;
@ -134,8 +134,8 @@ public class TerremarkVCloudRestClientModule<S, A> extends RestClientModule<S, A
bind(new TypeLiteral<Function<org.jclouds.trmk.vcloud_0_8.domain.Org, Iterable<? extends CatalogItem>>>() {
}).to(new TypeLiteral<AllCatalogItemsInOrg>() {
});
bindHttpApi(binder(), TerremarkVCloudVersionsClient.class, TerremarkVCloudVersionsAsyncClient.class);
bindHttpApi(binder(), TerremarkVCloudLoginClient.class, TerremarkVCloudLoginAsyncClient.class);
bindMappedHttpApi(binder(), TerremarkVCloudVersionsClient.class, TerremarkVCloudVersionsAsyncClient.class);
bindMappedHttpApi(binder(), TerremarkVCloudLoginClient.class, TerremarkVCloudLoginAsyncClient.class);
}
@Provides

View File

@ -31,7 +31,6 @@ import org.jclouds.date.DateService;
import org.jclouds.domain.Credentials;
import org.jclouds.json.Json;
import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.rest.HttpAsyncClient;
import org.jclouds.rest.HttpClient;
import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.SshClient.Factory;
@ -54,11 +53,12 @@ public class UtilsImpl extends org.jclouds.rest.internal.UtilsImpl implements Ut
private final Function<NodeMetadata, SshClient> sshForNode;
@Inject
UtilsImpl(Injector injector, Json json, XMLParser xml, HttpClient simpleClient, HttpAsyncClient simpleAsyncClient,
Crypto encryption, DateService date, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor, EventBus eventBus,
Map<String, Credentials> credentialStore, LoggerFactory loggerFactory,
Function<NodeMetadata, SshClient> sshForNode) {
UtilsImpl(Injector injector, Json json, XMLParser xml, HttpClient simpleClient,
org.jclouds.rest.HttpAsyncClient simpleAsyncClient, Crypto encryption, DateService date,
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor, EventBus eventBus,
Map<String, Credentials> credentialStore, LoggerFactory loggerFactory,
Function<NodeMetadata, SshClient> sshForNode) {
super(injector, json, xml, simpleClient, simpleAsyncClient, encryption, date, userExecutor, ioExecutor, eventBus,
credentialStore, loggerFactory);
this.sshForNode = sshForNode;

View File

@ -20,10 +20,12 @@ package org.jclouds;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Predicates.and;
import static com.google.common.base.Predicates.containsPattern;
import static com.google.common.base.Predicates.instanceOf;
import static com.google.common.base.Predicates.not;
import static com.google.common.base.Predicates.notNull;
import static com.google.common.base.Predicates.or;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.collect.Iterables.addAll;
import static com.google.common.collect.Iterables.any;
@ -57,6 +59,7 @@ import org.jclouds.apis.Apis;
import org.jclouds.concurrent.SingleThreaded;
import org.jclouds.concurrent.config.ConfiguresExecutorService;
import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.config.BindApiContextWithWildcardExtendsExplicitAndRawType;
import org.jclouds.config.BindNameToContext;
import org.jclouds.config.BindPropertiesToExpandedValues;
import org.jclouds.config.BindRestContextWithWildcardExtendsExplicitAndRawType;
@ -75,9 +78,14 @@ import org.jclouds.providers.Providers;
import org.jclouds.providers.config.BindProviderMetadataContextAndCredentials;
import org.jclouds.providers.internal.UpdateProviderMetadataFromProperties;
import org.jclouds.rest.ConfiguresCredentialStore;
import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.HttpApiMetadata;
import org.jclouds.rest.RestApiMetadata;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.config.CredentialStoreModule;
import org.jclouds.rest.config.HttpApiModule;
import org.jclouds.rest.config.MappedHttpInvocationModule;
import org.jclouds.rest.config.RestClientModule;
import org.jclouds.rest.config.RestModule;
@ -382,9 +390,9 @@ public class ContextBuilder {
public static Injector buildInjector(String name, ProviderMetadata providerMetadata, Supplier<Credentials> creds, List<Module> inputModules) {
List<Module> modules = newArrayList();
modules.addAll(inputModules);
boolean restModuleSpecifiedByUser = restClientModulePresent(inputModules);
Iterable<Module> defaultModules = ifSpecifiedByUserDontIncludeDefaultRestModule(
providerMetadata.getApiMetadata(), restModuleSpecifiedByUser);
boolean apiModuleSpecifiedByUser = apiModulePresent(inputModules);
Iterable<Module> defaultModules = ifSpecifiedByUserDontIncludeDefaultApiModule(
providerMetadata.getApiMetadata(), apiModuleSpecifiedByUser);
addAll(modules, defaultModules);
addClientModuleIfNotPresent(providerMetadata.getApiMetadata(), modules);
addRestContextBinding(providerMetadata.getApiMetadata(), modules);
@ -415,17 +423,24 @@ public class ContextBuilder {
}
static void addRestContextBinding(ApiMetadata apiMetadata, List<Module> modules) {
if (apiMetadata instanceof RestApiMetadata) {
if (apiMetadata instanceof HttpApiMetadata) {
try {
modules
.add(new BindApiContextWithWildcardExtendsExplicitAndRawType(HttpApiMetadata.class.cast(apiMetadata)));
} catch (IllegalArgumentException e) {
}
} else if (apiMetadata instanceof RestApiMetadata) {
try {
modules.add(new BindRestContextWithWildcardExtendsExplicitAndRawType(RestApiMetadata.class
.cast(apiMetadata)));
.cast(apiMetadata)));
} catch (IllegalArgumentException e) {
}
}
}
static Iterable<Module> ifSpecifiedByUserDontIncludeDefaultRestModule(ApiMetadata apiMetadata,
static Iterable<Module> ifSpecifiedByUserDontIncludeDefaultApiModule(ApiMetadata apiMetadata,
boolean restModuleSpecifiedByUser) {
Iterable<Module> defaultModules = transform(apiMetadata.getDefaultModules(),
new Function<Class<? extends Module>, Module>() {
@ -443,7 +458,7 @@ public class ContextBuilder {
});
if (restModuleSpecifiedByUser)
defaultModules = filter(defaultModules, not(configuresRest));
defaultModules = filter(defaultModules, and(not(configuresApi), not(configuresRest)));
return defaultModules;
}
@ -476,30 +491,40 @@ public class ContextBuilder {
@VisibleForTesting
static void addClientModuleIfNotPresent(ApiMetadata apiMetadata, List<Module> modules) {
if (!restClientModulePresent(modules)) {
if (!apiModulePresent(modules)) {
addClientModule(apiMetadata, modules);
}
}
private static boolean apiModulePresent(List<Module> modules) {
return any(modules, or(configuresApi, configuresRest));
}
static Predicate<Module> configuresRest = new Predicate<Module>() {
private static Predicate<Module> configuresApi = new Predicate<Module>() {
public boolean apply(Module input) {
return input.getClass().isAnnotationPresent(ConfiguresHttpApi.class);
}
};
private static Predicate<Module> configuresRest = new Predicate<Module>() {
public boolean apply(Module input) {
return input.getClass().isAnnotationPresent(ConfiguresRestClient.class);
}
};
static boolean restClientModulePresent(List<Module> modules) {
return any(modules, configuresRest);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
static void addClientModule(ApiMetadata apiMetadata, List<Module> modules) {
// TODO: move this up
if (apiMetadata instanceof RestApiMetadata) {
if (apiMetadata instanceof HttpApiMetadata) {
HttpApiMetadata api = HttpApiMetadata.class.cast(apiMetadata);
modules.add(new HttpApiModule(api.getApi()));
} else if (apiMetadata instanceof RestApiMetadata) {
RestApiMetadata rest = RestApiMetadata.class.cast(apiMetadata);
modules.add(new RestClientModule(typeToken(rest.getApi()), typeToken(rest.getAsyncApi())));
} else {
modules.add(new RestModule());
modules.add(new MappedHttpInvocationModule());
}
}

View File

@ -0,0 +1,70 @@
/**
* 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.config;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.reflect.Reflection2.typeToken;
import org.jclouds.rest.ApiContext;
import org.jclouds.rest.HttpApiMetadata;
import org.jclouds.rest.internal.ApiContextImpl;
import org.jclouds.rest.internal.BaseHttpApiMetadata;
import com.google.common.reflect.TypeToken;
import com.google.inject.AbstractModule;
import com.google.inject.TypeLiteral;
import com.google.inject.util.Types;
/**
* Allows you to lookup the {@link HttpApiMetadata#getContext()} as
* {@link ApiContext}, {@code ApiContext<Api>}, and {@code ApiContext<?>}.
*
* @author Adrian Cole
*/
public class BindApiContextWithWildcardExtendsExplicitAndRawType extends AbstractModule {
private final HttpApiMetadata<?> httpApiMetadata;
public BindApiContextWithWildcardExtendsExplicitAndRawType(HttpApiMetadata<?> httpApiMetadata)
throws IllegalArgumentException {
this.httpApiMetadata = checkNotNull(httpApiMetadata, "httpApiMetadata");
checkArgument(httpApiMetadata.getContext().getRawType().equals(ApiContext.class),
"this does not work as %s raw type is not ApiContext", httpApiMetadata.getContext());
}
@SuppressWarnings("unchecked")
@Override
protected void configure() {
TypeToken<?> concreteType = BaseHttpApiMetadata.contextToken(typeToken(httpApiMetadata.getApi()));
// bind explicit type
bind(TypeLiteral.get(concreteType.getType())).to(
TypeLiteral.class.cast(TypeLiteral.get(Types.newParameterizedType(ApiContextImpl.class,
httpApiMetadata.getApi()))));
// bind potentially wildcard type
if (!concreteType.equals(httpApiMetadata.getContext())) {
bind(TypeLiteral.get(httpApiMetadata.getContext().getType())).to(
TypeLiteral.class.cast(TypeLiteral.get(Types.newParameterizedType(ApiContextImpl.class,
httpApiMetadata.getApi()))));
}
// bind w/o types
bind(TypeLiteral.get(ApiContext.class)).to(
TypeLiteral.class.cast(TypeLiteral.get(Types.newParameterizedType(ApiContextImpl.class,
httpApiMetadata.getApi()))));
}
}

View File

@ -35,7 +35,10 @@ import com.google.inject.util.Types;
* Allows you to lookup the {@link RestApiMetadata#getContext()} as {@link RestContext}, {@code RestContext<Client, AsyncClient>}, and {@code
*
* @author Adrian Cole
* @deprecated please use {@link BindApiContextWithWildcardExtendsExplicitAndRawType} as
* async interface will be removed in jclouds 1.7.
*/
@Deprecated
public class BindRestContextWithWildcardExtendsExplicitAndRawType extends AbstractModule {
private final RestApiMetadata restApiMetadata;

View File

@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.apis.ApiMetadata;
import org.jclouds.providers.internal.BaseProviderMetadata;
import org.jclouds.rest.AnonymousHttpApiMetadata;
import org.jclouds.rest.AnonymousRestApiMetadata;
/**
@ -31,11 +32,14 @@ import org.jclouds.rest.AnonymousRestApiMetadata;
*/
public class AnonymousProviderMetadata extends BaseProviderMetadata {
public static <A> ProviderMetadata forApiOnEndpoint(Class<A> api, String endpoint) {
return forApiWithEndpoint(AnonymousHttpApiMetadata.forApi(api), endpoint);
}
public static ProviderMetadata forClientMappedToAsyncClientOnEndpoint(Class<?> client, Class<?> asyncClient,
String endpoint) {
return forApiWithEndpoint(AnonymousRestApiMetadata.forClientMappedToAsyncClient(client, asyncClient), endpoint);
}
public static ProviderMetadata forApiWithEndpoint(ApiMetadata md, String endpoint) {
checkNotNull(md, "api");
checkNotNull(endpoint, "endpoint (%s)", md.getEndpointName());

View File

@ -0,0 +1,45 @@
/**
* 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.reflect;
import static com.google.common.base.Preconditions.checkState;
import java.lang.reflect.TypeVariable;
import com.google.common.annotations.Beta;
import com.google.common.reflect.TypeToken;
/**
* @since 1.7
*/
@Beta
public class Types2 {
/**
* Helpful when you are capturing the type inside a constructor.
*
* @throws IllegalStateException
* if the type is an instanceof {@link TypeVariable}
*/
public static <T> TypeToken<T> checkBound(TypeToken<T> type) throws IllegalStateException {
checkState(!(type.getType() instanceof TypeVariable<?>),
"unbound type variable: %s, use ctor that explicitly assigns this", type);
return type;
}
}

View File

@ -0,0 +1,69 @@
/**
* 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.rest;
import java.net.URI;
import org.jclouds.rest.internal.BaseHttpApiMetadata;
import com.google.common.annotations.Beta;
/**
* Useful in creating arbitrary http apis.
*
* @author Adrian Cole
*/
@Beta
public class AnonymousHttpApiMetadata<A> extends BaseHttpApiMetadata<A> {
public static <A> AnonymousHttpApiMetadata<A> forApi(Class<A> httpApi) {
return new Builder<A>(httpApi).build();
}
@Override
public Builder<A> toBuilder() {
return new Builder<A>(getApi()).fromApiMetadata(this);
}
private AnonymousHttpApiMetadata(Builder<A> builder) {
super(builder);
}
private static final class Builder<A> extends BaseHttpApiMetadata.Builder<A, Builder<A>> {
private Builder(Class<A> api) {
super(api);
id(api.getSimpleName())
.identityName("unused")
.defaultIdentity("foo")
.version("1")
.documentation(URI.create("http://jclouds.org/documentation"));
}
@Override
public AnonymousHttpApiMetadata<A> build() {
return new AnonymousHttpApiMetadata<A>(this);
}
@Override
protected Builder<A> self() {
return this;
}
}
}

View File

@ -20,6 +20,7 @@ package org.jclouds.rest;
import java.net.URI;
import org.jclouds.rest.internal.BaseHttpApiMetadata;
import org.jclouds.rest.internal.BaseRestApiMetadata;
import com.google.common.annotations.Beta;
@ -28,6 +29,8 @@ import com.google.common.annotations.Beta;
* Useful in creating arbitrary clients.
*
* @author Adrian Cole
* @deprecated please use {@link AnonymousHttpApiMetadata} as
* async interface will be removed in jclouds 1.7.
*/
@Beta
public class AnonymousRestApiMetadata extends BaseRestApiMetadata {

View File

@ -0,0 +1,45 @@
/**
* 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.rest;
import org.jclouds.Context;
import org.jclouds.rest.internal.ApiContextImpl;
import com.google.inject.ImplementedBy;
/**
* Represents an authenticated context to the cloud.
*
* <h2>Note</h2> Please issue {@link #close()} when you are finished with this context in order to
* release resources.
*
*
* @author Adrian Cole
*/
@ImplementedBy(ApiContextImpl.class)
public interface ApiContext<A> extends Context {
/**
* low-level api to the cloud. Threadsafe implementations will return a singleton.
*
* @return a connection to the cloud where all methods block
*/
A getApi();
}

View File

@ -25,13 +25,13 @@ import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* designates the module configures a Client to a cloud.
* designates the module configures a top-level api which is annotated with http methods.
*
* @author Adrian Cole
*
*/
@Retention(RUNTIME)
@Target(TYPE)
public @interface ConfiguresRestContext {
public @interface ConfiguresHttpApi {
}

View File

@ -0,0 +1,47 @@
/**
* 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.rest;
import org.jclouds.apis.ApiMetadata;
import com.google.common.annotations.Beta;
/**
*
* @author Adrian Cole
* @since 1.6
* @see ConfiguresHttpApi
*/
@Beta
public interface HttpApiMetadata<A> extends ApiMetadata {
public static interface Builder<A, T extends Builder<A, T>> extends ApiMetadata.Builder<T> {
/**
* @see ApiMetadata#getApi()
*/
T javaApi(Class<A> api);
}
/**
*
* @return the type of the api which has http annotations on its methods.
*/
Class<A> getApi();
}

View File

@ -43,7 +43,10 @@ import com.google.common.util.concurrent.ListenableFuture;
* Simple rest client
*
* @author Adrian Cole
* @deprecated will be removed in jclouds 1.7, as async interfaces are no longer
* supported.
*/
@Deprecated
public interface HttpAsyncClient {
/**
* @see HttpClient#put

View File

@ -21,9 +21,21 @@ package org.jclouds.rest;
import java.io.InputStream;
import java.net.URI;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ParseETagHeader;
import org.jclouds.io.Payload;
import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.ResponseParser;
/**
* Simple client
@ -31,6 +43,34 @@ import org.jclouds.io.Payload;
* @author Adrian Cole
*/
public interface HttpClient {
/**
* @return eTag
*/
@PUT
@ResponseParser(ParseETagHeader.class)
String put(@EndpointParam URI location, Payload payload);
/**
* @return eTag
*/
@POST
@ResponseParser(ParseETagHeader.class)
String post(@EndpointParam URI location, Payload payload);
/**
* @see HttpClient#exists
*/
@HEAD
@Fallback(FalseOnNotFoundOr404.class)
boolean exists(@EndpointParam URI location);
/**
* @return null if the resource didn't exist.
*/
@GET
@Fallback(NullOnNotFoundOr404.class)
InputStream get(@EndpointParam URI location);
/**
*
* @param request
@ -38,25 +78,11 @@ public interface HttpClient {
*/
HttpResponse invoke(HttpRequest request);
/**
* @return eTag
*/
String put(URI location, Payload payload);
/**
* @return eTag
*/
String post(URI location, Payload payload);
boolean exists(URI location);
/**
* @return null if the resource didn't exist.
*/
InputStream get(URI location);
/**
* @return false if the resource didn't exist.
*/
boolean delete(URI location);
@DELETE
@Fallback(FalseOnNotFoundOr404.class)
boolean delete(@EndpointParam URI location);
}

View File

@ -21,12 +21,17 @@ package org.jclouds.rest;
import org.jclouds.apis.ApiMetadata;
import com.google.common.annotations.Beta;
import com.google.common.util.concurrent.ListenableFuture;
/**
*
* @author Adrian Cole
* @since 1.5
*
* @deprecated please use {@link HttpApiMetadata} as
* async interface will be removed in jclouds 1.7.
*/
@Deprecated
@Beta
public interface RestApiMetadata extends ApiMetadata {

View File

@ -75,11 +75,22 @@ public interface Utils {
*/
Json json();
/**
*
* @deprecated will be removed in jclouds 1.7, as async interfaces are no
* longer supported.
* @see #getHttpClient()
*/
@Deprecated
HttpAsyncClient getHttpAsyncClient();
/**
* #see #getHttpAsyncClient
*
* @deprecated will be removed in jclouds 1.7, as async interfaces are no
* longer supported.
* @see #http()
*/
@Deprecated
HttpAsyncClient asyncHttp();
HttpClient getHttpClient();

View File

@ -28,27 +28,26 @@ import org.jclouds.rest.internal.DelegatesToInvocationFunction;
import com.google.common.base.Function;
import com.google.inject.Provider;
import com.google.inject.TypeLiteral;
/**
*
* @author Adrian Cole
*/
@Singleton
public class AsyncHttpApiProvider<A> implements Provider<A> {
private final Class<? super A> asyncApiType;
public class AnnotatedHttpApiProvider<A> implements Provider<A> {
private final Class<A> annotatedApiType;
private final DelegatesToInvocationFunction<A, Function<Invocation, Object>> httpInvoker;
@Inject
private AsyncHttpApiProvider(DelegatesToInvocationFunction<A, Function<Invocation, Object>> httpInvoker,
TypeLiteral<A> asyncApiType) {
private AnnotatedHttpApiProvider(DelegatesToInvocationFunction<A, Function<Invocation, Object>> httpInvoker,
Class<A> annotatedApiType) {
this.httpInvoker = httpInvoker;
this.asyncApiType = asyncApiType.getRawType();
this.annotatedApiType = annotatedApiType;
}
@SuppressWarnings("unchecked")
@Override
public A get() {
return (A) Proxy.newProxyInstance(asyncApiType.getClassLoader(), new Class<?>[] { asyncApiType }, httpInvoker);
return (A) Proxy.newProxyInstance(annotatedApiType.getClassLoader(), new Class<?>[] { annotatedApiType }, httpInvoker);
}
}

View File

@ -0,0 +1,60 @@
/**
* 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.rest.config;
import java.lang.reflect.Proxy;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.reflect.Invocation;
import org.jclouds.rest.internal.DelegatesToInvocationFunction;
import org.jclouds.rest.internal.DelegatesToPotentiallyMappedInvocationFunction;
import com.google.common.base.Function;
import com.google.inject.Provider;
import com.google.inject.TypeLiteral;
/**
*
* @author Adrian Cole
* @deprecated please use {@link DelegatesToInvocationFunction} as async
* interface will be removed in jclouds 1.7.
*/
@Deprecated
@Singleton
public class AnnotatedMappedHttpApiProvider<A> implements Provider<A> {
private final Class<? super A> annotatedApiType;
private final DelegatesToPotentiallyMappedInvocationFunction<A, Function<Invocation, Object>> httpInvoker;
@Inject
private AnnotatedMappedHttpApiProvider(
DelegatesToPotentiallyMappedInvocationFunction<A, Function<Invocation, Object>> httpInvoker,
TypeLiteral<A> annotatedApiType) {
this.httpInvoker = httpInvoker;
this.annotatedApiType = annotatedApiType.getRawType();
}
@SuppressWarnings("unchecked")
@Override
public A get() {
return (A) Proxy.newProxyInstance(annotatedApiType.getClassLoader(), new Class<?>[] { annotatedApiType },
httpInvoker);
}
}

View File

@ -31,7 +31,33 @@ import com.google.inject.TypeLiteral;
public class BinderUtils {
/**
* adds an explicit binding for {@code async} by parsing its annotations. Then. adds an explicit binding for an
* adds an explicit binding for {@code async} by parsing its annotations.
*
* @param <S>
* sync interface that blocks
* @param <A>
* api type with http annotations
* @param binder
* guice binder
* @param api
* type with http annotations
*/
public static <S, A> void bindHttpApi(Binder binder, Class<A> api) {
bindClass(binder, api);
bindAnnotatedHttpApiProvider(binder, api);
}
@SuppressWarnings("unchecked")
private static <T> void bindAnnotatedHttpApiProvider(Binder binder, Class<T> annotated) {
TypeToken<AnnotatedHttpApiProvider<T>> token = new TypeToken<AnnotatedHttpApiProvider<T>>() {
private static final long serialVersionUID = 1L;
}.where(new TypeParameter<T>() {
}, annotated);
binder.bind(annotated).toProvider(TypeLiteral.class.cast(TypeLiteral.get(token.getType())));
}
/**
* adds an explicit binding for {@code async} by parsing its annotations. Then, adds an explicit binding for an
* interface which synchronously blocks on similar calls to an {@code async} type.
*
* @param <S>
@ -44,52 +70,79 @@ public class BinderUtils {
* type interface that blocks
* @param async
* type type that returns {@link ListenableFuture}
*
* @deprecated will be removed in jclouds 1.7, as async interfaces are no
* longer supported.
*/
public static <S, A> void bindHttpApi(Binder binder, Class<S> sync, Class<A> async) {
@Deprecated
public static <S, A> void bindMappedHttpApi(Binder binder, Class<S> sync, Class<A> async) {
bindClass(binder, sync);
bindClass(binder, async);
bindAsyncHttpApiProvider(binder, async);
bindAnnotatedMappedHttpApiProvider(binder, async);
bindHttpApiProvider(binder, sync, async);
}
/**
* @deprecated will be removed in jclouds 1.7, as async interfaces are no
* longer supported.
*/
@Deprecated
@SuppressWarnings("unchecked")
private static <T> void bindAsyncHttpApiProvider(Binder binder, Class<T> async) {
TypeToken<AsyncHttpApiProvider<T>> token = new TypeToken<AsyncHttpApiProvider<T>>() {
private static <T> void bindAnnotatedMappedHttpApiProvider(Binder binder, Class<T> annotated) {
TypeToken<AnnotatedMappedHttpApiProvider<T>> token = new TypeToken<AnnotatedMappedHttpApiProvider<T>>() {
private static final long serialVersionUID = 1L;
}.where(new TypeParameter<T>() {
}, async);
binder.bind(async).toProvider(TypeLiteral.class.cast(TypeLiteral.get(token.getType())));
}, annotated);
binder.bind(annotated).toProvider(TypeLiteral.class.cast(TypeLiteral.get(token.getType())));
}
/**
*
* @deprecated will be removed in jclouds 1.7, as async interfaces are no
* longer supported.
*/
@Deprecated
@SuppressWarnings("unchecked")
private static <S, A> void bindHttpApiProvider(Binder binder, Class<S> sync, Class<A> async) {
TypeToken<HttpApiProvider<S, A>> token = new TypeToken<HttpApiProvider<S, A>>() {
TypeToken<MappedHttpApiProvider<S, A>> token = new TypeToken<MappedHttpApiProvider<S, A>>() {
private static final long serialVersionUID = 1L;
}.where(new TypeParameter<S>() {
}, sync).where(new TypeParameter<A>() {
}, async);
binder.bind(sync).toProvider(TypeLiteral.class.cast(TypeLiteral.get(token.getType())));
}
/**
* adds an explicit binding for an interface which synchronously blocks on similar calls to an {@code async} type.
* adds an explicit binding for an interface which synchronously blocks on
* similar calls to an {@code async} type.
*
* @param <S>
* sync interface that blocks
* @param <A>
* async type where all methods have same args as {@code sync}, but returns {@link ListenableFuture}
* async type where all methods have same args as {@code sync}, but
* returns {@link ListenableFuture}
* @param binder
* guice binder
* @param sync
* type interface that blocks
* @param async
* type type that returns {@link ListenableFuture}
*
* @deprecated will be removed in jclouds 1.7, as async interfaces are no
* longer supported.
*/
public static <S, A> void bindBlockingApi(Binder binder, Class<S> sync, Class<A> async) {
@Deprecated
public static <S, A> void bindMappedApi(Binder binder, Class<S> sync, Class<A> async) {
bindClass(binder, sync);
bindClass(binder, async);
bindCallGetOnFutures(binder, sync, async);
}
/**
* @deprecated will be removed in jclouds 1.7, as async interfaces are no
* longer supported.
*/
@Deprecated
@SuppressWarnings("unchecked")
private static <S, A> void bindCallGetOnFutures(Binder binder, Class<S> sync, Class<A> async) {
TypeToken<CallGetOnFuturesProvider<S, A>> token = new TypeToken<CallGetOnFuturesProvider<S, A>>() {

View File

@ -24,7 +24,7 @@ import java.lang.reflect.Proxy;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.rest.internal.DelegatesToInvocationFunction;
import org.jclouds.rest.internal.DelegatesToPotentiallyMappedInvocationFunction;
import org.jclouds.rest.internal.InvokeAndCallGetOnFutures;
import com.google.common.cache.Cache;
@ -33,20 +33,22 @@ import com.google.inject.Provider;
/**
* @author Adrian Cole
* @deprecated will be removed in jclouds 1.7, as async interfaces are no longer supported.
*/
@Deprecated
@Singleton
public class CallGetOnFuturesProvider<S, A> implements Provider<S> {
private final Class<? super S> apiType;
private final DelegatesToInvocationFunction<S, InvokeAndCallGetOnFutures<A>> syncInvoker;
private final DelegatesToPotentiallyMappedInvocationFunction<S, InvokeAndCallGetOnFutures<A>> syncInvoker;
@Inject
private CallGetOnFuturesProvider(Cache<Invokable<?, ?>, Invokable<?, ?>> invokables,
DelegatesToInvocationFunction<S, InvokeAndCallGetOnFutures<A>> syncInvoker, Class<S> apiType,
DelegatesToPotentiallyMappedInvocationFunction<S, InvokeAndCallGetOnFutures<A>> syncInvoker, Class<S> apiType,
Class<A> asyncApiType) {
this.syncInvoker = syncInvoker;
this.apiType = apiType;
RestModule.putInvokables(apiType, asyncApiType, invokables);
MappedHttpInvocationModule.putInvokables(apiType, asyncApiType, invokables);
}
@SuppressWarnings("unchecked")

View File

@ -0,0 +1,102 @@
/**
* 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.rest.config;
import static org.jclouds.reflect.Types2.checkBound;
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
import org.jclouds.reflect.Invocation;
import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.rest.HttpAsyncClient;
import org.jclouds.rest.HttpClient;
import org.jclouds.rest.internal.InvokeHttpMethod;
import com.google.common.base.Function;
import com.google.common.reflect.TypeToken;
import com.google.inject.TypeLiteral;
/**
*
* @author Adrian Cole
*/
@ConfiguresHttpApi
public class HttpApiModule<A> extends RestModule {
protected final Class<A> api;
/**
* Note that this ctor requires that you instantiate w/resolved generic
* params. For example, via a subclass of a bound type, or natural
* instantiation w/resolved type params.
*/
@SuppressWarnings("unchecked")
protected HttpApiModule() {
this.api = Class.class.cast(checkBound(new TypeToken<A>(getClass()) {
private static final long serialVersionUID = 1L;
}).getRawType());
}
public HttpApiModule(Class<A> api) {
this.api = api;
}
@Override
protected void configure() {
super.configure();
bind(new TypeLiteral<Function<Invocation, Object>>() {
}).to(InvokeHttpMethod.class);
bindHttpApi(binder(), api);
bindHttpApi(binder(), HttpClient.class);
// TODO: remove when references are gone
bindHttpApi(binder(), HttpAsyncClient.class);
bindErrorHandlers();
bindRetryHandlers();
}
/**
* overrides this to change the default retry handlers for the http engine
*
* ex.
*
* <pre>
* bind(HttpRetryHandler.class).annotatedWith(Redirection.class).to(AWSRedirectionRetryHandler.class);
* bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(AWSClientErrorRetryHandler.class);
* </pre>
*
*/
protected void bindRetryHandlers() {
}
/**
* overrides this to change the default error handlers for the http engine
*
* ex.
*
* <pre>
* 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);
* </pre>
*
*
*/
protected void bindErrorHandlers() {
}
}

View File

@ -25,7 +25,7 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.reflect.Invocation;
import org.jclouds.rest.internal.DelegatesToInvocationFunction;
import org.jclouds.rest.internal.DelegatesToPotentiallyMappedInvocationFunction;
import com.google.common.base.Function;
import com.google.common.cache.Cache;
@ -35,18 +35,20 @@ import com.google.inject.Provider;
/**
*
* @author Adrian Cole
* @deprecated will be removed in jclouds 1.7; use {@link AnnotatedHttpApiProvider}
*/
@Deprecated
@Singleton
public class HttpApiProvider<S, A> implements Provider<S> {
public class MappedHttpApiProvider<S, A> implements Provider<S> {
private final Class<? super S> apiType;
private final DelegatesToInvocationFunction<S, Function<Invocation, Object>> httpInvoker;
private final DelegatesToPotentiallyMappedInvocationFunction<S, Function<Invocation, Object>> httpInvoker;
@Inject
private HttpApiProvider(Cache<Invokable<?, ?>, Invokable<?, ?>> invokables,
DelegatesToInvocationFunction<S, Function<Invocation, Object>> httpInvoker, Class<S> apiType, Class<A> asyncApiType) {
private MappedHttpApiProvider(Cache<Invokable<?, ?>, Invokable<?, ?>> invokables,
DelegatesToPotentiallyMappedInvocationFunction<S, Function<Invocation, Object>> httpInvoker, Class<S> apiType, Class<A> asyncApiType) {
this.httpInvoker = httpInvoker;
this.apiType = apiType;
RestModule.putInvokables(apiType, asyncApiType, invokables);
MappedHttpInvocationModule.putInvokables(apiType, asyncApiType, invokables);
}
@SuppressWarnings("unchecked")

View File

@ -0,0 +1,150 @@
/**
* 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.rest.config;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.toArray;
import static com.google.common.collect.Iterables.transform;
import static org.jclouds.reflect.Reflection2.method;
import static org.jclouds.reflect.Reflection2.methods;
import java.io.Closeable;
import java.util.Map;
import javax.inject.Singleton;
import org.jclouds.reflect.Invocation;
import org.jclouds.rest.HttpAsyncClient;
import org.jclouds.rest.HttpClient;
import org.jclouds.rest.internal.DelegatesToInvocationFunction;
import org.jclouds.rest.internal.DelegatesToPotentiallyMappedInvocationFunction;
import org.jclouds.rest.internal.InvokeAndCallGetOnFutures;
import org.jclouds.rest.internal.InvokeMappedHttpMethod;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.Invokable;
import com.google.common.reflect.Parameter;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.TypeLiteral;
/**
* supports sync-async mapping
*
* @deprecated will be removed in jclouds 1.7; use {@link HttpApiModule}
*/
@Deprecated
public class MappedHttpInvocationModule extends AbstractModule {
protected final Map<Class<?>, Class<?>> sync2Async;
public MappedHttpInvocationModule() {
this(ImmutableMap.<Class<?>, Class<?>> of());
}
public MappedHttpInvocationModule(Map<Class<?>, Class<?>> sync2Async) {
this.sync2Async = sync2Async;
}
@Override
protected void configure() {
bind(new TypeLiteral<Map<Class<?>, Class<?>>>() {
}).toInstance(sync2Async);
bind(new TypeLiteral<Function<Invocation, Object>>() {
}).to(InvokeMappedHttpMethod.class);
org.jclouds.rest.config.BinderUtils.bindMappedHttpApi(binder(), HttpClient.class, HttpAsyncClient.class);
}
/**
* seeds well-known invokables.
*/
@Provides
@Singleton
protected Cache<Invokable<?, ?>, Invokable<?, ?>> seedKnownSync2AsyncInvokables() {
return seedKnownSync2AsyncInvokables(sync2Async);
}
/**
* function view of above
*
* @see InvokeAndCallGetOnFutures
* @see InvokeMappedHttpMethod
*/
@Provides
@Singleton
protected Function<Invocation, Invocation> sync2async(final Cache<Invokable<?, ?>, Invokable<?, ?>> cache) {
return new Function<Invocation, Invocation>() {
public Invocation apply(Invocation in) {
return Invocation.create(
checkNotNull(cache.getIfPresent(in.getInvokable()), "invokable %s not in %s", in.getInvokable(),
cache), in.getArgs());
}
};
}
@VisibleForTesting
static Cache<Invokable<?, ?>, Invokable<?, ?>> seedKnownSync2AsyncInvokables(Map<Class<?>, Class<?>> sync2Async) {
Cache<Invokable<?, ?>, Invokable<?, ?>> sync2AsyncBuilder = CacheBuilder.newBuilder().build();
putInvokables(HttpClient.class, HttpAsyncClient.class, sync2AsyncBuilder);
for (Map.Entry<Class<?>, Class<?>> entry : sync2Async.entrySet()) {
putInvokables(entry.getKey(), entry.getValue(), sync2AsyncBuilder);
}
return sync2AsyncBuilder;
}
// accessible for ClientProvider
public static void putInvokables(Class<?> sync, Class<?> async, Cache<Invokable<?, ?>, Invokable<?, ?>> cache) {
for (Invokable<?, ?> invoked : methods(sync)) {
Invokable<?, ?> delegatedMethod = method(async, invoked.getName(), getParameterTypes(invoked));
checkArgument(delegatedMethod.getExceptionTypes().equals(invoked.getExceptionTypes())
|| isCloseable(delegatedMethod), "invoked %s has different typed exceptions than target %s", invoked,
delegatedMethod);
cache.put(invoked, delegatedMethod);
}
}
/**
* In JDK7 Closeable.close is declared in AutoCloseable, which throws
* Exception vs IOException, so we have to be more lenient about exception
* type declarations.
*
* <h4>note</h4>
*
* This will be refactored out when we delete Async code in jclouds 1.7.
*/
private static boolean isCloseable(Invokable<?, ?> delegatedMethod) {
return "close".equals(delegatedMethod.getName())
&& Closeable.class.isAssignableFrom(delegatedMethod.getDeclaringClass());
}
/**
* for portability with {@link Class#getMethod(String, Class...)}
*/
private static Class<?>[] getParameterTypes(Invokable<?, ?> in) {
return toArray(transform(checkNotNull(in, "invokable").getParameters(), new Function<Parameter, Class<?>>() {
public Class<?> apply(Parameter input) {
return input.getType().getRawType();
}
}), Class.class);
}
}

View File

@ -18,10 +18,9 @@
*/
package org.jclouds.rest.config;
import static com.google.common.base.Preconditions.checkState;
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
import static org.jclouds.reflect.Types2.checkBound;
import static org.jclouds.rest.config.BinderUtils.bindMappedHttpApi;
import java.lang.reflect.TypeVariable;
import java.util.Map;
import org.jclouds.rest.ConfiguresRestClient;
@ -32,18 +31,23 @@ import com.google.common.reflect.TypeToken;
/**
*
* @author Adrian Cole
*
* @deprecated will be removed in jclouds 1.7; use {@link HttpApiModule}
*/
@Deprecated
@ConfiguresRestClient
public class RestClientModule<S, A> extends RestModule {
protected final TypeToken<S> syncClientType;
protected final TypeToken<A> asyncClientType;
private final MappedHttpInvocationModule invocationModule;
/**
* Note that this ctor requires that you instantiate w/resolved generic params. For example, via
* a subclass of a bound type, or natural instantiation w/resolved type params.
*/
protected RestClientModule(Map<Class<?>, Class<?>> sync2Async) {
super(sync2Async);
this.invocationModule = new MappedHttpInvocationModule(sync2Async);
this.syncClientType = checkBound(new TypeToken<S>(getClass()) {
private static final long serialVersionUID = 1L;
});
@ -51,15 +55,6 @@ public class RestClientModule<S, A> extends RestModule {
private static final long serialVersionUID = 1L;
});
}
/**
* @throws IllegalStateException if the type is an instanceof {@link TypeVariable}
*/
private static <T> TypeToken<T> checkBound(TypeToken<T> type) throws IllegalStateException {
checkState(!(type.getType() instanceof TypeVariable<?>),
"unbound type variable: %s, use ctor that explicitly assigns this", type);
return type;
}
/**
* @see #RestClientModule(Map)
@ -79,7 +74,7 @@ public class RestClientModule<S, A> extends RestModule {
* only necessary when type params are not resolvable at runtime.
*/
public RestClientModule(TypeToken<S> syncClientType, TypeToken<A> asyncClientType, Map<Class<?>, Class<?>> sync2Async) {
super(sync2Async);
this.invocationModule = new MappedHttpInvocationModule(sync2Async);
this.syncClientType = checkBound(syncClientType);
this.asyncClientType = checkBound(asyncClientType);
}
@ -87,7 +82,8 @@ public class RestClientModule<S, A> extends RestModule {
@Override
protected void configure() {
super.configure();
bindHttpApi(binder(), syncClientType.getRawType(), asyncClientType.getRawType());
install(invocationModule);
bindMappedHttpApi(binder(), syncClientType.getRawType(), asyncClientType.getRawType());
bindErrorHandlers();
bindRetryHandlers();
}

Some files were not shown because too many files have changed in this diff Show More